[python-astropy] 01/03: New upstream release candidate 1.0rc1

Ole Streicher olebole-guest at moszumanska.debian.org
Fri Jan 30 08:24:17 UTC 2015


This is an automated email from the git hooks/post-receive script.

olebole-guest pushed a commit to branch debian
in repository python-astropy.

commit 08d784fb2c01046f5d348218e9677ae5ee23c170
Author: Ole Streicher <debian at liska.ath.cx>
Date:   Wed Jan 28 09:20:05 2015 +0100

    New upstream release candidate 1.0rc1
---
 CHANGES.rst                                        |   611 +-
 PKG-INFO                                           |     4 +-
 README.rst                                         |    16 +-
 ah_bootstrap.py                                    |  1005 +-
 astropy/__init__.py                                |    67 +-
 astropy/_erfa/__init__.py                          |     7 +
 astropy/_erfa/core.c                               | 39585 +++++++++++++++++++
 astropy/_erfa/core.py                              | 23230 +++++++++++
 astropy/_erfa/core.py.templ                        |   250 +
 astropy/_erfa/core.pyx                             |  3961 ++
 astropy/_erfa/core.pyx.templ                       |    91 +
 astropy/_erfa/erfa_generator.py                    |   468 +
 astropy/_erfa/setup_package.py                     |   108 +
 astropy/_erfa/tests/__init__.py                    |     1 +
 astropy/_erfa/tests/test_erfa.py                   |   169 +
 astropy/analytic_functions/__init__.py             |    10 +
 astropy/analytic_functions/blackbody.py            |   107 +
 astropy/analytic_functions/tests/__init__.py       |     0
 astropy/analytic_functions/tests/test_blackbody.py |    97 +
 astropy/config/tests/test_configs.py               |     6 +-
 astropy/conftest.py                                |     9 +-
 astropy/constants/tests/test_pickle.py             |    17 +
 astropy/convolution/boundary_extend.c              |   360 +-
 astropy/convolution/boundary_fill.c                |   360 +-
 astropy/convolution/boundary_none.c                |   360 +-
 astropy/convolution/boundary_wrap.c                |   360 +-
 astropy/convolution/convolve.py                    |    10 +-
 astropy/convolution/kernels.py                     |     6 +-
 astropy/convolution/tests/test_discretize.py       |    49 +
 astropy/convolution/tests/test_pickle.py           |    24 +
 astropy/convolution/utils.py                       |    43 +-
 astropy/coordinates/__init__.py                    |     1 +
 astropy/coordinates/angle_utilities.py             |    50 +-
 astropy/coordinates/angles.py                      |    33 +-
 astropy/coordinates/baseframe.py                   |   461 +-
 astropy/coordinates/builtin_frames.py              |   629 -
 astropy/coordinates/builtin_frames/__init__.py     |    85 +
 astropy/coordinates/builtin_frames/altaz.py        |   111 +
 astropy/coordinates/builtin_frames/cirs.py         |    47 +
 .../builtin_frames/cirs_observed_transforms.py     |   108 +
 astropy/coordinates/builtin_frames/fk4.py          |   243 +
 .../builtin_frames/fk4_fk5_transforms.py           |    67 +
 astropy/coordinates/builtin_frames/fk5.py          |    70 +
 astropy/coordinates/builtin_frames/galactic.py     |    63 +
 .../builtin_frames/galactic_transforms.py          |    46 +
 .../coordinates/builtin_frames/galactocentric.py   |   209 +
 astropy/coordinates/builtin_frames/gcrs.py         |    73 +
 astropy/coordinates/builtin_frames/icrs.py         |    45 +
 .../builtin_frames/icrs_cirs_transforms.py         |   168 +
 .../builtin_frames/icrs_fk5_transforms.py          |    46 +
 .../intermediate_rotation_transforms.py            |   128 +
 astropy/coordinates/builtin_frames/itrs.py         |    39 +
 astropy/coordinates/builtin_frames/utils.py        |    80 +
 astropy/coordinates/distances.py                   |   260 +-
 astropy/coordinates/earth.py                       |    48 +-
 astropy/coordinates/earth_orientation.py           |    14 +-
 astropy/coordinates/errors.py                      |     2 +-
 astropy/coordinates/funcs.py                       |   183 +
 astropy/coordinates/matching.py                    |   313 +-
 astropy/coordinates/representation.py              |    25 +-
 astropy/coordinates/sky_coordinate.py              |   525 +-
 .../coordinates/tests/accuracy/test_altaz_icrs.py  |   159 +
 astropy/coordinates/tests/test_angles.py           |    38 +-
 astropy/coordinates/tests/test_api_ape5.py         |     2 +-
 astropy/coordinates/tests/test_arrays.py           |     3 +-
 astropy/coordinates/tests/test_earth.py            |     2 +-
 astropy/coordinates/tests/test_frames.py           |   124 +-
 astropy/coordinates/tests/test_funcs.py            |    51 +
 astropy/coordinates/tests/test_iau_fullstack.py    |   154 +
 astropy/coordinates/tests/test_matching.py         |    26 +-
 astropy/coordinates/tests/test_pickle.py           |    56 +
 astropy/coordinates/tests/test_sky_coord.py        |   391 +-
 astropy/coordinates/tests/test_transformations.py  |   284 +-
 astropy/coordinates/tests/utils.py                 |    27 +
 astropy/coordinates/transformations.py             |    18 +-
 astropy/cosmology/core.py                          |   445 +-
 astropy/cosmology/funcs.py                         |   290 +-
 astropy/cosmology/parameters.py                    |     2 +-
 astropy/cosmology/tests/test_cosmology.py          |   367 +-
 astropy/cosmology/tests/test_pickle.py             |    18 +
 astropy/extern/bundled/six.py                      |   213 +-
 astropy/extern/configobj.py                        |     8 +-
 astropy/extern/configobj/__init__.py               |     0
 astropy/extern/configobj/configobj.py              |  2484 ++
 astropy/extern/configobj/validate.py               |  1472 +
 astropy/extern/configobj_py2/__init__.py           |   100 -
 astropy/extern/configobj_py2/configobj.py          |  2468 --
 astropy/extern/configobj_py2/validate.py           |  1450 -
 astropy/extern/configobj_py3/__init__.py           |   104 -
 astropy/extern/configobj_py3/configobj.py          |  2405 --
 astropy/extern/configobj_py3/validate.py           |  1419 -
 astropy/extern/six.py                              |     2 +-
 astropy/io/ascii/__init__.py                       |    10 +-
 astropy/io/ascii/basic.py                          |   210 +-
 astropy/io/ascii/cds.py                            |    33 +-
 astropy/io/ascii/connect.py                        |    29 +-
 astropy/io/ascii/core.py                           |   268 +-
 astropy/io/ascii/cparser.c                         | 28150 +++++++++++++
 astropy/io/ascii/cparser.pyx                       |  1068 +
 astropy/io/ascii/daophot.py                        |   179 +-
 astropy/io/ascii/ecsv.py                           |   424 +
 astropy/io/ascii/fastbasic.py                      |   304 +
 astropy/io/ascii/fixedwidth.py                     |   110 +-
 astropy/io/ascii/html.py                           |   125 +-
 astropy/io/ascii/ipac.py                           |   431 +-
 astropy/io/ascii/latex.py                          |   168 +-
 astropy/io/ascii/setup_package.py                  |    14 +
 astropy/io/ascii/sextractor.py                     |    96 +-
 astropy/io/ascii/src/tokenizer.c                   |   888 +
 astropy/io/ascii/src/tokenizer.h                   |    97 +
 astropy/io/ascii/tests/t/fixed_width_2_line.txt    |     4 +
 astropy/io/ascii/tests/test_c_reader.py            |   764 +
 astropy/io/ascii/tests/test_compressed.py          |     4 +-
 astropy/io/ascii/tests/test_connect.py             |    15 +-
 astropy/io/ascii/tests/test_ecsv.py                |   176 +
 astropy/io/ascii/tests/test_fixedwidth.py          |    38 +
 astropy/io/ascii/tests/test_html.py                |    72 +-
 astropy/io/ascii/tests/test_ipac_definitions.py    |    29 +-
 astropy/io/ascii/tests/test_read.py                |   228 +-
 astropy/io/ascii/tests/test_write.py               |   145 +-
 astropy/io/ascii/ui.py                             |   192 +-
 astropy/io/fits/card.py                            |    28 +-
 astropy/io/fits/column.py                          |    21 +-
 astropy/io/fits/connect.py                         |     8 +-
 astropy/io/fits/convenience.py                     |     7 +-
 astropy/io/fits/diff.py                            |    46 +-
 astropy/io/fits/file.py                            |    39 +-
 astropy/io/fits/fitsrec.py                         |    15 +-
 astropy/io/fits/hdu/base.py                        |    23 +-
 astropy/io/fits/hdu/compressed.py                  |    21 +-
 astropy/io/fits/hdu/groups.py                      |     8 +-
 astropy/io/fits/hdu/hdulist.py                     |    40 +-
 astropy/io/fits/hdu/image.py                       |   206 +-
 astropy/io/fits/hdu/streaming.py                   |    30 +-
 astropy/io/fits/hdu/table.py                       |    23 +-
 astropy/io/fits/header.py                          |    12 +-
 astropy/io/fits/py3compat.py                       |    72 -
 astropy/io/fits/scripts/__init__.py                |     4 -
 astropy/io/fits/scripts/fitsdiff.py                |    49 +-
 astropy/io/fits/scripts/fitsheader.py              |   330 +-
 astropy/io/fits/tests/test_core.py                 |    24 +-
 astropy/io/fits/tests/test_diff.py                 |    34 +
 astropy/io/fits/tests/test_header.py               |   112 +-
 astropy/io/fits/tests/test_image.py                |   138 +-
 astropy/io/fits/tests/test_uint.py                 |     2 +
 astropy/io/fits/util.py                            |    60 +-
 astropy/io/misc/hdf5.py                            |    13 +-
 astropy/io/misc/pickle_helpers.py                  |     2 -
 astropy/io/misc/tests/test_hdf5.py                 |     4 +
 astropy/io/registry.py                             |     8 +-
 astropy/io/votable/connect.py                      |     7 +
 astropy/io/votable/exceptions.py                   |    12 +-
 astropy/io/votable/setup_package.py                |     2 -
 astropy/io/votable/table.py                        |    27 +-
 astropy/io/votable/tests/data/custom_datatype.xml  |    18 +
 astropy/io/votable/tests/vo_test.py                |    14 +-
 astropy/io/votable/tree.py                         |    13 +-
 astropy/logger.py                                  |    36 +-
 astropy/modeling/__init__.py                       |     1 +
 astropy/modeling/_compound_deprecated.py           |   420 +
 astropy/modeling/core.py                           |  2038 +-
 astropy/modeling/fitting.py                        |    67 +-
 astropy/modeling/functional_models.py              |   610 +-
 astropy/modeling/mappings.py                       |   175 +
 astropy/modeling/models.py                         |     7 +-
 astropy/modeling/optimizers.py                     |     3 +-
 astropy/modeling/parameters.py                     |   103 +-
 astropy/modeling/polynomial.py                     |   421 +-
 astropy/modeling/powerlaws.py                      |    61 +-
 astropy/modeling/projections.py                    |   402 +-
 astropy/modeling/rotations.py                      |   164 +-
 astropy/modeling/tests/example_models.py           |    13 +-
 astropy/modeling/tests/test_compound.py            |   716 +
 astropy/modeling/tests/test_constraints.py         |    48 +-
 astropy/modeling/tests/test_core.py                |   121 +-
 astropy/modeling/tests/test_fitters.py             |    11 +-
 astropy/modeling/tests/test_functional_models.py   |    45 +-
 astropy/modeling/tests/test_input.py               |   102 +-
 astropy/modeling/tests/test_mappings.py            |    64 +
 astropy/modeling/tests/test_models.py              |   157 +-
 astropy/modeling/tests/test_parameters.py          |   111 +-
 astropy/modeling/tests/test_polynomial.py          |    56 +-
 astropy/modeling/tests/test_projections.py         |    42 +-
 astropy/modeling/tests/test_rotations.py           |     7 +-
 astropy/modeling/tests/test_utils.py               |    68 +
 astropy/modeling/utils.py                          |   234 +-
 astropy/nddata/__init__.py                         |     9 +
 astropy/nddata/compat.py                           |   109 +
 astropy/nddata/decorators.py                       |   162 +
 astropy/nddata/flag_collection.py                  |    12 +-
 astropy/nddata/mixins/__init__.py                  |     0
 astropy/nddata/mixins/ndarithmetic.py              |   224 +
 astropy/nddata/mixins/ndio.py                      |    39 +
 astropy/nddata/mixins/ndslicing.py                 |    39 +
 astropy/nddata/nddata.py                           |   602 +-
 astropy/nddata/nddata_base.py                      |    92 +
 astropy/nddata/nduncertainty.py                    |   135 +-
 astropy/nddata/tests/test_decorators.py            |   182 +
 astropy/nddata/tests/test_flag_collection.py       |    17 +-
 astropy/nddata/tests/test_nddata.py                |   518 +-
 astropy/nddata/tests/test_nddata_base.py           |    60 +
 astropy/nddata/tests/test_utils.py                 |    75 +
 astropy/nddata/utils.py                            |   196 +
 astropy/setup_helpers.py                           |  1535 -
 astropy/sphinx/__init__.py                         |    10 -
 astropy/sphinx/conf.py                             |   311 -
 astropy/sphinx/ext/__init__.py                     |    13 -
 astropy/sphinx/ext/astropyautosummary.py           |    96 -
 astropy/sphinx/ext/automodapi.py                   |   353 -
 astropy/sphinx/ext/automodsumm.py                  |   579 -
 astropy/sphinx/ext/changelog_links.py              |    67 -
 astropy/sphinx/ext/comment_eater.py                |   162 -
 astropy/sphinx/ext/compiler_unparse.py             |   864 -
 astropy/sphinx/ext/docscrape.py                    |   512 -
 astropy/sphinx/ext/docscrape_sphinx.py             |   231 -
 astropy/sphinx/ext/doctest.py                      |    37 -
 astropy/sphinx/ext/edit_on_github.py               |   169 -
 astropy/sphinx/ext/numpydoc.py                     |   173 -
 astropy/sphinx/ext/phantom_import.py               |   166 -
 astropy/sphinx/ext/smart_resolver.py               |    73 -
 .../sphinx/ext/templates/autosummary_core/base.rst |    16 -
 .../ext/templates/autosummary_core/class.rst       |    71 -
 .../ext/templates/autosummary_core/module.rst      |    47 -
 astropy/sphinx/ext/tests/__init__.py               |     4 -
 astropy/sphinx/ext/tests/test_automodapi.py        |   300 -
 astropy/sphinx/ext/tests/test_automodsumm.py       |    77 -
 astropy/sphinx/ext/tocdepthfix.py                  |    22 -
 astropy/sphinx/ext/traitsdoc.py                    |   144 -
 astropy/sphinx/ext/viewcode.py                     |   216 -
 astropy/sphinx/setup_package.py                    |    13 -
 astropy/sphinx/themes/bootstrap-astropy/README.md  |     4 -
 .../sphinx/themes/bootstrap-astropy/layout.html    |    94 -
 astropy/stats/__init__.py                          |     1 +
 astropy/stats/funcs.py                             |   217 +-
 astropy/stats/sigma_clipping.py                    |   189 +
 astropy/stats/tests/test_funcs.py                  |    95 +-
 astropy/stats/tests/test_sigma_clipping.py         |    98 +
 astropy/table/__init__.py                          |     6 +-
 astropy/table/_np_utils.c                          |   356 +-
 astropy/table/column.py                            |   417 +-
 astropy/table/groups.py                            |    23 +-
 astropy/table/jsviewer.py                          |   108 +-
 astropy/table/np_utils.py                          |    16 +-
 astropy/table/operations.py                        |   633 +-
 astropy/table/pprint.py                            |   146 +-
 astropy/table/row.py                               |   145 +-
 astropy/table/table.py                             |   817 +-
 astropy/table/table_helpers.py                     |   169 +
 astropy/table/tests/conftest.py                    |    43 +
 astropy/table/tests/test_column.py                 |   198 +-
 astropy/table/tests/test_groups.py                 |     6 +-
 astropy/table/tests/test_init_table.py             |    35 +-
 astropy/table/tests/test_item_access.py            |     6 +-
 astropy/table/tests/test_jsviewer.py               |    65 +
 astropy/table/tests/test_masked.py                 |    23 +-
 astropy/table/tests/test_mixin.py                  |   376 +
 astropy/table/tests/test_operations.py             |   110 +-
 astropy/table/tests/test_pprint.py                 |   169 +-
 astropy/table/tests/test_row.py                    |    77 +-
 astropy/table/tests/test_subclass.py               |    40 +-
 astropy/table/tests/test_table.py                  |   160 +-
 astropy/tests/helper.py                            |   336 +-
 astropy/tests/output_checker.py                    |     2 +-
 astropy/tests/pytest_plugins.py                    |   147 +-
 astropy/tests/tests/run_after_2to3.py              |    12 -
 astropy/tests/tests/test_quantity_helpers.py       |    39 +
 astropy/tests/tests/test_run_tests.py              |     9 -
 astropy/time/core.py                               |   531 +-
 astropy/time/erfa_time.c                           | 20866 ----------
 astropy/time/erfa_time.py                          |    40 +
 astropy/time/erfa_time.pyx                         |  2056 -
 astropy/time/setup_package.py                      |    31 -
 astropy/time/tests/test_basic.py                   |   145 +-
 astropy/time/tests/test_delta.py                   |     2 +-
 astropy/time/tests/test_precision.py               |    10 +
 astropy/time/tests/test_quantity_interaction.py    |    23 +
 astropy/units/__init__.py                          |     1 +
 astropy/units/astrophys.py                         |    47 +-
 astropy/units/cds.py                               |     9 +-
 astropy/units/cgs.py                               |     2 +-
 astropy/units/core.py                              |   106 +-
 astropy/units/decorators.py                        |   132 +
 astropy/units/format/__init__.py                   |    34 +-
 astropy/units/format/base.py                       |    18 +-
 astropy/units/format/cds.py                        |     2 +-
 astropy/units/format/console.py                    |    24 +-
 astropy/units/format/fits.py                       |    69 +-
 astropy/units/format/generic.py                    |    96 +-
 astropy/units/format/generic_lextab.py             |     4 +-
 astropy/units/format/generic_parsetab.py           |    98 +-
 astropy/units/format/latex.py                      |   108 +-
 astropy/units/format/ogip.py                       |    97 +-
 astropy/units/format/unicode_format.py             |    14 +-
 astropy/units/format/utils.py                      |    93 +
 astropy/units/format/vounit.py                     |   215 +-
 astropy/units/quantity.py                          |   130 +-
 astropy/units/si.py                                |    11 +-
 .../units/tests/py3_test_quantity_annotations.py   |   224 +
 astropy/units/tests/test_format.py                 |    90 +-
 astropy/units/tests/test_physical.py               |     5 +
 astropy/units/tests/test_quantity.py               |   102 +-
 astropy/units/tests/test_quantity_array_methods.py |    14 +-
 astropy/units/tests/test_quantity_decorator.py     |   195 +
 astropy/units/tests/test_quantity_ufuncs.py        |     6 -
 astropy/units/tests/test_units.py                  |     4 +
 astropy/units/utils.py                             |     1 -
 astropy/utils/__init__.py                          |     3 +
 astropy/utils/codegen.py                           |   144 +
 astropy/utils/compat/_funcsigs.py                  |   813 +
 astropy/utils/compat/argparse.py                   |     2 -
 astropy/utils/compat/funcsigs.py                   |     6 +
 astropy/utils/compat/gzip.py                       |     8 +-
 astropy/utils/compat/misc.py                       |    86 +-
 astropy/utils/compat/numpy/__init__.py             |    10 +
 astropy/utils/compat/numpy/lib/__init__.py         |     0
 astropy/utils/compat/numpy/lib/stride_tricks.py    |   164 +
 astropy/utils/compat/numpy/tests/__init__.py       |     0
 .../compat/numpy/tests/test_broadcast_arrays.py    |    48 +
 astropy/utils/console.py                           |   131 +-
 astropy/utils/data.py                              |     2 +-
 astropy/utils/decorators.py                        |   573 +
 astropy/utils/iers/data/eopc04_IAU2000.62-now      |   590 +-
 astropy/utils/iers/iers.py                         |   110 +-
 astropy/utils/introspection.py                     |   267 +
 astropy/utils/metadata.py                          |     4 +-
 astropy/utils/misc.py                              |   577 +-
 astropy/utils/release.py                           |   134 +
 astropy/utils/tests/test_codegen.py                |    42 +
 astropy/utils/tests/test_console.py                |    13 +-
 astropy/utils/tests/test_decorators.py             |   252 +
 astropy/utils/tests/test_introspection.py          |    94 +
 astropy/utils/tests/test_misc.py                   |   179 +-
 astropy/utils/timer.py                             |     2 +-
 astropy/utils/xml/writer.py                        |    13 +-
 astropy/version.py                                 |    12 +-
 astropy/version_helpers.py                         |   258 -
 astropy/visualization/__init__.py                  |     7 +
 astropy/visualization/interval.py                  |   142 +
 astropy/visualization/mpl_normalize.py             |    85 +
 astropy/visualization/mpl_style.py                 |   113 +
 astropy/visualization/scripts/__init__.py          |     1 +
 astropy/visualization/scripts/fits2bitmap.py       |   138 +
 astropy/visualization/scripts/tests/__init__.py    |     1 +
 .../scripts/tests/test_fits2bitmap.py              |    27 +
 astropy/visualization/stretch.py                   |   468 +
 astropy/visualization/tests/__init__.py            |     1 +
 astropy/visualization/tests/test_interval.py       |    89 +
 astropy/visualization/tests/test_norm.py           |    89 +
 astropy/visualization/tests/test_stretch.py        |   108 +
 astropy/visualization/tests/test_ui.py             |    46 +
 astropy/visualization/transform.py                 |    42 +
 astropy/visualization/ui.py                        |   102 +
 astropy/vo/client/async.py                         |     2 +-
 astropy/vo/client/conesearch.py                    |     2 +-
 astropy/vo/samp/client.py                          |    16 +-
 astropy/vo/samp/lockfile_helpers.py                |     4 +-
 astropy/vo/samp/standard_profile.py                |     4 +-
 astropy/vo/samp/tests/test_standard_profile.py     |     2 -
 astropy/vo/samp/web_profile.py                     |     3 -
 astropy/vo/validator/inspect.py                    |     2 +-
 astropy/vo/validator/tests/test_validate.py        |     5 -
 astropy/wcs/docstrings.py                          |    18 +-
 astropy/wcs/include/astropy_wcs/docstrings.h       |    12 +-
 astropy/wcs/include/astropy_wcs/wcsconfig.h        |     2 +-
 astropy/wcs/include/wcsconfig.h                    |     2 +-
 astropy/wcs/include/wcslib/cel.h                   |     6 +-
 astropy/wcs/include/wcslib/lin.h                   |     6 +-
 astropy/wcs/include/wcslib/prj.h                   |     6 +-
 astropy/wcs/include/wcslib/spc.h                   |     6 +-
 astropy/wcs/include/wcslib/spx.h                   |     6 +-
 astropy/wcs/include/wcslib/tab.h                   |    15 +-
 astropy/wcs/include/wcslib/wcs.h                   |    15 +-
 astropy/wcs/include/wcslib/wcserr.h                |     4 +-
 astropy/wcs/include/wcslib/wcsmath.h               |     4 +-
 astropy/wcs/include/wcslib/wcsprintf.h             |     6 +-
 astropy/wcs/setup_package.py                       |     5 +-
 astropy/wcs/src/docstrings.c                       |   694 +-
 astropy/wcs/src/unit_list_proxy.c                  |    10 +-
 astropy/wcs/src/wcslib_wrap.c                      |    44 +-
 astropy/wcs/tests/data/j94f05bgq_flt.fits          |     1 +
 astropy/wcs/tests/extension/test_extension.py      |     2 +-
 astropy/wcs/tests/test_utils.py                    |   257 +-
 astropy/wcs/tests/test_wcs.py                      |   146 +-
 astropy/wcs/tests/test_wcsprm.py                   |   137 +-
 astropy/wcs/utils.py                               |   415 +-
 astropy/wcs/wcs.py                                 |   848 +-
 astropy_helpers/.coveragerc                        |    21 +
 astropy_helpers/.travis.yml                        |    57 +
 astropy_helpers/CHANGES.rst                        |   156 +
 astropy_helpers/CONTRIBUTING.md                    |    20 +
 astropy_helpers/LICENSE.rst                        |    26 +
 astropy_helpers/MANIFEST.in                        |    10 +
 astropy_helpers/README.rst                         |    32 +
 astropy_helpers/ah_bootstrap.py                    |   897 +
 astropy_helpers/appveyor.yml                       |    52 +
 astropy_helpers/astropy_helpers.egg-info/PKG-INFO  |    52 +
 .../astropy_helpers.egg-info/SOURCES.txt           |    77 +
 .../astropy_helpers.egg-info/dependency_links.txt  |     1 +
 .../astropy_helpers.egg-info/not-zip-safe          |     1 +
 .../astropy_helpers.egg-info/top_level.txt         |     1 +
 astropy_helpers/astropy_helpers/__init__.py        |     6 +
 .../astropy_helpers/commands/__init__.py           |     0
 .../astropy_helpers/commands/build_ext.py          |   179 +
 .../astropy_helpers/commands/build_py.py           |    39 +
 .../astropy_helpers/commands/build_sphinx.py       |   215 +
 .../astropy_helpers/commands/install.py            |    14 +
 .../astropy_helpers/commands/install_lib.py        |    14 +
 .../astropy_helpers/commands/register.py           |    53 +
 astropy_helpers/astropy_helpers/compat/__init__.py |    12 +
 .../compat/_subprocess_py2/__init__.py             |    38 +
 .../astropy_helpers/compat/subprocess.py           |    19 +
 .../astropy_helpers/distutils_helpers.py           |   257 +
 astropy_helpers/astropy_helpers/git_helpers.py     |   155 +
 astropy_helpers/astropy_helpers/setup_helpers.py   |   843 +
 astropy_helpers/astropy_helpers/sphinx/__init__.py |     6 +
 astropy_helpers/astropy_helpers/sphinx/conf.py     |   311 +
 .../astropy_helpers/sphinx/ext/__init__.py         |     3 +
 .../sphinx/ext/astropyautosummary.py               |   113 +
 .../sphinx/ext/autodoc_enhancements.py             |    56 +
 .../astropy_helpers/sphinx/ext/automodapi.py       |   350 +
 .../astropy_helpers/sphinx/ext/automodsumm.py      |   592 +
 .../astropy_helpers/sphinx/ext/changelog_links.py  |    78 +
 .../astropy_helpers/sphinx/ext/comment_eater.py    |   169 +
 .../astropy_helpers/sphinx/ext/compiler_unparse.py |   865 +
 .../astropy_helpers/sphinx/ext/docscrape.py        |   531 +
 .../astropy_helpers/sphinx/ext/docscrape_sphinx.py |   274 +
 .../astropy_helpers/sphinx/ext/doctest.py          |    38 +
 .../astropy_helpers/sphinx/ext/edit_on_github.py   |   165 +
 .../astropy_helpers/sphinx/ext/numpydoc.py         |   187 +
 .../astropy_helpers/sphinx/ext/phantom_import.py   |   167 +
 .../astropy_helpers/sphinx/ext/smart_resolver.py   |    92 +
 .../sphinx/ext/templates/autosummary_core/base.rst |    10 +
 .../ext/templates/autosummary_core/class.rst       |    65 +
 .../ext/templates/autosummary_core/module.rst      |    41 +
 .../astropy_helpers/sphinx/ext/tests/__init__.py   |    70 +
 .../sphinx/ext/tests/test_autodoc_enhancements.py  |    56 +
 .../sphinx/ext/tests/test_automodapi.py            |   343 +
 .../sphinx/ext/tests/test_automodsumm.py           |   112 +
 .../sphinx/ext/tests/test_docscrape.py             |   762 +
 .../astropy_helpers/sphinx/ext/tests/test_utils.py |    34 +
 .../astropy_helpers/sphinx/ext/tocdepthfix.py      |    18 +
 .../astropy_helpers/sphinx/ext/traitsdoc.py        |   142 +
 .../astropy_helpers/sphinx/ext/utils.py            |    65 +
 .../astropy_helpers/sphinx/ext/viewcode.py         |   219 +
 .../astropy_helpers/sphinx/local/python3links.inv  |   Bin 0 -> 483 bytes
 .../astropy_helpers/sphinx/local/python3links.txt  |    20 +
 .../astropy_helpers/sphinx/setup_package.py        |    10 +
 .../sphinx/themes/bootstrap-astropy/globaltoc.html |     0
 .../sphinx/themes/bootstrap-astropy/layout.html    |    96 +
 .../sphinx/themes/bootstrap-astropy/localtoc.html  |     0
 .../sphinx/themes/bootstrap-astropy/searchbox.html |     0
 .../static/astropy_linkout_20.png                  |   Bin
 .../bootstrap-astropy/static/astropy_logo.ico      |   Bin
 .../bootstrap-astropy/static/astropy_logo_32.png   |   Bin
 .../bootstrap-astropy/static/bootstrap-astropy.css |     0
 .../themes/bootstrap-astropy/static/copybutton.js  |    57 +
 .../themes/bootstrap-astropy/static/sidebar.js     |     0
 .../sphinx/themes/bootstrap-astropy/theme.conf     |     0
 astropy_helpers/astropy_helpers/src/__init__.py    |     0
 astropy_helpers/astropy_helpers/src/compiler.c     |   129 +
 .../astropy_helpers/src/setup_package.py           |     2 +
 astropy_helpers/astropy_helpers/test_helpers.py    |   250 +
 astropy_helpers/astropy_helpers/tests/__init__.py  |   157 +
 .../astropy_helpers/tests/test_ah_bootstrap.py     |   419 +
 .../astropy_helpers/tests/test_git_helpers.py      |   176 +
 .../astropy_helpers/tests/test_setup_helpers.py    |   254 +
 astropy_helpers/astropy_helpers/utils.py           |   591 +
 astropy_helpers/astropy_helpers/version.py         |   171 +
 astropy_helpers/astropy_helpers/version_helpers.py |   227 +
 .../appveyor/install-miniconda.ps1                 |    71 +
 .../appveyor/windows_sdk.cmd                       |    47 +
 .../travis/install_conda_linux.sh                  |     7 +
 .../travis/install_conda_osx.sh                    |     7 +
 .../travis/install_graphviz_linux.sh               |     4 +
 .../travis/install_graphviz_osx.sh                 |     4 +
 astropy_helpers/ez_setup.py                        |   382 +
 astropy_helpers/licenses/LICENSE_COPYBUTTON.rst    |    50 +
 astropy_helpers/licenses/LICENSE_NUMPYDOC.rst      |    94 +
 astropy_helpers/setup.cfg                          |     5 +
 astropy_helpers/setup.py                           |    50 +
 astropy_helpers/tox.ini                            |    14 +
 cextern/erfa/a2af.c                                |   129 +
 cextern/erfa/a2tf.c                                |   125 +
 cextern/erfa/ab.c                                  |   137 +
 cextern/erfa/af2a.c                                |   116 +
 cextern/erfa/anp.c                                 |    91 +
 cextern/erfa/anpm.c                                |    91 +
 cextern/erfa/apcg.c                                |   181 +
 cextern/erfa/apcg13.c                              |   184 +
 cextern/erfa/apci.c                                |   190 +
 cextern/erfa/apci13.c                              |   202 +
 cextern/erfa/apco.c                                |   264 +
 cextern/erfa/apco13.c                              |   287 +
 cextern/erfa/apcs.c                                |   233 +
 cextern/erfa/apcs13.c                              |   191 +
 cextern/erfa/aper.c                                |   162 +
 cextern/erfa/aper13.c                              |   181 +
 cextern/erfa/apio.c                                |   213 +
 cextern/erfa/apio13.c                              |   259 +
 cextern/erfa/atci13.c                              |   159 +
 cextern/erfa/atciq.c                               |   154 +
 cextern/erfa/atciqn.c                              |   191 +
 cextern/erfa/atciqz.c                              |   153 +
 cextern/erfa/atco13.c                              |   243 +
 cextern/erfa/atic13.c                              |   152 +
 cextern/erfa/aticq.c                               |   199 +
 cextern/erfa/aticqn.c                              |   237 +
 cextern/erfa/atio13.c                              |   222 +
 cextern/erfa/atioq.c                               |   244 +
 cextern/erfa/atoc13.c                              |   233 +
 cextern/erfa/atoi13.c                              |   228 +
 cextern/erfa/atoiq.c                               |   260 +
 cextern/erfa/bi00.c                                |   125 +
 cextern/erfa/bp00.c                                |   181 +
 cextern/erfa/bp06.c                                |   152 +
 cextern/erfa/bpn2xy.c                              |   109 +
 cextern/erfa/c2i00a.c                              |   148 +
 cextern/erfa/c2i00b.c                              |   148 +
 cextern/erfa/c2i06a.c                              |   145 +
 cextern/erfa/c2ibpn.c                              |   151 +
 cextern/erfa/c2ixy.c                               |   140 +
 cextern/erfa/c2ixys.c                              |   132 +
 cextern/erfa/c2s.c                                 |   105 +
 cextern/erfa/c2t00a.c                              |   163 +
 cextern/erfa/c2t00b.c                              |   159 +
 cextern/erfa/c2t06a.c                              |   161 +
 cextern/erfa/c2tcio.c                              |   131 +
 cextern/erfa/c2teqx.c                              |   131 +
 cextern/erfa/c2tpe.c                               |   176 +
 cextern/erfa/c2txy.c                               |   168 +
 cextern/erfa/cal2jd.c                              |   148 +
 cextern/erfa/cp.c                                  |    89 +
 cextern/erfa/cpv.c                                 |    91 +
 cextern/erfa/cr.c                                  |    92 +
 cextern/erfa/d2dtf.c                               |   245 +
 cextern/erfa/d2tf.c                                |   169 +
 cextern/erfa/dat.c                                 |   304 +
 cextern/erfa/dtdb.c                                |  1222 +
 cextern/erfa/dtf2d.c                               |   212 +
 cextern/erfa/ee00.c                                |   137 +
 cextern/erfa/ee00a.c                               |   144 +
 cextern/erfa/ee00b.c                               |   150 +
 cextern/erfa/ee06a.c                               |   131 +
 cextern/erfa/eect00.c                              |   291 +
 cextern/erfa/eform.c                               |   155 +
 cextern/erfa/eo06a.c                               |   140 +
 cextern/erfa/eors.c                                |   117 +
 cextern/erfa/epb.c                                 |   100 +
 cextern/erfa/epb2jd.c                              |   100 +
 cextern/erfa/epj.c                                 |   102 +
 cextern/erfa/epj2jd.c                              |   100 +
 cextern/erfa/epv00.c                               |  2598 ++
 cextern/erfa/eqeq94.c                              |   141 +
 cextern/erfa/era00.c                               |   145 +
 cextern/erfa/erfa.c                                | 27361 -------------
 cextern/erfa/erfa.h                                |   169 +-
 cextern/erfa/erfam.h                               |   208 +
 cextern/erfa/fad03.c                               |   112 +
 cextern/erfa/fae03.c                               |   111 +
 cextern/erfa/faf03.c                               |   115 +
 cextern/erfa/faju03.c                              |   111 +
 cextern/erfa/fal03.c                               |   112 +
 cextern/erfa/falp03.c                              |   112 +
 cextern/erfa/fama03.c                              |   111 +
 cextern/erfa/fame03.c                              |   111 +
 cextern/erfa/fane03.c                              |   108 +
 cextern/erfa/faom03.c                              |   113 +
 cextern/erfa/fapa03.c                              |   112 +
 cextern/erfa/fasa03.c                              |   111 +
 cextern/erfa/faur03.c                              |   108 +
 cextern/erfa/fave03.c                              |   111 +
 cextern/erfa/fk52h.c                               |   152 +
 cextern/erfa/fk5hip.c                              |   135 +
 cextern/erfa/fk5hz.c                               |   169 +
 cextern/erfa/fw2m.c                                |   143 +
 cextern/erfa/fw2xy.c                               |   130 +
 cextern/erfa/gc2gd.c                               |   143 +
 cextern/erfa/gc2gde.c                              |   208 +
 cextern/erfa/gd2gc.c                               |   142 +
 cextern/erfa/gd2gce.c                              |   146 +
 cextern/erfa/gmst00.c                              |   154 +
 cextern/erfa/gmst06.c                              |   145 +
 cextern/erfa/gmst82.c                              |   160 +
 cextern/erfa/gst00a.c                              |   147 +
 cextern/erfa/gst00b.c                              |   155 +
 cextern/erfa/gst06.c                               |   149 +
 cextern/erfa/gst06a.c                              |   140 +
 cextern/erfa/gst94.c                               |   140 +
 cextern/erfa/h2fk5.c                               |   157 +
 cextern/erfa/hfk5z.c                               |   184 +
 cextern/erfa/ir.c                                  |    92 +
 cextern/erfa/jd2cal.c                              |   164 +
 cextern/erfa/jdcalf.c                              |   170 +
 cextern/erfa/ld.c                                  |   161 +
 cextern/erfa/ldn.c                                 |   183 +
 cextern/erfa/ldsun.c                               |   105 +
 cextern/erfa/num00a.c                              |   130 +
 cextern/erfa/num00b.c                              |   130 +
 cextern/erfa/num06a.c                              |   134 +
 cextern/erfa/numat.c                               |   118 +
 cextern/erfa/nut00a.c                              |  2056 +
 cextern/erfa/nut00b.c                              |   381 +
 cextern/erfa/nut06a.c                              |   162 +
 cextern/erfa/nut80.c                               |   334 +
 cextern/erfa/nutm80.c                              |   126 +
 cextern/erfa/obl06.c                               |   127 +
 cextern/erfa/obl80.c                               |   127 +
 cextern/erfa/p06e.c                                |   330 +
 cextern/erfa/p2pv.c                                |    92 +
 cextern/erfa/p2s.c                                 |   100 +
 cextern/erfa/pap.c                                 |   148 +
 cextern/erfa/pas.c                                 |   105 +
 cextern/erfa/pb06.c                                |   153 +
 cextern/erfa/pdp.c                                 |    93 +
 cextern/erfa/pfw06.c                               |   174 +
 cextern/erfa/plan94.c                              |   523 +
 cextern/erfa/pm.c                                  |    85 +
 cextern/erfa/pmat00.c                              |   127 +
 cextern/erfa/pmat06.c                              |   131 +
 cextern/erfa/pmat76.c                              |   150 +
 cextern/erfa/pmp.c                                 |    94 +
 cextern/erfa/pmpx.c                                |   153 +
 cextern/erfa/pmsafe.c                              |   206 +
 cextern/erfa/pn.c                                  |   118 +
 cextern/erfa/pn00.c                                |   186 +
 cextern/erfa/pn00a.c                               |   172 +
 cextern/erfa/pn00b.c                               |   172 +
 cextern/erfa/pn06.c                                |   196 +
 cextern/erfa/pn06a.c                               |   162 +
 cextern/erfa/pnm00a.c                              |   130 +
 cextern/erfa/pnm00b.c                              |   130 +
 cextern/erfa/pnm06a.c                              |   133 +
 cextern/erfa/pnm80.c                               |   135 +
 cextern/erfa/pom00.c                               |   124 +
 cextern/erfa/ppp.c                                 |    94 +
 cextern/erfa/ppsp.c                                |   103 +
 cextern/erfa/pr00.c                                |   151 +
 cextern/erfa/prec76.c                              |   157 +
 cextern/erfa/pv2p.c                                |    90 +
 cextern/erfa/pv2s.c                                |   153 +
 cextern/erfa/pvdpv.c                               |   111 +
 cextern/erfa/pvm.c                                 |    95 +
 cextern/erfa/pvmpv.c                               |    96 +
 cextern/erfa/pvppv.c                               |    96 +
 cextern/erfa/pvstar.c                              |   216 +
 cextern/erfa/pvtob.c                               |   162 +
 cextern/erfa/pvu.c                                 |   102 +
 cextern/erfa/pvup.c                                |    97 +
 cextern/erfa/pvxpv.c                               |   116 +
 cextern/erfa/pxp.c                                 |   103 +
 cextern/erfa/refco.c                               |   262 +
 cextern/erfa/rm2v.c                                |   120 +
 cextern/erfa/rv2m.c                                |   127 +
 cextern/erfa/rx.c                                  |   119 +
 cextern/erfa/rxp.c                                 |   108 +
 cextern/erfa/rxpv.c                                |    95 +
 cextern/erfa/rxr.c                                 |   108 +
 cextern/erfa/ry.c                                  |   119 +
 cextern/erfa/rz.c                                  |   119 +
 cextern/erfa/s00.c                                 |   380 +
 cextern/erfa/s00a.c                                |   152 +
 cextern/erfa/s00b.c                                |   152 +
 cextern/erfa/s06.c                                 |   377 +
 cextern/erfa/s06a.c                                |   154 +
 cextern/erfa/s2c.c                                 |    94 +
 cextern/erfa/s2p.c                                 |    97 +
 cextern/erfa/s2pv.c                                |   112 +
 cextern/erfa/s2xpv.c                               |    96 +
 cextern/erfa/sepp.c                                |   114 +
 cextern/erfa/seps.c                                |   102 +
 cextern/erfa/sp00.c                                |   127 +
 cextern/erfa/starpm.c                              |   214 +
 cextern/erfa/starpv.c                              |   273 +
 cextern/erfa/sxp.c                                 |    93 +
 cextern/erfa/sxpv.c                                |    94 +
 cextern/erfa/taitt.c                               |   119 +
 cextern/erfa/taiut1.c                              |   120 +
 cextern/erfa/taiutc.c                              |   168 +
 cextern/erfa/tcbtdb.c                              |   141 +
 cextern/erfa/tcgtt.c                               |   118 +
 cextern/erfa/tdbtcb.c                              |   146 +
 cextern/erfa/tdbtt.c                               |   130 +
 cextern/erfa/tf2a.c                                |   116 +
 cextern/erfa/tf2d.c                                |   116 +
 cextern/erfa/tr.c                                  |   102 +
 cextern/erfa/trxp.c                                |   102 +
 cextern/erfa/trxpv.c                               |   102 +
 cextern/erfa/tttai.c                               |   119 +
 cextern/erfa/tttcg.c                               |   121 +
 cextern/erfa/tttdb.c                               |   130 +
 cextern/erfa/ttut1.c                               |   119 +
 cextern/erfa/ut1tai.c                              |   120 +
 cextern/erfa/ut1tt.c                               |   119 +
 cextern/erfa/ut1utc.c                              |   202 +
 cextern/erfa/utctai.c                              |   186 +
 cextern/erfa/utcut1.c                              |   156 +
 cextern/erfa/xy06.c                                |  2767 ++
 cextern/erfa/xys00a.c                              |   142 +
 cextern/erfa/xys00b.c                              |   142 +
 cextern/erfa/xys06a.c                              |   142 +
 cextern/erfa/zp.c                                  |    86 +
 cextern/erfa/zpv.c                                 |    88 +
 cextern/erfa/zr.c                                  |    92 +
 cextern/wcslib/C/GNUmakefile                       |     4 +-
 cextern/wcslib/C/cel.c                             |     4 +-
 cextern/wcslib/C/cel.h                             |     6 +-
 cextern/wcslib/C/fitshdr.h                         |     4 +-
 cextern/wcslib/C/fitshdr.l                         |     4 +-
 cextern/wcslib/C/flexed/fitshdr.c                  |     4 +-
 cextern/wcslib/C/flexed/wcsbth.c                   |     4 +-
 cextern/wcslib/C/flexed/wcspih.c                   |     4 +-
 cextern/wcslib/C/flexed/wcsulex.c                  |     4 +-
 cextern/wcslib/C/flexed/wcsutrn.c                  |     4 +-
 cextern/wcslib/C/getwcstab.c                       |     4 +-
 cextern/wcslib/C/getwcstab.h                       |     4 +-
 cextern/wcslib/C/lin.c                             |     4 +-
 cextern/wcslib/C/lin.h                             |     6 +-
 cextern/wcslib/C/log.c                             |     4 +-
 cextern/wcslib/C/log.h                             |     6 +-
 cextern/wcslib/C/prj.c                             |     4 +-
 cextern/wcslib/C/prj.h                             |     6 +-
 cextern/wcslib/C/spc.c                             |     4 +-
 cextern/wcslib/C/spc.h                             |     6 +-
 cextern/wcslib/C/sph.c                             |     4 +-
 cextern/wcslib/C/sph.h                             |     6 +-
 cextern/wcslib/C/spx.c                             |     4 +-
 cextern/wcslib/C/spx.h                             |     6 +-
 cextern/wcslib/C/tab.c                             |    11 +-
 cextern/wcslib/C/tab.h                             |    15 +-
 cextern/wcslib/C/tan.fits                          |     1 +
 cextern/wcslib/C/tan.hdr                           |    21 +
 cextern/wcslib/C/wcs.c                             |    91 +-
 cextern/wcslib/C/wcs.h                             |    15 +-
 cextern/wcslib/C/wcsbth.l                          |     4 +-
 cextern/wcslib/C/wcserr.c                          |     4 +-
 cextern/wcslib/C/wcserr.h                          |     4 +-
 cextern/wcslib/C/wcsfix.c                          |     4 +-
 cextern/wcslib/C/wcsfix.h                          |     6 +-
 cextern/wcslib/C/wcshdr.c                          |     4 +-
 cextern/wcslib/C/wcshdr.h                          |     6 +-
 cextern/wcslib/C/wcslib.h                          |     6 +-
 cextern/wcslib/C/wcsmath.h                         |     4 +-
 cextern/wcslib/C/wcspih.l                          |     4 +-
 cextern/wcslib/C/wcsprintf.c                       |     4 +-
 cextern/wcslib/C/wcsprintf.h                       |     6 +-
 cextern/wcslib/C/wcstrig.c                         |     4 +-
 cextern/wcslib/C/wcstrig.h                         |     4 +-
 cextern/wcslib/C/wcsulex.l                         |     4 +-
 cextern/wcslib/C/wcsunits.c                        |     4 +-
 cextern/wcslib/C/wcsunits.h                        |     6 +-
 cextern/wcslib/C/wcsutil.c                         |    25 +-
 cextern/wcslib/C/wcsutil.h                         |    16 +-
 cextern/wcslib/C/wcsutrn.l                         |     4 +-
 cextern/wcslib/CHANGES                             |    31 +-
 cextern/wcslib/GNUmakefile                         |     4 +-
 cextern/wcslib/INSTALL                             |     8 +-
 cextern/wcslib/README                              |     6 +-
 cextern/wcslib/THANKS                              |     2 +-
 cextern/wcslib/VALIDATION                          |     2 +-
 cextern/wcslib/configure                           | 14553 +++----
 cextern/wcslib/configure.ac                        |    13 +-
 cextern/wcslib/flavours                            |     2 +-
 cextern/wcslib/makedefs.in                         |     8 +-
 cextern/wcslib/wcsconfig.h.in                      |     4 +-
 cextern/wcslib/wcsconfig_f77.h.in                  |     4 +-
 cextern/wcslib/wcsconfig_tests.h.in                |     4 +-
 cextern/wcslib/wcsconfig_utils.h.in                |     4 +-
 docs/analytic_functions/index.rst                  |   119 +
 docs/coordinates/frames.rst                        |    18 +-
 docs/coordinates/galactocentric.rst                |   115 +
 docs/coordinates/index.rst                         |    43 +-
 docs/coordinates/matchsep.rst                      |    15 +
 docs/coordinates/observing-example.rst             |   135 +
 docs/coordinates/skycoord.rst                      |   137 +-
 docs/coordinates/transforming.rst                  |    42 +-
 docs/cosmology/index.rst                           |    50 +-
 docs/credits.rst                                   |     1 +
 docs/development/affiliated-packages.rst           |   322 +-
 docs/development/building.rst                      |     6 +-
 docs/development/ccython.rst                       |    13 +-
 docs/development/codeguide.rst                     |    24 +-
 docs/development/docrules.rst                      |     6 +-
 docs/development/releasing.rst                     |     8 +-
 docs/development/scripts.rst                       |    47 +-
 docs/development/testguide.rst                     |     3 -
 docs/getting_started.rst                           |     3 +
 docs/index.rst                                     |     6 +-
 docs/install.rst                                   |    12 +-
 docs/io/ascii/fast_ascii_io.rst                    |   173 +
 docs/io/ascii/fixed_width_gallery.rst              |   128 +-
 docs/io/ascii/index.rst                            |   107 +-
 docs/io/ascii/read.rst                             |   158 +-
 docs/io/ascii/toc.txt                              |     1 +
 docs/io/ascii/write.rst                            |    24 +-
 docs/io/fits/index.rst                             |    11 +-
 docs/io/unified.rst                                |     1 +
 docs/known_issues.rst                              |    12 -
 docs/modeling/compound-models.rst                  |   862 +
 docs/modeling/design.rst                           |    28 -
 docs/modeling/fitting.rst                          |     6 +-
 docs/modeling/index.rst                            |   122 +-
 docs/modeling/models.rst                           |    10 +-
 docs/modeling/new.rst                              |   278 +-
 docs/modeling/parameters.rst                       |     4 +-
 docs/nddata/decorator.rst                          |    71 +
 docs/nddata/index.rst                              |   150 +-
 docs/nddata/mixins/index.rst                       |     9 +
 docs/nddata/mixins/ndarithmetic.rst                |    49 +
 docs/nddata/mixins/ndio.rst                        |    11 +
 docs/nddata/mixins/ndslicing.rst                   |    22 +
 docs/nddata/nddata.rst                             |   191 +-
 docs/nddata/subclassing.rst                        |    51 +-
 docs/nitpick-exceptions                            |     5 +-
 docs/rtd-pip-requirements                          |     2 +-
 docs/stability.rst                                 |    22 +
 docs/table/access_table.rst                        |   249 +-
 docs/table/construct_table.rst                     |   216 +-
 docs/table/implementation_change_1.0.rst           |   188 +
 docs/table/implementation_details.rst              |    47 +
 docs/table/index.rst                               |   112 +-
 docs/table/io.rst                                  |     4 +-
 docs/table/masking.rst                             |    13 +-
 docs/table/mixin_columns.rst                       |   276 +
 docs/table/modify_table.rst                        |    21 +-
 docs/table/operations.rst                          |   126 +-
 docs/table/references.txt                          |     1 +
 docs/table/table_after_1.0.png                     |   Bin 0 -> 19735 bytes
 docs/table/table_architecture.png                  |   Bin 0 -> 28771 bytes
 docs/table/table_before_1.0.png                    |   Bin 0 -> 21356 bytes
 docs/table/table_column_after_1.0.png              |   Bin 0 -> 19735 bytes
 docs/table/table_column_before_1.0.png             |   Bin 0 -> 21915 bytes
 docs/table/table_repr_html.png                     |   Bin 9278 -> 17283 bytes
 docs/table/table_row.png                           |   Bin 0 -> 41362 bytes
 docs/table/table_row_after_1.0.png                 |   Bin 0 -> 27899 bytes
 docs/table/table_row_before_1.0.png                |   Bin 0 -> 16091 bytes
 docs/time/index.rst                                |    45 +-
 docs/units/decomposing_and_composing.rst           |     2 +-
 docs/units/equivalencies.rst                       |    34 +-
 docs/units/format.rst                              |    27 +-
 docs/units/index.rst                               |    12 +-
 docs/units/quantity.rst                            |    32 +
 docs/utils/index.rst                               |    25 +-
 docs/utils/numpy.rst                               |    54 +
 docs/visualization/index.rst                       |    43 +
 docs/visualization/normalization.rst               |   157 +
 docs/wcs/index.rst                                 |    24 +
 docs/whatsnew/0.4.rst                              |     2 +-
 docs/whatsnew/1.0.rst                              |   247 +
 docs/whatsnew/index.rst                            |     1 +
 licenses/NUMPY_LICENSE.rst                         |    30 +
 scripts/README.rst                                 |     5 -
 scripts/fitscheck                                  |     8 -
 scripts/fitsdiff                                   |     8 -
 scripts/fitsheader                                 |     5 -
 scripts/samp_hub                                   |     4 -
 scripts/volint                                     |     5 -
 scripts/wcslint                                    |     5 -
 setup.cfg                                          |    11 +
 setup.py                                           |    23 +-
 859 files changed, 196401 insertions(+), 86306 deletions(-)

diff --git a/CHANGES.rst b/CHANGES.rst
index 0815a5c..3d9803b 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,578 @@
+1.0rc1 (2015-01-27)
+-------------------
+
+General
+^^^^^^^
+
+astropy now requires a Numpy 1.6.0 or later.
+
+New Features
+^^^^^^^^^^^^
+
+- ``astropy.analytic_functions``
+
+  - The ``astropy.analytic_functions`` was added to contain analytic functions
+    useful for astronomy [#3077].
+
+- ``astropy.coordinates``
+
+  - ``astropy.coordinates`` now has a full stack of frames allowing
+    transformations from ICRS or other celestial systems down to Alt/Az
+    coordinates. [#3217]
+
+  - ``astropy.coordinates`` now has a ``get_sun`` function that gives
+    the coordinates  of the Sun at a specified time. [#3217]
+
+  - ``SkyCoord`` now has ``to_pixel`` and ``from_pixel`` methods that convert
+    between celestial coordinates as ``SkyCoord`` objects and pixel coordinates
+    given an ``astropy.wcs.WCS`` object. [#3002]
+
+  - ``SkyCoord`` now has ``search_around_sky`` and ``search_around_3d``
+    convenience methods that allow searching for all coordinates within
+    a certain distance of another ``SkyCoord``. [#2953]
+
+  - ``SkyCoord`` can now accept a frame instance for the ``frame=`` keyword
+    argument. [#3063]
+
+  - ``SkyCoord`` now has a ``guess_from_table`` method that can be used to
+    quickly create ``SkyCoord`` objects from an ``astropy.table.Table``
+    object. [#2951]
+
+  - ``astropy.coordinates`` now has a ``Galactocentric`` frame, a coordinate
+    frame centered on a (user specified) center of the Milky Way. [#2761, #3286]
+
+  - ``SkyCoord`` now accepts more formats of the coordinate string when the
+    representation has ``ra`` and ``dec`` attributes. [#2920]
+
+  - ``SkyCoord`` can now accept lists of ``SkyCoord`` objects, frame objects,
+    or representation objects and will combine them into a single object.
+    [#3285]
+
+  - Frames and ``SkyCoord`` instances now have a method ``is_equivalent_frame``
+    that can be used to check that two frames are equivalent (ignoring the data).
+    [#3330]
+
+- ``astropy.cosmology``
+
+  - Add lookback_distance, which is c * lookback_time. [#3145]
+
+  - Add baryonic matter density and dark matter only density parameters
+    to cosmology objects [#2757].
+
+  - Add a ``clone`` method to cosmology objects to allow copies
+    of cosmological objects to be created with the specified variables
+    modified [#2592].
+
+  - Increase default numerical precision of ``z_at_value`` following
+    the accurate by default, fast by explicit request model [#3074].
+
+  - Cosmology functions that take a single (redshift) input now
+    broadcast like numpy ufuncs.  So, passing an arbitrarily shaped
+    array of inputs will produce an output of the same shape. [#3178, #3194]
+
+- ``astropy.erfa``
+
+  - ``astropy.erfa`` was added as a new subpackage wrapping the functionality
+    of the ERFA library in python.  This is primarily of use for other astropy
+    subpackages, but the API may be made more public in the future. [#2992]
+
+- ``astropy.io.ascii``
+
+  - Simplify the way new Reader classes are defined, allowing custom behavior
+    entirely by overriding inherited class attributes instead of setting
+    instance attributes in the Reader ``__init__`` method. [#2812]
+
+  - There is now a faster C/Cython engine available for reading and writing
+    simple ASCII formats like CSV. Both are enabled by default, and fast
+    reading will fall back on an ordinary reader in case of a parsing
+    failure. Their behavior can be altered with the parameter ``fast_reader``
+    in ``read`` and ``fast_writer`` in ``write``. [#2716]
+
+  - Make Latex/AASTex tables use unit attribute of Column for output. [#3064]
+
+  - Store comment lines encountered during reading in metadata of the
+    output table via ``meta['comment_lines']``. [#3222]
+
+  - Write comment lines in Table metadata during output for all basic formats,
+    IPAC, and fast writers. This functionality can be disabled with
+    ``comment=False``. [#3255]
+  - Add reader / writer for the Enhanced CSV format which stores table and
+    column meta data, in particular data type and unit. [#2319]
+
+- ``astropy.io.fits``
+
+  - The ``fitsdiff`` script ignores some things by default when comparing fits
+    files (e.g. empty header lines). This adds a ``--exact`` option where
+    nothing is ignored. [#2782, #3110]
+
+  - The ``fitsheader`` script now takes a ``--keyword`` option to extract a
+    specific keyword from the header of a FITS file, and a ``--table`` option
+    to export headers into any of the data formats supported by
+    ``astropy.table``. [#2555, #2588]
+
+  - ``Section`` now supports all advanced indexing features ``ndarray`` does
+    (slices with any steps, integer arrays, boolean arrays, None, Ellipsis).
+    It also properly returns scalars when this is appropriate.
+  - The ``fitsdiff`` script ignore some things be default when comparing fits
+    files (e.g. empty header lines). This add as ``--exact`` option where
+    nothing is ignored. [#2782], finished in [#3110]
+
+- ``astropy.io.votable``
+
+  - ``astropy.io.votable.parse`` now takes a ``datatype_mapping``
+    keyword argument to map invalid datatype names to valid ones in
+    order to support non-compliant files. [#2675]
+
+- ``astropy.modeling``
+
+  - A new ``custom_model`` decorator/factory function has been added for
+    converting normal functions to ``Model`` classes that can work within
+    the Astropy modeling framework.  This replaces the old ``custom_model_1d``
+    function which is now deprecated.  The new function works the same as
+    the old one but is less limited in the types of models it can be used to
+    created.  [#1763]
+
+  - The ``Model`` and ``Fitter`` classes have ``.registry`` attributes which
+    provide sets of all loaded ``Model`` and ``Fitter`` classes (this is
+    useful for building UIs for models and fitting). [#2725]
+
+  - A dict-like ``meta`` member was added to ``Model``. it is to be used to
+    store any optional information which is relevant to a project and is not
+    in the standard ``Model`` class. [#2189]
+
+  - Added ``Ellipse2D`` model. [#3124]
+
+- ``astropy.nddata``
+
+  - New array-related utility functions in ``astropy.nddata.utils`` for adding
+    and removing arrays from other arrays with different sizes/shapes. [#3201]
+
+  - New metaclass ``NDDataBase`` for enforcing the nddata interface in
+    subclasses without restricting implementation of the data storage. [#2905]
+
+  - New mixin classes ``NDSlicingMixin`` for slicing, ``NDArithmeticMixin``
+    for arithmetic operations, and ``NDIOMixin`` for input/ouput in NDData. [#2905]
+
+  - Added a decorator ``support_nddata`` that can be used to write functions
+    that can either take separate arguments or NDData objects. [#2855]
+
+- ``astropy.stats``
+
+  - Added ``mad_std()`` function. [#3208]
+
+  - Added ``gaussian_fwhm_to_sigma`` and ``gaussian_sigma_to_fwhm``
+    constants. [#3208]
+
+  - New function ``sigma_clipped_stats`` which can be used to quickly get
+    common statistics for an array, using sigma clipping at the same time.
+    [#3201]
+
+- ``astropy.table``
+
+  - Changed the internal implementation of the ``Table`` class changed so that
+    it no longer uses numpy structured arrays as the core table data container.
+    [#2790, #3179]
+
+  - Tables can now be written to an html file that includes interactive
+    browsing capabilities. To write out to this format, use
+    ``Table.write('filename.html', format='jsviewer')``. [#2875]
+
+  - A ``quantity`` property and ``to`` method were added to ``Table``
+    columns that allow the column values to be easily converted to
+    ``astropy.units.Quantity`` objects. [#2950]
+
+  - Add ``unique`` convenience method to table. [#3185]
+
+- ``astropy.tests``
+
+  - Added a new Quantity-aware ``assert_quantity_allclose``. [#3273]
+
+- ``astropy.time``
+
+  - ``Time`` can now handle arbitrary array dimensions, with operations
+    following standard numpy broadcasting rules. [#3138]
+
+- ``astropy.units``
+
+  - Support for VOUnit has been updated to be compliant with version
+    1.0 of the standard. [#2901]
+
+  - Added an ``insert`` method to insert values into a ``Quantity`` object.
+    This is similar to the ``numpy.insert`` function. [#3049]
+
+  - When viewed in IPython, ``Quantity`` objects with array values now render
+    using LaTeX and scientific notation. [#2271]
+
+  - Added ``units.quantity_input`` decorator to validate quantity inputs to a
+    function for unit compatibility. [#3072]
+
+  - Added ``units.astronomical_unit`` as a long form for ``units.au``. [#3303]
+
+- ``astropy.utils``
+
+  - Added a new decorator ``astropy.utils.wraps`` which acts as a replacement
+    for the standard library's ``functools.wraps``, the only difference being
+    that the decorated function also preserves the wrapped function's call
+    signature. [#2849]
+
+  - ``astropy.utils.compat.numpy`` has been revised such that it can include
+    patched versions of routines from newer ``numpy`` versions.  The first
+    addition is a version of ``broadcast_arrays`` that can be used with
+    ``Quantity`` and other ``ndarray`` subclasses (using the ``subok=True``
+    flag). [#2327]
+
+- ``astropy.visualization``
+
+  - Created ``astropy.visualization`` module and added functionality relating
+    to image normalization (i.e. stretching and scaling) as well as a new
+    script ``fits2bitmap`` that can produce a bitmap image from a FITS file.
+    [#3201]
+
+  - Added dictionary ``astropy.visualization.mpl_style.astropy_mpl_style``
+    which can be used to set a uniform plotstyle specifically for tutorials
+    that is improved compared to matplotlib defaults. [#2719, #2787, #3200]
+
+- ``astropy.wcs``
+
+  - ``wcslib`` has been upgraded to version 4.25.  This brings a
+    single new feature:
+
+    - ``equinox`` and ``radesys`` will now be given default values
+      conforming with the WCS specification if ``EQUINOXa`` and
+      ``RADESYSa``, respectively, are not present in the header.
+
+  - The minimum required version of ``wcslib`` is now 4.24. [#2503]
+
+  - Added a new function ``wcs_to_celestial_frame`` that can be used to find
+    the astropy.coordinates celestial frame corresponding to a particular WCS.
+    [#2730]
+
+  - ``astropy.wcs.WCS.compare`` now supports a ``tolerance`` keyword argument
+    to allow for approximate comparison of floating-point values. [#2503]
+
+  - added ``pixel_scale_matrix``, ``celestial``, ``is_celestial``, and
+    ``has_celestial`` convenience attributes. Added
+    ``proj_plane_pixel_scales``, ``proj_plane_pixel_area``, and
+    ``non_celestial_pixel_scales`` utility functions for retrieving WCS pixel
+    scale and area information [#2832, #3304]
+
+  - Added two functions ``pixel_to_skycoord`` and
+    ``skycoord_to_pixel`` that make it easy to convert between
+    SkyCoord objects and pixel coordinates. [#2885]
+
+  - ``all_world2pix`` now uses a much more sophisticated and complete
+    algorithm to iteratively compute the inverse WCS transform. [#2816]
+
+  - Add ability to use ``WCS`` object to define projections in Matplotlib,
+    using the ``WCSAxes`` package. [#3183]
+
+API Changes
+^^^^^^^^^^^
+
+- ``astropy.coordinates``
+
+  - Subclasses of ``BaseCoordinateFrame`` which define a custom ``repr`` should
+    be aware of the format expected in ``SkyCoord.__repr__()``, which changed in
+    this release. [#2704, #2882]
+
+  - The ``CartesianPoints`` class (deprecated in v0.4) has now been removed.
+    [#2990]
+
+  - The previous ``astropy.coordinates.builtin_frames`` module is now a
+    subpackage.  Everything that was in the
+    ``astropy.coordinates.builtin_frames`` module is still accessible from the
+    new package, but the classes are now in separate modules.  This should have
+    no direct impact at the user level. [#3120]
+
+  - Support for passing a frame as a positional argument in the ``SkyCoord``
+    class has now been deprecated, except in the case where a frame with data
+    is passed as the sole positional argument. [#3152]
+
+- ``astropy.cosmology``
+
+  - The functional interface to the cosmological routines as well as
+    ``set_current`` and ``get_current`` (deprecated in v0.4) have now been
+    removed. [#2990]
+
+- ``astropy.io.ascii``
+
+  - Added a new argument to ``htmldict`` in the HTML reader named
+    ``parser``, which allows the user to specify which parser
+    BeautifulSoup should use as a backend. [#2815]
+
+  - Add ``FixedWidthTwoLine`` reader to guessing. This will allows to read tables
+    that a copied from screen output like ``print my_table`` to be read
+    automatically. Discussed in #3025 and #3099 [#3109]
+
+- ``astropy.io.fits``
+
+  - A new optional argument ``cache`` has been added to
+    ``astropy.io.fits.open()``.  When opening a FITS file from a URL,
+    ``cache`` is a boolean value specifying whether or not to save the
+    file locally in Astropy's download cache (``True`` by default). [#3041]
+
+- ``astropy.modeling``
+
+  - Model classes should now specify ``inputs`` and ``outputs`` class
+    attributes instead of the old ``n_inputs`` and ``n_outputs``.  These
+    should be tuples providing human-readable *labels* for all inputs and
+    outputs of the model.  The length of the tuple indicates the numbers
+    of inputs and outputs.  See "What's New in Astropy 1.0" for more
+    details. [#2835]
+
+  - It is no longer necessary to include ``__init__`` or ``__call__``
+    definitions in ``Model`` subclasses if all they do is wrap the
+    super-method in order to provide a nice call signature to the docs.
+    The ``inputs`` class attribute is now used to generate a nice call
+    signature, so these methods should only be overridden by ``Model``
+    subclasses in order to provide new functionality. [#2835]
+
+  - Most models included in Astropy now have sensible default values for most
+    or all of their parameters.  Call ``help(ModelClass)`` on any model to
+    check what those defaults are.  Most of them time they should be
+    overridden, but some of them are useful (for example spatial offsets are
+    always set at the origin by default). Another rule of thumb is that, where
+    possible, default parameters are set so that the model is a no-op, or
+    close to it, by default. [#2932]
+
+  - The ``Model.inverse`` method has been changed to a *property*, so that
+    now accessing ``model.inverse`` on a model returns a new model that
+    implements that model's inverse, and *calling* ``model.inverse(...)``` on
+    some independent variable computes the value of the inverse (similar to what
+    the old ``Model.invert()`` method was meant to do).  [#3024]
+
+  - The ``Model.invert()`` method has been removed entirely (it was never
+    implemented and there should not be any existing code that relies on it).
+    [#3024]
+
+  - ``custom_model_1d`` is deprecated in favor of the new ``custom_model``
+    (see "New Features" above).  [#1763]
+
+  - The ``Model.param_dim`` property (deprecated in v0.4) has now been removed.
+    [#2990]
+
+  - The ``Beta1D`` and ``Beta2D`` models have been renamed to
+    ``Moffat1D`` and ``Moffat2D`` [#3029]
+
+- ``astropy.nddata``
+
+  - ``flags``, ``shape``, ``size``, ``dtype`` and ``ndim`` properties removed
+    from ``astropy.nddata.NDData``. [#2905]
+
+  - Arithmetic operations, uncertainty propagation, slicing and automatic
+    conversion to a numpy array removed from ``astropy.nddata.NDData``. The
+    class ``astropy.nddata.NDDataArray`` is functionally equivalent to the
+    old ``NDData``.  [#2905]
+
+- ``astropy.table``
+
+  - The ``Column.units`` property (deprecated in v0.3) has now been removed.
+    [#2990]
+
+  - The ``Row.data`` and ``Table._data`` attributes have been deprecated
+    related to the change in Table implementation.  They are replaced by
+    ``Row.as_void()`` and ``Table.as_array()`` methods, respectively. [#2790]
+
+  - The ``Table.create_mask`` method has been removed.  This undocumented
+    method was a development orphan and would cause corruption of the
+    table if called. [#2790]
+
+  - The return type for integer item access to a Column (e.g. col[12] or
+    t['a'][12]) is now always a numpy scalar, numpy ``ndarray``, or numpy
+    ``MaskedArray``.  Previously if the column was multidimensional then a
+    Column object would be returned. [#3095]
+
+  - The representation of Table and Column objects has been changed to
+    be formatted similar to the print output. [#3239]
+
+- ``astropy.time``
+
+  - The ``Time.val`` and ``Time.vals`` properties (deprecated in v0.3) and the
+    ``Time.lon``, and ``Time.lat`` properties (deprecated in v0.4) have now
+    been removed. [#2990]
+
+  - Add ``decimalyear`` format that represents time as a decimal year. [#3265]
+
+- ``astropy.units``
+
+  - Support for VOUnit has been updated to be compliant with version
+    1.0 of the standard. This means that some VOUnit strings that were
+    rejected before are now acceptable. [#2901] Notably:
+
+      - SI prefixes are supported on most units
+      - Binary prefixes are supported on "bits" and "bytes"
+      - Custom units can be defined "inline" by placing them between single
+        quotes.
+
+- ``astropy.utils``
+
+  - Some members of ``astropy.utils.misc`` were moved into new submodules.
+    Specifically:
+
+    - ``deprecated``, ``deprecated_attribute``, and ``lazyproperty`` ->
+      ``astropy.utils.decorators``
+
+    - ``find_current_module``, ``find_mod_objs`` ->
+      ``astropy.utils.introspection``
+
+    All of these functions can be imported directly from ``astropy.utils``
+    which should be preferred over referencing individual submodules of
+    ``astropy.utils``.  [#2857]
+
+  - The ProgressBar.iterate class method (deprecated in v0.3) has now been
+    removed. [#2990]
+
+  - Updated ``astropy/utils/console.py`` ProgressBar() module to
+    display output to IPython notebook with the addition of an
+    ``interactive`` kwarg. [#2658] [#2789]
+
+- ``astropy.wcs``
+
+  - The ``WCS.calcFootprint`` method (deprecated in v0.4) has now been removed.
+    [#2990]
+
+  - An invalid unit in a ``CUNITn`` keyword now displays a warning and
+    returns a ``UnrecognizedUnit`` instance rather than raising an
+    exception [#3190]
+
+Bug Fixes
+^^^^^^^^^
+
+- ``astropy.convolution``
+
+  - ``astropy.convolution.discretize_model`` now handles arbitrary callables correctly [#2274].
+
+- ``astropy.coordinates``
+
+  - ``Angle.to_string`` now outputs unicode arrays instead of object arrays [#2981]
+
+  - ``SkyCoord.to_string`` no longer gives an error when used with an array
+    coordinate with more than one dimension. [#3340]
+
+  - Fixed support for subclasses of ``UnitSphericalRepresentation`` and
+    ``SphericalRepresentation`` [#3354, #3366]
+
+- ``astropy.io.ascii``
+
+  - In the ``CommentedHeader`` the ``data_start`` parameter now defaults to
+    ``0``, which is the first uncommented line. Discussed in #2692. [#3054]
+
+  - Position lines in ``FixedWidthTwoLine`` reader could consist of many characters.
+    Now, only one character in addition to the delimiter is allowed. This bug was
+    discovered as part of [#3109]
+
+  - The IPAC table writer now consistently uses the ``fill_values`` keyword to
+    specify the output null values.  Previously the behavior was inconsistent
+    or incorrect. [#3259]
+
+  - The IPAC table reader now correctly interprets abbreviated column types. [#3279]
+
+  - Tables that look almost, but not quite like DAOPhot tables could cause guessing
+    to fail. [#3342]
+
+- ``astropy.io.fits``
+
+  - Fixed the problem in ``fits.open`` of some filenames with colon (``:``) in
+    the name being recognized as URLs instead of file names. [#3122]
+
+  - Setting ``memmap=True`` in ``fits.open`` and related functions now raises a ValueError if opening a file in memory-mapped mode is impossible. [#2298]
+
+  - CONTINUE cards no longer end the value of the final card in the series with an ampersand, per the specification of the CONTINUE card convention. [#3282]
+
+- ``astropy.logger``
+
+  - Fix a bug that occurred when displaying warnings that produced an error
+    message ``dictionary changed size during iteration``. [#3353]
+
+- ``astropy.modeling``
+
+  - Fixed a bug in ``SLSQPLSQFitter`` where the ``maxiter`` argument was not
+    passed correctly to the optimizer. [#3339]
+
+- ``astropy.table``
+
+  - Fix a problem where ``table.hstack`` fails to stack multiple references to
+    the same table, e.g. ``table.hstack([t, t])``. [#2995]
+
+  - Fixed a problem where ``table.vstack`` and ``table.hstack`` failed to stack
+    a single table, e.g. ``table.vstack([t])``. [#3313]
+
+  - Fix a problem when doing nested iterators on a single table. [#3358]
+
+- ``astropy.time``
+
+  - When creating a Time object from a datetime object the time zone
+    info is now correctly used. [#3160]
+
+- ``astropy.units``
+
+  - Added a ``latex_inline`` unit format that returns the units in LaTeX math
+    notation with negative exponents instead of fractions [#2622].
+
+  - When using a unit that is deprecated in a given unit format,
+    non-deprecated alternatives will be suggested. [#2806] For
+    example::
+
+      >>> import astropy.units as u
+      >>> u.Unit('Angstrom', format='fits')
+      WARNING: UnitsWarning: The unit 'Angstrom' has been deprecated
+      in the FITS standard. Suggested: nm (with data multiplied by
+      0.1).  [astropy.units.format.utils]
+
+- ``astropy.utils``
+
+  - ``treat_deprecations_as_exceptions`` has been fixed to recognize Astropy
+    deprecation warnings. [#3015]
+
+- ``astropy.wcs``
+
+  - ``astropy.wcs.WCS.sub`` now accepts unicode strings as input on
+    Python 2.x [#3356]
+
+Other Changes and Additions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Updated ``astropy.extern.configobj`` to Version 5. Version 5 uses ``six``
+  and the same code covers both Python 2 and Python 3. [#3149]
+
+- ``astropy.coordinates``
+
+  - The ``repr`` of ``SkyCoord`` and coordinate frame classes now separate
+    frame attributes and coordinate information.  [#2704, #2882]
+
+- ``astropy.io.fits``
+
+  - Overwriting an existing file using the ``clobber=True`` option no longer
+    displays a warning message. [#1963]
+
+  - ``fits.open`` no longer catches ``OSError`` exceptions on missing or
+    unreadable files-- instead it raises the standard Python exceptions in such
+    cases. [#2756, #2785]
+
+- ``astropy.table``
+
+  - Sped up setting of ``Column`` slices by an order of magnitude. [#2994, #3020]
+
+- Updated the bundled ``six`` module to version 1.7.3 and made 1.7.3 the
+  minimum acceptable version of ``six``. [#2814]
+
+- The version of ERFA included with Astropy is now v1.1.1 [#2971]
+
+- The code base is now fully Python 2 and 3 compatible and no longer requires
+  2to3. [#2033]
+
+- `funcsigs <https://pypi.python.org/pypi/funcsigs>`_ is included in
+  utils.compat, but defaults to the inspect module components where available
+  (3.3+) [#3151].
+
+- The list of modules displayed in the pytest header can now be customized.
+  [#3157]
+
+- `jinja2 <http://jinja.pocoo.org/docs/dev/>`_ is now required to build the
+  source code from the git repository, in order to allow the ERFA wrappers to
+  be generated. [#3166]
+
+
 0.4.4 (2015-01-21)
 ------------------
 
@@ -17,7 +592,7 @@ API Changes
 - ``astropy.vo.samp``
 
   - The default SSL protocol used is now determined from the default
-    used in the Python `ssl` standard library.  This default may be
+    used in the Python ``ssl`` standard library.  This default may be
     different depending on the exact version of Python you are using.
     [#3308]
 
@@ -109,7 +684,7 @@ Bug Fixes
   - Operations on quantities with incompatible types now raises a much
     more informative ``TypeError``. [#2934]
 
-  - ``Quantity.tolist`` now overrides the ``ndarray`` method to give a 
+  - ``Quantity.tolist`` now overrides the ``ndarray`` method to give a
     ``NotImplementedError`` (by renaming the previous ``list`` method). [#3050]
 
   - ``Quantity.round`` now always returns a ``Quantity`` (previously it
@@ -139,7 +714,7 @@ Bug Fixes
     ``super()`` in their ``__init__`` method. [#3004]
 
   - Fixed a bug which caused the ``metadata_conflicts`` parameter to be
-    ignored in the ``astropy.utils.metadata.merge`` function. [#3294]  
+    ignored in the ``astropy.utils.metadata.merge`` function. [#3294]
 
 - ``astropy.vo``
 
@@ -159,13 +734,6 @@ Bug Fixes
   - Astropy will now work if your Python interpreter does not have the
     ``bz2`` module installed. [#3104]
 
-  - Invalid or out of range values passed to ``wcs_world2pix`` will
-    now be correctly identified and returned as ``nan``
-    values. [#2965]
-
-  - Fixed an issue which meant that Python thought ``WCS`` objects were
-    iterable. [#3066]
-
   - Fixed ``ResourceWarning`` for ``astropy/extern/bundled/six.py`` that could
     occur sometimes after using Astropy in Python 3.4. [#3156]
 
@@ -189,7 +757,7 @@ Bug Fixes
   - ``Angle`` accepts hours:mins or deg:mins initializers (without
      seconds). In these cases float minutes are also accepted.
 
-  - The ``repr`` for coordinate frames now displayes the frame attributes
+  - The ``repr`` for coordinate frames now displays the frame attributes
     (ex: ra, dec) in a consistent order.  It should be noted that as part of
     this fix, the ``BaseCoordinateFrame.get_frame_attr_names()`` method now
     returns an ``OrderedDict`` instead of just a ``dict``. [#2845]
@@ -201,7 +769,7 @@ Bug Fixes
     [#2710]
 
   - Fixed a crash when reading data from an HDU whose header contained in
-    invalid value for the BLANK keyword (eg. a string value instead of an
+    invalid value for the BLANK keyword (e.g., a string value instead of an
     integer as required by the FITS Standard). Invalid BLANK keywords are now
     warned about, but are otherwise ignored. [#2711]
 
@@ -623,8 +1191,8 @@ New Features
 
 - ``astropy.wcs``
 
-  - astropy now requires wcslib version 4.23 or later.  The version of
-    wcslib included with astropy has been updated to version 4.23.
+  - astropy now requires wcslib version 4.23.  The version of wcslib
+    included with astropy has been updated to version 4.23.
 
   - Bounds checking is now performed on native spherical
     coordinates.  Any out-of-bounds values will be returned as
@@ -985,8 +1553,8 @@ Bug Fixes
 
 - ``astropy.wcs``
 
-  - Astropy now requires wcslib version 4.23 or later.  The version of
-    wcslib included with astropy has been updated to version 4.23.
+  - Astropy now requires wcslib version 4.23.  The version of wcslib
+    included with astropy has been updated to version 4.23.
 
   - Bug fixes in the projection routines: in ``hpxx2s`` [the
     cartesian-to-spherical operation of the ``HPX`` projection]
@@ -1146,7 +1714,7 @@ Bug Fixes
   - Allow pickling of ``FITS_rec`` objects. [#1597]
 
   - Improved behavior when writing large compressed images on OSX by removing
-    an unncessary check for platform architecture. [#2345]
+    an unnecessary check for platform architecture. [#2345]
 
   - Fixed an issue where Astropy ``Table`` objects containing boolean columns
     were not correctly written out to FITS files. [#1953]
@@ -1206,6 +1774,9 @@ Bug Fixes
   - Progressbar will be limited to 100% so that the bar does not exceed the
     terminal width.  The numerical display can still exceed 100%, however.
 
+  - Converted representation of progress bar units without suffix
+    from float to int in console.human_file_size. [#2201,#2202,#2721,#3299]
+
 - ``astropy.vo``
 
   - Fixed ``format()`` compatibility with Python 2.6. [#2129]
@@ -2057,7 +2628,7 @@ API Changes
 - The ``--enable-legacy`` option for ``setup.py`` has been removed. [#1493]
 
 Bug Fixes
-^^^^^^^^^^
+^^^^^^^^^
 
 - ``astropy.io.ascii``
 
@@ -2162,7 +2733,7 @@ Other Changes and Additions
 
 - ``astropy.coordinates``
 
-  - Angles containing out of bounds minutes or seconds (eg. 60) can be
+  - Angles containing out of bounds minutes or seconds (e.g. 60) can be
     parsed--the value modulo 60 is used with carry to the hours/minutes, and a
     warning is issued rather than raising an exception. [#990]
 
@@ -2896,7 +3467,7 @@ see the "What's New" section of the documentation for more details.
 
 - ``astropy.wcs``
 
-  - From updating the the underlying wcslib 4.16:
+  - From updating the underlying wcslib 4.16:
 
     - When ``astropy.wcs.WCS`` constructs a default coordinate representation
       it will give it the special name "DEFAULTS", and will not report "Found
diff --git a/PKG-INFO b/PKG-INFO
index 50ccea1..6f5cac1 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: astropy
-Version: 0.4.4
+Version: 1.0rc1
 Summary: Community-developed python astronomy tools
 Home-page: http://astropy.org
 Author: The Astropy Developers
 Author-email: astropy.team at gmail.com
 License: BSD
-Download-URL: http://pypi.python.org/packages/source/a/astropy/astropy-0.4.4.tar.gz
+Download-URL: http://pypi.python.org/packages/source/a/astropy/astropy-1.0rc1.tar.gz
 Description: 
         Astropy is a package intended to contain core functionality and some
         common tools needed for performing astronomy and astrophysics research with
diff --git a/README.rst b/README.rst
index 7e813ef..c592ed0 100644
--- a/README.rst
+++ b/README.rst
@@ -26,20 +26,22 @@ For system packagers: Please install Astropy with the command::
 This will prevent the astropy_helpers bootstrap script from attempting to
 reach out to PyPI.
 
+Project Status
+--------------
 
-Travis Build Status
--------------------
 .. image:: https://travis-ci.org/astropy/astropy.png
     :target: https://travis-ci.org/astropy/astropy
 
-
-Test Coverage Status
---------------------
-
 .. image:: https://coveralls.io/repos/astropy/astropy/badge.png
     :target: https://coveralls.io/r/astropy/astropy
 
+.. image:: https://ci.appveyor.com/api/projects/status/ym7lxajcs5qwm31e/branch/master?svg=true
+    :target: https://ci.appveyor.com/project/Astropy/astropy/branch/master
+
+For an overview of the testing and build status of all packages associated 
+with the Astropy Project, see http://dashboard.astropy.org.
+
 License
 -------
 Astropy is licensed under a 3-clause BSD style license - see the
-``licenses/LICENSE.rst`` file.
\ No newline at end of file
+``licenses/LICENSE.rst`` file.
diff --git a/ah_bootstrap.py b/ah_bootstrap.py
index 6888c3e..6281e4f 100644
--- a/ah_bootstrap.py
+++ b/ah_bootstrap.py
@@ -87,6 +87,7 @@ except:
 from distutils import log
 from distutils.debug import DEBUG
 
+
 # In case it didn't successfully import before the ez_setup checks
 import pkg_resources
 
@@ -112,199 +113,309 @@ PACKAGE_NAME = 'astropy_helpers'
 DOWNLOAD_IF_NEEDED = True
 INDEX_URL = 'https://pypi.python.org/simple'
 USE_GIT = True
+OFFLINE = False
 AUTO_UPGRADE = True
 
+# A list of all the configuration options and their required types
+CFG_OPTIONS = [
+    ('auto_use', bool), ('path', str), ('download_if_needed', bool),
+    ('index_url', str), ('use_git', bool), ('offline', bool),
+    ('auto_upgrade', bool)
+]
+
 
-def use_astropy_helpers(path=None, download_if_needed=None, index_url=None,
-                        use_git=None, auto_upgrade=None):
+class _Bootstrapper(object):
+    """
+    Bootstrapper implementation.  See ``use_astropy_helpers`` for parameter
+    documentation.
     """
-    Ensure that the `astropy_helpers` module is available and is importable.
-    This supports automatic submodule initialization if astropy_helpers is
-    included in a project as a git submodule, or will download it from PyPI if
-    necessary.
 
-    Parameters
-    ----------
+    def __init__(self, path=None, index_url=None, use_git=None, offline=None,
+                 download_if_needed=None, auto_upgrade=None):
 
-    path : str or None, optional
-        A filesystem path relative to the root of the project's source code
-        that should be added to `sys.path` so that `astropy_helpers` can be
-        imported from that path.
+        if path is None:
+            path = PACKAGE_NAME
 
-        If the path is a git submodule it will automatically be initialzed
-        and/or updated.
+        if not (isinstance(path, _str_types) or path is False):
+            raise TypeError('path must be a string or False')
 
-        The path may also be to a ``.tar.gz`` archive of the astropy_helpers
-        source distribution.  In this case the archive is automatically
-        unpacked and made temporarily available on `sys.path` as a ``.egg``
-        archive.
+        if PY3 and not isinstance(path, _text_type):
+            fs_encoding = sys.getfilesystemencoding()
+            path = path.decode(fs_encoding)  # path to unicode
 
-        If `None` skip straight to downloading.
+        self.path = path
 
-    download_if_needed : bool, optional
-        If the provided filesystem path is not found an attempt will be made to
-        download astropy_helpers from PyPI.  It will then be made temporarily
-        available on `sys.path` as a ``.egg`` archive (using the
-        ``setup_requires`` feature of setuptools.  If the ``--offline`` option
-        is given at the command line the value of this argument is overridden
-        to `False`.
+        # Set other option attributes, using defaults where necessary
+        self.index_url = index_url if index_url is not None else INDEX_URL
+        self.offline = offline if offline is not None else OFFLINE
 
-    index_url : str, optional
-        If provided, use a different URL for the Python package index than the
-        main PyPI server.
+        # If offline=True, override download and auto-upgrade
+        if self.offline:
+            download_if_needed = False
+            auto_upgrade = False
 
-    use_git : bool, optional
-        If `False` no git commands will be used--this effectively disables
-        support for git submodules. If the ``--no-git`` option is given at the
-        command line the value of this argument is overridden to `False`.
+        self.download = (download_if_needed
+                         if download_if_needed is not None
+                         else DOWNLOAD_IF_NEEDED)
+        self.auto_upgrade = (auto_upgrade
+                             if auto_upgrade is not None else AUTO_UPGRADE)
 
-    auto_upgrade : bool, optional
-        By default, when installing a package from a non-development source
-        distribution ah_boostrap will try to automatically check for patch
-        releases to astropy-helpers on PyPI and use the patched version over
-        any bundled versions.  Setting this to `False` will disable that
-        functionality. If the ``--offline`` option is given at the command line
-        the value of this argument is overridden to `False`.
-    """
+        # If this is a release then the .git directory will not exist so we
+        # should not use git.
+        git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git'))
+        if use_git is None and not git_dir_exists:
+            use_git = False
 
-    # True by default, unless the --offline option was provided on the command
-    # line
-    if '--offline' in sys.argv:
-        download_if_needed = False
-        auto_upgrade = False
-        offline = True
-        sys.argv.remove('--offline')
-    else:
-        offline = False
-
-    if '--no-git' in sys.argv:
-        use_git = False
-        sys.argv.remove('--no-git')
-
-    if path is None:
-        path = PACKAGE_NAME
-
-    if download_if_needed is None:
-        download_if_needed = DOWNLOAD_IF_NEEDED
-
-    if index_url is None:
-        index_url = INDEX_URL
-
-    # If this is a release then the .git directory will not exist so we
-    # should not use git.
-    git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git'))
-    if use_git is None and not git_dir_exists:
-        use_git = False
-
-    if use_git is None:
-        use_git = USE_GIT
-
-    if auto_upgrade is None:
-        auto_upgrade = AUTO_UPGRADE
-
-    # Declared as False by default--later we check if astropy-helpers can be
-    # upgraded from PyPI, but only if not using a source distribution (as in
-    # the case of import from a git submodule)
-    is_submodule = False
-
-    if not isinstance(path, _str_types):
-        if path is not None:
-            raise TypeError('path must be a string or None')
-
-        if not download_if_needed:
-            log.debug('a path was not given and download from PyPI was not '
-                      'allowed so this is effectively a no-op')
-            return
-    elif not os.path.exists(path) or os.path.isdir(path):
-        # Even if the given path does not exist on the filesystem, if it *is* a
-        # submodule, `git submodule init` will create it
-        is_submodule = _check_submodule(path, use_git=use_git,
-                                        offline=offline)
-
-        if is_submodule or os.path.isdir(path):
-            log.info(
-                'Attempting to import astropy_helpers from {0} {1!r}'.format(
-                    'submodule' if is_submodule else 'directory', path))
-            dist = _directory_import(path)
+        self.use_git = use_git if use_git is not None else USE_GIT
+        # Declared as False by default--later we check if astropy-helpers can be
+        # upgraded from PyPI, but only if not using a source distribution (as in
+        # the case of import from a git submodule)
+        self.is_submodule = False
+
+    @classmethod
+    def main(cls, argv=None):
+        if argv is None:
+            argv = sys.argv
+
+        config = cls.parse_config()
+        config.update(cls.parse_command_line(argv))
+
+        auto_use = config.pop('auto_use', False)
+        bootstrapper = cls(**config)
+
+        if auto_use:
+            # Run the bootstrapper, otherwise the setup.py is using the old
+            # use_astropy_helpers() interface, in which case it will run the
+            # bootstrapper manually after reconfiguring it.
+            bootstrapper.run()
+
+        return bootstrapper
+
+    @classmethod
+    def parse_config(cls):
+        if not os.path.exists('setup.cfg'):
+            return {}
+
+        cfg = ConfigParser()
+
+        try:
+            cfg.read('setup.cfg')
+        except Exception as e:
+            if DEBUG:
+                raise
+
+            log.error(
+                "Error reading setup.cfg: {0!r}\n{1} will not be "
+                "automatically bootstrapped and package installation may fail."
+                "\n{2}".format(e, PACKAGE_NAME, _err_help_msg))
+            return {}
+
+        if not cfg.has_section('ah_bootstrap'):
+            return {}
+
+        config = {}
+
+        for option, type_ in CFG_OPTIONS:
+            if not cfg.has_option('ah_bootstrap', option):
+                continue
+
+            if type_ is bool:
+                value = cfg.getboolean('ah_bootstrap', option)
+            else:
+                value = cfg.get('ah_bootstrap', option)
+
+            config[option] = value
+
+        return config
+
+    @classmethod
+    def parse_command_line(cls, argv=None):
+        if argv is None:
+            argv = sys.argv
+
+        config = {}
+
+        # For now we just pop recognized ah_bootstrap options out of the
+        # arg list.  This is imperfect; in the unlikely case that a setup.py
+        # custom command or even custom Distribution class defines an argument
+        # of the same name then we will break that.  However there's a catch22
+        # here that we can't just do full argument parsing right here, because
+        # we don't yet know *how* to parse all possible command-line arguments.
+        if '--no-git' in argv:
+            config['use_git'] = False
+            argv.remove('--no-git')
+
+        if '--offline' in argv:
+            config['offline'] = True
+            argv.remove('--offline')
+
+        return config
+
+    def run(self):
+        strategies = ['local_directory', 'local_file', 'index']
+        dist = None
+
+        # Check to see if the path is a submodule
+        self.is_submodule = self._check_submodule()
+
+        for strategy in strategies:
+            method = getattr(self, 'get_{0}_dist'.format(strategy))
+            dist = method()
+            if dist is not None:
+                break
         else:
-            dist = None
+            raise _AHBootstrapSystemExit(
+                "No source found for the {0!r} package; {0} must be "
+                "available and importable as a prerequisite to building "
+                "or installing this package.".format(PACKAGE_NAME))
+
+        # Otherwise we found a version of astropy-helpers, so we're done
+        # Just active the found distribution on sys.path--if we did a
+        # download this usually happens automatically but it doesn't hurt to
+        # do it again
+        # Note: Adding the dist to the global working set also activates it
+        # (makes it importable on sys.path) by default
+        pkg_resources.working_set.add(dist)
+
+    @property
+    def config(self):
+        """
+        A `dict` containing the options this `_Bootstrapper` was configured
+        with.
+        """
+
+        return dict((optname, getattr(self, optname))
+                    for optname, _ in CFG_OPTIONS if hasattr(self, optname))
+
+    def get_local_directory_dist(self):
+        """
+        Handle importing a vendored package from a subdirectory of the source
+        distribution.
+        """
+
+        if not os.path.isdir(self.path):
+            return
+
+        log.info('Attempting to import astropy_helpers from {0} {1!r}'.format(
+                 'submodule' if self.is_submodule else 'directory',
+                 self.path))
+
+        dist = self._directory_import()
 
         if dist is None:
-            msg = (
+            log.warn(
                 'The requested path {0!r} for importing {1} does not '
-                'exist, or does not contain a copy of the {1} package.  '
-                'Attempting download instead.'.format(path, PACKAGE_NAME))
-            if download_if_needed:
-                log.warn(msg)
-            else:
-                raise _AHBootstrapSystemExit(msg)
-    elif os.path.isfile(path):
-        # Handle importing from a source archive; this also uses setup_requires
-        # but points easy_install directly to the source archive
+                'exist, or does not contain a copy of the {1} '
+                'package.'.format(self.path, PACKAGE_NAME))
+        elif self.auto_upgrade and not self.is_submodule:
+            # A version of astropy-helpers was found on the available path, but
+            # check to see if a bugfix release is available on PyPI
+            upgrade = self._do_upgrade(dist)
+            if upgrade is not None:
+                dist = upgrade
+
+        return dist
+
+    def get_local_file_dist(self):
+        """
+        Handle importing from a source archive; this also uses setup_requires
+        but points easy_install directly to the source archive.
+        """
+
+        if not os.path.isfile(self.path):
+            return
+
+        log.info('Attempting to unpack and import astropy_helpers from '
+                 '{0!r}'.format(self.path))
+
         try:
-            dist = _do_download(find_links=[path])
+            dist = self._do_download(find_links=[self.path])
         except Exception as e:
-            if download_if_needed:
-                log.warn('{0}\nWill attempt to download astropy_helpers from '
-                         'PyPI instead.'.format(str(e)))
-                dist = None
-            else:
-                raise _AHBootstrapSystemExit(e.args[0])
-    else:
-        msg = ('{0!r} is not a valid file or directory (it could be a '
-               'symlink?)'.format(path))
-        if download_if_needed:
-            log.warn(msg)
+            if DEBUG:
+                raise
+
+            log.warn(
+                'Failed to import {0} from the specified archive {1!r}: '
+                '{2}'.format(PACKAGE_NAME, self.path, str(e)))
             dist = None
-        else:
-            raise _AHBootstrapSystemExit(msg)
 
-    if dist is not None and auto_upgrade and not is_submodule:
-        # A version of astropy-helpers was found on the available path, but
-        # check to see if a bugfix release is available on PyPI
-        upgrade = _do_upgrade(dist, index_url)
-        if upgrade is not None:
-            dist = upgrade
-    elif dist is None:
-        # Last resort--go ahead and try to download the latest version from
-        # PyPI
+        if dist is not None and self.auto_upgrade:
+            # A version of astropy-helpers was found on the available path, but
+            # check to see if a bugfix release is available on PyPI
+            upgrade = self._do_upgrade(dist)
+            if upgrade is not None:
+                dist = upgrade
+
+        return dist
+
+    def get_index_dist(self):
+        if not self.download:
+            log.warn('Downloading {0!r} disabled.'.format(DIST_NAME))
+            return False
+
+        log.warn(
+            "Downloading {0!r}; run setup.py with the --offline option to "
+            "force offline installation.".format(DIST_NAME))
+
         try:
-            if download_if_needed:
-                log.warn(
-                    "Downloading astropy_helpers; run setup.py with the "
-                    "--offline option to force offline installation.")
-                dist = _do_download(index_url=index_url)
-            else:
-                raise _AHBootstrapSystemExit(
-                    "No source for the astropy_helpers package; "
-                    "astropy_helpers must be available as a prerequisite to "
-                    "installing this package.")
+            dist = self._do_download()
         except Exception as e:
             if DEBUG:
                 raise
-            else:
-                raise _AHBootstrapSystemExit(e.args[0])
-
-    if dist is not None:
-        # Otherwise we found a version of astropy-helpers so we're done
-        # Just activate the found distribibution on sys.path--if we did a
-        # download this usually happens automatically but do it again just to
-        # be sure
-        # Note: Adding the dist to the global working set also activates it by
-        # default
-        pkg_resources.working_set.add(dist)
+            log.warn(
+                'Failed to download and/or install {0!r} from {1!r}:\n'
+                '{2}'.format(DIST_NAME, self.index_url, str(e)))
+            dist = None
 
+        # No need to run auto-upgrade here since we've already presumably
+        # gotten the most up-to-date version from the package index
+        return dist
 
-def _do_download(version='', find_links=None, index_url=None):
-    try:
+    def _directory_import(self):
+        """
+        Import astropy_helpers from the given path, which will be added to
+        sys.path.
+
+        Must return True if the import succeeded, and False otherwise.
+        """
+
+        # Return True on success, False on failure but download is allowed, and
+        # otherwise raise SystemExit
+        path = os.path.abspath(self.path)
+
+        # Use an empty WorkingSet rather than the man
+        # pkg_resources.working_set, since on older versions of setuptools this
+        # will invoke a VersionConflict when trying to install an upgrade
+        ws = pkg_resources.WorkingSet([])
+        ws.add_entry(path)
+        dist = ws.by_key.get(DIST_NAME)
+
+        if dist is None:
+            # We didn't find an egg-info/dist-info in the given path, but if a
+            # setup.py exists we can generate it
+            setup_py = os.path.join(path, 'setup.py')
+            if os.path.isfile(setup_py):
+                with _silence():
+                    run_setup(os.path.join(path, 'setup.py'),
+                              ['egg_info'])
+
+                for dist in pkg_resources.find_distributions(path, True):
+                    # There should be only one...
+                    return dist
+
+        return dist
+
+    def _do_download(self, version='', find_links=None):
         if find_links:
             allow_hosts = ''
             index_url = None
         else:
             allow_hosts = None
+            index_url = self.index_url
+
         # Annoyingly, setuptools will not handle other arguments to
         # Distribution (such as options) before handling setup_requires, so it
-        # is not straightfoward to programmatically augment the arguments which
+        # is not straightforward to programmatically augment the arguments which
         # are passed to easy_install
         class _Distribution(Distribution):
             def get_option_dict(self, command_name):
@@ -324,129 +435,281 @@ def _do_download(version='', find_links=None, index_url=None):
             req = DIST_NAME
 
         attrs = {'setup_requires': [req]}
-        if DEBUG:
-            dist = _Distribution(attrs=attrs)
+
+        try:
+            if DEBUG:
+                _Distribution(attrs=attrs)
+            else:
+                with _silence():
+                    _Distribution(attrs=attrs)
+
+            # If the setup_requires succeeded it will have added the new dist to
+            # the main working_set
+            return pkg_resources.working_set.by_key.get(DIST_NAME)
+        except Exception as e:
+            if DEBUG:
+                raise
+
+            msg = 'Error retrieving {0} from {1}:\n{2}'
+            if find_links:
+                source = find_links[0]
+            elif index_url != INDEX_URL:
+                source = index_url
+            else:
+                source = 'PyPI'
+
+            raise Exception(msg.format(DIST_NAME, source, repr(e)))
+
+    def _do_upgrade(self, dist):
+        # Build up a requirement for a higher bugfix release but a lower minor
+        # release (so API compatibility is guaranteed)
+        # sketchy version parsing--maybe come up with something a bit more
+        # robust for this
+        major, minor = (int(part) for part in dist.parsed_version[:2])
+        next_minor = '.'.join([str(major), str(minor + 1), '0'])
+        req = pkg_resources.Requirement.parse(
+            '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_minor))
+
+        package_index = PackageIndex(index_url=self.index_url)
+
+        upgrade = package_index.obtain(req)
+
+        if upgrade is not None:
+            return self._do_download(version=upgrade.version)
+
+    def _check_submodule(self):
+        """
+        Check if the given path is a git submodule.
+
+        See the docstrings for ``_check_submodule_using_git`` and
+        ``_check_submodule_no_git`` for further details.
+        """
+
+        if (self.path is None or
+                (os.path.exists(self.path) and not os.path.isdir(self.path))):
+            return False
+
+        if self.use_git:
+            return self._check_submodule_using_git()
         else:
-            with _silence():
-                dist = _Distribution(attrs=attrs)
+            return self._check_submodule_no_git()
 
-        # If the setup_requires succeeded it will have added the new dist to
-        # the main working_set
-        return pkg_resources.working_set.by_key.get(DIST_NAME)
-    except Exception as e:
-        if DEBUG:
-            raise
+    def _check_submodule_using_git(self):
+        """
+        Check if the given path is a git submodule.  If so, attempt to initialize
+        and/or update the submodule if needed.
 
-        msg = 'Error retrieving astropy helpers from {0}:\n{1}'
-        if find_links:
-            source = find_links[0]
-        elif index_url:
-            source = index_url
+        This function makes calls to the ``git`` command in subprocesses.  The
+        ``_check_submodule_no_git`` option uses pure Python to check if the given
+        path looks like a git submodule, but it cannot perform updates.
+        """
+
+        cmd = ['git', 'submodule', 'status', '--', self.path]
+
+        try:
+            log.info('Running `{0}`; use the --no-git option to disable git '
+                     'commands'.format(' '.join(cmd)))
+            returncode, stdout, stderr = run_cmd(cmd)
+        except _CommandNotFound:
+            # The git command simply wasn't found; this is most likely the
+            # case on user systems that don't have git and are simply
+            # trying to install the package from PyPI or a source
+            # distribution.  Silently ignore this case and simply don't try
+            # to use submodules
+            return False
+
+        stderr = stderr.strip()
+
+        if returncode != 0 and stderr:
+            # Unfortunately the return code alone cannot be relied on, as
+            # earlier versions of git returned 0 even if the requested submodule
+            # does not exist
+
+            # This is a warning that occurs in perl (from running git submodule)
+            # which only occurs with a malformatted locale setting which can
+            # happen sometimes on OSX.  See again
+            # https://github.com/astropy/astropy/issues/2749
+            perl_warning = ('perl: warning: Falling back to the standard locale '
+                            '("C").')
+            if not stderr.strip().endswith(perl_warning):
+                # Some other uknown error condition occurred
+                log.warn('git submodule command failed '
+                         'unexpectedly:\n{0}'.format(stderr))
+                return False
+
+        # Output of `git submodule status` is as follows:
+        #
+        # 1: Status indicator: '-' for submodule is uninitialized, '+' if
+        # submodule is initialized but is not at the commit currently indicated
+        # in .gitmodules (and thus needs to be updated), or 'U' if the
+        # submodule is in an unstable state (i.e. has merge conflicts)
+        #
+        # 2. SHA-1 hash of the current commit of the submodule (we don't really
+        # need this information but it's useful for checking that the output is
+        # correct)
+        #
+        # 3. The output of `git describe` for the submodule's current commit
+        # hash (this includes for example what branches the commit is on) but
+        # only if the submodule is initialized.  We ignore this information for
+        # now
+        _git_submodule_status_re = re.compile(
+            '^(?P<status>[+-U ])(?P<commit>[0-9a-f]{40}) '
+            '(?P<submodule>\S+)( .*)?$')
+
+        # The stdout should only contain one line--the status of the
+        # requested submodule
+        m = _git_submodule_status_re.match(stdout)
+        if m:
+            # Yes, the path *is* a git submodule
+            self._update_submodule(m.group('submodule'), m.group('status'))
+            return True
         else:
-            source = 'PyPI'
+            log.warn(
+                'Unexpected output from `git submodule status`:\n{0}\n'
+                'Will attempt import from {1!r} regardless.'.format(
+                    stdout, self.path))
+            return False
 
-        raise Exception(msg.format(source, repr(e)))
+    def _check_submodule_no_git(self):
+        """
+        Like ``_check_submodule_using_git``, but simply parses the .gitmodules file
+        to determine if the supplied path is a git submodule, and does not exec any
+        subprocesses.
 
+        This can only determine if a path is a submodule--it does not perform
+        updates, etc.  This function may need to be updated if the format of the
+        .gitmodules file is changed between git versions.
+        """
 
-def _do_upgrade(dist, index_url):
-    # Build up a requirement for a higher bugfix release but a lower minor
-    # release (so API compatibility is guaranteed)
-    # sketchy version parsing--maybe come up with something a bit more
-    # robust for this
-    major, minor = (int(part) for part in dist.parsed_version[:2])
-    next_minor = '.'.join([str(major), str(minor + 1), '0'])
-    req = pkg_resources.Requirement.parse(
-        '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_minor))
+        gitmodules_path = os.path.abspath('.gitmodules')
 
-    package_index = PackageIndex(index_url=index_url)
+        if not os.path.isfile(gitmodules_path):
+            return False
 
-    upgrade = package_index.obtain(req)
+        # This is a minimal reader for gitconfig-style files.  It handles a few of
+        # the quirks that make gitconfig files incompatible with ConfigParser-style
+        # files, but does not support the full gitconfig syntax (just enough
+        # needed to read a .gitmodules file).
+        gitmodules_fileobj = io.StringIO()
 
-    if upgrade is not None:
-        return _do_download(version=upgrade.version, index_url=index_url)
+        # Must use io.open for cross-Python-compatible behavior wrt unicode
+        with io.open(gitmodules_path) as f:
+            for line in f:
+                # gitconfig files are more flexible with leading whitespace; just
+                # go ahead and remove it
+                line = line.lstrip()
 
+                # comments can start with either # or ;
+                if line and line[0] in (':', ';'):
+                    continue
 
-def _directory_import(path):
-    """
-    Import astropy_helpers from the given path, which will be added to
-    sys.path.
+                gitmodules_fileobj.write(line)
 
-    Must return True if the import succeeded, and False otherwise.
-    """
+        gitmodules_fileobj.seek(0)
 
-    # Return True on success, False on failure but download is allowed, and
-    # otherwise raise SystemExit
-    path = os.path.abspath(path)
+        cfg = RawConfigParser()
 
-    # Use an empty WorkingSet rather than the man pkg_resources.working_set,
-    # since on older versions of setuptools this will invoke a VersionConflict
-    # when trying to install an upgrade
-    ws = pkg_resources.WorkingSet([])
-    ws.add_entry(path)
-    dist = ws.by_key.get(DIST_NAME)
+        try:
+            cfg.readfp(gitmodules_fileobj)
+        except Exception as exc:
+            log.warn('Malformatted .gitmodules file: {0}\n'
+                     '{1} cannot be assumed to be a git submodule.'.format(
+                         exc, self.path))
+            return False
 
-    if dist is None:
-        # We didn't find an egg-info/dist-info in the given path, but if a
-        # setup.py exists we can generate it
-        setup_py = os.path.join(path, 'setup.py')
-        if os.path.isfile(setup_py):
-            with _silence():
-                run_setup(os.path.join(path, 'setup.py'), ['egg_info'])
+        for section in cfg.sections():
+            if not cfg.has_option(section, 'path'):
+                continue
 
-            for dist in pkg_resources.find_distributions(path, True):
-                # There should be only one...
-                return dist
+            submodule_path = cfg.get(section, 'path').rstrip(os.sep)
 
-    return dist
+            if submodule_path == self.path.rstrip(os.sep):
+                return True
 
+        return False
 
-def _check_submodule(path, use_git=True, offline=False):
-    """
-    Check if the given path is a git submodule.
+    def _update_submodule(self, submodule, status):
+        if status == ' ':
+            # The submodule is up to date; no action necessary
+            return
+        elif status == '-':
+            if self.offline:
+                raise _AHBootstrapSystemExit(
+                    "Cannot initialize the {0} submodule in --offline mode; "
+                    "this requires being able to clone the submodule from an "
+                    "online repository.".format(submodule))
+            cmd = ['update', '--init']
+            action = 'Initializing'
+        elif status == '+':
+            cmd = ['update']
+            action = 'Updating'
+            if self.offline:
+                cmd.append('--no-fetch')
+        elif status == 'U':
+            raise _AHBoostrapSystemExit(
+                'Error: Submodule {0} contains unresolved merge conflicts.  '
+                'Please complete or abandon any changes in the submodule so that '
+                'it is in a usable state, then try again.'.format(submodule))
+        else:
+            log.warn('Unknown status {0!r} for git submodule {1!r}.  Will '
+                     'attempt to use the submodule as-is, but try to ensure '
+                     'that the submodule is in a clean state and contains no '
+                     'conflicts or errors.\n{2}'.format(status, submodule,
+                                                        _err_help_msg))
+            return
 
-    See the docstrings for ``_check_submodule_using_git`` and
-    ``_check_submodule_no_git`` for futher details.
-    """
+        err_msg = None
+        cmd = ['git', 'submodule'] + cmd + ['--', submodule]
+        log.warn('{0} {1} submodule with: `{2}`'.format(
+            action, submodule, ' '.join(cmd)))
 
-    if use_git:
-        return _check_submodule_using_git(path, offline)
-    else:
-        return _check_submodule_no_git(path)
+        try:
+            log.info('Running `{0}`; use the --no-git option to disable git '
+                     'commands'.format(' '.join(cmd)))
+            returncode, stdout, stderr = run_cmd(cmd)
+        except OSError as e:
+            err_msg = str(e)
+        else:
+            if returncode != 0:
+                err_msg = stderr
 
+        if err_msg is not None:
+            log.warn('An unexpected error occurred updating the git submodule '
+                     '{0!r}:\n{1}\n{2}'.format(submodule, err_msg,
+                                               _err_help_msg))
 
-def _check_submodule_using_git(path, offline):
+class _CommandNotFound(OSError):
+    """
+    An exception raised when a command run with run_cmd is not found on the
+    system.
     """
-    Check if the given path is a git submodule.  If so, attempt to initialize
-    and/or update the submodule if needed.
 
-    This function makes calls to the ``git`` command in subprocesses.  The
-    ``_check_submodule_no_git`` option uses pure Python to check if the given
-    path looks like a git submodule, but it cannot perform updates.
+
+def run_cmd(cmd):
     """
+    Run a command in a subprocess, given as a list of command-line
+    arguments.
 
-    if PY3 and not isinstance(path, _text_type):
-        fs_encoding = sys.getfilesystemencoding()
-        path = path.decode(fs_encoding)
+    Returns a ``(returncode, stdout, stderr)`` tuple.
+    """
 
     try:
-        p = sp.Popen(['git', 'submodule', 'status', '--', path],
-                     stdout=sp.PIPE, stderr=sp.PIPE)
+        p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
+        # XXX: May block if either stdout or stderr fill their buffers;
+        # however for the commands this is currently used for that is
+        # unlikely (they should have very brief output)
         stdout, stderr = p.communicate()
     except OSError as e:
         if DEBUG:
             raise
 
         if e.errno == errno.ENOENT:
-            # The git command simply wasn't found; this is most likely the
-            # case on user systems that don't have git and are simply
-            # trying to install the package from PyPI or a source
-            # distribution.  Silently ignore this case and simply don't try
-            # to use submodules
-            return False
+            msg = 'Command not found: `{0}`'.format(' '.join(cmd))
+            raise _CommandNotFound(msg, cmd)
         else:
             raise _AHBoostrapSystemExit(
                 'An unexpected error occurred when running the '
-                '`git submodule status` command:\n{0}'.format(str(e)))
+                '`{0}` command:\n{1}'.format(' '.join(cmd), str(e)))
 
 
     # Can fail of the default locale is not configured properly.  See
@@ -460,148 +723,13 @@ def _check_submodule_using_git(path, offline):
         # http://bugs.python.org/issue18378
         stdio_encoding = 'latin1'
 
-    if p.returncode != 0 or stderr:
-        # Unfortunately the return code alone cannot be relied on, as
-        # earlier versions of git returned 0 even if the requested submodule
-        # does not exist
-        stderr = stderr.decode(stdio_encoding)
-
-        # This is a warning that occurs in perl (from running git submodule)
-        # which only occurs with a malformatted locale setting which can
-        # happen sometimes on OSX.  See again
-        # https://github.com/astropy/astropy/issues/2749
-        perl_warning = ('perl: warning: Falling back to the standard locale '
-                        '("C").')
-        if not stderr.strip().endswith(perl_warning):
-            # Some other uknown error condition occurred
-            log.warn('git submodule command failed '
-                     'unexpectedly:\n{0}'.format(stderr))
-            return False
-
-    stdout = stdout.decode(stdio_encoding)
-    # The stdout should only contain one line--the status of the
-    # requested submodule
-    m = _git_submodule_status_re.match(stdout)
-    if m:
-        # Yes, the path *is* a git submodule
-        _update_submodule(m.group('submodule'), m.group('status'), offline)
-        return True
-    else:
-        log.warn(
-            'Unexpected output from `git submodule status`:\n{0}\n'
-            'Will attempt import from {1!r} regardless.'.format(
-                stdout, path))
-        return False
-
-
-def _check_submodule_no_git(path):
-    """
-    Like ``_check_submodule_using_git``, but simply parses the .gitmodules file
-    to determine if the supplied path is a git submodule, and does not exec any
-    subprocesses.
-
-    This can only determine if a path is a submodule--it does not perform
-    updates, etc.  This function may need to be updated if the format of the
-    .gitmodules file is changed between git versions.
-    """
-
-    gitmodules_path = os.path.abspath('.gitmodules')
-
-    if not os.path.isfile(gitmodules_path):
-        return False
-
-    # This is a minimal reader for gitconfig-style files.  It handles a few of
-    # the quirks that make gitconfig files incompatible with ConfigParser-style
-    # files, but does not support the full gitconfig syntaix (just enough
-    # needed to read a .gitmodules file).
-    gitmodules_fileobj = io.StringIO()
-
-    # Must use io.open for cross-Python-compatible behavior wrt unicode
-    with io.open(gitmodules_path) as f:
-        for line in f:
-            # gitconfig files are more flexible with leading whitespace; just
-            # go ahead and remove it
-            line = line.lstrip()
-
-            # comments can start with either # or ;
-            if line and line[0] in (':', ';'):
-                continue
-
-            gitmodules_fileobj.write(line)
+    # Unlikely to fail at this point but even then let's be flexible
+    if not isinstance(stdout, _text_type):
+        stdout = stdout.decode(stdio_encoding, 'replace')
+    if not isinstance(stderr, _text_type):
+        stderr = stderr.decode(stdio_encoding, 'replace')
 
-    gitmodules_fileobj.seek(0)
-
-    cfg = RawConfigParser()
-
-    try:
-        cfg.readfp(gitmodules_fileobj)
-    except Exception as exc:
-        log.warn('Malformatted .gitmodules file: {0}\n'
-                 '{1} cannot be assumed to be a git submodule.'.format(
-                     exc, path))
-        return False
-
-    for section in cfg.sections():
-        if not cfg.has_option(section, 'path'):
-            continue
-
-        submodule_path = cfg.get(section, 'path').rstrip(os.sep)
-
-        if submodule_path == path.rstrip(os.sep):
-            return True
-
-    return False
-
-
-def _update_submodule(submodule, status, offline):
-    if status == ' ':
-        # The submodule is up to date; no action necessary
-        return
-    elif status == '-':
-        if offline:
-            raise _AHBootstrapSystemExit(
-                "Cannot initialize the {0} submodule in --offline mode; this "
-                "requires being able to clone the submodule from an online "
-                "repository.".format(submodule))
-        cmd = ['update', '--init']
-        action = 'Initializing'
-    elif status == '+':
-        cmd = ['update']
-        action = 'Updating'
-        if offline:
-            cmd.append('--no-fetch')
-    elif status == 'U':
-        raise _AHBoostrapSystemExit(
-            'Error: Submodule {0} contains unresolved merge conflicts.  '
-            'Please complete or abandon any changes in the submodule so that '
-            'it is in a usable state, then try again.'.format(submodule))
-    else:
-        log.warn('Unknown status {0!r} for git submodule {1!r}.  Will '
-                 'attempt to use the submodule as-is, but try to ensure '
-                 'that the submodule is in a clean state and contains no '
-                 'conflicts or errors.\n{2}'.format(status, submodule,
-                                                    _err_help_msg))
-        return
-
-    err_msg = None
-
-    cmd = ['git', 'submodule'] + cmd + ['--', submodule]
-    log.warn('{0} {1} submodule with: `{2}`'.format(
-        action, submodule, ' '.join(cmd)))
-
-    try:
-        p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
-        stdout, stderr = p.communicate()
-    except OSError as e:
-        err_msg = str(e)
-    else:
-        if p.returncode != 0:
-            stderr_encoding = locale.getdefaultlocale()[1]
-            err_msg = stderr.decode(stderr_encoding)
-
-    if err_msg:
-        log.warn('An unexpected error occurred updating the git submodule '
-                 '{0!r}:\n{1}\n{2}'.format(submodule, err_msg, _err_help_msg))
+    return (p.returncode, stdout, stderr)
 
 
 class _DummyFile(object):
@@ -699,66 +827,71 @@ if sys.version_info[:2] < (2, 7):
 
     log = log()
 
-# Output of `git submodule status` is as follows:
-#
-# 1: Status indicator: '-' for submodule is uninitialized, '+' if submodule is
-# initialized but is not at the commit currently indicated in .gitmodules (and
-# thus needs to be updated), or 'U' if the submodule is in an unstable state
-# (i.e. has merge conflicts)
-#
-# 2. SHA-1 hash of the current commit of the submodule (we don't really need
-# this information but it's useful for checking that the output is correct)
-#
-# 3. The output of `git describe` for the submodule's current commit hash (this
-# includes for example what branches the commit is on) but only if the
-# submodule is initialized.  We ignore this information for now
-_git_submodule_status_re = re.compile(
-    '^(?P<status>[+-U ])(?P<commit>[0-9a-f]{40}) (?P<submodule>\S+)( .*)?$')
-
-
-# Implement the auto-use feature; this allows use_astropy_helpers() to be used
-# at import-time automatically so long as the correct options are specified in
-# setup.cfg
-_CFG_OPTIONS = [('auto_use', bool), ('path', str),
-                ('download_if_needed', bool), ('index_url', str),
-                ('use_git', bool), ('auto_upgrade', bool)]
-
-def _main():
-    if not os.path.exists('setup.cfg'):
-        return
-
-    cfg = ConfigParser()
 
-    try:
-        cfg.read('setup.cfg')
-    except Exception as e:
-        if DEBUG:
-            raise
+BOOTSTRAPPER = _Bootstrapper.main()
+
 
-        log.error(
-            "Error reading setup.cfg: {0!r}\nastropy_helpers will not be "
-            "automatically bootstrapped and package installation may fail."
-            "\n{1}".format(e, _err_help_msg))
-        return
+def use_astropy_helpers(**kwargs):
+    """
+    Ensure that the `astropy_helpers` module is available and is importable.
+    This supports automatic submodule initialization if astropy_helpers is
+    included in a project as a git submodule, or will download it from PyPI if
+    necessary.
 
-    if not cfg.has_section('ah_bootstrap'):
-        return
+    Parameters
+    ----------
 
-    kwargs = {}
+    path : str or None, optional
+        A filesystem path relative to the root of the project's source code
+        that should be added to `sys.path` so that `astropy_helpers` can be
+        imported from that path.
 
-    for option, type_ in _CFG_OPTIONS:
-        if not cfg.has_option('ah_bootstrap', option):
-            continue
+        If the path is a git submodule it will automatically be initialzed
+        and/or updated.
 
-        if type_ is bool:
-            value = cfg.getboolean('ah_bootstrap', option)
-        else:
-            value = cfg.get('ah_bootstrap', option)
+        The path may also be to a ``.tar.gz`` archive of the astropy_helpers
+        source distribution.  In this case the archive is automatically
+        unpacked and made temporarily available on `sys.path` as a ``.egg``
+        archive.
+
+        If `None` skip straight to downloading.
+
+    download_if_needed : bool, optional
+        If the provided filesystem path is not found an attempt will be made to
+        download astropy_helpers from PyPI.  It will then be made temporarily
+        available on `sys.path` as a ``.egg`` archive (using the
+        ``setup_requires`` feature of setuptools.  If the ``--offline`` option
+        is given at the command line the value of this argument is overridden
+        to `False`.
+
+    index_url : str, optional
+        If provided, use a different URL for the Python package index than the
+        main PyPI server.
+
+    use_git : bool, optional
+        If `False` no git commands will be used--this effectively disables
+        support for git submodules. If the ``--no-git`` option is given at the
+        command line the value of this argument is overridden to `False`.
+
+    auto_upgrade : bool, optional
+        By default, when installing a package from a non-development source
+        distribution ah_boostrap will try to automatically check for patch
+        releases to astropy-helpers on PyPI and use the patched version over
+        any bundled versions.  Setting this to `False` will disable that
+        functionality. If the ``--offline`` option is given at the command line
+        the value of this argument is overridden to `False`.
 
-        kwargs[option] = value
+    offline : bool, optional
+        If `False` disable all actions that require an internet connection,
+        including downloading packages from the package index and fetching
+        updates to any git submodule.  Defaults to `True`.
+    """
 
-    if kwargs.pop('auto_use', False):
-        use_astropy_helpers(**kwargs)
+    global BOOTSTRAPPER
 
+    config = BOOTSTRAPPER.config
+    config.update(**kwargs)
 
-_main()
+    # Create a new bootstrapper with the updated configuration and run it
+    BOOTSTRAPPER = _Bootstrapper(**config)
+    BOOTSTRAPPER.run()
diff --git a/astropy/__init__.py b/astropy/__init__.py
index af955ac..671b6be 100644
--- a/astropy/__init__.py
+++ b/astropy/__init__.py
@@ -6,6 +6,8 @@ Python. It also provides an index for other astronomy packages and tools for
 managing them.
 """
 
+from __future__ import absolute_import
+
 # this indicates whether or not we are in astropy's setup.py
 try:
     _ASTROPY_SETUP_
@@ -31,7 +33,7 @@ except ImportError:
     __githash__ = ''
 
 
-__minimum_numpy_version__ = '1.5.1'
+__minimum_numpy_version__ = '1.6.0'
 
 
 # The location of the online documentation for astropy
@@ -174,14 +176,13 @@ def test(package=None, test_path=None, args=None, plugins=None,
 
     open_files : bool, optional
         Fail when any tests leave files open.  Off by default, because
-        this adds extra run time to the test suite.  Works only on
-        platforms with a working `lsof` command.
+        this adds extra run time to the test suite.  Requires the
+        ``psutil`` package.
 
     parallel : int, optional
         When provided, run the tests in parallel on the specified
         number of CPUs.  If parallel is negative, it will use the all
-        the cores on the machine.  Requires the `pytest-xdist` plugin
-        is installed.
+        the cores on the machine.  Requires the `pytest-xdist` plugin.
 
     docs_path : str, optional
         The path to the documentation .rst files.
@@ -217,8 +218,10 @@ def _initialize_astropy():
     from warnings import warn
 
     # If this __init__.py file is in ./astropy/ then import is within a source dir
-    is_astropy_source_dir = (os.path.abspath(os.path.dirname(__file__)) ==
-                             os.path.abspath('astropy') and os.path.exists('setup.py'))
+    source_dir = os.path.abspath(os.path.dirname(__file__))
+    is_astropy_source_dir = (
+            os.path.exists(os.path.join(source_dir, os.pardir, '.git')) and
+            os.path.isfile(os.path.join(source_dir, os.pardir, 'setup.py')))
 
     def _rollback_import(message):
         log.error(message)
@@ -238,11 +241,21 @@ def _initialize_astropy():
         from .utils import _compiler
     except ImportError:
         if is_astropy_source_dir:
-            _rollback_import(
-                'You appear to be trying to import astropy from within a '
-                'source checkout; please run `./setup.py develop` or '
-                '`./setup.py build_ext --inplace` first so that extension '
-                'modules can be compiled and made importable.')
+            log.warn('You appear to be trying to import astropy from '
+                     'within a source checkout without building the '
+                     'extension modules first.  Attempting to (re)build '
+                     'extension modules:')
+
+            try:
+                _rebuild_extensions()
+            except:
+                _rollback_import(
+                    'An error occurred while attempting to rebuild the '
+                    'extension modules.  Please try manually running '
+                    '`./setup.py develop` or `./setup.py build_ext '
+                    '--inplace` to see what the issue was.  Extension '
+                    'modules must be successfully compiled and importable '
+                    'in order to import astropy.')
         else:
             # Outright broken installation; don't be nice.
             raise
@@ -258,6 +271,36 @@ def _initialize_astropy():
         warn(config.configuration.ConfigurationDefaultMissingWarning(wmsg))
 
 
+def _rebuild_extensions():
+    import os
+    import subprocess
+    import sys
+    import time
+
+    from .utils.console import Spinner
+    from .extern.six import next
+
+    devnull = open(os.devnull, 'w')
+    old_cwd = os.getcwd()
+    os.chdir(os.path.join(os.path.dirname(__file__), os.pardir))
+    try:
+        sp = subprocess.Popen([sys.executable, 'setup.py', 'build_ext',
+                               '--inplace'], stdout=devnull,
+                               stderr=devnull)
+        with Spinner('Rebuilding extension modules') as spinner:
+            while sp.poll() is None:
+                next(spinner)
+                time.sleep(0.05)
+    finally:
+        os.chdir(old_cwd)
+
+    if sp.returncode != 0:
+        raise OSError('Running setup.py build_ext --inplace failed '
+                      'with error code {0}: try rerunning this command '
+                      'manually to check what the error was.'.format(
+                          sp.returncode))
+
+
 import logging
 
 # Use the root logger as a dummy log before initilizing Astropy's logger
diff --git a/astropy/_erfa/__init__.py b/astropy/_erfa/__init__.py
new file mode 100644
index 0000000..35bb1ab
--- /dev/null
+++ b/astropy/_erfa/__init__.py
@@ -0,0 +1,7 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+try:
+    # The ERFA wrappers are not guaranteed available at setup time
+    from .core import *
+except ImportError:
+    if not _ASTROPY_SETUP_:
+        raise
diff --git a/astropy/_erfa/core.c b/astropy/_erfa/core.c
new file mode 100644
index 0000000..13c5861
--- /dev/null
+++ b/astropy/_erfa/core.c
@@ -0,0 +1,39585 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+    x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__astropy___erfa___core
+#define __PYX_HAVE_API__astropy___erfa___core
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "erfam.h"
+#include "erfa.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
+    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
+    (sizeof(type) > sizeof(Py_ssize_t) &&               \
+          likely(v < (type)PY_SSIZE_T_MAX ||            \
+                 v == (type)PY_SSIZE_T_MAX)  &&         \
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
+                                v == (type)PY_SSIZE_T_MIN)))  ||  \
+    (sizeof(type) == sizeof(Py_ssize_t) &&              \
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
+                               v == (type)PY_SSIZE_T_MAX)))  )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "/astropy/_erfa/core.pyx",
+  "__init__.pxd",
+  "type.pxd",
+};
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+struct __pyx_t_7astropy_5_erfa_5_core_NewNpyArrayIterObject;
+typedef struct __pyx_t_7astropy_5_erfa_5_core_NewNpyArrayIterObject __pyx_t_7astropy_5_erfa_5_core_NewNpyArrayIterObject;
+
+/* "astropy/_erfa/core.pyx":34
+ * #<-----------------------------NpyIter handling------------------------------->
+ * 
+ * ctypedef void NpyIter             # <<<<<<<<<<<<<<
+ * ctypedef int (*IterNextFunc)(NpyIter * iter) nogil
+ * 
+ */
+typedef void __pyx_t_7astropy_5_erfa_5_core_NpyIter;
+
+/* "astropy/_erfa/core.pyx":35
+ * 
+ * ctypedef void NpyIter
+ * ctypedef int (*IterNextFunc)(NpyIter * iter) nogil             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "numpy/arrayobject.h":
+ */
+typedef int (*__pyx_t_7astropy_5_erfa_5_core_IterNextFunc)(__pyx_t_7astropy_5_erfa_5_core_NpyIter *);
+
+/* "astropy/_erfa/core.pyx":41
+ *     char** GetDataPtrArray "NpyIter_GetDataPtrArray" (NpyIter* iter)
+ * 
+ * ctypedef struct NewNpyArrayIterObject:             # <<<<<<<<<<<<<<
+ *     PyObject base
+ *     NpyIter *iter
+ */
+struct __pyx_t_7astropy_5_erfa_5_core_NewNpyArrayIterObject {
+  PyObject base;
+  __pyx_t_7astropy_5_erfa_5_core_NpyIter *iter;
+};
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {                            \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_XDECREF(tmp);                              \
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {                             \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_DECREF(tmp);                               \
+    } while (0)
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'astropy._erfa._core' */
+static CYTHON_INLINE __pyx_t_7astropy_5_erfa_5_core_NpyIter *__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(PyObject *); /*proto*/
+#define __Pyx_MODULE_NAME "astropy._erfa._core"
+int __pyx_module_is_main_astropy___erfa___core = 0;
+
+/* Implementation of 'astropy._erfa._core' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core__cal2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_2_epb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_4_epb2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_6_epj(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_8_epj2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_10_jd2cal(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_12_jdcalf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_14_ab(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_16_apcg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_18_apcg13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_20_apci(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_22_apci13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_24_apco(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_26_apco13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_28_apcs(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_30_apcs13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_32_aper(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_34_aper13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_36_apio(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_38_apio13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_40_atci13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_42_atciq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_44_atciqn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_46_atciqz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_48_atco13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_50_atic13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_52_aticq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_54_aticqn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_56_atio13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_58_atioq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_60_atoc13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_62_atoi13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_64_atoiq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_66_ld(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_68_ldn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_70_ldsun(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_72_pmpx(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_74_pmsafe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_76_refco(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_78_epv00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_80_plan94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_82_fad03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_84_fae03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_86_faf03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_88_faju03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_90_fal03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_92_falp03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_94_fama03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_96_fame03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_98_fane03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_100_faom03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_102_fapa03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_104_fasa03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_106_faur03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_108_fave03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_110_bi00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_112_bp00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_114_bp06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_116_bpn2xy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_118_c2i00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_120_c2i00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_122_c2i06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_124_c2ibpn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_126_c2ixy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_128_c2ixys(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_130_c2t00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_132_c2t00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_134_c2t06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_136_c2tcio(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_138_c2teqx(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_140_c2tpe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_142_c2txy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_144_eo06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_146_eors(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_148_fw2m(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_150_fw2xy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_152_num00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_154_num00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_156_num06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_158_numat(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_160_nut00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_162_nut00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_164_nut06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_166_nut80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_168_nutm80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_170_obl06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_172_obl80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_174_p06e(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_176_pb06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_178_pfw06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_180_pmat00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_182_pmat06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_184_pmat76(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_186_pn00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_188_pn00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_190_pn00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_192_pn06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_194_pn06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_196_pnm00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_198_pnm00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_200_pnm06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_202_pnm80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_204_pom00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_206_pr00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_208_prec76(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_210_s00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_212_s00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_214_s00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_216_s06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_218_s06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_220_sp00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_222_xy06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_224_xys00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_226_xys00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_228_xys06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_230_ee00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_232_ee00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_234_ee00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_236_ee06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_238_eect00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_240_eqeq94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_242_era00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_244_gmst00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_246_gmst06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_248_gmst82(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_250_gst00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_252_gst00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_254_gst06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_256_gst06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_258_gst94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_260_pmsafe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_262_pvstar(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_264_starpv(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_266_fk52h(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_268_fk5hip(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_270_fk5hz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_272_h2fk5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_274_hfk5z(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_276_starpm(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_278_eform(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_280_gc2gd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_282_gc2gde(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_284_gd2gc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_286_gd2gce(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_288_pvtob(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_290_d2dtf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_292_dat(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_294_dtdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_296_dtf2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_298_taitt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_300_taiut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_302_taiutc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_304_tcbtdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_306_tcgtt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_308_tdbtcb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_310_tdbtt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_312_tttai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_314_tttcg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_316_tttdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_318_ttut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_320_ut1tai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_322_ut1tt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_324_ut1utc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_326_utctai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_328_utcut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_a[] = "_a";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_e[] = "_e";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_n[] = "_n";
+static char __pyx_k_p[] = "_p";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_r[] = "_r";
+static char __pyx_k_s[] = "_s";
+static char __pyx_k_t[] = "_t";
+static char __pyx_k_u[] = "_u";
+static char __pyx_k_v[] = "_v";
+static char __pyx_k_x[] = "_x";
+static char __pyx_k_y[] = "_y";
+static char __pyx_k_z[] = "_z";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_ab[] = "_ab";
+static char __pyx_k_bm[] = "_bm";
+static char __pyx_k_bz[] = "_bz";
+static char __pyx_k_d1[] = "_d1";
+static char __pyx_k_d2[] = "_d2";
+static char __pyx_k_d5[] = "_d5";
+static char __pyx_k_dc[] = "_dc";
+static char __pyx_k_dh[] = "_dh";
+static char __pyx_k_di[] = "_di";
+static char __pyx_k_dt[] = "_dt";
+static char __pyx_k_em[] = "_em";
+static char __pyx_k_eo[] = "_eo";
+static char __pyx_k_fd[] = "_fd";
+static char __pyx_k_hm[] = "_hm";
+static char __pyx_k_id[] = "_id";
+static char __pyx_k_im[] = "_im";
+static char __pyx_k_it[] = "it";
+static char __pyx_k_iy[] = "_iy";
+static char __pyx_k_ld[] = "_ld";
+static char __pyx_k_np[] = "_np";
+static char __pyx_k_ob[] = "_ob";
+static char __pyx_k_p1[] = "_p1";
+static char __pyx_k_pa[] = "_pa";
+static char __pyx_k_pd[] = "_pd";
+static char __pyx_k_pr[] = "_pr";
+static char __pyx_k_pv[] = "_pv";
+static char __pyx_k_px[] = "_px";
+static char __pyx_k_r5[] = "_r5";
+static char __pyx_k_ra[] = "_ra";
+static char __pyx_k_rb[] = "_rb";
+static char __pyx_k_rc[] = "_rc";
+static char __pyx_k_rh[] = "_rh";
+static char __pyx_k_ri[] = "_ri";
+static char __pyx_k_rn[] = "_rn";
+static char __pyx_k_rp[] = "_rp";
+static char __pyx_k_rv[] = "_rv";
+static char __pyx_k_sc[] = "_sc";
+static char __pyx_k_sn[] = "_sn";
+static char __pyx_k_sp[] = "_sp";
+static char __pyx_k_tc[] = "_tc";
+static char __pyx_k_ut[] = "_ut";
+static char __pyx_k_wl[] = "_wl";
+static char __pyx_k_xp[] = "_xp";
+static char __pyx_k_yp[] = "_yp";
+static char __pyx_k_za[] = "_za";
+static char __pyx_k_all[] = "__all__";
+static char __pyx_k_aob[] = "_aob";
+static char __pyx_k_b_2[] = "_b";
+static char __pyx_k_bm1[] = "_bm1";
+static char __pyx_k_bpa[] = "_bpa";
+static char __pyx_k_bqa[] = "_bqa";
+static char __pyx_k_dat[] = "_dat";
+static char __pyx_k_dd5[] = "_dd5";
+static char __pyx_k_ddh[] = "_ddh";
+static char __pyx_k_dec[] = "_dec";
+static char __pyx_k_dj1[] = "_dj1";
+static char __pyx_k_dj2[] = "_dj2";
+static char __pyx_k_djm[] = "_djm";
+static char __pyx_k_dob[] = "_dob";
+static char __pyx_k_dr5[] = "_dr5";
+static char __pyx_k_dra[] = "_dra";
+static char __pyx_k_drh[] = "_drh";
+static char __pyx_k_dta[] = "_dta";
+static char __pyx_k_dtr[] = "_dtr";
+static char __pyx_k_ehp[] = "_ehp";
+static char __pyx_k_epb[] = "_epb";
+static char __pyx_k_epj[] = "_epj";
+static char __pyx_k_eps[] = "_eps";
+static char __pyx_k_era[] = "_era";
+static char __pyx_k_f_2[] = "_f";
+static char __pyx_k_gam[] = "_gam";
+static char __pyx_k_gst[] = "_gst";
+static char __pyx_k_hob[] = "_hob";
+static char __pyx_k_ihr[] = "_ihr";
+static char __pyx_k_imn[] = "_imn";
+static char __pyx_k_ldn[] = "_ldn";
+static char __pyx_k_ndp[] = "_ndp";
+static char __pyx_k_ob1[] = "_ob1";
+static char __pyx_k_ob2[] = "_ob2";
+static char __pyx_k_oma[] = "_oma";
+static char __pyx_k_pco[] = "_pco";
+static char __pyx_k_phi[] = "_phi";
+static char __pyx_k_pia[] = "_pia";
+static char __pyx_k_pmd[] = "_pmd";
+static char __pyx_k_pmr[] = "_pmr";
+static char __pyx_k_pmt[] = "_pmt";
+static char __pyx_k_pob[] = "_pob";
+static char __pyx_k_ppr[] = "_ppr";
+static char __pyx_k_psi[] = "_psi";
+static char __pyx_k_pvb[] = "_pvb";
+static char __pyx_k_pvh[] = "_pvh";
+static char __pyx_k_px1[] = "_px1";
+static char __pyx_k_px2[] = "_px2";
+static char __pyx_k_px5[] = "_px5";
+static char __pyx_k_pxh[] = "_pxh";
+static char __pyx_k_q_2[] = "_q";
+static char __pyx_k_r5h[] = "_r5h";
+static char __pyx_k_ra1[] = "_ra1";
+static char __pyx_k_ra2[] = "_ra2";
+static char __pyx_k_rbp[] = "_rbp";
+static char __pyx_k_rob[] = "_rob";
+static char __pyx_k_rv1[] = "_rv1";
+static char __pyx_k_rv2[] = "_rv2";
+static char __pyx_k_rv5[] = "_rv5";
+static char __pyx_k_rvh[] = "_rvh";
+static char __pyx_k_s00[] = "_s00";
+static char __pyx_k_s06[] = "_s06";
+static char __pyx_k_s5h[] = "_s5h";
+static char __pyx_k_sec[] = "_sec";
+static char __pyx_k_tt1[] = "_tt1";
+static char __pyx_k_tt2[] = "_tt2";
+static char __pyx_k_tta[] = "_tta";
+static char __pyx_k_ttb[] = "_ttb";
+static char __pyx_k_uta[] = "_uta";
+static char __pyx_k_utb[] = "_utb";
+static char __pyx_k_xyz[] = "_xyz";
+static char __pyx_k_zob[] = "_zob";
+static char __pyx_k_apcg[] = "_apcg";
+static char __pyx_k_apci[] = "_apci";
+static char __pyx_k_apco[] = "_apco";
+static char __pyx_k_apcs[] = "_apcs";
+static char __pyx_k_aper[] = "_aper";
+static char __pyx_k_apio[] = "_apio";
+static char __pyx_k_bi00[] = "_bi00";
+static char __pyx_k_bp00[] = "_bp00";
+static char __pyx_k_bp06[] = "_bp06";
+static char __pyx_k_bpia[] = "_bpia";
+static char __pyx_k_chia[] = "_chia";
+static char __pyx_k_dec1[] = "_dec1";
+static char __pyx_k_dec2[] = "_dec2";
+static char __pyx_k_deps[] = "_deps";
+static char __pyx_k_djm0[] = "_djm0";
+static char __pyx_k_dlim[] = "_dlim";
+static char __pyx_k_dpsi[] = "_dpsi";
+static char __pyx_k_dtdb[] = "_dtdb";
+static char __pyx_k_dut1[] = "_dut1";
+static char __pyx_k_ebpv[] = "_ebpv";
+static char __pyx_k_ee00[] = "_ee00";
+static char __pyx_k_eors[] = "_eors";
+static char __pyx_k_ep1a[] = "_ep1a";
+static char __pyx_k_ep1b[] = "_ep1b";
+static char __pyx_k_ep2a[] = "_ep2a";
+static char __pyx_k_ep2b[] = "_ep2b";
+static char __pyx_k_eps0[] = "_eps0";
+static char __pyx_k_epsa[] = "_epsa";
+static char __pyx_k_fw2m[] = "_fw2m";
+static char __pyx_k_gamb[] = "_gamb";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_p06e[] = "_p06e";
+static char __pyx_k_pb06[] = "_pb06";
+static char __pyx_k_phib[] = "_phib";
+static char __pyx_k_phpa[] = "_phpa";
+static char __pyx_k_pmd1[] = "_pmd1";
+static char __pyx_k_pmd2[] = "_pmd2";
+static char __pyx_k_pmpx[] = "_pmpx";
+static char __pyx_k_pmr1[] = "_pmr1";
+static char __pyx_k_pmr2[] = "_pmr2";
+static char __pyx_k_pn00[] = "_pn00";
+static char __pyx_k_pn06[] = "_pn06";
+static char __pyx_k_pnat[] = "_pnat";
+static char __pyx_k_pr00[] = "_pr00";
+static char __pyx_k_psia[] = "_psia";
+static char __pyx_k_psib[] = "_psib";
+static char __pyx_k_rbpn[] = "_rbpn";
+static char __pyx_k_rc2i[] = "_rc2i";
+static char __pyx_k_rc2t[] = "_rc2t";
+static char __pyx_k_refa[] = "_refa";
+static char __pyx_k_refb[] = "_refb";
+static char __pyx_k_rnpb[] = "_rnpb";
+static char __pyx_k_rpom[] = "_rpom";
+static char __pyx_k_s00a[] = "_s00a";
+static char __pyx_k_s00b[] = "_s00b";
+static char __pyx_k_s06a[] = "_s06a";
+static char __pyx_k_sp00[] = "_sp00";
+static char __pyx_k_tai1[] = "_tai1";
+static char __pyx_k_tai2[] = "_tai2";
+static char __pyx_k_tcb1[] = "_tcb1";
+static char __pyx_k_tcb2[] = "_tcb2";
+static char __pyx_k_tcg1[] = "_tcg1";
+static char __pyx_k_tcg2[] = "_tcg2";
+static char __pyx_k_tdb1[] = "_tdb1";
+static char __pyx_k_tdb2[] = "_tdb2";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_type[] = "_type";
+static char __pyx_k_ut11[] = "_ut11";
+static char __pyx_k_ut12[] = "_ut12";
+static char __pyx_k_utc1[] = "_utc1";
+static char __pyx_k_utc2[] = "_utc2";
+static char __pyx_k_xy06[] = "_xy06";
+static char __pyx_k_zeta[] = "_zeta";
+static char __pyx_k_atciq[] = "_atciq";
+static char __pyx_k_aticq[] = "_aticq";
+static char __pyx_k_atioq[] = "_atioq";
+static char __pyx_k_atoiq[] = "_atoiq";
+static char __pyx_k_bzeta[] = "_bzeta";
+static char __pyx_k_c2ixy[] = "_c2ixy";
+static char __pyx_k_c2tpe[] = "_c2tpe";
+static char __pyx_k_c2txy[] = "_c2txy";
+static char __pyx_k_d2dtf[] = "_d2dtf";
+static char __pyx_k_date1[] = "_date1";
+static char __pyx_k_date2[] = "_date2";
+static char __pyx_k_dtf2d[] = "_dtf2d";
+static char __pyx_k_ee00a[] = "_ee00a";
+static char __pyx_k_ee00b[] = "_ee00b";
+static char __pyx_k_ee06a[] = "_ee06a";
+static char __pyx_k_eform[] = "_eform";
+static char __pyx_k_elong[] = "_elong";
+static char __pyx_k_eo06a[] = "_eo06a";
+static char __pyx_k_epv00[] = "_epv00";
+static char __pyx_k_era00[] = "_era00";
+static char __pyx_k_fad03[] = "_fad03";
+static char __pyx_k_fae03[] = "_fae03";
+static char __pyx_k_faf03[] = "_faf03";
+static char __pyx_k_fal03[] = "_fal03";
+static char __pyx_k_fk52h[] = "_fk52h";
+static char __pyx_k_fk5hz[] = "_fk5hz";
+static char __pyx_k_fw2xy[] = "_fw2xy";
+static char __pyx_k_gc2gd[] = "_gc2gd";
+static char __pyx_k_gd2gc[] = "_gd2gc";
+static char __pyx_k_gst06[] = "_gst06";
+static char __pyx_k_gst94[] = "_gst94";
+static char __pyx_k_h2fk5[] = "_h2fk5";
+static char __pyx_k_hfk5z[] = "_hfk5z";
+static char __pyx_k_ihmsf[] = "_ihmsf";
+static char __pyx_k_iymdf[] = "_iymdf";
+static char __pyx_k_ldsun[] = "_ldsun";
+static char __pyx_k_numat[] = "_numat";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_nut80[] = "_nut80";
+static char __pyx_k_obl06[] = "_obl06";
+static char __pyx_k_obl80[] = "_obl80";
+static char __pyx_k_pfw06[] = "_pfw06";
+static char __pyx_k_pn00a[] = "_pn00a";
+static char __pyx_k_pn00b[] = "_pn00b";
+static char __pyx_k_pn06a[] = "_pn06a";
+static char __pyx_k_pnm80[] = "_pnm80";
+static char __pyx_k_pom00[] = "_pom00";
+static char __pyx_k_pvtob[] = "_pvtob";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_refco[] = "_refco";
+static char __pyx_k_rmatn[] = "_rmatn";
+static char __pyx_k_rmatp[] = "_rmatp";
+static char __pyx_k_scale[] = "_scale";
+static char __pyx_k_taitt[] = "_taitt";
+static char __pyx_k_tcgtt[] = "_tcgtt";
+static char __pyx_k_tdbtt[] = "_tdbtt";
+static char __pyx_k_theta[] = "_theta";
+static char __pyx_k_tttai[] = "_tttai";
+static char __pyx_k_tttcg[] = "_tttcg";
+static char __pyx_k_tttdb[] = "_tttdb";
+static char __pyx_k_ttut1[] = "_ttut1";
+static char __pyx_k_ut1tt[] = "_ut1tt";
+static char __pyx_k_zetaa[] = "_zetaa";
+static char __pyx_k_apcg13[] = "_apcg13";
+static char __pyx_k_apci13[] = "_apci13";
+static char __pyx_k_apco13[] = "_apco13";
+static char __pyx_k_apcs13[] = "_apcs13";
+static char __pyx_k_aper13[] = "_aper13";
+static char __pyx_k_apio13[] = "_apio13";
+static char __pyx_k_astrom[] = "_astrom";
+static char __pyx_k_atci13[] = "_atci13";
+static char __pyx_k_atciqn[] = "_atciqn";
+static char __pyx_k_atciqz[] = "_atciqz";
+static char __pyx_k_atco13[] = "_atco13";
+static char __pyx_k_atic13[] = "_atic13";
+static char __pyx_k_aticqn[] = "_aticqn";
+static char __pyx_k_atio13[] = "_atio13";
+static char __pyx_k_atoc13[] = "_atoc13";
+static char __pyx_k_atoi13[] = "_atoi13";
+static char __pyx_k_bpn2xy[] = "_bpn2xy";
+static char __pyx_k_btheta[] = "_btheta";
+static char __pyx_k_c2i00a[] = "_c2i00a";
+static char __pyx_k_c2i00b[] = "_c2i00b";
+static char __pyx_k_c2i06a[] = "_c2i06a";
+static char __pyx_k_c2ibpn[] = "_c2ibpn";
+static char __pyx_k_c2ixys[] = "_c2ixys";
+static char __pyx_k_c2t00a[] = "_c2t00a";
+static char __pyx_k_c2t00b[] = "_c2t00b";
+static char __pyx_k_c2t06a[] = "_c2t06a";
+static char __pyx_k_c2tcio[] = "_c2tcio";
+static char __pyx_k_c2teqx[] = "_c2teqx";
+static char __pyx_k_cal2jd[] = "_cal2jd";
+static char __pyx_k_date01[] = "_date01";
+static char __pyx_k_date02[] = "_date02";
+static char __pyx_k_date11[] = "_date11";
+static char __pyx_k_date12[] = "_date12";
+static char __pyx_k_deltat[] = "_deltat";
+static char __pyx_k_depsbi[] = "_depsbi";
+static char __pyx_k_depspr[] = "_depspr";
+static char __pyx_k_dpsibi[] = "_dpsibi";
+static char __pyx_k_dpsipr[] = "_dpsipr";
+static char __pyx_k_eect00[] = "_eect00";
+static char __pyx_k_epb2jd[] = "_epb2jd";
+static char __pyx_k_epj2jd[] = "_epj2jd";
+static char __pyx_k_eqeq94[] = "_eqeq94";
+static char __pyx_k_faju03[] = "_faju03";
+static char __pyx_k_falp03[] = "_falp03";
+static char __pyx_k_fama03[] = "_fama03";
+static char __pyx_k_fame03[] = "_fame03";
+static char __pyx_k_fane03[] = "_fane03";
+static char __pyx_k_faom03[] = "_faom03";
+static char __pyx_k_fapa03[] = "_fapa03";
+static char __pyx_k_fasa03[] = "_fasa03";
+static char __pyx_k_faur03[] = "_faur03";
+static char __pyx_k_fave03[] = "_fave03";
+static char __pyx_k_fk5hip[] = "_fk5hip";
+static char __pyx_k_gc2gde[] = "_gc2gde";
+static char __pyx_k_gd2gce[] = "_gd2gce";
+static char __pyx_k_gmst00[] = "_gmst00";
+static char __pyx_k_gmst06[] = "_gmst06";
+static char __pyx_k_gmst82[] = "_gmst82";
+static char __pyx_k_gst00a[] = "_gst00a";
+static char __pyx_k_gst00b[] = "_gst00b";
+static char __pyx_k_gst06a[] = "_gst06a";
+static char __pyx_k_height[] = "_height";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_jd2cal[] = "_jd2cal";
+static char __pyx_k_jdcalf[] = "_jdcalf";
+static char __pyx_k_num00a[] = "_num00a";
+static char __pyx_k_num00b[] = "_num00b";
+static char __pyx_k_num06a[] = "_num06a";
+static char __pyx_k_nut00a[] = "_nut00a";
+static char __pyx_k_nut00b[] = "_nut00b";
+static char __pyx_k_nut06a[] = "_nut06a";
+static char __pyx_k_nutm80[] = "_nutm80";
+static char __pyx_k_plan94[] = "_plan94";
+static char __pyx_k_pmat00[] = "_pmat00";
+static char __pyx_k_pmat06[] = "_pmat06";
+static char __pyx_k_pmat76[] = "_pmat76";
+static char __pyx_k_pmsafe[] = "_pmsafe";
+static char __pyx_k_pnm00a[] = "_pnm00a";
+static char __pyx_k_pnm00b[] = "_pnm00b";
+static char __pyx_k_pnm06a[] = "_pnm06a";
+static char __pyx_k_prec76[] = "_prec76";
+static char __pyx_k_pvstar[] = "_pvstar";
+static char __pyx_k_rmatpn[] = "_rmatpn";
+static char __pyx_k_starpm[] = "_starpm";
+static char __pyx_k_starpv[] = "_starpv";
+static char __pyx_k_status[] = "status";
+static char __pyx_k_taiut1[] = "_taiut1";
+static char __pyx_k_taiutc[] = "_taiutc";
+static char __pyx_k_tcbtdb[] = "_tcbtdb";
+static char __pyx_k_tdbtcb[] = "_tdbtcb";
+static char __pyx_k_thetaa[] = "_thetaa";
+static char __pyx_k_ut1tai[] = "_ut1tai";
+static char __pyx_k_ut1utc[] = "_ut1utc";
+static char __pyx_k_utctai[] = "_utctai";
+static char __pyx_k_utcut1[] = "_utcut1";
+static char __pyx_k_xys00a[] = "_xys00a";
+static char __pyx_k_xys00b[] = "_xys00b";
+static char __pyx_k_xys06a[] = "_xys06a";
+static char __pyx_k_stat_ok[] = "stat_ok";
+static char __pyx_k_c_retval[] = "_c_retval";
+static char __pyx_k_iternext[] = "iternext";
+static char __pyx_k_warnings[] = "warnings";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_LooseVersion[] = "LooseVersion";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_dataptrarray[] = "dataptrarray";
+static char __pyx_k_utils_exceptions[] = "utils.exceptions";
+static char __pyx_k_distutils_version[] = "distutils.version";
+static char __pyx_k_AstropyUserWarning[] = "AstropyUserWarning";
+static char __pyx_k_astropy__erfa__core[] = "astropy._erfa._core";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/_erfa/core.pyx";
+static char __pyx_k_This_module_contains_the_Cython[] = "\nThis module contains the Cython parts of the ERFA python wrappers.\nThis is separated from the python code in ``core.py`` because putting it all in\nCython results in very long compile times.  By having only the vectorized core\nin Cython, the compilation time is kept short without sacrificing much (if any)\nperformance.\n\nFor more about the module and how to use it, see the ``core.py`` docstrings.\n";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_n_s_AstropyUserWarning;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_LooseVersion;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_a;
+static PyObject *__pyx_n_s_ab;
+static PyObject *__pyx_n_s_all;
+static PyObject *__pyx_n_s_aob;
+static PyObject *__pyx_n_s_apcg;
+static PyObject *__pyx_n_s_apcg13;
+static PyObject *__pyx_n_s_apci;
+static PyObject *__pyx_n_s_apci13;
+static PyObject *__pyx_n_s_apco;
+static PyObject *__pyx_n_s_apco13;
+static PyObject *__pyx_n_s_apcs;
+static PyObject *__pyx_n_s_apcs13;
+static PyObject *__pyx_n_s_aper;
+static PyObject *__pyx_n_s_aper13;
+static PyObject *__pyx_n_s_apio;
+static PyObject *__pyx_n_s_apio13;
+static PyObject *__pyx_n_s_astrom;
+static PyObject *__pyx_n_s_astropy__erfa__core;
+static PyObject *__pyx_n_s_atci13;
+static PyObject *__pyx_n_s_atciq;
+static PyObject *__pyx_n_s_atciqn;
+static PyObject *__pyx_n_s_atciqz;
+static PyObject *__pyx_n_s_atco13;
+static PyObject *__pyx_n_s_atic13;
+static PyObject *__pyx_n_s_aticq;
+static PyObject *__pyx_n_s_aticqn;
+static PyObject *__pyx_n_s_atio13;
+static PyObject *__pyx_n_s_atioq;
+static PyObject *__pyx_n_s_atoc13;
+static PyObject *__pyx_n_s_atoi13;
+static PyObject *__pyx_n_s_atoiq;
+static PyObject *__pyx_n_s_b_2;
+static PyObject *__pyx_n_s_bi00;
+static PyObject *__pyx_n_s_bm;
+static PyObject *__pyx_n_s_bm1;
+static PyObject *__pyx_n_s_bp00;
+static PyObject *__pyx_n_s_bp06;
+static PyObject *__pyx_n_s_bpa;
+static PyObject *__pyx_n_s_bpia;
+static PyObject *__pyx_n_s_bpn2xy;
+static PyObject *__pyx_n_s_bqa;
+static PyObject *__pyx_n_s_btheta;
+static PyObject *__pyx_n_s_bz;
+static PyObject *__pyx_n_s_bzeta;
+static PyObject *__pyx_n_s_c2i00a;
+static PyObject *__pyx_n_s_c2i00b;
+static PyObject *__pyx_n_s_c2i06a;
+static PyObject *__pyx_n_s_c2ibpn;
+static PyObject *__pyx_n_s_c2ixy;
+static PyObject *__pyx_n_s_c2ixys;
+static PyObject *__pyx_n_s_c2t00a;
+static PyObject *__pyx_n_s_c2t00b;
+static PyObject *__pyx_n_s_c2t06a;
+static PyObject *__pyx_n_s_c2tcio;
+static PyObject *__pyx_n_s_c2teqx;
+static PyObject *__pyx_n_s_c2tpe;
+static PyObject *__pyx_n_s_c2txy;
+static PyObject *__pyx_n_s_c_retval;
+static PyObject *__pyx_n_s_cal2jd;
+static PyObject *__pyx_n_s_chia;
+static PyObject *__pyx_n_s_d1;
+static PyObject *__pyx_n_s_d2;
+static PyObject *__pyx_n_s_d2dtf;
+static PyObject *__pyx_n_s_d5;
+static PyObject *__pyx_n_s_dat;
+static PyObject *__pyx_n_s_dataptrarray;
+static PyObject *__pyx_n_s_date01;
+static PyObject *__pyx_n_s_date02;
+static PyObject *__pyx_n_s_date1;
+static PyObject *__pyx_n_s_date11;
+static PyObject *__pyx_n_s_date12;
+static PyObject *__pyx_n_s_date2;
+static PyObject *__pyx_n_s_dc;
+static PyObject *__pyx_n_s_dd5;
+static PyObject *__pyx_n_s_ddh;
+static PyObject *__pyx_n_s_dec;
+static PyObject *__pyx_n_s_dec1;
+static PyObject *__pyx_n_s_dec2;
+static PyObject *__pyx_n_s_deltat;
+static PyObject *__pyx_n_s_deps;
+static PyObject *__pyx_n_s_depsbi;
+static PyObject *__pyx_n_s_depspr;
+static PyObject *__pyx_n_s_dh;
+static PyObject *__pyx_n_s_di;
+static PyObject *__pyx_n_s_distutils_version;
+static PyObject *__pyx_n_s_dj1;
+static PyObject *__pyx_n_s_dj2;
+static PyObject *__pyx_n_s_djm;
+static PyObject *__pyx_n_s_djm0;
+static PyObject *__pyx_n_s_dlim;
+static PyObject *__pyx_n_s_dob;
+static PyObject *__pyx_n_s_dpsi;
+static PyObject *__pyx_n_s_dpsibi;
+static PyObject *__pyx_n_s_dpsipr;
+static PyObject *__pyx_n_s_dr5;
+static PyObject *__pyx_n_s_dra;
+static PyObject *__pyx_n_s_drh;
+static PyObject *__pyx_n_s_dt;
+static PyObject *__pyx_n_s_dta;
+static PyObject *__pyx_n_s_dtdb;
+static PyObject *__pyx_n_s_dtf2d;
+static PyObject *__pyx_n_s_dtr;
+static PyObject *__pyx_n_s_dut1;
+static PyObject *__pyx_n_s_e;
+static PyObject *__pyx_n_s_ebpv;
+static PyObject *__pyx_n_s_ee00;
+static PyObject *__pyx_n_s_ee00a;
+static PyObject *__pyx_n_s_ee00b;
+static PyObject *__pyx_n_s_ee06a;
+static PyObject *__pyx_n_s_eect00;
+static PyObject *__pyx_n_s_eform;
+static PyObject *__pyx_n_s_ehp;
+static PyObject *__pyx_n_s_elong;
+static PyObject *__pyx_n_s_em;
+static PyObject *__pyx_n_s_eo;
+static PyObject *__pyx_n_s_eo06a;
+static PyObject *__pyx_n_s_eors;
+static PyObject *__pyx_n_s_ep1a;
+static PyObject *__pyx_n_s_ep1b;
+static PyObject *__pyx_n_s_ep2a;
+static PyObject *__pyx_n_s_ep2b;
+static PyObject *__pyx_n_s_epb;
+static PyObject *__pyx_n_s_epb2jd;
+static PyObject *__pyx_n_s_epj;
+static PyObject *__pyx_n_s_epj2jd;
+static PyObject *__pyx_n_s_eps;
+static PyObject *__pyx_n_s_eps0;
+static PyObject *__pyx_n_s_epsa;
+static PyObject *__pyx_n_s_epv00;
+static PyObject *__pyx_n_s_eqeq94;
+static PyObject *__pyx_n_s_era;
+static PyObject *__pyx_n_s_era00;
+static PyObject *__pyx_n_s_f_2;
+static PyObject *__pyx_n_s_fad03;
+static PyObject *__pyx_n_s_fae03;
+static PyObject *__pyx_n_s_faf03;
+static PyObject *__pyx_n_s_faju03;
+static PyObject *__pyx_n_s_fal03;
+static PyObject *__pyx_n_s_falp03;
+static PyObject *__pyx_n_s_fama03;
+static PyObject *__pyx_n_s_fame03;
+static PyObject *__pyx_n_s_fane03;
+static PyObject *__pyx_n_s_faom03;
+static PyObject *__pyx_n_s_fapa03;
+static PyObject *__pyx_n_s_fasa03;
+static PyObject *__pyx_n_s_faur03;
+static PyObject *__pyx_n_s_fave03;
+static PyObject *__pyx_n_s_fd;
+static PyObject *__pyx_n_s_fk52h;
+static PyObject *__pyx_n_s_fk5hip;
+static PyObject *__pyx_n_s_fk5hz;
+static PyObject *__pyx_n_s_fw2m;
+static PyObject *__pyx_n_s_fw2xy;
+static PyObject *__pyx_n_s_gam;
+static PyObject *__pyx_n_s_gamb;
+static PyObject *__pyx_n_s_gc2gd;
+static PyObject *__pyx_n_s_gc2gde;
+static PyObject *__pyx_n_s_gd2gc;
+static PyObject *__pyx_n_s_gd2gce;
+static PyObject *__pyx_n_s_gmst00;
+static PyObject *__pyx_n_s_gmst06;
+static PyObject *__pyx_n_s_gmst82;
+static PyObject *__pyx_n_s_gst;
+static PyObject *__pyx_n_s_gst00a;
+static PyObject *__pyx_n_s_gst00b;
+static PyObject *__pyx_n_s_gst06;
+static PyObject *__pyx_n_s_gst06a;
+static PyObject *__pyx_n_s_gst94;
+static PyObject *__pyx_n_s_h2fk5;
+static PyObject *__pyx_n_s_height;
+static PyObject *__pyx_n_s_hfk5z;
+static PyObject *__pyx_n_s_hm;
+static PyObject *__pyx_n_s_hob;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_ihmsf;
+static PyObject *__pyx_n_s_ihr;
+static PyObject *__pyx_n_s_im;
+static PyObject *__pyx_n_s_imn;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_it;
+static PyObject *__pyx_n_s_iternext;
+static PyObject *__pyx_n_s_iy;
+static PyObject *__pyx_n_s_iymdf;
+static PyObject *__pyx_n_s_jd2cal;
+static PyObject *__pyx_n_s_jdcalf;
+static PyObject *__pyx_n_s_ld;
+static PyObject *__pyx_n_s_ldn;
+static PyObject *__pyx_n_s_ldsun;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_n;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_ndp;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_num00a;
+static PyObject *__pyx_n_s_num00b;
+static PyObject *__pyx_n_s_num06a;
+static PyObject *__pyx_n_s_numat;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_nut00a;
+static PyObject *__pyx_n_s_nut00b;
+static PyObject *__pyx_n_s_nut06a;
+static PyObject *__pyx_n_s_nut80;
+static PyObject *__pyx_n_s_nutm80;
+static PyObject *__pyx_n_s_ob;
+static PyObject *__pyx_n_s_ob1;
+static PyObject *__pyx_n_s_ob2;
+static PyObject *__pyx_n_s_obl06;
+static PyObject *__pyx_n_s_obl80;
+static PyObject *__pyx_n_s_oma;
+static PyObject *__pyx_n_s_p;
+static PyObject *__pyx_n_s_p06e;
+static PyObject *__pyx_n_s_p1;
+static PyObject *__pyx_n_s_pa;
+static PyObject *__pyx_n_s_pb06;
+static PyObject *__pyx_n_s_pco;
+static PyObject *__pyx_n_s_pd;
+static PyObject *__pyx_n_s_pfw06;
+static PyObject *__pyx_n_s_phi;
+static PyObject *__pyx_n_s_phib;
+static PyObject *__pyx_n_s_phpa;
+static PyObject *__pyx_n_s_pia;
+static PyObject *__pyx_n_s_plan94;
+static PyObject *__pyx_n_s_pmat00;
+static PyObject *__pyx_n_s_pmat06;
+static PyObject *__pyx_n_s_pmat76;
+static PyObject *__pyx_n_s_pmd;
+static PyObject *__pyx_n_s_pmd1;
+static PyObject *__pyx_n_s_pmd2;
+static PyObject *__pyx_n_s_pmpx;
+static PyObject *__pyx_n_s_pmr;
+static PyObject *__pyx_n_s_pmr1;
+static PyObject *__pyx_n_s_pmr2;
+static PyObject *__pyx_n_s_pmsafe;
+static PyObject *__pyx_n_s_pmt;
+static PyObject *__pyx_n_s_pn00;
+static PyObject *__pyx_n_s_pn00a;
+static PyObject *__pyx_n_s_pn00b;
+static PyObject *__pyx_n_s_pn06;
+static PyObject *__pyx_n_s_pn06a;
+static PyObject *__pyx_n_s_pnat;
+static PyObject *__pyx_n_s_pnm00a;
+static PyObject *__pyx_n_s_pnm00b;
+static PyObject *__pyx_n_s_pnm06a;
+static PyObject *__pyx_n_s_pnm80;
+static PyObject *__pyx_n_s_pob;
+static PyObject *__pyx_n_s_pom00;
+static PyObject *__pyx_n_s_ppr;
+static PyObject *__pyx_n_s_pr;
+static PyObject *__pyx_n_s_pr00;
+static PyObject *__pyx_n_s_prec76;
+static PyObject *__pyx_n_s_psi;
+static PyObject *__pyx_n_s_psia;
+static PyObject *__pyx_n_s_psib;
+static PyObject *__pyx_n_s_pv;
+static PyObject *__pyx_n_s_pvb;
+static PyObject *__pyx_n_s_pvh;
+static PyObject *__pyx_n_s_pvstar;
+static PyObject *__pyx_n_s_pvtob;
+static PyObject *__pyx_n_s_px;
+static PyObject *__pyx_n_s_px1;
+static PyObject *__pyx_n_s_px2;
+static PyObject *__pyx_n_s_px5;
+static PyObject *__pyx_n_s_pxh;
+static PyObject *__pyx_n_s_q_2;
+static PyObject *__pyx_n_s_r;
+static PyObject *__pyx_n_s_r5;
+static PyObject *__pyx_n_s_r5h;
+static PyObject *__pyx_n_s_ra;
+static PyObject *__pyx_n_s_ra1;
+static PyObject *__pyx_n_s_ra2;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_rb;
+static PyObject *__pyx_n_s_rbp;
+static PyObject *__pyx_n_s_rbpn;
+static PyObject *__pyx_n_s_rc;
+static PyObject *__pyx_n_s_rc2i;
+static PyObject *__pyx_n_s_rc2t;
+static PyObject *__pyx_n_s_refa;
+static PyObject *__pyx_n_s_refb;
+static PyObject *__pyx_n_s_refco;
+static PyObject *__pyx_n_s_rh;
+static PyObject *__pyx_n_s_ri;
+static PyObject *__pyx_n_s_rmatn;
+static PyObject *__pyx_n_s_rmatp;
+static PyObject *__pyx_n_s_rmatpn;
+static PyObject *__pyx_n_s_rn;
+static PyObject *__pyx_n_s_rnpb;
+static PyObject *__pyx_n_s_rob;
+static PyObject *__pyx_n_s_rp;
+static PyObject *__pyx_n_s_rpom;
+static PyObject *__pyx_n_s_rv;
+static PyObject *__pyx_n_s_rv1;
+static PyObject *__pyx_n_s_rv2;
+static PyObject *__pyx_n_s_rv5;
+static PyObject *__pyx_n_s_rvh;
+static PyObject *__pyx_n_s_s;
+static PyObject *__pyx_n_s_s00;
+static PyObject *__pyx_n_s_s00a;
+static PyObject *__pyx_n_s_s00b;
+static PyObject *__pyx_n_s_s06;
+static PyObject *__pyx_n_s_s06a;
+static PyObject *__pyx_n_s_s5h;
+static PyObject *__pyx_n_s_sc;
+static PyObject *__pyx_n_s_scale;
+static PyObject *__pyx_n_s_sec;
+static PyObject *__pyx_n_s_sn;
+static PyObject *__pyx_n_s_sp;
+static PyObject *__pyx_n_s_sp00;
+static PyObject *__pyx_n_s_starpm;
+static PyObject *__pyx_n_s_starpv;
+static PyObject *__pyx_n_s_stat_ok;
+static PyObject *__pyx_n_s_status;
+static PyObject *__pyx_n_s_t;
+static PyObject *__pyx_n_s_tai1;
+static PyObject *__pyx_n_s_tai2;
+static PyObject *__pyx_n_s_taitt;
+static PyObject *__pyx_n_s_taiut1;
+static PyObject *__pyx_n_s_taiutc;
+static PyObject *__pyx_n_s_tc;
+static PyObject *__pyx_n_s_tcb1;
+static PyObject *__pyx_n_s_tcb2;
+static PyObject *__pyx_n_s_tcbtdb;
+static PyObject *__pyx_n_s_tcg1;
+static PyObject *__pyx_n_s_tcg2;
+static PyObject *__pyx_n_s_tcgtt;
+static PyObject *__pyx_n_s_tdb1;
+static PyObject *__pyx_n_s_tdb2;
+static PyObject *__pyx_n_s_tdbtcb;
+static PyObject *__pyx_n_s_tdbtt;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_theta;
+static PyObject *__pyx_n_s_thetaa;
+static PyObject *__pyx_n_s_tt1;
+static PyObject *__pyx_n_s_tt2;
+static PyObject *__pyx_n_s_tta;
+static PyObject *__pyx_n_s_ttb;
+static PyObject *__pyx_n_s_tttai;
+static PyObject *__pyx_n_s_tttcg;
+static PyObject *__pyx_n_s_tttdb;
+static PyObject *__pyx_n_s_ttut1;
+static PyObject *__pyx_n_s_type;
+static PyObject *__pyx_n_s_u;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_ut;
+static PyObject *__pyx_n_s_ut11;
+static PyObject *__pyx_n_s_ut12;
+static PyObject *__pyx_n_s_ut1tai;
+static PyObject *__pyx_n_s_ut1tt;
+static PyObject *__pyx_n_s_ut1utc;
+static PyObject *__pyx_n_s_uta;
+static PyObject *__pyx_n_s_utb;
+static PyObject *__pyx_n_s_utc1;
+static PyObject *__pyx_n_s_utc2;
+static PyObject *__pyx_n_s_utctai;
+static PyObject *__pyx_n_s_utcut1;
+static PyObject *__pyx_n_s_utils_exceptions;
+static PyObject *__pyx_n_s_v;
+static PyObject *__pyx_n_s_warnings;
+static PyObject *__pyx_n_s_wl;
+static PyObject *__pyx_n_s_x;
+static PyObject *__pyx_n_s_xp;
+static PyObject *__pyx_n_s_xy06;
+static PyObject *__pyx_n_s_xys00a;
+static PyObject *__pyx_n_s_xys00b;
+static PyObject *__pyx_n_s_xys06a;
+static PyObject *__pyx_n_s_xyz;
+static PyObject *__pyx_n_s_y;
+static PyObject *__pyx_n_s_yp;
+static PyObject *__pyx_n_s_z;
+static PyObject *__pyx_n_s_za;
+static PyObject *__pyx_n_s_zeta;
+static PyObject *__pyx_n_s_zetaa;
+static PyObject *__pyx_n_s_zob;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__55;
+static PyObject *__pyx_tuple__57;
+static PyObject *__pyx_tuple__59;
+static PyObject *__pyx_tuple__61;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_tuple__71;
+static PyObject *__pyx_tuple__73;
+static PyObject *__pyx_tuple__75;
+static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__79;
+static PyObject *__pyx_tuple__81;
+static PyObject *__pyx_tuple__83;
+static PyObject *__pyx_tuple__85;
+static PyObject *__pyx_tuple__87;
+static PyObject *__pyx_tuple__89;
+static PyObject *__pyx_tuple__91;
+static PyObject *__pyx_tuple__93;
+static PyObject *__pyx_tuple__95;
+static PyObject *__pyx_tuple__97;
+static PyObject *__pyx_tuple__99;
+static PyObject *__pyx_codeobj__8;
+static PyObject *__pyx_tuple__101;
+static PyObject *__pyx_tuple__103;
+static PyObject *__pyx_tuple__105;
+static PyObject *__pyx_tuple__107;
+static PyObject *__pyx_tuple__109;
+static PyObject *__pyx_tuple__111;
+static PyObject *__pyx_tuple__113;
+static PyObject *__pyx_tuple__115;
+static PyObject *__pyx_tuple__117;
+static PyObject *__pyx_tuple__119;
+static PyObject *__pyx_tuple__121;
+static PyObject *__pyx_tuple__123;
+static PyObject *__pyx_tuple__125;
+static PyObject *__pyx_tuple__127;
+static PyObject *__pyx_tuple__129;
+static PyObject *__pyx_tuple__131;
+static PyObject *__pyx_tuple__133;
+static PyObject *__pyx_tuple__135;
+static PyObject *__pyx_tuple__137;
+static PyObject *__pyx_tuple__139;
+static PyObject *__pyx_tuple__141;
+static PyObject *__pyx_tuple__143;
+static PyObject *__pyx_tuple__145;
+static PyObject *__pyx_tuple__147;
+static PyObject *__pyx_tuple__149;
+static PyObject *__pyx_tuple__151;
+static PyObject *__pyx_tuple__153;
+static PyObject *__pyx_tuple__155;
+static PyObject *__pyx_tuple__157;
+static PyObject *__pyx_tuple__159;
+static PyObject *__pyx_tuple__161;
+static PyObject *__pyx_tuple__163;
+static PyObject *__pyx_tuple__165;
+static PyObject *__pyx_tuple__167;
+static PyObject *__pyx_tuple__169;
+static PyObject *__pyx_tuple__171;
+static PyObject *__pyx_tuple__173;
+static PyObject *__pyx_tuple__175;
+static PyObject *__pyx_tuple__177;
+static PyObject *__pyx_tuple__179;
+static PyObject *__pyx_tuple__181;
+static PyObject *__pyx_tuple__183;
+static PyObject *__pyx_tuple__185;
+static PyObject *__pyx_tuple__187;
+static PyObject *__pyx_tuple__189;
+static PyObject *__pyx_tuple__191;
+static PyObject *__pyx_tuple__193;
+static PyObject *__pyx_tuple__195;
+static PyObject *__pyx_tuple__197;
+static PyObject *__pyx_tuple__199;
+static PyObject *__pyx_tuple__201;
+static PyObject *__pyx_tuple__203;
+static PyObject *__pyx_tuple__205;
+static PyObject *__pyx_tuple__207;
+static PyObject *__pyx_tuple__209;
+static PyObject *__pyx_tuple__211;
+static PyObject *__pyx_tuple__213;
+static PyObject *__pyx_tuple__215;
+static PyObject *__pyx_tuple__217;
+static PyObject *__pyx_tuple__219;
+static PyObject *__pyx_tuple__221;
+static PyObject *__pyx_tuple__223;
+static PyObject *__pyx_tuple__225;
+static PyObject *__pyx_tuple__227;
+static PyObject *__pyx_tuple__229;
+static PyObject *__pyx_tuple__231;
+static PyObject *__pyx_tuple__233;
+static PyObject *__pyx_tuple__235;
+static PyObject *__pyx_tuple__237;
+static PyObject *__pyx_tuple__239;
+static PyObject *__pyx_tuple__241;
+static PyObject *__pyx_tuple__243;
+static PyObject *__pyx_tuple__245;
+static PyObject *__pyx_tuple__247;
+static PyObject *__pyx_tuple__249;
+static PyObject *__pyx_tuple__251;
+static PyObject *__pyx_tuple__253;
+static PyObject *__pyx_tuple__255;
+static PyObject *__pyx_tuple__257;
+static PyObject *__pyx_tuple__259;
+static PyObject *__pyx_tuple__261;
+static PyObject *__pyx_tuple__263;
+static PyObject *__pyx_tuple__265;
+static PyObject *__pyx_tuple__267;
+static PyObject *__pyx_tuple__269;
+static PyObject *__pyx_tuple__271;
+static PyObject *__pyx_tuple__273;
+static PyObject *__pyx_tuple__275;
+static PyObject *__pyx_tuple__277;
+static PyObject *__pyx_tuple__279;
+static PyObject *__pyx_tuple__281;
+static PyObject *__pyx_tuple__283;
+static PyObject *__pyx_tuple__285;
+static PyObject *__pyx_tuple__287;
+static PyObject *__pyx_tuple__289;
+static PyObject *__pyx_tuple__291;
+static PyObject *__pyx_tuple__293;
+static PyObject *__pyx_tuple__295;
+static PyObject *__pyx_tuple__297;
+static PyObject *__pyx_tuple__299;
+static PyObject *__pyx_tuple__301;
+static PyObject *__pyx_tuple__303;
+static PyObject *__pyx_tuple__305;
+static PyObject *__pyx_tuple__307;
+static PyObject *__pyx_tuple__309;
+static PyObject *__pyx_tuple__311;
+static PyObject *__pyx_tuple__313;
+static PyObject *__pyx_tuple__315;
+static PyObject *__pyx_tuple__317;
+static PyObject *__pyx_tuple__319;
+static PyObject *__pyx_tuple__321;
+static PyObject *__pyx_tuple__323;
+static PyObject *__pyx_tuple__325;
+static PyObject *__pyx_tuple__327;
+static PyObject *__pyx_tuple__329;
+static PyObject *__pyx_tuple__331;
+static PyObject *__pyx_tuple__333;
+static PyObject *__pyx_tuple__335;
+static PyObject *__pyx_codeobj__10;
+static PyObject *__pyx_codeobj__12;
+static PyObject *__pyx_codeobj__14;
+static PyObject *__pyx_codeobj__16;
+static PyObject *__pyx_codeobj__18;
+static PyObject *__pyx_codeobj__20;
+static PyObject *__pyx_codeobj__22;
+static PyObject *__pyx_codeobj__24;
+static PyObject *__pyx_codeobj__26;
+static PyObject *__pyx_codeobj__28;
+static PyObject *__pyx_codeobj__30;
+static PyObject *__pyx_codeobj__32;
+static PyObject *__pyx_codeobj__34;
+static PyObject *__pyx_codeobj__36;
+static PyObject *__pyx_codeobj__38;
+static PyObject *__pyx_codeobj__40;
+static PyObject *__pyx_codeobj__42;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+static PyObject *__pyx_codeobj__50;
+static PyObject *__pyx_codeobj__52;
+static PyObject *__pyx_codeobj__54;
+static PyObject *__pyx_codeobj__56;
+static PyObject *__pyx_codeobj__58;
+static PyObject *__pyx_codeobj__60;
+static PyObject *__pyx_codeobj__62;
+static PyObject *__pyx_codeobj__64;
+static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__68;
+static PyObject *__pyx_codeobj__70;
+static PyObject *__pyx_codeobj__72;
+static PyObject *__pyx_codeobj__74;
+static PyObject *__pyx_codeobj__76;
+static PyObject *__pyx_codeobj__78;
+static PyObject *__pyx_codeobj__80;
+static PyObject *__pyx_codeobj__82;
+static PyObject *__pyx_codeobj__84;
+static PyObject *__pyx_codeobj__86;
+static PyObject *__pyx_codeobj__88;
+static PyObject *__pyx_codeobj__90;
+static PyObject *__pyx_codeobj__92;
+static PyObject *__pyx_codeobj__94;
+static PyObject *__pyx_codeobj__96;
+static PyObject *__pyx_codeobj__98;
+static PyObject *__pyx_codeobj__100;
+static PyObject *__pyx_codeobj__102;
+static PyObject *__pyx_codeobj__104;
+static PyObject *__pyx_codeobj__106;
+static PyObject *__pyx_codeobj__108;
+static PyObject *__pyx_codeobj__110;
+static PyObject *__pyx_codeobj__112;
+static PyObject *__pyx_codeobj__114;
+static PyObject *__pyx_codeobj__116;
+static PyObject *__pyx_codeobj__118;
+static PyObject *__pyx_codeobj__120;
+static PyObject *__pyx_codeobj__122;
+static PyObject *__pyx_codeobj__124;
+static PyObject *__pyx_codeobj__126;
+static PyObject *__pyx_codeobj__128;
+static PyObject *__pyx_codeobj__130;
+static PyObject *__pyx_codeobj__132;
+static PyObject *__pyx_codeobj__134;
+static PyObject *__pyx_codeobj__136;
+static PyObject *__pyx_codeobj__138;
+static PyObject *__pyx_codeobj__140;
+static PyObject *__pyx_codeobj__142;
+static PyObject *__pyx_codeobj__144;
+static PyObject *__pyx_codeobj__146;
+static PyObject *__pyx_codeobj__148;
+static PyObject *__pyx_codeobj__150;
+static PyObject *__pyx_codeobj__152;
+static PyObject *__pyx_codeobj__154;
+static PyObject *__pyx_codeobj__156;
+static PyObject *__pyx_codeobj__158;
+static PyObject *__pyx_codeobj__160;
+static PyObject *__pyx_codeobj__162;
+static PyObject *__pyx_codeobj__164;
+static PyObject *__pyx_codeobj__166;
+static PyObject *__pyx_codeobj__168;
+static PyObject *__pyx_codeobj__170;
+static PyObject *__pyx_codeobj__172;
+static PyObject *__pyx_codeobj__174;
+static PyObject *__pyx_codeobj__176;
+static PyObject *__pyx_codeobj__178;
+static PyObject *__pyx_codeobj__180;
+static PyObject *__pyx_codeobj__182;
+static PyObject *__pyx_codeobj__184;
+static PyObject *__pyx_codeobj__186;
+static PyObject *__pyx_codeobj__188;
+static PyObject *__pyx_codeobj__190;
+static PyObject *__pyx_codeobj__192;
+static PyObject *__pyx_codeobj__194;
+static PyObject *__pyx_codeobj__196;
+static PyObject *__pyx_codeobj__198;
+static PyObject *__pyx_codeobj__200;
+static PyObject *__pyx_codeobj__202;
+static PyObject *__pyx_codeobj__204;
+static PyObject *__pyx_codeobj__206;
+static PyObject *__pyx_codeobj__208;
+static PyObject *__pyx_codeobj__210;
+static PyObject *__pyx_codeobj__212;
+static PyObject *__pyx_codeobj__214;
+static PyObject *__pyx_codeobj__216;
+static PyObject *__pyx_codeobj__218;
+static PyObject *__pyx_codeobj__220;
+static PyObject *__pyx_codeobj__222;
+static PyObject *__pyx_codeobj__224;
+static PyObject *__pyx_codeobj__226;
+static PyObject *__pyx_codeobj__228;
+static PyObject *__pyx_codeobj__230;
+static PyObject *__pyx_codeobj__232;
+static PyObject *__pyx_codeobj__234;
+static PyObject *__pyx_codeobj__236;
+static PyObject *__pyx_codeobj__238;
+static PyObject *__pyx_codeobj__240;
+static PyObject *__pyx_codeobj__242;
+static PyObject *__pyx_codeobj__244;
+static PyObject *__pyx_codeobj__246;
+static PyObject *__pyx_codeobj__248;
+static PyObject *__pyx_codeobj__250;
+static PyObject *__pyx_codeobj__252;
+static PyObject *__pyx_codeobj__254;
+static PyObject *__pyx_codeobj__256;
+static PyObject *__pyx_codeobj__258;
+static PyObject *__pyx_codeobj__260;
+static PyObject *__pyx_codeobj__262;
+static PyObject *__pyx_codeobj__264;
+static PyObject *__pyx_codeobj__266;
+static PyObject *__pyx_codeobj__268;
+static PyObject *__pyx_codeobj__270;
+static PyObject *__pyx_codeobj__272;
+static PyObject *__pyx_codeobj__274;
+static PyObject *__pyx_codeobj__276;
+static PyObject *__pyx_codeobj__278;
+static PyObject *__pyx_codeobj__280;
+static PyObject *__pyx_codeobj__282;
+static PyObject *__pyx_codeobj__284;
+static PyObject *__pyx_codeobj__286;
+static PyObject *__pyx_codeobj__288;
+static PyObject *__pyx_codeobj__290;
+static PyObject *__pyx_codeobj__292;
+static PyObject *__pyx_codeobj__294;
+static PyObject *__pyx_codeobj__296;
+static PyObject *__pyx_codeobj__298;
+static PyObject *__pyx_codeobj__300;
+static PyObject *__pyx_codeobj__302;
+static PyObject *__pyx_codeobj__304;
+static PyObject *__pyx_codeobj__306;
+static PyObject *__pyx_codeobj__308;
+static PyObject *__pyx_codeobj__310;
+static PyObject *__pyx_codeobj__312;
+static PyObject *__pyx_codeobj__314;
+static PyObject *__pyx_codeobj__316;
+static PyObject *__pyx_codeobj__318;
+static PyObject *__pyx_codeobj__320;
+static PyObject *__pyx_codeobj__322;
+static PyObject *__pyx_codeobj__324;
+static PyObject *__pyx_codeobj__326;
+static PyObject *__pyx_codeobj__328;
+static PyObject *__pyx_codeobj__330;
+static PyObject *__pyx_codeobj__332;
+static PyObject *__pyx_codeobj__334;
+static PyObject *__pyx_codeobj__336;
+
+/* "astropy/_erfa/core.pyx":45
+ *     NpyIter *iter
+ * 
+ * cdef inline NpyIter* GetNpyIter(object iter):             # <<<<<<<<<<<<<<
+ *     return (<NewNpyArrayIterObject*>iter).iter
+ * 
+ */
+
+static CYTHON_INLINE __pyx_t_7astropy_5_erfa_5_core_NpyIter *__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(PyObject *__pyx_v_iter) {
+  __pyx_t_7astropy_5_erfa_5_core_NpyIter *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("GetNpyIter", 0);
+
+  /* "astropy/_erfa/core.pyx":46
+ * 
+ * cdef inline NpyIter* GetNpyIter(object iter):
+ *     return (<NewNpyArrayIterObject*>iter).iter             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = ((__pyx_t_7astropy_5_erfa_5_core_NewNpyArrayIterObject *)__pyx_v_iter)->iter;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":45
+ *     NpyIter *iter
+ * 
+ * cdef inline NpyIter* GetNpyIter(object iter):             # <<<<<<<<<<<<<<
+ *     return (<NewNpyArrayIterObject*>iter).iter
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":225
+ * 
+ * 
+ * def _cal2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_1_cal2jd(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_1_cal2jd = {"_cal2jd", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_1_cal2jd, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_1_cal2jd(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_cal2jd (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core__cal2jd(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core__cal2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__iy;
+  int __pyx_v__im;
+  int __pyx_v__id;
+  double *__pyx_v__djm0;
+  double *__pyx_v__djm;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_cal2jd", 0);
+
+  /* "astropy/_erfa/core.pyx":233
+ *     cdef double * _djm
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":234
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":235
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":236
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":237
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":238
+ *     cdef int status = 1
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__iy = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":239
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _djm0 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__im = (((int *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":240
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _djm0 = (<double *>(dataptrarray[3]))
+ *         _djm = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__id = (((int *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":241
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _djm0 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _djm = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)
+ */
+    __pyx_v__djm0 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":242
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _djm0 = (<double *>(dataptrarray[3]))
+ *         _djm = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__djm = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":243
+ *         _djm0 = (<double *>(dataptrarray[3]))
+ *         _djm = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraCal2jd(__pyx_v__iy, __pyx_v__im, __pyx_v__id, __pyx_v__djm0, __pyx_v__djm);
+
+    /* "astropy/_erfa/core.pyx":244
+ *         _djm = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":245
+ *         _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":246
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":247
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":248
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":225
+ * 
+ * 
+ * def _cal2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._cal2jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":251
+ * 
+ * 
+ * def _epb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_3_epb(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_3_epb = {"_epb", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_3_epb, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_3_epb(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_epb (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_2_epb(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_2_epb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_epb", 0);
+
+  /* "astropy/_erfa/core.pyx":256
+ *     cdef double _dj2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":257
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":258
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":259
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":260
+ *     cdef int status = 1
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpb(_dj1, _dj2)
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":261
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEpb(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":262
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpb(_dj1, _dj2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEpb(__pyx_v__dj1, __pyx_v__dj2);
+
+    /* "astropy/_erfa/core.pyx":263
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpb(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":264
+ *         _c_retval = eraEpb(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":251
+ * 
+ * 
+ * def _epb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":267
+ * 
+ * 
+ * def _epb2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epb
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_5_epb2jd(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_5_epb2jd = {"_epb2jd", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_5_epb2jd, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_5_epb2jd(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_epb2jd (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_4_epb2jd(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_4_epb2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__epb;
+  double *__pyx_v__djm0;
+  double *__pyx_v__djm;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_epb2jd", 0);
+
+  /* "astropy/_erfa/core.pyx":272
+ *     cdef double * _djm0
+ *     cdef double * _djm
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":273
+ *     cdef double * _djm
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":274
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _epb = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":275
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _epb = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":276
+ *     cdef int status = 1
+ *     while status:
+ *         _epb = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__epb = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":277
+ *     while status:
+ *         _epb = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpb2jd(_epb, _djm0, _djm)
+ */
+    __pyx_v__djm0 = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":278
+ *         _epb = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraEpb2jd(_epb, _djm0, _djm)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__djm = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":279
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpb2jd(_epb, _djm0, _djm)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraEpb2jd(__pyx_v__epb, __pyx_v__djm0, __pyx_v__djm);
+
+    /* "astropy/_erfa/core.pyx":280
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpb2jd(_epb, _djm0, _djm)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":267
+ * 
+ * 
+ * def _epb2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epb
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":283
+ * 
+ * 
+ * def _epj(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_7_epj(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_7_epj = {"_epj", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_7_epj, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_7_epj(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_epj (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_6_epj(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_6_epj(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_epj", 0);
+
+  /* "astropy/_erfa/core.pyx":288
+ *     cdef double _dj2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":289
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":290
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":291
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":292
+ *     cdef int status = 1
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpj(_dj1, _dj2)
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":293
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEpj(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":294
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpj(_dj1, _dj2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEpj(__pyx_v__dj1, __pyx_v__dj2);
+
+    /* "astropy/_erfa/core.pyx":295
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEpj(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":296
+ *         _c_retval = eraEpj(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":283
+ * 
+ * 
+ * def _epj(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":299
+ * 
+ * 
+ * def _epj2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epj
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_9_epj2jd(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_9_epj2jd = {"_epj2jd", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_9_epj2jd, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_9_epj2jd(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_epj2jd (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_8_epj2jd(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_8_epj2jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__epj;
+  double *__pyx_v__djm0;
+  double *__pyx_v__djm;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_epj2jd", 0);
+
+  /* "astropy/_erfa/core.pyx":304
+ *     cdef double * _djm0
+ *     cdef double * _djm
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":305
+ *     cdef double * _djm
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":306
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _epj = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":307
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _epj = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":308
+ *     cdef int status = 1
+ *     while status:
+ *         _epj = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__epj = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":309
+ *     while status:
+ *         _epj = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpj2jd(_epj, _djm0, _djm)
+ */
+    __pyx_v__djm0 = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":310
+ *         _epj = (<double *>(dataptrarray[0]))[0]
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraEpj2jd(_epj, _djm0, _djm)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__djm = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":311
+ *         _djm0 = (<double *>(dataptrarray[1]))
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpj2jd(_epj, _djm0, _djm)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraEpj2jd(__pyx_v__epj, __pyx_v__djm0, __pyx_v__djm);
+
+    /* "astropy/_erfa/core.pyx":312
+ *         _djm = (<double *>(dataptrarray[2]))
+ *         eraEpj2jd(_epj, _djm0, _djm)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":299
+ * 
+ * 
+ * def _epj2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epj
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":315
+ * 
+ * 
+ * def _jd2cal(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_11_jd2cal(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_11_jd2cal = {"_jd2cal", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_11_jd2cal, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_11_jd2cal(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_jd2cal (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_10_jd2cal(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_10_jd2cal(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  int *__pyx_v__iy;
+  int *__pyx_v__im;
+  int *__pyx_v__id;
+  double *__pyx_v__fd;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_jd2cal", 0);
+
+  /* "astropy/_erfa/core.pyx":324
+ *     cdef double * _fd
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":325
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":326
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":327
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":328
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":329
+ *     cdef int status = 1
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _iy = (<int *>(dataptrarray[2]))
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":330
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _iy = (<int *>(dataptrarray[2]))
+ *         _im = (<int *>(dataptrarray[3]))
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":331
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _iy = (<int *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _im = (<int *>(dataptrarray[3]))
+ *         _id = (<int *>(dataptrarray[4]))
+ */
+    __pyx_v__iy = ((int *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":332
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _iy = (<int *>(dataptrarray[2]))
+ *         _im = (<int *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _id = (<int *>(dataptrarray[4]))
+ *         _fd = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__im = ((int *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":333
+ *         _iy = (<int *>(dataptrarray[2]))
+ *         _im = (<int *>(dataptrarray[3]))
+ *         _id = (<int *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _fd = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)
+ */
+    __pyx_v__id = ((int *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":334
+ *         _im = (<int *>(dataptrarray[3]))
+ *         _id = (<int *>(dataptrarray[4]))
+ *         _fd = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ */
+    __pyx_v__fd = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":335
+ *         _id = (<int *>(dataptrarray[4]))
+ *         _fd = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraJd2cal(__pyx_v__dj1, __pyx_v__dj2, __pyx_v__iy, __pyx_v__im, __pyx_v__id, __pyx_v__fd);
+
+    /* "astropy/_erfa/core.pyx":336
+ *         _fd = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[6]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":337
+ *         _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":338
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":339
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":340
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":315
+ * 
+ * 
+ * def _jd2cal(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._jd2cal", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":343
+ * 
+ * 
+ * def _jdcalf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _ndp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_13_jdcalf(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_13_jdcalf = {"_jdcalf", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_13_jdcalf, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_13_jdcalf(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_jdcalf (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_12_jdcalf(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_12_jdcalf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__ndp;
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  int *__pyx_v__iymdf;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_jdcalf", 0);
+
+  /* "astropy/_erfa/core.pyx":350
+ *     cdef int * _iymdf
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":351
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":352
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":353
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ndp = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":354
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ndp = (<int *>(dataptrarray[0]))[0]
+ *         _dj1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":355
+ *     cdef int status = 1
+ *     while status:
+ *         _ndp = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[1]))[0]
+ *         _dj2 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ndp = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":356
+ *     while status:
+ *         _ndp = (<int *>(dataptrarray[0]))[0]
+ *         _dj1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[2]))[0]
+ *         _iymdf = (<int *>(dataptrarray[3]))
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":357
+ *         _ndp = (<int *>(dataptrarray[0]))[0]
+ *         _dj1 = (<double *>(dataptrarray[1]))[0]
+ *         _dj2 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _iymdf = (<int *>(dataptrarray[3]))
+ *         _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":358
+ *         _dj1 = (<double *>(dataptrarray[1]))[0]
+ *         _dj2 = (<double *>(dataptrarray[2]))[0]
+ *         _iymdf = (<int *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__iymdf = ((int *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":359
+ *         _dj2 = (<double *>(dataptrarray[2]))[0]
+ *         _iymdf = (<int *>(dataptrarray[3]))
+ *         _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraJdcalf(__pyx_v__ndp, __pyx_v__dj1, __pyx_v__dj2, __pyx_v__iymdf);
+
+    /* "astropy/_erfa/core.pyx":360
+ *         _iymdf = (<int *>(dataptrarray[3]))
+ *         _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":361
+ *         _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":362
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":363
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":364
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":343
+ * 
+ * 
+ * def _jdcalf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _ndp
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._jdcalf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":367
+ * 
+ * 
+ * def _ab(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pnat
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_15_ab(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_15_ab = {"_ab", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_15_ab, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_15_ab(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ab (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_14_ab(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_14_ab(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__pnat;
+  double *__pyx_v__v;
+  double __pyx_v__s;
+  double __pyx_v__bm1;
+  double *__pyx_v__ppr;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ab", 0);
+
+  /* "astropy/_erfa/core.pyx":374
+ *     cdef double _bm1
+ *     cdef double * _ppr
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":375
+ *     cdef double * _ppr
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":376
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _pnat = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":377
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _pnat = (<double *>(dataptrarray[0]))
+ *         _v = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":378
+ *     cdef int status = 1
+ *     while status:
+ *         _pnat = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _v = (<double *>(dataptrarray[1]))
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__pnat = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":379
+ *     while status:
+ *         _pnat = (<double *>(dataptrarray[0]))
+ *         _v = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _bm1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__v = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":380
+ *         _pnat = (<double *>(dataptrarray[0]))
+ *         _v = (<double *>(dataptrarray[1]))
+ *         _s = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _bm1 = (<double *>(dataptrarray[3]))[0]
+ *         _ppr = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__s = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":381
+ *         _v = (<double *>(dataptrarray[1]))
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _bm1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _ppr = (<double *>(dataptrarray[4]))
+ *         eraAb(_pnat, _v, _s, _bm1, _ppr)
+ */
+    __pyx_v__bm1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":382
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _bm1 = (<double *>(dataptrarray[3]))[0]
+ *         _ppr = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraAb(_pnat, _v, _s, _bm1, _ppr)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__ppr = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":383
+ *         _bm1 = (<double *>(dataptrarray[3]))[0]
+ *         _ppr = (<double *>(dataptrarray[4]))
+ *         eraAb(_pnat, _v, _s, _bm1, _ppr)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAb(__pyx_v__pnat, __pyx_v__v, __pyx_v__s, __pyx_v__bm1, __pyx_v__ppr);
+
+    /* "astropy/_erfa/core.pyx":384
+ *         _ppr = (<double *>(dataptrarray[4]))
+ *         eraAb(_pnat, _v, _s, _bm1, _ppr)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":367
+ * 
+ * 
+ * def _ab(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pnat
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":387
+ * 
+ * 
+ * def _apcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_17_apcg(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_17_apcg = {"_apcg", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_17_apcg, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_17_apcg(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apcg (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_16_apcg(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_16_apcg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__ebpv;
+  double *__pyx_v__ehp;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apcg", 0);
+
+  /* "astropy/_erfa/core.pyx":394
+ *     cdef double * _ehp
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":395
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":396
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":397
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":398
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":399
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":400
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[4]))
+ */
+    __pyx_v__ebpv = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":401
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[4]))
+ *         eraApcg(_date1, _date2, _ebpv, _ehp, _astrom)
+ */
+    __pyx_v__ehp = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":402
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraApcg(_date1, _date2, _ebpv, _ehp, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":403
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[4]))
+ *         eraApcg(_date1, _date2, _ebpv, _ehp, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApcg(__pyx_v__date1, __pyx_v__date2, __pyx_v__ebpv, __pyx_v__ehp, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":404
+ *         _astrom = (<eraASTROM *>(dataptrarray[4]))
+ *         eraApcg(_date1, _date2, _ebpv, _ehp, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":387
+ * 
+ * 
+ * def _apcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":407
+ * 
+ * 
+ * def _apcg13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_19_apcg13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_19_apcg13 = {"_apcg13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_19_apcg13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_19_apcg13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apcg13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_18_apcg13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_18_apcg13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apcg13", 0);
+
+  /* "astropy/_erfa/core.pyx":412
+ *     cdef double _date2
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":413
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":414
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":415
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":416
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":417
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraApcg13(_date1, _date2, _astrom)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":418
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraApcg13(_date1, _date2, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":419
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraApcg13(_date1, _date2, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApcg13(__pyx_v__date1, __pyx_v__date2, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":420
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraApcg13(_date1, _date2, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":407
+ * 
+ * 
+ * def _apcg13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":423
+ * 
+ * 
+ * def _apci(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_21_apci(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_21_apci = {"_apci", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_21_apci, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_21_apci(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apci (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_20_apci(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_20_apci(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__ebpv;
+  double *__pyx_v__ehp;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__s;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apci", 0);
+
+  /* "astropy/_erfa/core.pyx":433
+ *     cdef double _s
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":434
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":435
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":436
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":437
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":438
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":439
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__ebpv = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":440
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__ehp = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":441
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":442
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[7]))
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":443
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[7]))
+ *         eraApci(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _astrom)
+ */
+    __pyx_v__s = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":444
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         eraApci(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":445
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[7]))
+ *         eraApci(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApci(__pyx_v__date1, __pyx_v__date2, __pyx_v__ebpv, __pyx_v__ehp, __pyx_v__x, __pyx_v__y, __pyx_v__s, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":446
+ *         _astrom = (<eraASTROM *>(dataptrarray[7]))
+ *         eraApci(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":423
+ * 
+ * 
+ * def _apci(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":449
+ * 
+ * 
+ * def _apci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_23_apci13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_23_apci13 = {"_apci13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_23_apci13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_23_apci13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apci13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_22_apci13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_22_apci13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__eo;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apci13", 0);
+
+  /* "astropy/_erfa/core.pyx":455
+ *     cdef eraASTROM * _astrom
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":456
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":457
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":458
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":459
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":460
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _eo = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":461
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _eo = (<double *>(dataptrarray[3]))
+ *         eraApci13(_date1, _date2, _astrom, _eo)
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":462
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _eo = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraApci13(_date1, _date2, _astrom, _eo)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__eo = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":463
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _eo = (<double *>(dataptrarray[3]))
+ *         eraApci13(_date1, _date2, _astrom, _eo)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApci13(__pyx_v__date1, __pyx_v__date2, __pyx_v__astrom, __pyx_v__eo);
+
+    /* "astropy/_erfa/core.pyx":464
+ *         _eo = (<double *>(dataptrarray[3]))
+ *         eraApci13(_date1, _date2, _astrom, _eo)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":449
+ * 
+ * 
+ * def _apci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":467
+ * 
+ * 
+ * def _apco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_25_apco(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_25_apco = {"_apco", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_25_apco, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_25_apco(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apco (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_24_apco(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_24_apco(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__ebpv;
+  double *__pyx_v__ehp;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__s;
+  double __pyx_v__theta;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__sp;
+  double __pyx_v__refa;
+  double __pyx_v__refb;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apco", 0);
+
+  /* "astropy/_erfa/core.pyx":486
+ *     cdef double _refb
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":487
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":488
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":489
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":490
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":491
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":492
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__ebpv = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":493
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__ehp = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":494
+ *         _ebpv = (<double *>(dataptrarray[2]))
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":495
+ *         _ehp = (<double *>(dataptrarray[3]))
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _theta = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":496
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _theta = (<double *>(dataptrarray[7]))[0]
+ *         _elong = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__s = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":497
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _theta = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[8]))[0]
+ *         _phi = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__theta = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":498
+ *         _s = (<double *>(dataptrarray[6]))[0]
+ *         _theta = (<double *>(dataptrarray[7]))[0]
+ *         _elong = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[9]))[0]
+ *         _hm = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":499
+ *         _theta = (<double *>(dataptrarray[7]))[0]
+ *         _elong = (<double *>(dataptrarray[8]))[0]
+ *         _phi = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[10]))[0]
+ *         _xp = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":500
+ *         _elong = (<double *>(dataptrarray[8]))[0]
+ *         _phi = (<double *>(dataptrarray[9]))[0]
+ *         _hm = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[11]))[0]
+ *         _yp = (<double *>(dataptrarray[12]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":501
+ *         _phi = (<double *>(dataptrarray[9]))[0]
+ *         _hm = (<double *>(dataptrarray[10]))[0]
+ *         _xp = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[12]))[0]
+ *         _sp = (<double *>(dataptrarray[13]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":502
+ *         _hm = (<double *>(dataptrarray[10]))[0]
+ *         _xp = (<double *>(dataptrarray[11]))[0]
+ *         _yp = (<double *>(dataptrarray[12]))[0]             # <<<<<<<<<<<<<<
+ *         _sp = (<double *>(dataptrarray[13]))[0]
+ *         _refa = (<double *>(dataptrarray[14]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[12]))[0]);
+
+    /* "astropy/_erfa/core.pyx":503
+ *         _xp = (<double *>(dataptrarray[11]))[0]
+ *         _yp = (<double *>(dataptrarray[12]))[0]
+ *         _sp = (<double *>(dataptrarray[13]))[0]             # <<<<<<<<<<<<<<
+ *         _refa = (<double *>(dataptrarray[14]))[0]
+ *         _refb = (<double *>(dataptrarray[15]))[0]
+ */
+    __pyx_v__sp = (((double *)(__pyx_v_dataptrarray[13]))[0]);
+
+    /* "astropy/_erfa/core.pyx":504
+ *         _yp = (<double *>(dataptrarray[12]))[0]
+ *         _sp = (<double *>(dataptrarray[13]))[0]
+ *         _refa = (<double *>(dataptrarray[14]))[0]             # <<<<<<<<<<<<<<
+ *         _refb = (<double *>(dataptrarray[15]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[16]))
+ */
+    __pyx_v__refa = (((double *)(__pyx_v_dataptrarray[14]))[0]);
+
+    /* "astropy/_erfa/core.pyx":505
+ *         _sp = (<double *>(dataptrarray[13]))[0]
+ *         _refa = (<double *>(dataptrarray[14]))[0]
+ *         _refb = (<double *>(dataptrarray[15]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[16]))
+ *         eraApco(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _theta, _elong, _phi, _hm, _xp, _yp, _sp, _refa, _refb, _astrom)
+ */
+    __pyx_v__refb = (((double *)(__pyx_v_dataptrarray[15]))[0]);
+
+    /* "astropy/_erfa/core.pyx":506
+ *         _refa = (<double *>(dataptrarray[14]))[0]
+ *         _refb = (<double *>(dataptrarray[15]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[16]))             # <<<<<<<<<<<<<<
+ *         eraApco(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _theta, _elong, _phi, _hm, _xp, _yp, _sp, _refa, _refb, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[16]));
+
+    /* "astropy/_erfa/core.pyx":507
+ *         _refb = (<double *>(dataptrarray[15]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[16]))
+ *         eraApco(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _theta, _elong, _phi, _hm, _xp, _yp, _sp, _refa, _refb, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApco(__pyx_v__date1, __pyx_v__date2, __pyx_v__ebpv, __pyx_v__ehp, __pyx_v__x, __pyx_v__y, __pyx_v__s, __pyx_v__theta, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__sp, __pyx_v__refa, __pyx_v__refb, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":508
+ *         _astrom = (<eraASTROM *>(dataptrarray[16]))
+ *         eraApco(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _theta, _elong, _phi, _hm, _xp, _yp, _sp, _refa, _refb, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":467
+ * 
+ * 
+ * def _apco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":511
+ * 
+ * 
+ * def _apco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_27_apco13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_27_apco13 = {"_apco13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_27_apco13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_27_apco13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apco13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_26_apco13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_26_apco13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__eo;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_apco13", 0);
+
+  /* "astropy/_erfa/core.pyx":528
+ *     cdef double * _eo
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":529
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":530
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":531
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":532
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":533
+ *     cdef int status = 1
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":534
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":535
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":536
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":537
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":538
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":539
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":540
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":541
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":542
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":543
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":544
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _eo = (<double *>(dataptrarray[13]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":545
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _eo = (<double *>(dataptrarray[13]))
+ *         _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":546
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _eo = (<double *>(dataptrarray[13]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)
+ *         (<int *>(dataptrarray[14]))[0] = _c_retval
+ */
+    __pyx_v__eo = ((double *)(__pyx_v_dataptrarray[13]));
+
+    /* "astropy/_erfa/core.pyx":547
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _eo = (<double *>(dataptrarray[13]))
+ *         _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[14]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraApco13(__pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__astrom, __pyx_v__eo);
+
+    /* "astropy/_erfa/core.pyx":548
+ *         _eo = (<double *>(dataptrarray[13]))
+ *         _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)
+ *         (<int *>(dataptrarray[14]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[14]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":549
+ *         _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)
+ *         (<int *>(dataptrarray[14]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":550
+ *         (<int *>(dataptrarray[14]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":551
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":552
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":511
+ * 
+ * 
+ * def _apco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._apco13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":555
+ * 
+ * 
+ * def _apcs(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_29_apcs(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_29_apcs = {"_apcs", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_29_apcs, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_29_apcs(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apcs (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_28_apcs(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_28_apcs(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__pv;
+  double *__pyx_v__ebpv;
+  double *__pyx_v__ehp;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apcs", 0);
+
+  /* "astropy/_erfa/core.pyx":563
+ *     cdef double * _ehp
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":564
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":565
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":566
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":567
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":568
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _ebpv = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":569
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _ebpv = (<double *>(dataptrarray[3]))
+ *         _ehp = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":570
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _ebpv = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _ehp = (<double *>(dataptrarray[4]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[5]))
+ */
+    __pyx_v__ebpv = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":571
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _ebpv = (<double *>(dataptrarray[3]))
+ *         _ehp = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[5]))
+ *         eraApcs(_date1, _date2, _pv, _ebpv, _ehp, _astrom)
+ */
+    __pyx_v__ehp = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":572
+ *         _ebpv = (<double *>(dataptrarray[3]))
+ *         _ehp = (<double *>(dataptrarray[4]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraApcs(_date1, _date2, _pv, _ebpv, _ehp, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":573
+ *         _ehp = (<double *>(dataptrarray[4]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[5]))
+ *         eraApcs(_date1, _date2, _pv, _ebpv, _ehp, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApcs(__pyx_v__date1, __pyx_v__date2, __pyx_v__pv, __pyx_v__ebpv, __pyx_v__ehp, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":574
+ *         _astrom = (<eraASTROM *>(dataptrarray[5]))
+ *         eraApcs(_date1, _date2, _pv, _ebpv, _ehp, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":555
+ * 
+ * 
+ * def _apcs(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":577
+ * 
+ * 
+ * def _apcs13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_31_apcs13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_31_apcs13 = {"_apcs13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_31_apcs13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_31_apcs13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apcs13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_30_apcs13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_30_apcs13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__pv;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apcs13", 0);
+
+  /* "astropy/_erfa/core.pyx":583
+ *     cdef double * _pv
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":584
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":585
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":586
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":587
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":588
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":589
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         eraApcs13(_date1, _date2, _pv, _astrom)
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":590
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraApcs13(_date1, _date2, _pv, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":591
+ *         _pv = (<double *>(dataptrarray[2]))
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         eraApcs13(_date1, _date2, _pv, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApcs13(__pyx_v__date1, __pyx_v__date2, __pyx_v__pv, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":592
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         eraApcs13(_date1, _date2, _pv, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":577
+ * 
+ * 
+ * def _apcs13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":595
+ * 
+ * 
+ * def _aper(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _theta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_33_aper(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_33_aper = {"_aper", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_33_aper, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_33_aper(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_aper (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_32_aper(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_32_aper(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__theta;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_aper", 0);
+
+  /* "astropy/_erfa/core.pyx":599
+ *     cdef double _theta
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":600
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":601
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _theta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":602
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _theta = (<double *>(dataptrarray[0]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":603
+ *     cdef int status = 1
+ *     while status:
+ *         _theta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[1]))
+ *         eraAper(_theta, _astrom)
+ */
+    __pyx_v__theta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":604
+ *     while status:
+ *         _theta = (<double *>(dataptrarray[0]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         eraAper(_theta, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":605
+ *         _theta = (<double *>(dataptrarray[0]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[1]))
+ *         eraAper(_theta, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAper(__pyx_v__theta, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":606
+ *         _astrom = (<eraASTROM *>(dataptrarray[1]))
+ *         eraAper(_theta, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":595
+ * 
+ * 
+ * def _aper(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _theta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":609
+ * 
+ * 
+ * def _aper13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_35_aper13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_35_aper13 = {"_aper13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_35_aper13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_35_aper13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_aper13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_34_aper13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_34_aper13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ut11;
+  double __pyx_v__ut12;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_aper13", 0);
+
+  /* "astropy/_erfa/core.pyx":614
+ *     cdef double _ut12
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":615
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":616
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":617
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":618
+ *     cdef int status = 1
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__ut11 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":619
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraAper13(_ut11, _ut12, _astrom)
+ */
+    __pyx_v__ut12 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":620
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraAper13(_ut11, _ut12, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":621
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraAper13(_ut11, _ut12, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAper13(__pyx_v__ut11, __pyx_v__ut12, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":622
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         eraAper13(_ut11, _ut12, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":609
+ * 
+ * 
+ * def _aper13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":625
+ * 
+ * 
+ * def _apio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _sp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_37_apio(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_37_apio = {"_apio", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_37_apio, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_37_apio(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apio (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_36_apio(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_36_apio(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__sp;
+  double __pyx_v__theta;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__refa;
+  double __pyx_v__refb;
+  struct eraASTROM *__pyx_v__astrom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_apio", 0);
+
+  /* "astropy/_erfa/core.pyx":637
+ *     cdef double _refb
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":638
+ *     cdef eraASTROM * _astrom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":639
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _sp = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":640
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _sp = (<double *>(dataptrarray[0]))[0]
+ *         _theta = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":641
+ *     cdef int status = 1
+ *     while status:
+ *         _sp = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _theta = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__sp = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":642
+ *     while status:
+ *         _sp = (<double *>(dataptrarray[0]))[0]
+ *         _theta = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__theta = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":643
+ *         _sp = (<double *>(dataptrarray[0]))[0]
+ *         _theta = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _hm = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":644
+ *         _theta = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[4]))[0]
+ *         _xp = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":645
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _hm = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[5]))[0]
+ *         _yp = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":646
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _hm = (<double *>(dataptrarray[4]))[0]
+ *         _xp = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[6]))[0]
+ *         _refa = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":647
+ *         _hm = (<double *>(dataptrarray[4]))[0]
+ *         _xp = (<double *>(dataptrarray[5]))[0]
+ *         _yp = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _refa = (<double *>(dataptrarray[7]))[0]
+ *         _refb = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":648
+ *         _xp = (<double *>(dataptrarray[5]))[0]
+ *         _yp = (<double *>(dataptrarray[6]))[0]
+ *         _refa = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _refb = (<double *>(dataptrarray[8]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[9]))
+ */
+    __pyx_v__refa = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":649
+ *         _yp = (<double *>(dataptrarray[6]))[0]
+ *         _refa = (<double *>(dataptrarray[7]))[0]
+ *         _refb = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[9]))
+ *         eraApio(_sp, _theta, _elong, _phi, _hm, _xp, _yp, _refa, _refb, _astrom)
+ */
+    __pyx_v__refb = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":650
+ *         _refa = (<double *>(dataptrarray[7]))[0]
+ *         _refb = (<double *>(dataptrarray[8]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraApio(_sp, _theta, _elong, _phi, _hm, _xp, _yp, _refa, _refb, _astrom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":651
+ *         _refb = (<double *>(dataptrarray[8]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[9]))
+ *         eraApio(_sp, _theta, _elong, _phi, _hm, _xp, _yp, _refa, _refb, _astrom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraApio(__pyx_v__sp, __pyx_v__theta, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__refa, __pyx_v__refb, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":652
+ *         _astrom = (<eraASTROM *>(dataptrarray[9]))
+ *         eraApio(_sp, _theta, _elong, _phi, _hm, _xp, _yp, _refa, _refb, _astrom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":625
+ * 
+ * 
+ * def _apio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _sp
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":655
+ * 
+ * 
+ * def _apio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_39_apio13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_39_apio13 = {"_apio13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_39_apio13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_39_apio13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_apio13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_38_apio13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_38_apio13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  struct eraASTROM *__pyx_v__astrom;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_apio13", 0);
+
+  /* "astropy/_erfa/core.pyx":671
+ *     cdef eraASTROM * _astrom
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":672
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":673
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":674
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":675
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":676
+ *     cdef int status = 1
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":677
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":678
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":679
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":680
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":681
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":682
+ *         _phi = (<double *>(dataptrarray[4]))[0]
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":683
+ *         _hm = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":684
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":685
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":686
+ *         _phpa = (<double *>(dataptrarray[8]))[0]
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":687
+ *         _tc = (<double *>(dataptrarray[9]))[0]
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":688
+ *         _rh = (<double *>(dataptrarray[10]))[0]
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)
+ *         (<int *>(dataptrarray[13]))[0] = _c_retval
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":689
+ *         _wl = (<double *>(dataptrarray[11]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[13]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraApio13(__pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__astrom);
+
+    /* "astropy/_erfa/core.pyx":690
+ *         _astrom = (<eraASTROM *>(dataptrarray[12]))
+ *         _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)
+ *         (<int *>(dataptrarray[13]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[13]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":691
+ *         _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)
+ *         (<int *>(dataptrarray[13]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":692
+ *         (<int *>(dataptrarray[13]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":693
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":694
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":655
+ * 
+ * 
+ * def _apio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._apio13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":697
+ * 
+ * 
+ * def _atci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_41_atci13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_41_atci13 = {"_atci13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_41_atci13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_41_atci13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atci13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_40_atci13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_40_atci13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  double __pyx_v__pr;
+  double __pyx_v__pd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  double *__pyx_v__eo;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atci13", 0);
+
+  /* "astropy/_erfa/core.pyx":710
+ *     cdef double * _di
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":711
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":712
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":713
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":714
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":715
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":716
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":717
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":718
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _date1 = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":719
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[6]))[0]
+ *         _date2 = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":720
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _date1 = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[7]))[0]
+ *         _ri = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":721
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _date1 = (<double *>(dataptrarray[6]))[0]
+ *         _date2 = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[8]))
+ *         _di = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":722
+ *         _date1 = (<double *>(dataptrarray[6]))[0]
+ *         _date2 = (<double *>(dataptrarray[7]))[0]
+ *         _ri = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[9]))
+ *         _eo = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":723
+ *         _date2 = (<double *>(dataptrarray[7]))[0]
+ *         _ri = (<double *>(dataptrarray[8]))
+ *         _di = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         _eo = (<double *>(dataptrarray[10]))
+ *         eraAtci13(_rc, _dc, _pr, _pd, _px, _rv, _date1, _date2, _ri, _di, _eo)
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":724
+ *         _ri = (<double *>(dataptrarray[8]))
+ *         _di = (<double *>(dataptrarray[9]))
+ *         _eo = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         eraAtci13(_rc, _dc, _pr, _pd, _px, _rv, _date1, _date2, _ri, _di, _eo)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__eo = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":725
+ *         _di = (<double *>(dataptrarray[9]))
+ *         _eo = (<double *>(dataptrarray[10]))
+ *         eraAtci13(_rc, _dc, _pr, _pd, _px, _rv, _date1, _date2, _ri, _di, _eo)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtci13(__pyx_v__rc, __pyx_v__dc, __pyx_v__pr, __pyx_v__pd, __pyx_v__px, __pyx_v__rv, __pyx_v__date1, __pyx_v__date2, __pyx_v__ri, __pyx_v__di, __pyx_v__eo);
+
+    /* "astropy/_erfa/core.pyx":726
+ *         _eo = (<double *>(dataptrarray[10]))
+ *         eraAtci13(_rc, _dc, _pr, _pd, _px, _rv, _date1, _date2, _ri, _di, _eo)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":697
+ * 
+ * 
+ * def _atci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":729
+ * 
+ * 
+ * def _atciq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_43_atciq(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_43_atciq = {"_atciq", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_43_atciq, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_43_atciq(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atciq (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_42_atciq(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_42_atciq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  double __pyx_v__pr;
+  double __pyx_v__pd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atciq", 0);
+
+  /* "astropy/_erfa/core.pyx":740
+ *     cdef double * _ri
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":741
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":742
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":743
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":744
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":745
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":746
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":747
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":748
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":749
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _ri = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":750
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[7]))
+ *         _di = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":751
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _ri = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[8]))
+ *         eraAtciq(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _ri, _di)
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":752
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _ri = (<double *>(dataptrarray[7]))
+ *         _di = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         eraAtciq(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":753
+ *         _ri = (<double *>(dataptrarray[7]))
+ *         _di = (<double *>(dataptrarray[8]))
+ *         eraAtciq(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _ri, _di)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtciq(__pyx_v__rc, __pyx_v__dc, __pyx_v__pr, __pyx_v__pd, __pyx_v__px, __pyx_v__rv, __pyx_v__astrom, __pyx_v__ri, __pyx_v__di);
+
+    /* "astropy/_erfa/core.pyx":754
+ *         _di = (<double *>(dataptrarray[8]))
+ *         eraAtciq(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":729
+ * 
+ * 
+ * def _atciq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":757
+ * 
+ * 
+ * def _atciqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_45_atciqn(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_45_atciqn = {"_atciqn", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_45_atciqn, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_45_atciqn(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atciqn (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_44_atciqn(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_44_atciqn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  double __pyx_v__pr;
+  double __pyx_v__pd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  struct eraASTROM *__pyx_v__astrom;
+  int __pyx_v__n;
+  struct eraLDBODY *__pyx_v__b;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atciqn", 0);
+
+  /* "astropy/_erfa/core.pyx":770
+ *     cdef double * _ri
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":771
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":772
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":773
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":774
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":775
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":776
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":777
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":778
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":779
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _n = (<int *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":780
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[7]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[8]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":781
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _n = (<int *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _b = (<eraLDBODY *>(dataptrarray[8]))
+ *         _ri = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":782
+ *         _astrom = (<eraASTROM *>(dataptrarray[6]))
+ *         _n = (<int *>(dataptrarray[7]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[9]))
+ *         _di = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__b = ((struct eraLDBODY *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":783
+ *         _n = (<int *>(dataptrarray[7]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[8]))
+ *         _ri = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[10]))
+ *         eraAtciqn(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _n, _b, _ri, _di)
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":784
+ *         _b = (<eraLDBODY *>(dataptrarray[8]))
+ *         _ri = (<double *>(dataptrarray[9]))
+ *         _di = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         eraAtciqn(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _n, _b, _ri, _di)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":785
+ *         _ri = (<double *>(dataptrarray[9]))
+ *         _di = (<double *>(dataptrarray[10]))
+ *         eraAtciqn(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _n, _b, _ri, _di)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtciqn(__pyx_v__rc, __pyx_v__dc, __pyx_v__pr, __pyx_v__pd, __pyx_v__px, __pyx_v__rv, __pyx_v__astrom, __pyx_v__n, __pyx_v__b, __pyx_v__ri, __pyx_v__di);
+
+    /* "astropy/_erfa/core.pyx":786
+ *         _di = (<double *>(dataptrarray[10]))
+ *         eraAtciqn(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _n, _b, _ri, _di)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":757
+ * 
+ * 
+ * def _atciqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":789
+ * 
+ * 
+ * def _atciqz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_47_atciqz(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_47_atciqz = {"_atciqz", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_47_atciqz, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_47_atciqz(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atciqz (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_46_atciqz(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_46_atciqz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atciqz", 0);
+
+  /* "astropy/_erfa/core.pyx":796
+ *     cdef double * _ri
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":797
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":798
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":799
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":800
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":801
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _ri = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":802
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[3]))
+ *         _di = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":803
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _ri = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[4]))
+ *         eraAtciqz(_rc, _dc, _astrom, _ri, _di)
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":804
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _ri = (<double *>(dataptrarray[3]))
+ *         _di = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraAtciqz(_rc, _dc, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":805
+ *         _ri = (<double *>(dataptrarray[3]))
+ *         _di = (<double *>(dataptrarray[4]))
+ *         eraAtciqz(_rc, _dc, _astrom, _ri, _di)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtciqz(__pyx_v__rc, __pyx_v__dc, __pyx_v__astrom, __pyx_v__ri, __pyx_v__di);
+
+    /* "astropy/_erfa/core.pyx":806
+ *         _di = (<double *>(dataptrarray[4]))
+ *         eraAtciqz(_rc, _dc, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":789
+ * 
+ * 
+ * def _atciqz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":809
+ * 
+ * 
+ * def _atco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_49_atco13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_49_atco13 = {"_atco13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_49_atco13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_49_atco13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atco13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_48_atco13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_48_atco13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  double __pyx_v__pr;
+  double __pyx_v__pd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  double *__pyx_v__aob;
+  double *__pyx_v__zob;
+  double *__pyx_v__hob;
+  double *__pyx_v__dob;
+  double *__pyx_v__rob;
+  double *__pyx_v__eo;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_atco13", 0);
+
+  /* "astropy/_erfa/core.pyx":836
+ *     cdef double * _eo
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":837
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":838
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":839
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":840
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":841
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":842
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":843
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":844
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":845
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _utc1 = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":846
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[6]))[0]
+ *         _utc2 = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":847
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _utc1 = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[7]))[0]
+ *         _dut1 = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":848
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _utc1 = (<double *>(dataptrarray[6]))[0]
+ *         _utc2 = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[8]))[0]
+ *         _elong = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":849
+ *         _utc1 = (<double *>(dataptrarray[6]))[0]
+ *         _utc2 = (<double *>(dataptrarray[7]))[0]
+ *         _dut1 = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[9]))[0]
+ *         _phi = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":850
+ *         _utc2 = (<double *>(dataptrarray[7]))[0]
+ *         _dut1 = (<double *>(dataptrarray[8]))[0]
+ *         _elong = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[10]))[0]
+ *         _hm = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":851
+ *         _dut1 = (<double *>(dataptrarray[8]))[0]
+ *         _elong = (<double *>(dataptrarray[9]))[0]
+ *         _phi = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[11]))[0]
+ *         _xp = (<double *>(dataptrarray[12]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":852
+ *         _elong = (<double *>(dataptrarray[9]))[0]
+ *         _phi = (<double *>(dataptrarray[10]))[0]
+ *         _hm = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[12]))[0]
+ *         _yp = (<double *>(dataptrarray[13]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":853
+ *         _phi = (<double *>(dataptrarray[10]))[0]
+ *         _hm = (<double *>(dataptrarray[11]))[0]
+ *         _xp = (<double *>(dataptrarray[12]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[13]))[0]
+ *         _phpa = (<double *>(dataptrarray[14]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[12]))[0]);
+
+    /* "astropy/_erfa/core.pyx":854
+ *         _hm = (<double *>(dataptrarray[11]))[0]
+ *         _xp = (<double *>(dataptrarray[12]))[0]
+ *         _yp = (<double *>(dataptrarray[13]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[14]))[0]
+ *         _tc = (<double *>(dataptrarray[15]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[13]))[0]);
+
+    /* "astropy/_erfa/core.pyx":855
+ *         _xp = (<double *>(dataptrarray[12]))[0]
+ *         _yp = (<double *>(dataptrarray[13]))[0]
+ *         _phpa = (<double *>(dataptrarray[14]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[15]))[0]
+ *         _rh = (<double *>(dataptrarray[16]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[14]))[0]);
+
+    /* "astropy/_erfa/core.pyx":856
+ *         _yp = (<double *>(dataptrarray[13]))[0]
+ *         _phpa = (<double *>(dataptrarray[14]))[0]
+ *         _tc = (<double *>(dataptrarray[15]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[16]))[0]
+ *         _wl = (<double *>(dataptrarray[17]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[15]))[0]);
+
+    /* "astropy/_erfa/core.pyx":857
+ *         _phpa = (<double *>(dataptrarray[14]))[0]
+ *         _tc = (<double *>(dataptrarray[15]))[0]
+ *         _rh = (<double *>(dataptrarray[16]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[17]))[0]
+ *         _aob = (<double *>(dataptrarray[18]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[16]))[0]);
+
+    /* "astropy/_erfa/core.pyx":858
+ *         _tc = (<double *>(dataptrarray[15]))[0]
+ *         _rh = (<double *>(dataptrarray[16]))[0]
+ *         _wl = (<double *>(dataptrarray[17]))[0]             # <<<<<<<<<<<<<<
+ *         _aob = (<double *>(dataptrarray[18]))
+ *         _zob = (<double *>(dataptrarray[19]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[17]))[0]);
+
+    /* "astropy/_erfa/core.pyx":859
+ *         _rh = (<double *>(dataptrarray[16]))[0]
+ *         _wl = (<double *>(dataptrarray[17]))[0]
+ *         _aob = (<double *>(dataptrarray[18]))             # <<<<<<<<<<<<<<
+ *         _zob = (<double *>(dataptrarray[19]))
+ *         _hob = (<double *>(dataptrarray[20]))
+ */
+    __pyx_v__aob = ((double *)(__pyx_v_dataptrarray[18]));
+
+    /* "astropy/_erfa/core.pyx":860
+ *         _wl = (<double *>(dataptrarray[17]))[0]
+ *         _aob = (<double *>(dataptrarray[18]))
+ *         _zob = (<double *>(dataptrarray[19]))             # <<<<<<<<<<<<<<
+ *         _hob = (<double *>(dataptrarray[20]))
+ *         _dob = (<double *>(dataptrarray[21]))
+ */
+    __pyx_v__zob = ((double *)(__pyx_v_dataptrarray[19]));
+
+    /* "astropy/_erfa/core.pyx":861
+ *         _aob = (<double *>(dataptrarray[18]))
+ *         _zob = (<double *>(dataptrarray[19]))
+ *         _hob = (<double *>(dataptrarray[20]))             # <<<<<<<<<<<<<<
+ *         _dob = (<double *>(dataptrarray[21]))
+ *         _rob = (<double *>(dataptrarray[22]))
+ */
+    __pyx_v__hob = ((double *)(__pyx_v_dataptrarray[20]));
+
+    /* "astropy/_erfa/core.pyx":862
+ *         _zob = (<double *>(dataptrarray[19]))
+ *         _hob = (<double *>(dataptrarray[20]))
+ *         _dob = (<double *>(dataptrarray[21]))             # <<<<<<<<<<<<<<
+ *         _rob = (<double *>(dataptrarray[22]))
+ *         _eo = (<double *>(dataptrarray[23]))
+ */
+    __pyx_v__dob = ((double *)(__pyx_v_dataptrarray[21]));
+
+    /* "astropy/_erfa/core.pyx":863
+ *         _hob = (<double *>(dataptrarray[20]))
+ *         _dob = (<double *>(dataptrarray[21]))
+ *         _rob = (<double *>(dataptrarray[22]))             # <<<<<<<<<<<<<<
+ *         _eo = (<double *>(dataptrarray[23]))
+ *         _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)
+ */
+    __pyx_v__rob = ((double *)(__pyx_v_dataptrarray[22]));
+
+    /* "astropy/_erfa/core.pyx":864
+ *         _dob = (<double *>(dataptrarray[21]))
+ *         _rob = (<double *>(dataptrarray[22]))
+ *         _eo = (<double *>(dataptrarray[23]))             # <<<<<<<<<<<<<<
+ *         _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 *>(dataptrarray[24]))[0] = _c_retval
+ */
+    __pyx_v__eo = ((double *)(__pyx_v_dataptrarray[23]));
+
+    /* "astropy/_erfa/core.pyx":865
+ *         _rob = (<double *>(dataptrarray[22]))
+ *         _eo = (<double *>(dataptrarray[23]))
+ *         _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 *>(dataptrarray[24]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraAtco13(__pyx_v__rc, __pyx_v__dc, __pyx_v__pr, __pyx_v__pd, __pyx_v__px, __pyx_v__rv, __pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__aob, __pyx_v__zob, __pyx_v__hob, __pyx_v__dob, __pyx_v__rob, __pyx_v__eo);
+
+    /* "astropy/_erfa/core.pyx":866
+ *         _eo = (<double *>(dataptrarray[23]))
+ *         _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 *>(dataptrarray[24]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[24]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":867
+ *         _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 *>(dataptrarray[24]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":868
+ *         (<int *>(dataptrarray[24]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":869
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":870
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 870; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":809
+ * 
+ * 
+ * def _atco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._atco13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":873
+ * 
+ * 
+ * def _atic13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_51_atic13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_51_atic13 = {"_atic13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_51_atic13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_51_atic13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atic13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_50_atic13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_50_atic13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ri;
+  double __pyx_v__di;
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rc;
+  double *__pyx_v__dc;
+  double *__pyx_v__eo;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atic13", 0);
+
+  /* "astropy/_erfa/core.pyx":882
+ *     cdef double * _dc
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":883
+ *     cdef double * _eo
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":884
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":885
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":886
+ *     cdef int status = 1
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ri = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":887
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__di = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":888
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rc = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":889
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[4]))
+ *         _dc = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":890
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rc = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[5]))
+ *         _eo = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__rc = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":891
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rc = (<double *>(dataptrarray[4]))
+ *         _dc = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _eo = (<double *>(dataptrarray[6]))
+ *         eraAtic13(_ri, _di, _date1, _date2, _rc, _dc, _eo)
+ */
+    __pyx_v__dc = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":892
+ *         _rc = (<double *>(dataptrarray[4]))
+ *         _dc = (<double *>(dataptrarray[5]))
+ *         _eo = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraAtic13(_ri, _di, _date1, _date2, _rc, _dc, _eo)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__eo = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":893
+ *         _dc = (<double *>(dataptrarray[5]))
+ *         _eo = (<double *>(dataptrarray[6]))
+ *         eraAtic13(_ri, _di, _date1, _date2, _rc, _dc, _eo)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtic13(__pyx_v__ri, __pyx_v__di, __pyx_v__date1, __pyx_v__date2, __pyx_v__rc, __pyx_v__dc, __pyx_v__eo);
+
+    /* "astropy/_erfa/core.pyx":894
+ *         _eo = (<double *>(dataptrarray[6]))
+ *         eraAtic13(_ri, _di, _date1, _date2, _rc, _dc, _eo)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":873
+ * 
+ * 
+ * def _atic13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":897
+ * 
+ * 
+ * def _aticq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_53_aticq(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_53_aticq = {"_aticq", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_53_aticq, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_53_aticq(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_aticq (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_52_aticq(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_52_aticq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ri;
+  double __pyx_v__di;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__rc;
+  double *__pyx_v__dc;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_aticq", 0);
+
+  /* "astropy/_erfa/core.pyx":904
+ *     cdef double * _rc
+ *     cdef double * _dc
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":905
+ *     cdef double * _dc
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":906
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":907
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":908
+ *     cdef int status = 1
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__ri = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":909
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _rc = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__di = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":910
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[3]))
+ *         _dc = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":911
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _rc = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[4]))
+ *         eraAticq(_ri, _di, _astrom, _rc, _dc)
+ */
+    __pyx_v__rc = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":912
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _rc = (<double *>(dataptrarray[3]))
+ *         _dc = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraAticq(_ri, _di, _astrom, _rc, _dc)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__dc = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":913
+ *         _rc = (<double *>(dataptrarray[3]))
+ *         _dc = (<double *>(dataptrarray[4]))
+ *         eraAticq(_ri, _di, _astrom, _rc, _dc)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAticq(__pyx_v__ri, __pyx_v__di, __pyx_v__astrom, __pyx_v__rc, __pyx_v__dc);
+
+    /* "astropy/_erfa/core.pyx":914
+ *         _dc = (<double *>(dataptrarray[4]))
+ *         eraAticq(_ri, _di, _astrom, _rc, _dc)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":897
+ * 
+ * 
+ * def _aticq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":917
+ * 
+ * 
+ * def _aticqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_55_aticqn(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_55_aticqn = {"_aticqn", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_55_aticqn, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_55_aticqn(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_aticqn (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_54_aticqn(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_54_aticqn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ri;
+  double __pyx_v__di;
+  struct eraASTROM *__pyx_v__astrom;
+  int __pyx_v__n;
+  struct eraLDBODY *__pyx_v__b;
+  double *__pyx_v__rc;
+  double *__pyx_v__dc;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_aticqn", 0);
+
+  /* "astropy/_erfa/core.pyx":926
+ *     cdef double * _rc
+ *     cdef double * _dc
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":927
+ *     cdef double * _dc
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":928
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":929
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":930
+ *     cdef int status = 1
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__ri = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":931
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _n = (<int *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__di = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":932
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[3]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[4]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":933
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _n = (<int *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _b = (<eraLDBODY *>(dataptrarray[4]))
+ *         _rc = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":934
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _n = (<int *>(dataptrarray[3]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[5]))
+ *         _dc = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__b = ((struct eraLDBODY *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":935
+ *         _n = (<int *>(dataptrarray[3]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[4]))
+ *         _rc = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[6]))
+ *         eraAticqn(_ri, _di, _astrom, _n, _b, _rc, _dc)
+ */
+    __pyx_v__rc = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":936
+ *         _b = (<eraLDBODY *>(dataptrarray[4]))
+ *         _rc = (<double *>(dataptrarray[5]))
+ *         _dc = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraAticqn(_ri, _di, _astrom, _n, _b, _rc, _dc)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__dc = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":937
+ *         _rc = (<double *>(dataptrarray[5]))
+ *         _dc = (<double *>(dataptrarray[6]))
+ *         eraAticqn(_ri, _di, _astrom, _n, _b, _rc, _dc)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAticqn(__pyx_v__ri, __pyx_v__di, __pyx_v__astrom, __pyx_v__n, __pyx_v__b, __pyx_v__rc, __pyx_v__dc);
+
+    /* "astropy/_erfa/core.pyx":938
+ *         _dc = (<double *>(dataptrarray[6]))
+ *         eraAticqn(_ri, _di, _astrom, _n, _b, _rc, _dc)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":917
+ * 
+ * 
+ * def _aticqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":941
+ * 
+ * 
+ * def _atio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_57_atio13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_57_atio13 = {"_atio13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_57_atio13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_57_atio13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atio13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_56_atio13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_56_atio13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ri;
+  double __pyx_v__di;
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  double *__pyx_v__aob;
+  double *__pyx_v__zob;
+  double *__pyx_v__hob;
+  double *__pyx_v__dob;
+  double *__pyx_v__rob;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_atio13", 0);
+
+  /* "astropy/_erfa/core.pyx":963
+ *     cdef double * _rob
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":964
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":965
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":966
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":967
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":968
+ *     cdef int status = 1
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ri = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":969
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc2 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__di = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":970
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[3]))[0]
+ *         _dut1 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":971
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc2 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[4]))[0]
+ *         _elong = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":972
+ *         _utc1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc2 = (<double *>(dataptrarray[3]))[0]
+ *         _dut1 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[5]))[0]
+ *         _phi = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":973
+ *         _utc2 = (<double *>(dataptrarray[3]))[0]
+ *         _dut1 = (<double *>(dataptrarray[4]))[0]
+ *         _elong = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[6]))[0]
+ *         _hm = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":974
+ *         _dut1 = (<double *>(dataptrarray[4]))[0]
+ *         _elong = (<double *>(dataptrarray[5]))[0]
+ *         _phi = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[7]))[0]
+ *         _xp = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":975
+ *         _elong = (<double *>(dataptrarray[5]))[0]
+ *         _phi = (<double *>(dataptrarray[6]))[0]
+ *         _hm = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[8]))[0]
+ *         _yp = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":976
+ *         _phi = (<double *>(dataptrarray[6]))[0]
+ *         _hm = (<double *>(dataptrarray[7]))[0]
+ *         _xp = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[9]))[0]
+ *         _phpa = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":977
+ *         _hm = (<double *>(dataptrarray[7]))[0]
+ *         _xp = (<double *>(dataptrarray[8]))[0]
+ *         _yp = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[10]))[0]
+ *         _tc = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":978
+ *         _xp = (<double *>(dataptrarray[8]))[0]
+ *         _yp = (<double *>(dataptrarray[9]))[0]
+ *         _phpa = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[11]))[0]
+ *         _rh = (<double *>(dataptrarray[12]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":979
+ *         _yp = (<double *>(dataptrarray[9]))[0]
+ *         _phpa = (<double *>(dataptrarray[10]))[0]
+ *         _tc = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[12]))[0]
+ *         _wl = (<double *>(dataptrarray[13]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":980
+ *         _phpa = (<double *>(dataptrarray[10]))[0]
+ *         _tc = (<double *>(dataptrarray[11]))[0]
+ *         _rh = (<double *>(dataptrarray[12]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[13]))[0]
+ *         _aob = (<double *>(dataptrarray[14]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[12]))[0]);
+
+    /* "astropy/_erfa/core.pyx":981
+ *         _tc = (<double *>(dataptrarray[11]))[0]
+ *         _rh = (<double *>(dataptrarray[12]))[0]
+ *         _wl = (<double *>(dataptrarray[13]))[0]             # <<<<<<<<<<<<<<
+ *         _aob = (<double *>(dataptrarray[14]))
+ *         _zob = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[13]))[0]);
+
+    /* "astropy/_erfa/core.pyx":982
+ *         _rh = (<double *>(dataptrarray[12]))[0]
+ *         _wl = (<double *>(dataptrarray[13]))[0]
+ *         _aob = (<double *>(dataptrarray[14]))             # <<<<<<<<<<<<<<
+ *         _zob = (<double *>(dataptrarray[15]))
+ *         _hob = (<double *>(dataptrarray[16]))
+ */
+    __pyx_v__aob = ((double *)(__pyx_v_dataptrarray[14]));
+
+    /* "astropy/_erfa/core.pyx":983
+ *         _wl = (<double *>(dataptrarray[13]))[0]
+ *         _aob = (<double *>(dataptrarray[14]))
+ *         _zob = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _hob = (<double *>(dataptrarray[16]))
+ *         _dob = (<double *>(dataptrarray[17]))
+ */
+    __pyx_v__zob = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":984
+ *         _aob = (<double *>(dataptrarray[14]))
+ *         _zob = (<double *>(dataptrarray[15]))
+ *         _hob = (<double *>(dataptrarray[16]))             # <<<<<<<<<<<<<<
+ *         _dob = (<double *>(dataptrarray[17]))
+ *         _rob = (<double *>(dataptrarray[18]))
+ */
+    __pyx_v__hob = ((double *)(__pyx_v_dataptrarray[16]));
+
+    /* "astropy/_erfa/core.pyx":985
+ *         _zob = (<double *>(dataptrarray[15]))
+ *         _hob = (<double *>(dataptrarray[16]))
+ *         _dob = (<double *>(dataptrarray[17]))             # <<<<<<<<<<<<<<
+ *         _rob = (<double *>(dataptrarray[18]))
+ *         _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)
+ */
+    __pyx_v__dob = ((double *)(__pyx_v_dataptrarray[17]));
+
+    /* "astropy/_erfa/core.pyx":986
+ *         _hob = (<double *>(dataptrarray[16]))
+ *         _dob = (<double *>(dataptrarray[17]))
+ *         _rob = (<double *>(dataptrarray[18]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)
+ *         (<int *>(dataptrarray[19]))[0] = _c_retval
+ */
+    __pyx_v__rob = ((double *)(__pyx_v_dataptrarray[18]));
+
+    /* "astropy/_erfa/core.pyx":987
+ *         _dob = (<double *>(dataptrarray[17]))
+ *         _rob = (<double *>(dataptrarray[18]))
+ *         _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[19]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraAtio13(__pyx_v__ri, __pyx_v__di, __pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__aob, __pyx_v__zob, __pyx_v__hob, __pyx_v__dob, __pyx_v__rob);
+
+    /* "astropy/_erfa/core.pyx":988
+ *         _rob = (<double *>(dataptrarray[18]))
+ *         _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)
+ *         (<int *>(dataptrarray[19]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[19]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":989
+ *         _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)
+ *         (<int *>(dataptrarray[19]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":990
+ *         (<int *>(dataptrarray[19]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":991
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":992
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":941
+ * 
+ * 
+ * def _atio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._atio13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":995
+ * 
+ * 
+ * def _atioq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_59_atioq(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_59_atioq = {"_atioq", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_59_atioq, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_59_atioq(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atioq (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_58_atioq(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_58_atioq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ri;
+  double __pyx_v__di;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__aob;
+  double *__pyx_v__zob;
+  double *__pyx_v__hob;
+  double *__pyx_v__dob;
+  double *__pyx_v__rob;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atioq", 0);
+
+  /* "astropy/_erfa/core.pyx":1005
+ *     cdef double * _dob
+ *     cdef double * _rob
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1006
+ *     cdef double * _rob
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1007
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1008
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1009
+ *     cdef int status = 1
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ */
+    __pyx_v__ri = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1010
+ *     while status:
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _aob = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__di = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1011
+ *         _ri = (<double *>(dataptrarray[0]))[0]
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _aob = (<double *>(dataptrarray[3]))
+ *         _zob = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1012
+ *         _di = (<double *>(dataptrarray[1]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _aob = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _zob = (<double *>(dataptrarray[4]))
+ *         _hob = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__aob = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1013
+ *         _astrom = (<eraASTROM *>(dataptrarray[2]))
+ *         _aob = (<double *>(dataptrarray[3]))
+ *         _zob = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _hob = (<double *>(dataptrarray[5]))
+ *         _dob = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__zob = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1014
+ *         _aob = (<double *>(dataptrarray[3]))
+ *         _zob = (<double *>(dataptrarray[4]))
+ *         _hob = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _dob = (<double *>(dataptrarray[6]))
+ *         _rob = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__hob = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":1015
+ *         _zob = (<double *>(dataptrarray[4]))
+ *         _hob = (<double *>(dataptrarray[5]))
+ *         _dob = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rob = (<double *>(dataptrarray[7]))
+ *         eraAtioq(_ri, _di, _astrom, _aob, _zob, _hob, _dob, _rob)
+ */
+    __pyx_v__dob = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":1016
+ *         _hob = (<double *>(dataptrarray[5]))
+ *         _dob = (<double *>(dataptrarray[6]))
+ *         _rob = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         eraAtioq(_ri, _di, _astrom, _aob, _zob, _hob, _dob, _rob)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rob = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":1017
+ *         _dob = (<double *>(dataptrarray[6]))
+ *         _rob = (<double *>(dataptrarray[7]))
+ *         eraAtioq(_ri, _di, _astrom, _aob, _zob, _hob, _dob, _rob)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtioq(__pyx_v__ri, __pyx_v__di, __pyx_v__astrom, __pyx_v__aob, __pyx_v__zob, __pyx_v__hob, __pyx_v__dob, __pyx_v__rob);
+
+    /* "astropy/_erfa/core.pyx":1018
+ *         _rob = (<double *>(dataptrarray[7]))
+ *         eraAtioq(_ri, _di, _astrom, _aob, _zob, _hob, _dob, _rob)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":995
+ * 
+ * 
+ * def _atioq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1021
+ * 
+ * 
+ * def _atoc13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_61_atoc13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_61_atoc13 = {"_atoc13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_61_atoc13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_61_atoc13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atoc13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_60_atoc13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_60_atoc13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  char const *__pyx_v__type;
+  double __pyx_v__ob1;
+  double __pyx_v__ob2;
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  double *__pyx_v__rc;
+  double *__pyx_v__dc;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_atoc13", 0);
+
+  /* "astropy/_erfa/core.pyx":1041
+ *     cdef double * _dc
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":1042
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1043
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1044
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1045
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1046
+ *     cdef int status = 1
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__type = ((char const *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1047
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ob1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1048
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__ob2 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1049
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1050
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1051
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1052
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1053
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1054
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1055
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1056
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1057
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1058
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[12]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1059
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _rc = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[13]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1060
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[15]))
+ *         _dc = (<double *>(dataptrarray[16]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[14]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1061
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _rc = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)
+ */
+    __pyx_v__rc = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":1062
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _rc = (<double *>(dataptrarray[15]))
+ *         _dc = (<double *>(dataptrarray[16]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ */
+    __pyx_v__dc = ((double *)(__pyx_v_dataptrarray[16]));
+
+    /* "astropy/_erfa/core.pyx":1063
+ *         _rc = (<double *>(dataptrarray[15]))
+ *         _dc = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraAtoc13(__pyx_v__type, __pyx_v__ob1, __pyx_v__ob2, __pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__rc, __pyx_v__dc);
+
+    /* "astropy/_erfa/core.pyx":1064
+ *         _dc = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[17]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1065
+ *         _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":1066
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":1067
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1068
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":1021
+ * 
+ * 
+ * def _atoc13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._atoc13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1071
+ * 
+ * 
+ * def _atoi13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_63_atoi13(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_63_atoi13 = {"_atoi13", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_63_atoi13, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_63_atoi13(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atoi13 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_62_atoi13(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_62_atoi13(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  char const *__pyx_v__type;
+  double __pyx_v__ob1;
+  double __pyx_v__ob2;
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_atoi13", 0);
+
+  /* "astropy/_erfa/core.pyx":1091
+ *     cdef double * _di
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":1092
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1093
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1094
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1095
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1096
+ *     cdef int status = 1
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__type = ((char const *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1097
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ob1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1098
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__ob2 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1099
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1100
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1101
+ *         _utc1 = (<double *>(dataptrarray[3]))[0]
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1102
+ *         _utc2 = (<double *>(dataptrarray[4]))[0]
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1103
+ *         _dut1 = (<double *>(dataptrarray[5]))[0]
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1104
+ *         _elong = (<double *>(dataptrarray[6]))[0]
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1105
+ *         _phi = (<double *>(dataptrarray[7]))[0]
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1106
+ *         _hm = (<double *>(dataptrarray[8]))[0]
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[10]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1107
+ *         _xp = (<double *>(dataptrarray[9]))[0]
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[11]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1108
+ *         _yp = (<double *>(dataptrarray[10]))[0]
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[12]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1109
+ *         _phpa = (<double *>(dataptrarray[11]))[0]
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _ri = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[13]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1110
+ *         _tc = (<double *>(dataptrarray[12]))[0]
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[15]))
+ *         _di = (<double *>(dataptrarray[16]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[14]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1111
+ *         _rh = (<double *>(dataptrarray[13]))[0]
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _ri = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":1112
+ *         _wl = (<double *>(dataptrarray[14]))[0]
+ *         _ri = (<double *>(dataptrarray[15]))
+ *         _di = (<double *>(dataptrarray[16]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[16]));
+
+    /* "astropy/_erfa/core.pyx":1113
+ *         _ri = (<double *>(dataptrarray[15]))
+ *         _di = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraAtoi13(__pyx_v__type, __pyx_v__ob1, __pyx_v__ob2, __pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__ri, __pyx_v__di);
+
+    /* "astropy/_erfa/core.pyx":1114
+ *         _di = (<double *>(dataptrarray[16]))
+ *         _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[17]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1115
+ *         _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":1116
+ *         (<int *>(dataptrarray[17]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":1117
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1118
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":1071
+ * 
+ * 
+ * def _atoi13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._atoi13", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1121
+ * 
+ * 
+ * def _atoiq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_65_atoiq(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_65_atoiq = {"_atoiq", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_65_atoiq, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_65_atoiq(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_atoiq (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_64_atoiq(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_64_atoiq(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  char const *__pyx_v__type;
+  double __pyx_v__ob1;
+  double __pyx_v__ob2;
+  struct eraASTROM *__pyx_v__astrom;
+  double *__pyx_v__ri;
+  double *__pyx_v__di;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_atoiq", 0);
+
+  /* "astropy/_erfa/core.pyx":1129
+ *     cdef double * _ri
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1130
+ *     cdef double * _di
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1131
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1132
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1133
+ *     cdef int status = 1
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__type = ((char const *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1134
+ *     while status:
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ */
+    __pyx_v__ob1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1135
+ *         _type = (<const char *>(dataptrarray[0]))
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         _ri = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__ob2 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1136
+ *         _ob1 = (<double *>(dataptrarray[1]))[0]
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _ri = (<double *>(dataptrarray[4]))
+ *         _di = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__astrom = ((struct eraASTROM *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1137
+ *         _ob2 = (<double *>(dataptrarray[2]))[0]
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         _ri = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _di = (<double *>(dataptrarray[5]))
+ *         eraAtoiq(_type, _ob1, _ob2, _astrom, _ri, _di)
+ */
+    __pyx_v__ri = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1138
+ *         _astrom = (<eraASTROM *>(dataptrarray[3]))
+ *         _ri = (<double *>(dataptrarray[4]))
+ *         _di = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraAtoiq(_type, _ob1, _ob2, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__di = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":1139
+ *         _ri = (<double *>(dataptrarray[4]))
+ *         _di = (<double *>(dataptrarray[5]))
+ *         eraAtoiq(_type, _ob1, _ob2, _astrom, _ri, _di)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraAtoiq(__pyx_v__type, __pyx_v__ob1, __pyx_v__ob2, __pyx_v__astrom, __pyx_v__ri, __pyx_v__di);
+
+    /* "astropy/_erfa/core.pyx":1140
+ *         _di = (<double *>(dataptrarray[5]))
+ *         eraAtoiq(_type, _ob1, _ob2, _astrom, _ri, _di)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1121
+ * 
+ * 
+ * def _atoiq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1143
+ * 
+ * 
+ * def _ld(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _bm
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_67_ld(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_67_ld = {"_ld", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_67_ld, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_67_ld(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ld (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_66_ld(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_66_ld(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__bm;
+  double *__pyx_v__p;
+  double *__pyx_v__q;
+  double *__pyx_v__e;
+  double __pyx_v__em;
+  double __pyx_v__dlim;
+  double *__pyx_v__p1;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ld", 0);
+
+  /* "astropy/_erfa/core.pyx":1152
+ *     cdef double _dlim
+ *     cdef double * _p1
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1153
+ *     cdef double * _p1
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1154
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _bm = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1155
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _bm = (<double *>(dataptrarray[0]))[0]
+ *         _p = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1156
+ *     cdef int status = 1
+ *     while status:
+ *         _bm = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _p = (<double *>(dataptrarray[1]))
+ *         _q = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__bm = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1157
+ *     while status:
+ *         _bm = (<double *>(dataptrarray[0]))[0]
+ *         _p = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _q = (<double *>(dataptrarray[2]))
+ *         _e = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__p = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":1158
+ *         _bm = (<double *>(dataptrarray[0]))[0]
+ *         _p = (<double *>(dataptrarray[1]))
+ *         _q = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _e = (<double *>(dataptrarray[3]))
+ *         _em = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__q = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1159
+ *         _p = (<double *>(dataptrarray[1]))
+ *         _q = (<double *>(dataptrarray[2]))
+ *         _e = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _em = (<double *>(dataptrarray[4]))[0]
+ *         _dlim = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__e = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1160
+ *         _q = (<double *>(dataptrarray[2]))
+ *         _e = (<double *>(dataptrarray[3]))
+ *         _em = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _dlim = (<double *>(dataptrarray[5]))[0]
+ *         _p1 = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__em = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1161
+ *         _e = (<double *>(dataptrarray[3]))
+ *         _em = (<double *>(dataptrarray[4]))[0]
+ *         _dlim = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _p1 = (<double *>(dataptrarray[6]))
+ *         eraLd(_bm, _p, _q, _e, _em, _dlim, _p1)
+ */
+    __pyx_v__dlim = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1162
+ *         _em = (<double *>(dataptrarray[4]))[0]
+ *         _dlim = (<double *>(dataptrarray[5]))[0]
+ *         _p1 = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraLd(_bm, _p, _q, _e, _em, _dlim, _p1)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__p1 = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":1163
+ *         _dlim = (<double *>(dataptrarray[5]))[0]
+ *         _p1 = (<double *>(dataptrarray[6]))
+ *         eraLd(_bm, _p, _q, _e, _em, _dlim, _p1)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraLd(__pyx_v__bm, __pyx_v__p, __pyx_v__q, __pyx_v__e, __pyx_v__em, __pyx_v__dlim, __pyx_v__p1);
+
+    /* "astropy/_erfa/core.pyx":1164
+ *         _p1 = (<double *>(dataptrarray[6]))
+ *         eraLd(_bm, _p, _q, _e, _em, _dlim, _p1)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1143
+ * 
+ * 
+ * def _ld(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _bm
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1167
+ * 
+ * 
+ * def _ldn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_69_ldn(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_69_ldn = {"_ldn", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_69_ldn, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_69_ldn(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ldn (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_68_ldn(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_68_ldn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__n;
+  struct eraLDBODY *__pyx_v__b;
+  double *__pyx_v__ob;
+  double *__pyx_v__sc;
+  double *__pyx_v__sn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ldn", 0);
+
+  /* "astropy/_erfa/core.pyx":1174
+ *     cdef double * _sc
+ *     cdef double * _sn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1175
+ *     cdef double * _sn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1176
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1177
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1178
+ *     cdef int status = 1
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _b = (<eraLDBODY *>(dataptrarray[1]))
+ *         _ob = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1179
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _ob = (<double *>(dataptrarray[2]))
+ *         _sc = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__b = ((struct eraLDBODY *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":1180
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _b = (<eraLDBODY *>(dataptrarray[1]))
+ *         _ob = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _sc = (<double *>(dataptrarray[3]))
+ *         _sn = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__ob = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1181
+ *         _b = (<eraLDBODY *>(dataptrarray[1]))
+ *         _ob = (<double *>(dataptrarray[2]))
+ *         _sc = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _sn = (<double *>(dataptrarray[4]))
+ *         eraLdn(_n, _b, _ob, _sc, _sn)
+ */
+    __pyx_v__sc = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1182
+ *         _ob = (<double *>(dataptrarray[2]))
+ *         _sc = (<double *>(dataptrarray[3]))
+ *         _sn = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraLdn(_n, _b, _ob, _sc, _sn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__sn = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1183
+ *         _sc = (<double *>(dataptrarray[3]))
+ *         _sn = (<double *>(dataptrarray[4]))
+ *         eraLdn(_n, _b, _ob, _sc, _sn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraLdn(__pyx_v__n, __pyx_v__b, __pyx_v__ob, __pyx_v__sc, __pyx_v__sn);
+
+    /* "astropy/_erfa/core.pyx":1184
+ *         _sn = (<double *>(dataptrarray[4]))
+ *         eraLdn(_n, _b, _ob, _sc, _sn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1167
+ * 
+ * 
+ * def _ldn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1187
+ * 
+ * 
+ * def _ldsun(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _p
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_71_ldsun(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_71_ldsun = {"_ldsun", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_71_ldsun, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_71_ldsun(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ldsun (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_70_ldsun(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_70_ldsun(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__p;
+  double *__pyx_v__e;
+  double __pyx_v__em;
+  double *__pyx_v__p1;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ldsun", 0);
+
+  /* "astropy/_erfa/core.pyx":1193
+ *     cdef double _em
+ *     cdef double * _p1
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1194
+ *     cdef double * _p1
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1195
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _p = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1196
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _p = (<double *>(dataptrarray[0]))
+ *         _e = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1197
+ *     cdef int status = 1
+ *     while status:
+ *         _p = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _e = (<double *>(dataptrarray[1]))
+ *         _em = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__p = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1198
+ *     while status:
+ *         _p = (<double *>(dataptrarray[0]))
+ *         _e = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _em = (<double *>(dataptrarray[2]))[0]
+ *         _p1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__e = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":1199
+ *         _p = (<double *>(dataptrarray[0]))
+ *         _e = (<double *>(dataptrarray[1]))
+ *         _em = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _p1 = (<double *>(dataptrarray[3]))
+ *         eraLdsun(_p, _e, _em, _p1)
+ */
+    __pyx_v__em = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1200
+ *         _e = (<double *>(dataptrarray[1]))
+ *         _em = (<double *>(dataptrarray[2]))[0]
+ *         _p1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraLdsun(_p, _e, _em, _p1)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__p1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1201
+ *         _em = (<double *>(dataptrarray[2]))[0]
+ *         _p1 = (<double *>(dataptrarray[3]))
+ *         eraLdsun(_p, _e, _em, _p1)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraLdsun(__pyx_v__p, __pyx_v__e, __pyx_v__em, __pyx_v__p1);
+
+    /* "astropy/_erfa/core.pyx":1202
+ *         _p1 = (<double *>(dataptrarray[3]))
+ *         eraLdsun(_p, _e, _em, _p1)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1187
+ * 
+ * 
+ * def _ldsun(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _p
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1205
+ * 
+ * 
+ * def _pmpx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_73_pmpx(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_73_pmpx = {"_pmpx", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_73_pmpx, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_73_pmpx(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmpx (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_72_pmpx(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_72_pmpx(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rc;
+  double __pyx_v__dc;
+  double __pyx_v__pr;
+  double __pyx_v__pd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  double __pyx_v__pmt;
+  double *__pyx_v__pob;
+  double *__pyx_v__pco;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pmpx", 0);
+
+  /* "astropy/_erfa/core.pyx":1216
+ *     cdef double * _pob
+ *     cdef double * _pco
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1217
+ *     cdef double * _pco
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1218
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1219
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1220
+ *     cdef int status = 1
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rc = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1221
+ *     while status:
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1222
+ *         _rc = (<double *>(dataptrarray[0]))[0]
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1223
+ *         _dc = (<double *>(dataptrarray[1]))[0]
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1224
+ *         _pr = (<double *>(dataptrarray[2]))[0]
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pmt = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1225
+ *         _pd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _pmt = (<double *>(dataptrarray[6]))[0]
+ *         _pob = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1226
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pmt = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _pob = (<double *>(dataptrarray[7]))
+ *         _pco = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__pmt = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1227
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pmt = (<double *>(dataptrarray[6]))[0]
+ *         _pob = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _pco = (<double *>(dataptrarray[8]))
+ *         eraPmpx(_rc, _dc, _pr, _pd, _px, _rv, _pmt, _pob, _pco)
+ */
+    __pyx_v__pob = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":1228
+ *         _pmt = (<double *>(dataptrarray[6]))[0]
+ *         _pob = (<double *>(dataptrarray[7]))
+ *         _pco = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         eraPmpx(_rc, _dc, _pr, _pd, _px, _rv, _pmt, _pob, _pco)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__pco = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":1229
+ *         _pob = (<double *>(dataptrarray[7]))
+ *         _pco = (<double *>(dataptrarray[8]))
+ *         eraPmpx(_rc, _dc, _pr, _pd, _px, _rv, _pmt, _pob, _pco)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPmpx(__pyx_v__rc, __pyx_v__dc, __pyx_v__pr, __pyx_v__pd, __pyx_v__px, __pyx_v__rv, __pyx_v__pmt, __pyx_v__pob, __pyx_v__pco);
+
+    /* "astropy/_erfa/core.pyx":1230
+ *         _pco = (<double *>(dataptrarray[8]))
+ *         eraPmpx(_rc, _dc, _pr, _pd, _px, _rv, _pmt, _pob, _pco)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1205
+ * 
+ * 
+ * def _pmpx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1233
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_75_pmsafe(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_75_pmsafe = {"_pmsafe", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_75_pmsafe, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_75_pmsafe(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmsafe (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_74_pmsafe(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_74_pmsafe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ra1;
+  double __pyx_v__dec1;
+  double __pyx_v__pmr1;
+  double __pyx_v__pmd1;
+  double __pyx_v__px1;
+  double __pyx_v__rv1;
+  double __pyx_v__ep1a;
+  double __pyx_v__ep1b;
+  double __pyx_v__ep2a;
+  double __pyx_v__ep2b;
+  double *__pyx_v__ra2;
+  double *__pyx_v__dec2;
+  double *__pyx_v__pmr2;
+  double *__pyx_v__pmd2;
+  double *__pyx_v__px2;
+  double *__pyx_v__rv2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_pmsafe", 0);
+
+  /* "astropy/_erfa/core.pyx":1252
+ *     cdef double * _rv2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":1253
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1254
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1255
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1256
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1257
+ *     cdef int status = 1
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ra1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1258
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dec1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1259
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pmr1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1260
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pmd1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1261
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px1 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1262
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv1 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1263
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__ep1a = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1264
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__ep1b = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1265
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__ep2a = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1266
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__ep2b = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1267
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ */
+    __pyx_v__ra2 = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":1268
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ */
+    __pyx_v__dec2 = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":1269
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ */
+    __pyx_v__pmr2 = ((double *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":1270
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))             # <<<<<<<<<<<<<<
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__pmd2 = ((double *)(__pyx_v_dataptrarray[13]));
+
+    /* "astropy/_erfa/core.pyx":1271
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))             # <<<<<<<<<<<<<<
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ */
+    __pyx_v__px2 = ((double *)(__pyx_v_dataptrarray[14]));
+
+    /* "astropy/_erfa/core.pyx":1272
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ */
+    __pyx_v__rv2 = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":1273
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraPmsafe(__pyx_v__ra1, __pyx_v__dec1, __pyx_v__pmr1, __pyx_v__pmd1, __pyx_v__px1, __pyx_v__rv1, __pyx_v__ep1a, __pyx_v__ep1b, __pyx_v__ep2a, __pyx_v__ep2b, __pyx_v__ra2, __pyx_v__dec2, __pyx_v__pmr2, __pyx_v__pmd2, __pyx_v__px2, __pyx_v__rv2);
+
+    /* "astropy/_erfa/core.pyx":1274
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[16]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1275
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":1276
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":1277
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1278
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":1233
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._pmsafe", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1281
+ * 
+ * 
+ * def _refco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _phpa
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_77_refco(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_77_refco = {"_refco", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_77_refco, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_77_refco(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_refco (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_76_refco(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_76_refco(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__phpa;
+  double __pyx_v__tc;
+  double __pyx_v__rh;
+  double __pyx_v__wl;
+  double *__pyx_v__refa;
+  double *__pyx_v__refb;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_refco", 0);
+
+  /* "astropy/_erfa/core.pyx":1289
+ *     cdef double * _refa
+ *     cdef double * _refb
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1290
+ *     cdef double * _refb
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1291
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _phpa = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1292
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _phpa = (<double *>(dataptrarray[0]))[0]
+ *         _tc = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1293
+ *     cdef int status = 1
+ *     while status:
+ *         _phpa = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tc = (<double *>(dataptrarray[1]))[0]
+ *         _rh = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__phpa = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1294
+ *     while status:
+ *         _phpa = (<double *>(dataptrarray[0]))[0]
+ *         _tc = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[2]))[0]
+ *         _wl = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__tc = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1295
+ *         _phpa = (<double *>(dataptrarray[0]))[0]
+ *         _tc = (<double *>(dataptrarray[1]))[0]
+ *         _rh = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _wl = (<double *>(dataptrarray[3]))[0]
+ *         _refa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1296
+ *         _tc = (<double *>(dataptrarray[1]))[0]
+ *         _rh = (<double *>(dataptrarray[2]))[0]
+ *         _wl = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _refa = (<double *>(dataptrarray[4]))
+ *         _refb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__wl = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1297
+ *         _rh = (<double *>(dataptrarray[2]))[0]
+ *         _wl = (<double *>(dataptrarray[3]))[0]
+ *         _refa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _refb = (<double *>(dataptrarray[5]))
+ *         eraRefco(_phpa, _tc, _rh, _wl, _refa, _refb)
+ */
+    __pyx_v__refa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1298
+ *         _wl = (<double *>(dataptrarray[3]))[0]
+ *         _refa = (<double *>(dataptrarray[4]))
+ *         _refb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraRefco(_phpa, _tc, _rh, _wl, _refa, _refb)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__refb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":1299
+ *         _refa = (<double *>(dataptrarray[4]))
+ *         _refb = (<double *>(dataptrarray[5]))
+ *         eraRefco(_phpa, _tc, _rh, _wl, _refa, _refb)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraRefco(__pyx_v__phpa, __pyx_v__tc, __pyx_v__rh, __pyx_v__wl, __pyx_v__refa, __pyx_v__refb);
+
+    /* "astropy/_erfa/core.pyx":1300
+ *         _refb = (<double *>(dataptrarray[5]))
+ *         eraRefco(_phpa, _tc, _rh, _wl, _refa, _refb)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1281
+ * 
+ * 
+ * def _refco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _phpa
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1303
+ * 
+ * 
+ * def _epv00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_79_epv00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_79_epv00 = {"_epv00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_79_epv00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_79_epv00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_epv00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_78_epv00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_78_epv00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__pvh;
+  double *__pyx_v__pvb;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_epv00", 0);
+
+  /* "astropy/_erfa/core.pyx":1310
+ *     cdef double * _pvb
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":1311
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1312
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1313
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1314
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1315
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pvh = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1316
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pvh = (<double *>(dataptrarray[2]))
+ *         _pvb = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1317
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pvh = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _pvb = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)
+ */
+    __pyx_v__pvh = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1318
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _pvh = (<double *>(dataptrarray[2]))
+ *         _pvb = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__pvb = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1319
+ *         _pvh = (<double *>(dataptrarray[2]))
+ *         _pvb = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraEpv00(__pyx_v__date1, __pyx_v__date2, __pyx_v__pvh, __pyx_v__pvb);
+
+    /* "astropy/_erfa/core.pyx":1320
+ *         _pvb = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1321
+ *         _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":1322
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":1323
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1324
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":1303
+ * 
+ * 
+ * def _epv00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._epv00", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1327
+ * 
+ * 
+ * def _plan94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_81_plan94(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_81_plan94 = {"_plan94", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_81_plan94, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_81_plan94(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_plan94 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_80_plan94(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_80_plan94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  int __pyx_v__np;
+  double *__pyx_v__pv;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_plan94", 0);
+
+  /* "astropy/_erfa/core.pyx":1334
+ *     cdef double * _pv
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":1335
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1336
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1337
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1338
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1339
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _np = (<int *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1340
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _np = (<int *>(dataptrarray[2]))[0]
+ *         _pv = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1341
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _np = (<int *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraPlan94(_date1, _date2, _np, _pv)
+ */
+    __pyx_v__np = (((int *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1342
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _np = (<int *>(dataptrarray[2]))[0]
+ *         _pv = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraPlan94(_date1, _date2, _np, _pv)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1343
+ *         _np = (<int *>(dataptrarray[2]))[0]
+ *         _pv = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraPlan94(_date1, _date2, _np, _pv)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraPlan94(__pyx_v__date1, __pyx_v__date2, __pyx_v__np, __pyx_v__pv);
+
+    /* "astropy/_erfa/core.pyx":1344
+ *         _pv = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraPlan94(_date1, _date2, _np, _pv)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1345
+ *         _c_retval = eraPlan94(_date1, _date2, _np, _pv)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":1346
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":1347
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1348
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":1327
+ * 
+ * 
+ * def _plan94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._plan94", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1351
+ * 
+ * 
+ * def _fad03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_83_fad03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_83_fad03 = {"_fad03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_83_fad03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_83_fad03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fad03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_82_fad03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_82_fad03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fad03", 0);
+
+  /* "astropy/_erfa/core.pyx":1355
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1356
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1357
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1358
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFad03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1359
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFad03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1360
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFad03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFad03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1361
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFad03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1362
+ *         _c_retval = eraFad03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1351
+ * 
+ * 
+ * def _fad03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1365
+ * 
+ * 
+ * def _fae03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_85_fae03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_85_fae03 = {"_fae03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_85_fae03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_85_fae03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fae03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_84_fae03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_84_fae03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fae03", 0);
+
+  /* "astropy/_erfa/core.pyx":1369
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1370
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1371
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1372
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFae03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1373
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFae03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1374
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFae03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFae03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1375
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFae03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1376
+ *         _c_retval = eraFae03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1365
+ * 
+ * 
+ * def _fae03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1379
+ * 
+ * 
+ * def _faf03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_87_faf03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_87_faf03 = {"_faf03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_87_faf03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_87_faf03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_faf03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_86_faf03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_86_faf03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_faf03", 0);
+
+  /* "astropy/_erfa/core.pyx":1383
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1384
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1385
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1386
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaf03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1387
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFaf03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1388
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaf03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFaf03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1389
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaf03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1390
+ *         _c_retval = eraFaf03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1379
+ * 
+ * 
+ * def _faf03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1393
+ * 
+ * 
+ * def _faju03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_89_faju03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_89_faju03 = {"_faju03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_89_faju03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_89_faju03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_faju03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_88_faju03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_88_faju03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_faju03", 0);
+
+  /* "astropy/_erfa/core.pyx":1397
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1398
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1399
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1400
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaju03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1401
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFaju03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1402
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaju03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFaju03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1403
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaju03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1404
+ *         _c_retval = eraFaju03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1393
+ * 
+ * 
+ * def _faju03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1407
+ * 
+ * 
+ * def _fal03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_91_fal03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_91_fal03 = {"_fal03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_91_fal03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_91_fal03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fal03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_90_fal03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_90_fal03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fal03", 0);
+
+  /* "astropy/_erfa/core.pyx":1411
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1412
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1413
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1414
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFal03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1415
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFal03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1416
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFal03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFal03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1417
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFal03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1418
+ *         _c_retval = eraFal03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1407
+ * 
+ * 
+ * def _fal03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1421
+ * 
+ * 
+ * def _falp03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_93_falp03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_93_falp03 = {"_falp03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_93_falp03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_93_falp03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_falp03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_92_falp03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_92_falp03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_falp03", 0);
+
+  /* "astropy/_erfa/core.pyx":1425
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1426
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1427
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1428
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFalp03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1429
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFalp03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1430
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFalp03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFalp03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1431
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFalp03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1432
+ *         _c_retval = eraFalp03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1421
+ * 
+ * 
+ * def _falp03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1435
+ * 
+ * 
+ * def _fama03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_95_fama03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_95_fama03 = {"_fama03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_95_fama03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_95_fama03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fama03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_94_fama03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_94_fama03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fama03", 0);
+
+  /* "astropy/_erfa/core.pyx":1439
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1440
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1441
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1442
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFama03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1443
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFama03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1444
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFama03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFama03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1445
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFama03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1446
+ *         _c_retval = eraFama03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1435
+ * 
+ * 
+ * def _fama03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1449
+ * 
+ * 
+ * def _fame03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_97_fame03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_97_fame03 = {"_fame03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_97_fame03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_97_fame03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fame03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_96_fame03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_96_fame03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fame03", 0);
+
+  /* "astropy/_erfa/core.pyx":1453
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1454
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1455
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1456
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFame03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1457
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFame03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1458
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFame03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFame03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1459
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFame03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1460
+ *         _c_retval = eraFame03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1449
+ * 
+ * 
+ * def _fame03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1463
+ * 
+ * 
+ * def _fane03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_99_fane03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_99_fane03 = {"_fane03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_99_fane03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_99_fane03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fane03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_98_fane03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_98_fane03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fane03", 0);
+
+  /* "astropy/_erfa/core.pyx":1467
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1468
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1469
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1470
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFane03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1471
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFane03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1472
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFane03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFane03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1473
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFane03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1474
+ *         _c_retval = eraFane03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1463
+ * 
+ * 
+ * def _fane03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1477
+ * 
+ * 
+ * def _faom03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_101_faom03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_101_faom03 = {"_faom03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_101_faom03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_101_faom03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_faom03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_100_faom03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_100_faom03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_faom03", 0);
+
+  /* "astropy/_erfa/core.pyx":1481
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1482
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1483
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1484
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaom03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1485
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFaom03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1486
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaom03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFaom03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1487
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaom03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1488
+ *         _c_retval = eraFaom03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1477
+ * 
+ * 
+ * def _faom03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1491
+ * 
+ * 
+ * def _fapa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_103_fapa03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_103_fapa03 = {"_fapa03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_103_fapa03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_103_fapa03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fapa03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_102_fapa03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_102_fapa03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fapa03", 0);
+
+  /* "astropy/_erfa/core.pyx":1495
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1496
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1497
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1498
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFapa03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1499
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFapa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1500
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFapa03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFapa03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1501
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFapa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1502
+ *         _c_retval = eraFapa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1491
+ * 
+ * 
+ * def _fapa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1505
+ * 
+ * 
+ * def _fasa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_105_fasa03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_105_fasa03 = {"_fasa03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_105_fasa03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_105_fasa03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fasa03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_104_fasa03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_104_fasa03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fasa03", 0);
+
+  /* "astropy/_erfa/core.pyx":1509
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1510
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1511
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1512
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFasa03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1513
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFasa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1514
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFasa03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFasa03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1515
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFasa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1516
+ *         _c_retval = eraFasa03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1505
+ * 
+ * 
+ * def _fasa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1519
+ * 
+ * 
+ * def _faur03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_107_faur03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_107_faur03 = {"_faur03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_107_faur03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_107_faur03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_faur03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_106_faur03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_106_faur03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_faur03", 0);
+
+  /* "astropy/_erfa/core.pyx":1523
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1524
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1525
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1526
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaur03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1527
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFaur03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1528
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaur03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFaur03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1529
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFaur03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1530
+ *         _c_retval = eraFaur03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1519
+ * 
+ * 
+ * def _faur03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1533
+ * 
+ * 
+ * def _fave03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_109_fave03(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_109_fave03 = {"_fave03", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_109_fave03, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_109_fave03(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fave03 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_108_fave03(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_108_fave03(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__t;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fave03", 0);
+
+  /* "astropy/_erfa/core.pyx":1537
+ *     cdef double _t
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1538
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1539
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1540
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFave03(_t)
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1541
+ *     cdef int status = 1
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraFave03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ */
+    __pyx_v__t = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1542
+ *     while status:
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFave03(_t)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraFave03(__pyx_v__t);
+
+    /* "astropy/_erfa/core.pyx":1543
+ *         _t = (<double *>(dataptrarray[0]))[0]
+ *         _c_retval = eraFave03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[1]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1544
+ *         _c_retval = eraFave03(_t)
+ *         (<double *>(dataptrarray[1]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1533
+ * 
+ * 
+ * def _fave03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1547
+ * 
+ * 
+ * def _bi00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _dpsibi
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_111_bi00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_111_bi00 = {"_bi00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_111_bi00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_111_bi00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_bi00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_110_bi00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_110_bi00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__dpsibi;
+  double *__pyx_v__depsbi;
+  double *__pyx_v__dra;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_bi00", 0);
+
+  /* "astropy/_erfa/core.pyx":1552
+ *     cdef double * _depsbi
+ *     cdef double * _dra
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1553
+ *     cdef double * _dra
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1554
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dpsibi = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1555
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dpsibi = (<double *>(dataptrarray[0]))
+ *         _depsbi = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1556
+ *     cdef int status = 1
+ *     while status:
+ *         _dpsibi = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _depsbi = (<double *>(dataptrarray[1]))
+ *         _dra = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__dpsibi = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1557
+ *     while status:
+ *         _dpsibi = (<double *>(dataptrarray[0]))
+ *         _depsbi = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _dra = (<double *>(dataptrarray[2]))
+ *         eraBi00(_dpsibi, _depsbi, _dra)
+ */
+    __pyx_v__depsbi = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":1558
+ *         _dpsibi = (<double *>(dataptrarray[0]))
+ *         _depsbi = (<double *>(dataptrarray[1]))
+ *         _dra = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraBi00(_dpsibi, _depsbi, _dra)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__dra = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1559
+ *         _depsbi = (<double *>(dataptrarray[1]))
+ *         _dra = (<double *>(dataptrarray[2]))
+ *         eraBi00(_dpsibi, _depsbi, _dra)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraBi00(__pyx_v__dpsibi, __pyx_v__depsbi, __pyx_v__dra);
+
+    /* "astropy/_erfa/core.pyx":1560
+ *         _dra = (<double *>(dataptrarray[2]))
+ *         eraBi00(_dpsibi, _depsbi, _dra)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1547
+ * 
+ * 
+ * def _bi00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _dpsibi
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1563
+ * 
+ * 
+ * def _bp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_113_bp00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_113_bp00 = {"_bp00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_113_bp00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_113_bp00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_bp00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_112_bp00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_112_bp00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_bp00", 0);
+
+  /* "astropy/_erfa/core.pyx":1570
+ *     cdef double * _rp
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1571
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1572
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1573
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1574
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1575
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1576
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1577
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp00(_date1, _date2, _rb, _rp, _rbp)
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1578
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraBp00(_date1, _date2, _rb, _rp, _rbp)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1579
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp00(_date1, _date2, _rb, _rp, _rbp)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraBp00(__pyx_v__date1, __pyx_v__date2, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp);
+
+    /* "astropy/_erfa/core.pyx":1580
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp00(_date1, _date2, _rb, _rp, _rbp)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1563
+ * 
+ * 
+ * def _bp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1583
+ * 
+ * 
+ * def _bp06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_115_bp06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_115_bp06 = {"_bp06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_115_bp06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_115_bp06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_bp06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_114_bp06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_114_bp06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_bp06", 0);
+
+  /* "astropy/_erfa/core.pyx":1590
+ *     cdef double * _rp
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1591
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1592
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1593
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1594
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1595
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1596
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1597
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp06(_date1, _date2, _rb, _rp, _rbp)
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1598
+ *         _rb = (<double *>(dataptrarray[2]))
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraBp06(_date1, _date2, _rb, _rp, _rbp)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1599
+ *         _rp = (<double *>(dataptrarray[3]))
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp06(_date1, _date2, _rb, _rp, _rbp)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraBp06(__pyx_v__date1, __pyx_v__date2, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp);
+
+    /* "astropy/_erfa/core.pyx":1600
+ *         _rbp = (<double *>(dataptrarray[4]))
+ *         eraBp06(_date1, _date2, _rb, _rp, _rbp)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1583
+ * 
+ * 
+ * def _bp06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1603
+ * 
+ * 
+ * def _bpn2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_117_bpn2xy(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_117_bpn2xy = {"_bpn2xy", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_117_bpn2xy, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_117_bpn2xy(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_bpn2xy (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_116_bpn2xy(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_116_bpn2xy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__rbpn;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_bpn2xy", 0);
+
+  /* "astropy/_erfa/core.pyx":1608
+ *     cdef double * _x
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1609
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1610
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1611
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _x = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1612
+ *     cdef int status = 1
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[1]))
+ *         _y = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1613
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _x = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[2]))
+ *         eraBpn2xy(_rbpn, _x, _y)
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":1614
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _x = (<double *>(dataptrarray[1]))
+ *         _y = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraBpn2xy(_rbpn, _x, _y)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1615
+ *         _x = (<double *>(dataptrarray[1]))
+ *         _y = (<double *>(dataptrarray[2]))
+ *         eraBpn2xy(_rbpn, _x, _y)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraBpn2xy(__pyx_v__rbpn, __pyx_v__x, __pyx_v__y);
+
+    /* "astropy/_erfa/core.pyx":1616
+ *         _y = (<double *>(dataptrarray[2]))
+ *         eraBpn2xy(_rbpn, _x, _y)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1603
+ * 
+ * 
+ * def _bpn2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1619
+ * 
+ * 
+ * def _c2i00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_119_c2i00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_119_c2i00a = {"_c2i00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_119_c2i00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_119_c2i00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2i00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_118_c2i00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_118_c2i00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2i00a", 0);
+
+  /* "astropy/_erfa/core.pyx":1624
+ *     cdef double _date2
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1625
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1626
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1627
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1628
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1629
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00a(_date1, _date2, _rc2i)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1630
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraC2i00a(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1631
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00a(_date1, _date2, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2i00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1632
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00a(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1619
+ * 
+ * 
+ * def _c2i00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1635
+ * 
+ * 
+ * def _c2i00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_121_c2i00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_121_c2i00b = {"_c2i00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_121_c2i00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_121_c2i00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2i00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_120_c2i00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_120_c2i00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2i00b", 0);
+
+  /* "astropy/_erfa/core.pyx":1640
+ *     cdef double _date2
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1641
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1642
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1643
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1644
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1645
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00b(_date1, _date2, _rc2i)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1646
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraC2i00b(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1647
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00b(_date1, _date2, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2i00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1648
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i00b(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1635
+ * 
+ * 
+ * def _c2i00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1651
+ * 
+ * 
+ * def _c2i06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_123_c2i06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_123_c2i06a = {"_c2i06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_123_c2i06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_123_c2i06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2i06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_122_c2i06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_122_c2i06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2i06a", 0);
+
+  /* "astropy/_erfa/core.pyx":1656
+ *     cdef double _date2
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1657
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1658
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1659
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1660
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1661
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i06a(_date1, _date2, _rc2i)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1662
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraC2i06a(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1663
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i06a(_date1, _date2, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2i06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1664
+ *         _rc2i = (<double *>(dataptrarray[2]))
+ *         eraC2i06a(_date1, _date2, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1651
+ * 
+ * 
+ * def _c2i06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1667
+ * 
+ * 
+ * def _c2ibpn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_125_c2ibpn(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_125_c2ibpn = {"_c2ibpn", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_125_c2ibpn, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_125_c2ibpn(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2ibpn (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_124_c2ibpn(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_124_c2ibpn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rbpn;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2ibpn", 0);
+
+  /* "astropy/_erfa/core.pyx":1673
+ *     cdef double * _rbpn
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1674
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1675
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1676
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1677
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1678
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1679
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ibpn(_date1, _date2, _rbpn, _rc2i)
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1680
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         _rc2i = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraC2ibpn(_date1, _date2, _rbpn, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1681
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ibpn(_date1, _date2, _rbpn, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2ibpn(__pyx_v__date1, __pyx_v__date2, __pyx_v__rbpn, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1682
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ibpn(_date1, _date2, _rbpn, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1667
+ * 
+ * 
+ * def _c2ibpn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1685
+ * 
+ * 
+ * def _c2ixy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_127_c2ixy(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_127_c2ixy = {"_c2ixy", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_127_c2ixy, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_127_c2ixy(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2ixy (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_126_c2ixy(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_126_c2ixy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2ixy", 0);
+
+  /* "astropy/_erfa/core.pyx":1692
+ *     cdef double _y
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1693
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1694
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1695
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1696
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1697
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1698
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _rc2i = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1699
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[4]))
+ *         eraC2ixy(_date1, _date2, _x, _y, _rc2i)
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1700
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _rc2i = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraC2ixy(_date1, _date2, _x, _y, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1701
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _rc2i = (<double *>(dataptrarray[4]))
+ *         eraC2ixy(_date1, _date2, _x, _y, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2ixy(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1702
+ *         _rc2i = (<double *>(dataptrarray[4]))
+ *         eraC2ixy(_date1, _date2, _x, _y, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1685
+ * 
+ * 
+ * def _c2ixy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1705
+ * 
+ * 
+ * def _c2ixys(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _x
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_129_c2ixys(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_129_c2ixys = {"_c2ixys", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_129_c2ixys, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_129_c2ixys(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2ixys (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_128_c2ixys(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_128_c2ixys(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__s;
+  double *__pyx_v__rc2i;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2ixys", 0);
+
+  /* "astropy/_erfa/core.pyx":1711
+ *     cdef double _s
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1712
+ *     cdef double * _rc2i
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1713
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _x = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1714
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[0]))[0]
+ *         _y = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1715
+ *     cdef int status = 1
+ *     while status:
+ *         _x = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[1]))[0]
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1716
+ *     while status:
+ *         _x = (<double *>(dataptrarray[0]))[0]
+ *         _y = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1717
+ *         _x = (<double *>(dataptrarray[0]))[0]
+ *         _y = (<double *>(dataptrarray[1]))[0]
+ *         _s = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ixys(_x, _y, _s, _rc2i)
+ */
+    __pyx_v__s = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1718
+ *         _y = (<double *>(dataptrarray[1]))[0]
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _rc2i = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraC2ixys(_x, _y, _s, _rc2i)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1719
+ *         _s = (<double *>(dataptrarray[2]))[0]
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ixys(_x, _y, _s, _rc2i)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2ixys(__pyx_v__x, __pyx_v__y, __pyx_v__s, __pyx_v__rc2i);
+
+    /* "astropy/_erfa/core.pyx":1720
+ *         _rc2i = (<double *>(dataptrarray[3]))
+ *         eraC2ixys(_x, _y, _s, _rc2i)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1705
+ * 
+ * 
+ * def _c2ixys(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _x
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1723
+ * 
+ * 
+ * def _c2t00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_131_c2t00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_131_c2t00a = {"_c2t00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_131_c2t00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_131_c2t00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2t00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_130_c2t00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_130_c2t00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2t00a", 0);
+
+  /* "astropy/_erfa/core.pyx":1732
+ *     cdef double _yp
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1733
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1734
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1735
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1736
+ *     cdef int status = 1
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1737
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1738
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1739
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1740
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1741
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1742
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraC2t00a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":1743
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2t00a(__pyx_v__tta, __pyx_v__ttb, __pyx_v__uta, __pyx_v__utb, __pyx_v__xp, __pyx_v__yp, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1744
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1723
+ * 
+ * 
+ * def _c2t00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1747
+ * 
+ * 
+ * def _c2t00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_133_c2t00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_133_c2t00b = {"_c2t00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_133_c2t00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_133_c2t00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2t00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_132_c2t00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_132_c2t00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2t00b", 0);
+
+  /* "astropy/_erfa/core.pyx":1756
+ *     cdef double _yp
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1757
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1758
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1759
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1760
+ *     cdef int status = 1
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1761
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1762
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1763
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1764
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1765
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00b(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1766
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraC2t00b(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":1767
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00b(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2t00b(__pyx_v__tta, __pyx_v__ttb, __pyx_v__uta, __pyx_v__utb, __pyx_v__xp, __pyx_v__yp, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1768
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t00b(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1747
+ * 
+ * 
+ * def _c2t00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1771
+ * 
+ * 
+ * def _c2t06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_135_c2t06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_135_c2t06a = {"_c2t06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_135_c2t06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_135_c2t06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2t06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_134_c2t06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_134_c2t06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2t06a", 0);
+
+  /* "astropy/_erfa/core.pyx":1780
+ *     cdef double _yp
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1781
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1782
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1783
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1784
+ *     cdef int status = 1
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1785
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1786
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1787
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1788
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1789
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t06a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1790
+ *         _xp = (<double *>(dataptrarray[4]))[0]
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraC2t06a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":1791
+ *         _yp = (<double *>(dataptrarray[5]))[0]
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t06a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2t06a(__pyx_v__tta, __pyx_v__ttb, __pyx_v__uta, __pyx_v__utb, __pyx_v__xp, __pyx_v__yp, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1792
+ *         _rc2t = (<double *>(dataptrarray[6]))
+ *         eraC2t06a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1771
+ * 
+ * 
+ * def _c2t06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1795
+ * 
+ * 
+ * def _c2tcio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rc2i
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_137_c2tcio(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_137_c2tcio = {"_c2tcio", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_137_c2tcio, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_137_c2tcio(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2tcio (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_136_c2tcio(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_136_c2tcio(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__rc2i;
+  double __pyx_v__era;
+  double *__pyx_v__rpom;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2tcio", 0);
+
+  /* "astropy/_erfa/core.pyx":1801
+ *     cdef double * _rpom
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1802
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1803
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rc2i = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1804
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rc2i = (<double *>(dataptrarray[0]))
+ *         _era = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1805
+ *     cdef int status = 1
+ *     while status:
+ *         _rc2i = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _era = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__rc2i = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1806
+ *     while status:
+ *         _rc2i = (<double *>(dataptrarray[0]))
+ *         _era = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__era = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1807
+ *         _rc2i = (<double *>(dataptrarray[0]))
+ *         _era = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2tcio(_rc2i, _era, _rpom, _rc2t)
+ */
+    __pyx_v__rpom = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1808
+ *         _era = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraC2tcio(_rc2i, _era, _rpom, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1809
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2tcio(_rc2i, _era, _rpom, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2tcio(__pyx_v__rc2i, __pyx_v__era, __pyx_v__rpom, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1810
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2tcio(_rc2i, _era, _rpom, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1795
+ * 
+ * 
+ * def _c2tcio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rc2i
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1813
+ * 
+ * 
+ * def _c2teqx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_139_c2teqx(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_139_c2teqx = {"_c2teqx", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_139_c2teqx, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_139_c2teqx(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2teqx (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_138_c2teqx(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_138_c2teqx(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__rbpn;
+  double __pyx_v__gst;
+  double *__pyx_v__rpom;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2teqx", 0);
+
+  /* "astropy/_erfa/core.pyx":1819
+ *     cdef double * _rpom
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1820
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1821
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1822
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _gst = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1823
+ *     cdef int status = 1
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _gst = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1824
+ *     while status:
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _gst = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__gst = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1825
+ *         _rbpn = (<double *>(dataptrarray[0]))
+ *         _gst = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2teqx(_rbpn, _gst, _rpom, _rc2t)
+ */
+    __pyx_v__rpom = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1826
+ *         _gst = (<double *>(dataptrarray[1]))[0]
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraC2teqx(_rbpn, _gst, _rpom, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":1827
+ *         _rpom = (<double *>(dataptrarray[2]))
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2teqx(_rbpn, _gst, _rpom, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2teqx(__pyx_v__rbpn, __pyx_v__gst, __pyx_v__rpom, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1828
+ *         _rc2t = (<double *>(dataptrarray[3]))
+ *         eraC2teqx(_rbpn, _gst, _rpom, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1813
+ * 
+ * 
+ * def _c2teqx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1831
+ * 
+ * 
+ * def _c2tpe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_141_c2tpe(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_141_c2tpe = {"_c2tpe", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_141_c2tpe, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_141_c2tpe(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2tpe (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_140_c2tpe(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_140_c2tpe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__dpsi;
+  double __pyx_v__deps;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2tpe", 0);
+
+  /* "astropy/_erfa/core.pyx":1842
+ *     cdef double _yp
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1843
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1844
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1845
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1846
+ *     cdef int status = 1
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1847
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1848
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _dpsi = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1849
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[4]))[0]
+ *         _deps = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1850
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _dpsi = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__dpsi = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1851
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _dpsi = (<double *>(dataptrarray[4]))[0]
+ *         _deps = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__deps = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1852
+ *         _dpsi = (<double *>(dataptrarray[4]))[0]
+ *         _deps = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1853
+ *         _deps = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2tpe(_tta, _ttb, _uta, _utb, _dpsi, _deps, _xp, _yp, _rc2t)
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1854
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         eraC2tpe(_tta, _ttb, _uta, _utb, _dpsi, _deps, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":1855
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2tpe(_tta, _ttb, _uta, _utb, _dpsi, _deps, _xp, _yp, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2tpe(__pyx_v__tta, __pyx_v__ttb, __pyx_v__uta, __pyx_v__utb, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__xp, __pyx_v__yp, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1856
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2tpe(_tta, _ttb, _uta, _utb, _dpsi, _deps, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1831
+ * 
+ * 
+ * def _c2tpe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1859
+ * 
+ * 
+ * def _c2txy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_143_c2txy(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_143_c2txy = {"_c2txy", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_143_c2txy, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_143_c2txy(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_c2txy (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_142_c2txy(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_142_c2txy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double *__pyx_v__rc2t;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_c2txy", 0);
+
+  /* "astropy/_erfa/core.pyx":1870
+ *     cdef double _yp
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1871
+ *     cdef double * _rc2t
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1872
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1873
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1874
+ *     cdef int status = 1
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1875
+ *     while status:
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1876
+ *         _tta = (<double *>(dataptrarray[0]))[0]
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1877
+ *         _ttb = (<double *>(dataptrarray[1]))[0]
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1878
+ *         _uta = (<double *>(dataptrarray[2]))[0]
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1879
+ *         _utb = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1880
+ *         _x = (<double *>(dataptrarray[4]))[0]
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1881
+ *         _y = (<double *>(dataptrarray[5]))[0]
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2txy(_tta, _ttb, _uta, _utb, _x, _y, _xp, _yp, _rc2t)
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1882
+ *         _xp = (<double *>(dataptrarray[6]))[0]
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         eraC2txy(_tta, _ttb, _uta, _utb, _x, _y, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rc2t = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":1883
+ *         _yp = (<double *>(dataptrarray[7]))[0]
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2txy(_tta, _ttb, _uta, _utb, _x, _y, _xp, _yp, _rc2t)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraC2txy(__pyx_v__tta, __pyx_v__ttb, __pyx_v__uta, __pyx_v__utb, __pyx_v__x, __pyx_v__y, __pyx_v__xp, __pyx_v__yp, __pyx_v__rc2t);
+
+    /* "astropy/_erfa/core.pyx":1884
+ *         _rc2t = (<double *>(dataptrarray[8]))
+ *         eraC2txy(_tta, _ttb, _uta, _utb, _x, _y, _xp, _yp, _rc2t)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1859
+ * 
+ * 
+ * def _c2txy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1887
+ * 
+ * 
+ * def _eo06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_145_eo06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_145_eo06a = {"_eo06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_145_eo06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_145_eo06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_eo06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_144_eo06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_144_eo06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_eo06a", 0);
+
+  /* "astropy/_erfa/core.pyx":1892
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1893
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1894
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1895
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1896
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEo06a(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1897
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEo06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1898
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEo06a(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEo06a(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":1899
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEo06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1900
+ *         _c_retval = eraEo06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1887
+ * 
+ * 
+ * def _eo06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1903
+ * 
+ * 
+ * def _eors(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rnpb
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_147_eors(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_147_eors = {"_eors", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_147_eors, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_147_eors(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_eors (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_146_eors(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_146_eors(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__rnpb;
+  double __pyx_v__s;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_eors", 0);
+
+  /* "astropy/_erfa/core.pyx":1908
+ *     cdef double _s
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1909
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1910
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rnpb = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1911
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rnpb = (<double *>(dataptrarray[0]))
+ *         _s = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1912
+ *     cdef int status = 1
+ *     while status:
+ *         _rnpb = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEors(_rnpb, _s)
+ */
+    __pyx_v__rnpb = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":1913
+ *     while status:
+ *         _rnpb = (<double *>(dataptrarray[0]))
+ *         _s = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEors(_rnpb, _s)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__s = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1914
+ *         _rnpb = (<double *>(dataptrarray[0]))
+ *         _s = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEors(_rnpb, _s)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEors(__pyx_v__rnpb, __pyx_v__s);
+
+    /* "astropy/_erfa/core.pyx":1915
+ *         _s = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEors(_rnpb, _s)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":1916
+ *         _c_retval = eraEors(_rnpb, _s)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1903
+ * 
+ * 
+ * def _eors(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rnpb
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1919
+ * 
+ * 
+ * def _fw2m(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_149_fw2m(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_149_fw2m = {"_fw2m", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_149_fw2m, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_149_fw2m(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fw2m (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_148_fw2m(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_148_fw2m(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__gamb;
+  double __pyx_v__phib;
+  double __pyx_v__psi;
+  double __pyx_v__eps;
+  double *__pyx_v__r;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fw2m", 0);
+
+  /* "astropy/_erfa/core.pyx":1926
+ *     cdef double _eps
+ *     cdef double * _r
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1927
+ *     cdef double * _r
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1928
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1929
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1930
+ *     cdef int status = 1
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__gamb = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1931
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__phib = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1932
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _r = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__psi = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1933
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _r = (<double *>(dataptrarray[4]))
+ *         eraFw2m(_gamb, _phib, _psi, _eps, _r)
+ */
+    __pyx_v__eps = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1934
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _r = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraFw2m(_gamb, _phib, _psi, _eps, _r)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__r = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1935
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _r = (<double *>(dataptrarray[4]))
+ *         eraFw2m(_gamb, _phib, _psi, _eps, _r)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraFw2m(__pyx_v__gamb, __pyx_v__phib, __pyx_v__psi, __pyx_v__eps, __pyx_v__r);
+
+    /* "astropy/_erfa/core.pyx":1936
+ *         _r = (<double *>(dataptrarray[4]))
+ *         eraFw2m(_gamb, _phib, _psi, _eps, _r)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1919
+ * 
+ * 
+ * def _fw2m(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1939
+ * 
+ * 
+ * def _fw2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_151_fw2xy(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_151_fw2xy = {"_fw2xy", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_151_fw2xy, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_151_fw2xy(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fw2xy (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_150_fw2xy(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_150_fw2xy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__gamb;
+  double __pyx_v__phib;
+  double __pyx_v__psi;
+  double __pyx_v__eps;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fw2xy", 0);
+
+  /* "astropy/_erfa/core.pyx":1947
+ *     cdef double * _x
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1948
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1949
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1950
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1951
+ *     cdef int status = 1
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__gamb = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1952
+ *     while status:
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__phib = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1953
+ *         _gamb = (<double *>(dataptrarray[0]))[0]
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__psi = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1954
+ *         _phib = (<double *>(dataptrarray[1]))[0]
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[4]))
+ *         _y = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__eps = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1955
+ *         _psi = (<double *>(dataptrarray[2]))[0]
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[5]))
+ *         eraFw2xy(_gamb, _phib, _psi, _eps, _x, _y)
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":1956
+ *         _eps = (<double *>(dataptrarray[3]))[0]
+ *         _x = (<double *>(dataptrarray[4]))
+ *         _y = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraFw2xy(_gamb, _phib, _psi, _eps, _x, _y)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":1957
+ *         _x = (<double *>(dataptrarray[4]))
+ *         _y = (<double *>(dataptrarray[5]))
+ *         eraFw2xy(_gamb, _phib, _psi, _eps, _x, _y)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraFw2xy(__pyx_v__gamb, __pyx_v__phib, __pyx_v__psi, __pyx_v__eps, __pyx_v__x, __pyx_v__y);
+
+    /* "astropy/_erfa/core.pyx":1958
+ *         _y = (<double *>(dataptrarray[5]))
+ *         eraFw2xy(_gamb, _phib, _psi, _eps, _x, _y)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1939
+ * 
+ * 
+ * def _fw2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1961
+ * 
+ * 
+ * def _num00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_153_num00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_153_num00a = {"_num00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_153_num00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_153_num00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_num00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_152_num00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_152_num00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_num00a", 0);
+
+  /* "astropy/_erfa/core.pyx":1966
+ *     cdef double _date2
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1967
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1968
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1969
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1970
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1971
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00a(_date1, _date2, _rmatn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1972
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraNum00a(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1973
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00a(_date1, _date2, _rmatn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNum00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatn);
+
+    /* "astropy/_erfa/core.pyx":1974
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00a(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1961
+ * 
+ * 
+ * def _num00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1977
+ * 
+ * 
+ * def _num00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_155_num00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_155_num00b = {"_num00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_155_num00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_155_num00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_num00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_154_num00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_154_num00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_num00b", 0);
+
+  /* "astropy/_erfa/core.pyx":1982
+ *     cdef double _date2
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1983
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":1984
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":1985
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":1986
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1987
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00b(_date1, _date2, _rmatn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":1988
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraNum00b(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":1989
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00b(_date1, _date2, _rmatn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNum00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatn);
+
+    /* "astropy/_erfa/core.pyx":1990
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum00b(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1977
+ * 
+ * 
+ * def _num00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":1993
+ * 
+ * 
+ * def _num06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_157_num06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_157_num06a = {"_num06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_157_num06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_157_num06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_num06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_156_num06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_156_num06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_num06a", 0);
+
+  /* "astropy/_erfa/core.pyx":1998
+ *     cdef double _date2
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":1999
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2000
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2001
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2002
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2003
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum06a(_date1, _date2, _rmatn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2004
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraNum06a(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2005
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum06a(_date1, _date2, _rmatn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNum06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatn);
+
+    /* "astropy/_erfa/core.pyx":2006
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNum06a(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":1993
+ * 
+ * 
+ * def _num06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2009
+ * 
+ * 
+ * def _numat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epsa
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_159_numat(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_159_numat = {"_numat", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_159_numat, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_159_numat(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_numat (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_158_numat(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_158_numat(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__epsa;
+  double __pyx_v__dpsi;
+  double __pyx_v__deps;
+  double *__pyx_v__rmatn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_numat", 0);
+
+  /* "astropy/_erfa/core.pyx":2015
+ *     cdef double _deps
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2016
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2017
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _epsa = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2018
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[0]))[0]
+ *         _dpsi = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2019
+ *     cdef int status = 1
+ *     while status:
+ *         _epsa = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[1]))[0]
+ *         _deps = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__epsa = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2020
+ *     while status:
+ *         _epsa = (<double *>(dataptrarray[0]))[0]
+ *         _dpsi = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[2]))[0]
+ *         _rmatn = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__dpsi = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2021
+ *         _epsa = (<double *>(dataptrarray[0]))[0]
+ *         _dpsi = (<double *>(dataptrarray[1]))[0]
+ *         _deps = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatn = (<double *>(dataptrarray[3]))
+ *         eraNumat(_epsa, _dpsi, _deps, _rmatn)
+ */
+    __pyx_v__deps = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2022
+ *         _dpsi = (<double *>(dataptrarray[1]))[0]
+ *         _deps = (<double *>(dataptrarray[2]))[0]
+ *         _rmatn = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraNumat(_epsa, _dpsi, _deps, _rmatn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatn = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2023
+ *         _deps = (<double *>(dataptrarray[2]))[0]
+ *         _rmatn = (<double *>(dataptrarray[3]))
+ *         eraNumat(_epsa, _dpsi, _deps, _rmatn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNumat(__pyx_v__epsa, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__rmatn);
+
+    /* "astropy/_erfa/core.pyx":2024
+ *         _rmatn = (<double *>(dataptrarray[3]))
+ *         eraNumat(_epsa, _dpsi, _deps, _rmatn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2009
+ * 
+ * 
+ * def _numat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epsa
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2027
+ * 
+ * 
+ * def _nut00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_161_nut00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_161_nut00a = {"_nut00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_161_nut00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_161_nut00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_nut00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_160_nut00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_160_nut00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_nut00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2033
+ *     cdef double * _dpsi
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2034
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2035
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2036
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2037
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2038
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2039
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00a(_date1, _date2, _dpsi, _deps)
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2040
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraNut00a(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2041
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00a(_date1, _date2, _dpsi, _deps)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNut00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps);
+
+    /* "astropy/_erfa/core.pyx":2042
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00a(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2027
+ * 
+ * 
+ * def _nut00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2045
+ * 
+ * 
+ * def _nut00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_163_nut00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_163_nut00b = {"_nut00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_163_nut00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_163_nut00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_nut00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_162_nut00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_162_nut00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_nut00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2051
+ *     cdef double * _dpsi
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2052
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2053
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2054
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2055
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2056
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2057
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00b(_date1, _date2, _dpsi, _deps)
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2058
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraNut00b(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2059
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00b(_date1, _date2, _dpsi, _deps)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNut00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps);
+
+    /* "astropy/_erfa/core.pyx":2060
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut00b(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2045
+ * 
+ * 
+ * def _nut00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2063
+ * 
+ * 
+ * def _nut06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_165_nut06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_165_nut06a = {"_nut06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_165_nut06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_165_nut06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_nut06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_164_nut06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_164_nut06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_nut06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2069
+ *     cdef double * _dpsi
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2070
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2071
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2072
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2073
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2074
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2075
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut06a(_date1, _date2, _dpsi, _deps)
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2076
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraNut06a(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2077
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut06a(_date1, _date2, _dpsi, _deps)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNut06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps);
+
+    /* "astropy/_erfa/core.pyx":2078
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut06a(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2063
+ * 
+ * 
+ * def _nut06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2081
+ * 
+ * 
+ * def _nut80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_167_nut80(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_167_nut80 = {"_nut80", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_167_nut80, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_167_nut80(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_nut80 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_166_nut80(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_166_nut80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_nut80", 0);
+
+  /* "astropy/_erfa/core.pyx":2087
+ *     cdef double * _dpsi
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2088
+ *     cdef double * _deps
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2089
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2090
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2091
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2092
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2093
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut80(_date1, _date2, _dpsi, _deps)
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2094
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraNut80(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2095
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut80(_date1, _date2, _dpsi, _deps)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNut80(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps);
+
+    /* "astropy/_erfa/core.pyx":2096
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         eraNut80(_date1, _date2, _dpsi, _deps)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2081
+ * 
+ * 
+ * def _nut80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2099
+ * 
+ * 
+ * def _nutm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_169_nutm80(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_169_nutm80 = {"_nutm80", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_169_nutm80, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_169_nutm80(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_nutm80 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_168_nutm80(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_168_nutm80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_nutm80", 0);
+
+  /* "astropy/_erfa/core.pyx":2104
+ *     cdef double _date2
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2105
+ *     cdef double * _rmatn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2106
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2107
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2108
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2109
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNutm80(_date1, _date2, _rmatn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2110
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraNutm80(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2111
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNutm80(_date1, _date2, _rmatn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraNutm80(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatn);
+
+    /* "astropy/_erfa/core.pyx":2112
+ *         _rmatn = (<double *>(dataptrarray[2]))
+ *         eraNutm80(_date1, _date2, _rmatn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2099
+ * 
+ * 
+ * def _nutm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2115
+ * 
+ * 
+ * def _obl06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_171_obl06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_171_obl06 = {"_obl06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_171_obl06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_171_obl06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_obl06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_170_obl06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_170_obl06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_obl06", 0);
+
+  /* "astropy/_erfa/core.pyx":2120
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2121
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2122
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2123
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2124
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl06(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2125
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraObl06(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2126
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl06(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraObl06(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2127
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl06(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2128
+ *         _c_retval = eraObl06(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2115
+ * 
+ * 
+ * def _obl06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2131
+ * 
+ * 
+ * def _obl80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_173_obl80(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_173_obl80 = {"_obl80", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_173_obl80, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_173_obl80(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_obl80 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_172_obl80(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_172_obl80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_obl80", 0);
+
+  /* "astropy/_erfa/core.pyx":2136
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2137
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2138
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2139
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2140
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl80(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2141
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraObl80(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2142
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl80(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraObl80(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2143
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraObl80(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2144
+ *         _c_retval = eraObl80(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2131
+ * 
+ * 
+ * def _obl80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2147
+ * 
+ * 
+ * def _p06e(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_175_p06e(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_175_p06e = {"_p06e", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_175_p06e, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_175_p06e(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_p06e (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_174_p06e(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_174_p06e(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__eps0;
+  double *__pyx_v__psia;
+  double *__pyx_v__oma;
+  double *__pyx_v__bpa;
+  double *__pyx_v__bqa;
+  double *__pyx_v__pia;
+  double *__pyx_v__bpia;
+  double *__pyx_v__epsa;
+  double *__pyx_v__chia;
+  double *__pyx_v__za;
+  double *__pyx_v__zetaa;
+  double *__pyx_v__thetaa;
+  double *__pyx_v__pa;
+  double *__pyx_v__gam;
+  double *__pyx_v__phi;
+  double *__pyx_v__psi;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_p06e", 0);
+
+  /* "astropy/_erfa/core.pyx":2167
+ *     cdef double * _phi
+ *     cdef double * _psi
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2168
+ *     cdef double * _psi
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2169
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2170
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2171
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _eps0 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2172
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _eps0 = (<double *>(dataptrarray[2]))
+ *         _psia = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2173
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _eps0 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _psia = (<double *>(dataptrarray[3]))
+ *         _oma = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__eps0 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2174
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _eps0 = (<double *>(dataptrarray[2]))
+ *         _psia = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _oma = (<double *>(dataptrarray[4]))
+ *         _bpa = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__psia = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2175
+ *         _eps0 = (<double *>(dataptrarray[2]))
+ *         _psia = (<double *>(dataptrarray[3]))
+ *         _oma = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _bpa = (<double *>(dataptrarray[5]))
+ *         _bqa = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__oma = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2176
+ *         _psia = (<double *>(dataptrarray[3]))
+ *         _oma = (<double *>(dataptrarray[4]))
+ *         _bpa = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _bqa = (<double *>(dataptrarray[6]))
+ *         _pia = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__bpa = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2177
+ *         _oma = (<double *>(dataptrarray[4]))
+ *         _bpa = (<double *>(dataptrarray[5]))
+ *         _bqa = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _pia = (<double *>(dataptrarray[7]))
+ *         _bpia = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__bqa = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2178
+ *         _bpa = (<double *>(dataptrarray[5]))
+ *         _bqa = (<double *>(dataptrarray[6]))
+ *         _pia = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _bpia = (<double *>(dataptrarray[8]))
+ *         _epsa = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__pia = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2179
+ *         _bqa = (<double *>(dataptrarray[6]))
+ *         _pia = (<double *>(dataptrarray[7]))
+ *         _bpia = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[9]))
+ *         _chia = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__bpia = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2180
+ *         _pia = (<double *>(dataptrarray[7]))
+ *         _bpia = (<double *>(dataptrarray[8]))
+ *         _epsa = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         _chia = (<double *>(dataptrarray[10]))
+ *         _za = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2181
+ *         _bpia = (<double *>(dataptrarray[8]))
+ *         _epsa = (<double *>(dataptrarray[9]))
+ *         _chia = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _za = (<double *>(dataptrarray[11]))
+ *         _zetaa = (<double *>(dataptrarray[12]))
+ */
+    __pyx_v__chia = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":2182
+ *         _epsa = (<double *>(dataptrarray[9]))
+ *         _chia = (<double *>(dataptrarray[10]))
+ *         _za = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         _zetaa = (<double *>(dataptrarray[12]))
+ *         _thetaa = (<double *>(dataptrarray[13]))
+ */
+    __pyx_v__za = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":2183
+ *         _chia = (<double *>(dataptrarray[10]))
+ *         _za = (<double *>(dataptrarray[11]))
+ *         _zetaa = (<double *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _thetaa = (<double *>(dataptrarray[13]))
+ *         _pa = (<double *>(dataptrarray[14]))
+ */
+    __pyx_v__zetaa = ((double *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":2184
+ *         _za = (<double *>(dataptrarray[11]))
+ *         _zetaa = (<double *>(dataptrarray[12]))
+ *         _thetaa = (<double *>(dataptrarray[13]))             # <<<<<<<<<<<<<<
+ *         _pa = (<double *>(dataptrarray[14]))
+ *         _gam = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__thetaa = ((double *)(__pyx_v_dataptrarray[13]));
+
+    /* "astropy/_erfa/core.pyx":2185
+ *         _zetaa = (<double *>(dataptrarray[12]))
+ *         _thetaa = (<double *>(dataptrarray[13]))
+ *         _pa = (<double *>(dataptrarray[14]))             # <<<<<<<<<<<<<<
+ *         _gam = (<double *>(dataptrarray[15]))
+ *         _phi = (<double *>(dataptrarray[16]))
+ */
+    __pyx_v__pa = ((double *)(__pyx_v_dataptrarray[14]));
+
+    /* "astropy/_erfa/core.pyx":2186
+ *         _thetaa = (<double *>(dataptrarray[13]))
+ *         _pa = (<double *>(dataptrarray[14]))
+ *         _gam = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[16]))
+ *         _psi = (<double *>(dataptrarray[17]))
+ */
+    __pyx_v__gam = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":2187
+ *         _pa = (<double *>(dataptrarray[14]))
+ *         _gam = (<double *>(dataptrarray[15]))
+ *         _phi = (<double *>(dataptrarray[16]))             # <<<<<<<<<<<<<<
+ *         _psi = (<double *>(dataptrarray[17]))
+ *         eraP06e(_date1, _date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi)
+ */
+    __pyx_v__phi = ((double *)(__pyx_v_dataptrarray[16]));
+
+    /* "astropy/_erfa/core.pyx":2188
+ *         _gam = (<double *>(dataptrarray[15]))
+ *         _phi = (<double *>(dataptrarray[16]))
+ *         _psi = (<double *>(dataptrarray[17]))             # <<<<<<<<<<<<<<
+ *         eraP06e(_date1, _date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__psi = ((double *)(__pyx_v_dataptrarray[17]));
+
+    /* "astropy/_erfa/core.pyx":2189
+ *         _phi = (<double *>(dataptrarray[16]))
+ *         _psi = (<double *>(dataptrarray[17]))
+ *         eraP06e(_date1, _date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraP06e(__pyx_v__date1, __pyx_v__date2, __pyx_v__eps0, __pyx_v__psia, __pyx_v__oma, __pyx_v__bpa, __pyx_v__bqa, __pyx_v__pia, __pyx_v__bpia, __pyx_v__epsa, __pyx_v__chia, __pyx_v__za, __pyx_v__zetaa, __pyx_v__thetaa, __pyx_v__pa, __pyx_v__gam, __pyx_v__phi, __pyx_v__psi);
+
+    /* "astropy/_erfa/core.pyx":2190
+ *         _psi = (<double *>(dataptrarray[17]))
+ *         eraP06e(_date1, _date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2147
+ * 
+ * 
+ * def _p06e(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2193
+ * 
+ * 
+ * def _pb06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_177_pb06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_177_pb06 = {"_pb06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_177_pb06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_177_pb06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pb06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_176_pb06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_176_pb06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__bzeta;
+  double *__pyx_v__bz;
+  double *__pyx_v__btheta;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pb06", 0);
+
+  /* "astropy/_erfa/core.pyx":2200
+ *     cdef double * _bz
+ *     cdef double * _btheta
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2201
+ *     cdef double * _btheta
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2202
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2203
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2204
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _bzeta = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2205
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _bzeta = (<double *>(dataptrarray[2]))
+ *         _bz = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2206
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _bzeta = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _bz = (<double *>(dataptrarray[3]))
+ *         _btheta = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__bzeta = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2207
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _bzeta = (<double *>(dataptrarray[2]))
+ *         _bz = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _btheta = (<double *>(dataptrarray[4]))
+ *         eraPb06(_date1, _date2, _bzeta, _bz, _btheta)
+ */
+    __pyx_v__bz = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2208
+ *         _bzeta = (<double *>(dataptrarray[2]))
+ *         _bz = (<double *>(dataptrarray[3]))
+ *         _btheta = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraPb06(_date1, _date2, _bzeta, _bz, _btheta)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__btheta = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2209
+ *         _bz = (<double *>(dataptrarray[3]))
+ *         _btheta = (<double *>(dataptrarray[4]))
+ *         eraPb06(_date1, _date2, _bzeta, _bz, _btheta)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPb06(__pyx_v__date1, __pyx_v__date2, __pyx_v__bzeta, __pyx_v__bz, __pyx_v__btheta);
+
+    /* "astropy/_erfa/core.pyx":2210
+ *         _btheta = (<double *>(dataptrarray[4]))
+ *         eraPb06(_date1, _date2, _bzeta, _bz, _btheta)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2193
+ * 
+ * 
+ * def _pb06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2213
+ * 
+ * 
+ * def _pfw06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_179_pfw06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_179_pfw06 = {"_pfw06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_179_pfw06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_179_pfw06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pfw06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_178_pfw06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_178_pfw06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__gamb;
+  double *__pyx_v__phib;
+  double *__pyx_v__psib;
+  double *__pyx_v__epsa;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pfw06", 0);
+
+  /* "astropy/_erfa/core.pyx":2221
+ *     cdef double * _psib
+ *     cdef double * _epsa
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2222
+ *     cdef double * _epsa
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2223
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2224
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2225
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _gamb = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2226
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _gamb = (<double *>(dataptrarray[2]))
+ *         _phib = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2227
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _gamb = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _phib = (<double *>(dataptrarray[3]))
+ *         _psib = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__gamb = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2228
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _gamb = (<double *>(dataptrarray[2]))
+ *         _phib = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _psib = (<double *>(dataptrarray[4]))
+ *         _epsa = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__phib = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2229
+ *         _gamb = (<double *>(dataptrarray[2]))
+ *         _phib = (<double *>(dataptrarray[3]))
+ *         _psib = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[5]))
+ *         eraPfw06(_date1, _date2, _gamb, _phib, _psib, _epsa)
+ */
+    __pyx_v__psib = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2230
+ *         _phib = (<double *>(dataptrarray[3]))
+ *         _psib = (<double *>(dataptrarray[4]))
+ *         _epsa = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraPfw06(_date1, _date2, _gamb, _phib, _psib, _epsa)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2231
+ *         _psib = (<double *>(dataptrarray[4]))
+ *         _epsa = (<double *>(dataptrarray[5]))
+ *         eraPfw06(_date1, _date2, _gamb, _phib, _psib, _epsa)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPfw06(__pyx_v__date1, __pyx_v__date2, __pyx_v__gamb, __pyx_v__phib, __pyx_v__psib, __pyx_v__epsa);
+
+    /* "astropy/_erfa/core.pyx":2232
+ *         _epsa = (<double *>(dataptrarray[5]))
+ *         eraPfw06(_date1, _date2, _gamb, _phib, _psib, _epsa)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2213
+ * 
+ * 
+ * def _pfw06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2235
+ * 
+ * 
+ * def _pmat00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_181_pmat00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_181_pmat00 = {"_pmat00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_181_pmat00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_181_pmat00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmat00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_180_pmat00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_180_pmat00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rbp;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pmat00", 0);
+
+  /* "astropy/_erfa/core.pyx":2240
+ *     cdef double _date2
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2241
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2242
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2243
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2244
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2245
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat00(_date1, _date2, _rbp)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2246
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPmat00(_date1, _date2, _rbp)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2247
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat00(_date1, _date2, _rbp)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPmat00(__pyx_v__date1, __pyx_v__date2, __pyx_v__rbp);
+
+    /* "astropy/_erfa/core.pyx":2248
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat00(_date1, _date2, _rbp)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2235
+ * 
+ * 
+ * def _pmat00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2251
+ * 
+ * 
+ * def _pmat06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_183_pmat06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_183_pmat06 = {"_pmat06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_183_pmat06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_183_pmat06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmat06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_182_pmat06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_182_pmat06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rbp;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pmat06", 0);
+
+  /* "astropy/_erfa/core.pyx":2256
+ *     cdef double _date2
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2257
+ *     cdef double * _rbp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2258
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2259
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2260
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2261
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat06(_date1, _date2, _rbp)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2262
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPmat06(_date1, _date2, _rbp)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2263
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat06(_date1, _date2, _rbp)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPmat06(__pyx_v__date1, __pyx_v__date2, __pyx_v__rbp);
+
+    /* "astropy/_erfa/core.pyx":2264
+ *         _rbp = (<double *>(dataptrarray[2]))
+ *         eraPmat06(_date1, _date2, _rbp)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2251
+ * 
+ * 
+ * def _pmat06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2267
+ * 
+ * 
+ * def _pmat76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_185_pmat76(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_185_pmat76 = {"_pmat76", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_185_pmat76, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_185_pmat76(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmat76 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_184_pmat76(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_184_pmat76(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatp;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pmat76", 0);
+
+  /* "astropy/_erfa/core.pyx":2272
+ *     cdef double _date2
+ *     cdef double * _rmatp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2273
+ *     cdef double * _rmatp
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2274
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2275
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2276
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatp = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2277
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatp = (<double *>(dataptrarray[2]))
+ *         eraPmat76(_date1, _date2, _rmatp)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2278
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatp = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPmat76(_date1, _date2, _rmatp)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatp = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2279
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatp = (<double *>(dataptrarray[2]))
+ *         eraPmat76(_date1, _date2, _rmatp)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPmat76(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatp);
+
+    /* "astropy/_erfa/core.pyx":2280
+ *         _rmatp = (<double *>(dataptrarray[2]))
+ *         eraPmat76(_date1, _date2, _rmatp)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2267
+ * 
+ * 
+ * def _pmat76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2283
+ * 
+ * 
+ * def _pn00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_187_pn00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_187_pn00 = {"_pn00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_187_pn00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_187_pn00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pn00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_186_pn00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_186_pn00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__dpsi;
+  double __pyx_v__deps;
+  double *__pyx_v__epsa;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  double *__pyx_v__rn;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pn00", 0);
+
+  /* "astropy/_erfa/core.pyx":2295
+ *     cdef double * _rn
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2296
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2297
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2298
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2299
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2300
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2301
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dpsi = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2302
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__deps = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2303
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2304
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2305
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2306
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2307
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ */
+    __pyx_v__rn = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2308
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraPn00(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2309
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPn00(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__epsa, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp, __pyx_v__rn, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2310
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2283
+ * 
+ * 
+ * def _pn00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2313
+ * 
+ * 
+ * def _pn00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_189_pn00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_189_pn00a = {"_pn00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_189_pn00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_189_pn00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pn00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_188_pn00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_188_pn00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  double *__pyx_v__epsa;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  double *__pyx_v__rn;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pn00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2325
+ *     cdef double * _rn
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2326
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2327
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2328
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2329
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2330
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2331
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2332
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2333
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2334
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2335
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2336
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2337
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ */
+    __pyx_v__rn = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2338
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraPn00a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2339
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPn00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__epsa, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp, __pyx_v__rn, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2340
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2313
+ * 
+ * 
+ * def _pn00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2343
+ * 
+ * 
+ * def _pn00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_191_pn00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_191_pn00b = {"_pn00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_191_pn00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_191_pn00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pn00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_190_pn00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_190_pn00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  double *__pyx_v__epsa;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  double *__pyx_v__rn;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pn00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2355
+ *     cdef double * _rn
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2356
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2357
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2358
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2359
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2360
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2361
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2362
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2363
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2364
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2365
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2366
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2367
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00b(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ */
+    __pyx_v__rn = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2368
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraPn00b(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2369
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00b(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPn00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__epsa, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp, __pyx_v__rn, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2370
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn00b(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2343
+ * 
+ * 
+ * def _pn00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2373
+ * 
+ * 
+ * def _pn06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_193_pn06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_193_pn06 = {"_pn06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_193_pn06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_193_pn06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pn06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_192_pn06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_192_pn06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__dpsi;
+  double __pyx_v__deps;
+  double *__pyx_v__epsa;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  double *__pyx_v__rn;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pn06", 0);
+
+  /* "astropy/_erfa/core.pyx":2385
+ *     cdef double * _rn
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2386
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2387
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2388
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2389
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2390
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2391
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dpsi = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2392
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__deps = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2393
+ *         _dpsi = (<double *>(dataptrarray[2]))[0]
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2394
+ *         _deps = (<double *>(dataptrarray[3]))[0]
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2395
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2396
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2397
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ */
+    __pyx_v__rn = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2398
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraPn06(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2399
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPn06(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__epsa, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp, __pyx_v__rn, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2400
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2373
+ * 
+ * 
+ * def _pn06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2403
+ * 
+ * 
+ * def _pn06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_195_pn06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_195_pn06a = {"_pn06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_195_pn06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_195_pn06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pn06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_194_pn06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_194_pn06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsi;
+  double *__pyx_v__deps;
+  double *__pyx_v__epsa;
+  double *__pyx_v__rb;
+  double *__pyx_v__rp;
+  double *__pyx_v__rbp;
+  double *__pyx_v__rn;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pn06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2415
+ *     cdef double * _rn
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2416
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2417
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2418
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2419
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2420
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2421
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dpsi = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2422
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__deps = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2423
+ *         _dpsi = (<double *>(dataptrarray[2]))
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__epsa = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2424
+ *         _deps = (<double *>(dataptrarray[3]))
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rb = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2425
+ *         _epsa = (<double *>(dataptrarray[4]))
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rp = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2426
+ *         _rb = (<double *>(dataptrarray[5]))
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__rbp = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":2427
+ *         _rp = (<double *>(dataptrarray[6]))
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ */
+    __pyx_v__rn = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":2428
+ *         _rbp = (<double *>(dataptrarray[7]))
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         eraPn06a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":2429
+ *         _rn = (<double *>(dataptrarray[8]))
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPn06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsi, __pyx_v__deps, __pyx_v__epsa, __pyx_v__rb, __pyx_v__rp, __pyx_v__rbp, __pyx_v__rn, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2430
+ *         _rbpn = (<double *>(dataptrarray[9]))
+ *         eraPn06a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2403
+ * 
+ * 
+ * def _pn06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2433
+ * 
+ * 
+ * def _pnm00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_197_pnm00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_197_pnm00a = {"_pnm00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_197_pnm00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_197_pnm00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pnm00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_196_pnm00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_196_pnm00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pnm00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2438
+ *     cdef double _date2
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2439
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2440
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2441
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2442
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2443
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00a(_date1, _date2, _rbpn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2444
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPnm00a(_date1, _date2, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2445
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00a(_date1, _date2, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPnm00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2446
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00a(_date1, _date2, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2433
+ * 
+ * 
+ * def _pnm00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2449
+ * 
+ * 
+ * def _pnm00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_199_pnm00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_199_pnm00b = {"_pnm00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_199_pnm00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_199_pnm00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pnm00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_198_pnm00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_198_pnm00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rbpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pnm00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2454
+ *     cdef double _date2
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2455
+ *     cdef double * _rbpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2456
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2457
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2458
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2459
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00b(_date1, _date2, _rbpn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2460
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPnm00b(_date1, _date2, _rbpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rbpn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2461
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00b(_date1, _date2, _rbpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPnm00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__rbpn);
+
+    /* "astropy/_erfa/core.pyx":2462
+ *         _rbpn = (<double *>(dataptrarray[2]))
+ *         eraPnm00b(_date1, _date2, _rbpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2449
+ * 
+ * 
+ * def _pnm00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2465
+ * 
+ * 
+ * def _pnm06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_201_pnm06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_201_pnm06a = {"_pnm06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_201_pnm06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_201_pnm06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pnm06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_200_pnm06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_200_pnm06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rnpb;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pnm06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2470
+ *     cdef double _date2
+ *     cdef double * _rnpb
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2471
+ *     cdef double * _rnpb
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2472
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2473
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2474
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rnpb = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2475
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rnpb = (<double *>(dataptrarray[2]))
+ *         eraPnm06a(_date1, _date2, _rnpb)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2476
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rnpb = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPnm06a(_date1, _date2, _rnpb)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rnpb = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2477
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rnpb = (<double *>(dataptrarray[2]))
+ *         eraPnm06a(_date1, _date2, _rnpb)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPnm06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__rnpb);
+
+    /* "astropy/_erfa/core.pyx":2478
+ *         _rnpb = (<double *>(dataptrarray[2]))
+ *         eraPnm06a(_date1, _date2, _rnpb)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2465
+ * 
+ * 
+ * def _pnm06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2481
+ * 
+ * 
+ * def _pnm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_203_pnm80(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_203_pnm80 = {"_pnm80", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_203_pnm80, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_203_pnm80(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pnm80 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_202_pnm80(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_202_pnm80(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rmatpn;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pnm80", 0);
+
+  /* "astropy/_erfa/core.pyx":2486
+ *     cdef double _date2
+ *     cdef double * _rmatpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2487
+ *     cdef double * _rmatpn
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2488
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2489
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2490
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatpn = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2491
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _rmatpn = (<double *>(dataptrarray[2]))
+ *         eraPnm80(_date1, _date2, _rmatpn)
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2492
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatpn = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         eraPnm80(_date1, _date2, _rmatpn)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rmatpn = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2493
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _rmatpn = (<double *>(dataptrarray[2]))
+ *         eraPnm80(_date1, _date2, _rmatpn)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPnm80(__pyx_v__date1, __pyx_v__date2, __pyx_v__rmatpn);
+
+    /* "astropy/_erfa/core.pyx":2494
+ *         _rmatpn = (<double *>(dataptrarray[2]))
+ *         eraPnm80(_date1, _date2, _rmatpn)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2481
+ * 
+ * 
+ * def _pnm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2497
+ * 
+ * 
+ * def _pom00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _xp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_205_pom00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_205_pom00 = {"_pom00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_205_pom00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_205_pom00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pom00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_204_pom00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_204_pom00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__sp;
+  double *__pyx_v__rpom;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pom00", 0);
+
+  /* "astropy/_erfa/core.pyx":2503
+ *     cdef double _sp
+ *     cdef double * _rpom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2504
+ *     cdef double * _rpom
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2505
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _xp = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2506
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[0]))[0]
+ *         _yp = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2507
+ *     cdef int status = 1
+ *     while status:
+ *         _xp = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[1]))[0]
+ *         _sp = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2508
+ *     while status:
+ *         _xp = (<double *>(dataptrarray[0]))[0]
+ *         _yp = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _sp = (<double *>(dataptrarray[2]))[0]
+ *         _rpom = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2509
+ *         _xp = (<double *>(dataptrarray[0]))[0]
+ *         _yp = (<double *>(dataptrarray[1]))[0]
+ *         _sp = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _rpom = (<double *>(dataptrarray[3]))
+ *         eraPom00(_xp, _yp, _sp, _rpom)
+ */
+    __pyx_v__sp = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2510
+ *         _yp = (<double *>(dataptrarray[1]))[0]
+ *         _sp = (<double *>(dataptrarray[2]))[0]
+ *         _rpom = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraPom00(_xp, _yp, _sp, _rpom)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rpom = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2511
+ *         _sp = (<double *>(dataptrarray[2]))[0]
+ *         _rpom = (<double *>(dataptrarray[3]))
+ *         eraPom00(_xp, _yp, _sp, _rpom)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPom00(__pyx_v__xp, __pyx_v__yp, __pyx_v__sp, __pyx_v__rpom);
+
+    /* "astropy/_erfa/core.pyx":2512
+ *         _rpom = (<double *>(dataptrarray[3]))
+ *         eraPom00(_xp, _yp, _sp, _rpom)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2497
+ * 
+ * 
+ * def _pom00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _xp
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2515
+ * 
+ * 
+ * def _pr00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_207_pr00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_207_pr00 = {"_pr00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_207_pr00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_207_pr00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pr00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_206_pr00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_206_pr00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__dpsipr;
+  double *__pyx_v__depspr;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pr00", 0);
+
+  /* "astropy/_erfa/core.pyx":2521
+ *     cdef double * _dpsipr
+ *     cdef double * _depspr
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2522
+ *     cdef double * _depspr
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2523
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2524
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2525
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsipr = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2526
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsipr = (<double *>(dataptrarray[2]))
+ *         _depspr = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2527
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsipr = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _depspr = (<double *>(dataptrarray[3]))
+ *         eraPr00(_date1, _date2, _dpsipr, _depspr)
+ */
+    __pyx_v__dpsipr = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2528
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _dpsipr = (<double *>(dataptrarray[2]))
+ *         _depspr = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraPr00(_date1, _date2, _dpsipr, _depspr)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__depspr = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2529
+ *         _dpsipr = (<double *>(dataptrarray[2]))
+ *         _depspr = (<double *>(dataptrarray[3]))
+ *         eraPr00(_date1, _date2, _dpsipr, _depspr)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPr00(__pyx_v__date1, __pyx_v__date2, __pyx_v__dpsipr, __pyx_v__depspr);
+
+    /* "astropy/_erfa/core.pyx":2530
+ *         _depspr = (<double *>(dataptrarray[3]))
+ *         eraPr00(_date1, _date2, _dpsipr, _depspr)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2515
+ * 
+ * 
+ * def _pr00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2533
+ * 
+ * 
+ * def _prec76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date01
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_209_prec76(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_209_prec76 = {"_prec76", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_209_prec76, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_209_prec76(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_prec76 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_208_prec76(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_208_prec76(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date01;
+  double __pyx_v__date02;
+  double __pyx_v__date11;
+  double __pyx_v__date12;
+  double *__pyx_v__zeta;
+  double *__pyx_v__z;
+  double *__pyx_v__theta;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_prec76", 0);
+
+  /* "astropy/_erfa/core.pyx":2542
+ *     cdef double * _z
+ *     cdef double * _theta
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2543
+ *     cdef double * _theta
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2544
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date01 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2545
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date01 = (<double *>(dataptrarray[0]))[0]
+ *         _date02 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2546
+ *     cdef int status = 1
+ *     while status:
+ *         _date01 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date02 = (<double *>(dataptrarray[1]))[0]
+ *         _date11 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date01 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2547
+ *     while status:
+ *         _date01 = (<double *>(dataptrarray[0]))[0]
+ *         _date02 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _date11 = (<double *>(dataptrarray[2]))[0]
+ *         _date12 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date02 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2548
+ *         _date01 = (<double *>(dataptrarray[0]))[0]
+ *         _date02 = (<double *>(dataptrarray[1]))[0]
+ *         _date11 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _date12 = (<double *>(dataptrarray[3]))[0]
+ *         _zeta = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__date11 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2549
+ *         _date02 = (<double *>(dataptrarray[1]))[0]
+ *         _date11 = (<double *>(dataptrarray[2]))[0]
+ *         _date12 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _zeta = (<double *>(dataptrarray[4]))
+ *         _z = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__date12 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2550
+ *         _date11 = (<double *>(dataptrarray[2]))[0]
+ *         _date12 = (<double *>(dataptrarray[3]))[0]
+ *         _zeta = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _z = (<double *>(dataptrarray[5]))
+ *         _theta = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__zeta = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2551
+ *         _date12 = (<double *>(dataptrarray[3]))[0]
+ *         _zeta = (<double *>(dataptrarray[4]))
+ *         _z = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _theta = (<double *>(dataptrarray[6]))
+ *         eraPrec76(_date01, _date02, _date11, _date12, _zeta, _z, _theta)
+ */
+    __pyx_v__z = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":2552
+ *         _zeta = (<double *>(dataptrarray[4]))
+ *         _z = (<double *>(dataptrarray[5]))
+ *         _theta = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         eraPrec76(_date01, _date02, _date11, _date12, _zeta, _z, _theta)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__theta = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":2553
+ *         _z = (<double *>(dataptrarray[5]))
+ *         _theta = (<double *>(dataptrarray[6]))
+ *         eraPrec76(_date01, _date02, _date11, _date12, _zeta, _z, _theta)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPrec76(__pyx_v__date01, __pyx_v__date02, __pyx_v__date11, __pyx_v__date12, __pyx_v__zeta, __pyx_v__z, __pyx_v__theta);
+
+    /* "astropy/_erfa/core.pyx":2554
+ *         _theta = (<double *>(dataptrarray[6]))
+ *         eraPrec76(_date01, _date02, _date11, _date12, _zeta, _z, _theta)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2533
+ * 
+ * 
+ * def _prec76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date01
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2557
+ * 
+ * 
+ * def _s00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_211_s00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_211_s00 = {"_s00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_211_s00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_211_s00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_s00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_210_s00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_210_s00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_s00", 0);
+
+  /* "astropy/_erfa/core.pyx":2564
+ *     cdef double _y
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2565
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2566
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2567
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2568
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2569
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2570
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS00(_date1, _date2, _x, _y)
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2571
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraS00(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2572
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS00(_date1, _date2, _x, _y)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraS00(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y);
+
+    /* "astropy/_erfa/core.pyx":2573
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS00(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2574
+ *         _c_retval = eraS00(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2557
+ * 
+ * 
+ * def _s00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2577
+ * 
+ * 
+ * def _s00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_213_s00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_213_s00a = {"_s00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_213_s00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_213_s00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_s00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_212_s00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_212_s00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_s00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2582
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2583
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2584
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2585
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2586
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00a(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2587
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraS00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2588
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00a(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraS00a(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2589
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2590
+ *         _c_retval = eraS00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2577
+ * 
+ * 
+ * def _s00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2593
+ * 
+ * 
+ * def _s00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_215_s00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_215_s00b = {"_s00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_215_s00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_215_s00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_s00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_214_s00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_214_s00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_s00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2598
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2599
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2600
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2601
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2602
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00b(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2603
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraS00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2604
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00b(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraS00b(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2605
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2606
+ *         _c_retval = eraS00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2593
+ * 
+ * 
+ * def _s00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2609
+ * 
+ * 
+ * def _s06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_217_s06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_217_s06 = {"_s06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_217_s06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_217_s06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_s06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_216_s06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_216_s06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__x;
+  double __pyx_v__y;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_s06", 0);
+
+  /* "astropy/_erfa/core.pyx":2616
+ *     cdef double _y
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2617
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2618
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2619
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2620
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2621
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2622
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS06(_date1, _date2, _x, _y)
+ */
+    __pyx_v__x = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2623
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraS06(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__y = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2624
+ *         _x = (<double *>(dataptrarray[2]))[0]
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS06(_date1, _date2, _x, _y)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraS06(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y);
+
+    /* "astropy/_erfa/core.pyx":2625
+ *         _y = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraS06(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2626
+ *         _c_retval = eraS06(_date1, _date2, _x, _y)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2609
+ * 
+ * 
+ * def _s06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2629
+ * 
+ * 
+ * def _s06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_219_s06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_219_s06a = {"_s06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_219_s06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_219_s06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_s06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_218_s06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_218_s06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_s06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2634
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2635
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2636
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2637
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2638
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS06a(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2639
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraS06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2640
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS06a(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraS06a(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2641
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraS06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2642
+ *         _c_retval = eraS06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2629
+ * 
+ * 
+ * def _s06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2645
+ * 
+ * 
+ * def _sp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_221_sp00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_221_sp00 = {"_sp00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_221_sp00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_221_sp00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_sp00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_220_sp00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_220_sp00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_sp00", 0);
+
+  /* "astropy/_erfa/core.pyx":2650
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2651
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2652
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2653
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2654
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraSp00(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2655
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraSp00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2656
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraSp00(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraSp00(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2657
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraSp00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2658
+ *         _c_retval = eraSp00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2645
+ * 
+ * 
+ * def _sp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2661
+ * 
+ * 
+ * def _xy06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_223_xy06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_223_xy06 = {"_xy06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_223_xy06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_223_xy06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_xy06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_222_xy06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_222_xy06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_xy06", 0);
+
+  /* "astropy/_erfa/core.pyx":2667
+ *     cdef double * _x
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2668
+ *     cdef double * _y
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2669
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2670
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2671
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2672
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2673
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))
+ *         eraXy06(_date1, _date2, _x, _y)
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2674
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         eraXy06(_date1, _date2, _x, _y)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2675
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ *         eraXy06(_date1, _date2, _x, _y)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraXy06(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y);
+
+    /* "astropy/_erfa/core.pyx":2676
+ *         _y = (<double *>(dataptrarray[3]))
+ *         eraXy06(_date1, _date2, _x, _y)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2661
+ * 
+ * 
+ * def _xy06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2679
+ * 
+ * 
+ * def _xys00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_225_xys00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_225_xys00a = {"_xys00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_225_xys00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_225_xys00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_xys00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_224_xys00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_224_xys00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  double *__pyx_v__s;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_xys00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2686
+ *     cdef double * _y
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2687
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2688
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2689
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2690
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2691
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2692
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2693
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00a(_date1, _date2, _x, _y, _s)
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2694
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraXys00a(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__s = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2695
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00a(_date1, _date2, _x, _y, _s)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraXys00a(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y, __pyx_v__s);
+
+    /* "astropy/_erfa/core.pyx":2696
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00a(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2679
+ * 
+ * 
+ * def _xys00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2699
+ * 
+ * 
+ * def _xys00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_227_xys00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_227_xys00b = {"_xys00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_227_xys00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_227_xys00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_xys00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_226_xys00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_226_xys00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  double *__pyx_v__s;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_xys00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2706
+ *     cdef double * _y
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2707
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2708
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2709
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2710
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2711
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2712
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2713
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00b(_date1, _date2, _x, _y, _s)
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2714
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraXys00b(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__s = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2715
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00b(_date1, _date2, _x, _y, _s)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraXys00b(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y, __pyx_v__s);
+
+    /* "astropy/_erfa/core.pyx":2716
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys00b(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2699
+ * 
+ * 
+ * def _xys00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2719
+ * 
+ * 
+ * def _xys06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_229_xys06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_229_xys06a = {"_xys06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_229_xys06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_229_xys06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_xys06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_228_xys06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_228_xys06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__x;
+  double *__pyx_v__y;
+  double *__pyx_v__s;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_xys06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2726
+ *     cdef double * _y
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2727
+ *     cdef double * _s
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2728
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2729
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2730
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2731
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2732
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__x = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":2733
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys06a(_date1, _date2, _x, _y, _s)
+ */
+    __pyx_v__y = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":2734
+ *         _x = (<double *>(dataptrarray[2]))
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         eraXys06a(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__s = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2735
+ *         _y = (<double *>(dataptrarray[3]))
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys06a(_date1, _date2, _x, _y, _s)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraXys06a(__pyx_v__date1, __pyx_v__date2, __pyx_v__x, __pyx_v__y, __pyx_v__s);
+
+    /* "astropy/_erfa/core.pyx":2736
+ *         _s = (<double *>(dataptrarray[4]))
+ *         eraXys06a(_date1, _date2, _x, _y, _s)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2719
+ * 
+ * 
+ * def _xys06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2739
+ * 
+ * 
+ * def _ee00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_231_ee00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_231_ee00 = {"_ee00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_231_ee00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_231_ee00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ee00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_230_ee00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_230_ee00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__epsa;
+  double __pyx_v__dpsi;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ee00", 0);
+
+  /* "astropy/_erfa/core.pyx":2746
+ *     cdef double _dpsi
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2747
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2748
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2749
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2750
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _epsa = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2751
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _epsa = (<double *>(dataptrarray[2]))[0]
+ *         _dpsi = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2752
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _epsa = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _dpsi = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)
+ */
+    __pyx_v__epsa = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2753
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _epsa = (<double *>(dataptrarray[2]))[0]
+ *         _dpsi = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__dpsi = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2754
+ *         _epsa = (<double *>(dataptrarray[2]))[0]
+ *         _dpsi = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEe00(__pyx_v__date1, __pyx_v__date2, __pyx_v__epsa, __pyx_v__dpsi);
+
+    /* "astropy/_erfa/core.pyx":2755
+ *         _dpsi = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2756
+ *         _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2739
+ * 
+ * 
+ * def _ee00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2759
+ * 
+ * 
+ * def _ee00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_233_ee00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_233_ee00a = {"_ee00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_233_ee00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_233_ee00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ee00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_232_ee00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_232_ee00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ee00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2764
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2765
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2766
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2767
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2768
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00a(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2769
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEe00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2770
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00a(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEe00a(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2771
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2772
+ *         _c_retval = eraEe00a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2759
+ * 
+ * 
+ * def _ee00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2775
+ * 
+ * 
+ * def _ee00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_235_ee00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_235_ee00b = {"_ee00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_235_ee00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_235_ee00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ee00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_234_ee00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_234_ee00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ee00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2780
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2781
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2782
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2783
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2784
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00b(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2785
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEe00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2786
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00b(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEe00b(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2787
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2788
+ *         _c_retval = eraEe00b(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2775
+ * 
+ * 
+ * def _ee00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2791
+ * 
+ * 
+ * def _ee06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_237_ee06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_237_ee06a = {"_ee06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_237_ee06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_237_ee06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ee06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_236_ee06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_236_ee06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_ee06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2796
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2797
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2798
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2799
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2800
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe06a(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2801
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEe06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2802
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe06a(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEe06a(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2803
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEe06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2804
+ *         _c_retval = eraEe06a(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2791
+ * 
+ * 
+ * def _ee06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2807
+ * 
+ * 
+ * def _eect00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_239_eect00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_239_eect00 = {"_eect00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_239_eect00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_239_eect00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_eect00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_238_eect00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_238_eect00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_eect00", 0);
+
+  /* "astropy/_erfa/core.pyx":2812
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2813
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2814
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2815
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2816
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEect00(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2817
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEect00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2818
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEect00(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEect00(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2819
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEect00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2820
+ *         _c_retval = eraEect00(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2807
+ * 
+ * 
+ * def _eect00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2823
+ * 
+ * 
+ * def _eqeq94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_241_eqeq94(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_241_eqeq94 = {"_eqeq94", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_241_eqeq94, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_241_eqeq94(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_eqeq94 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_240_eqeq94(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_240_eqeq94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_eqeq94", 0);
+
+  /* "astropy/_erfa/core.pyx":2828
+ *     cdef double _date2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2829
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2830
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2831
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2832
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEqeq94(_date1, _date2)
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2833
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEqeq94(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2834
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEqeq94(_date1, _date2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEqeq94(__pyx_v__date1, __pyx_v__date2);
+
+    /* "astropy/_erfa/core.pyx":2835
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEqeq94(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2836
+ *         _c_retval = eraEqeq94(_date1, _date2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2823
+ * 
+ * 
+ * def _eqeq94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2839
+ * 
+ * 
+ * def _era00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_243_era00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_243_era00 = {"_era00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_243_era00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_243_era00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_era00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_242_era00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_242_era00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_era00", 0);
+
+  /* "astropy/_erfa/core.pyx":2844
+ *     cdef double _dj2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2845
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2846
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2847
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2848
+ *     cdef int status = 1
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEra00(_dj1, _dj2)
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2849
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEra00(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2850
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEra00(_dj1, _dj2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraEra00(__pyx_v__dj1, __pyx_v__dj2);
+
+    /* "astropy/_erfa/core.pyx":2851
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraEra00(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2852
+ *         _c_retval = eraEra00(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2839
+ * 
+ * 
+ * def _era00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2855
+ * 
+ * 
+ * def _gmst00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_245_gmst00(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_245_gmst00 = {"_gmst00", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_245_gmst00, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_245_gmst00(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gmst00 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_244_gmst00(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_244_gmst00(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gmst00", 0);
+
+  /* "astropy/_erfa/core.pyx":2862
+ *     cdef double _ttb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2863
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2864
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2865
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2866
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2867
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2868
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2869
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2870
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGmst00(__pyx_v__uta, __pyx_v__utb, __pyx_v__tta, __pyx_v__ttb);
+
+    /* "astropy/_erfa/core.pyx":2871
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2872
+ *         _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2855
+ * 
+ * 
+ * def _gmst00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2875
+ * 
+ * 
+ * def _gmst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_247_gmst06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_247_gmst06 = {"_gmst06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_247_gmst06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_247_gmst06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gmst06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_246_gmst06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_246_gmst06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gmst06", 0);
+
+  /* "astropy/_erfa/core.pyx":2882
+ *     cdef double _ttb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2883
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2884
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2885
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2886
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2887
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2888
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2889
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2890
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGmst06(__pyx_v__uta, __pyx_v__utb, __pyx_v__tta, __pyx_v__ttb);
+
+    /* "astropy/_erfa/core.pyx":2891
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2892
+ *         _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2875
+ * 
+ * 
+ * def _gmst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2895
+ * 
+ * 
+ * def _gmst82(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_249_gmst82(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_249_gmst82 = {"_gmst82", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_249_gmst82, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_249_gmst82(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gmst82 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_248_gmst82(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_248_gmst82(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__dj1;
+  double __pyx_v__dj2;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gmst82", 0);
+
+  /* "astropy/_erfa/core.pyx":2900
+ *     cdef double _dj2
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2901
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2902
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2903
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2904
+ *     cdef int status = 1
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGmst82(_dj1, _dj2)
+ */
+    __pyx_v__dj1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2905
+ *     while status:
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGmst82(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__dj2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2906
+ *         _dj1 = (<double *>(dataptrarray[0]))[0]
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGmst82(_dj1, _dj2)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGmst82(__pyx_v__dj1, __pyx_v__dj2);
+
+    /* "astropy/_erfa/core.pyx":2907
+ *         _dj2 = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGmst82(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2908
+ *         _c_retval = eraGmst82(_dj1, _dj2)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2895
+ * 
+ * 
+ * def _gmst82(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2911
+ * 
+ * 
+ * def _gst00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_251_gst00a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_251_gst00a = {"_gst00a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_251_gst00a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_251_gst00a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gst00a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_250_gst00a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_250_gst00a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gst00a", 0);
+
+  /* "astropy/_erfa/core.pyx":2918
+ *     cdef double _ttb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2919
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2920
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2921
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2922
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2923
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2924
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2925
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2926
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGst00a(__pyx_v__uta, __pyx_v__utb, __pyx_v__tta, __pyx_v__ttb);
+
+    /* "astropy/_erfa/core.pyx":2927
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2928
+ *         _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2911
+ * 
+ * 
+ * def _gst00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2931
+ * 
+ * 
+ * def _gst00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_253_gst00b(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_253_gst00b = {"_gst00b", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_253_gst00b, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_253_gst00b(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gst00b (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_252_gst00b(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_252_gst00b(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gst00b", 0);
+
+  /* "astropy/_erfa/core.pyx":2936
+ *     cdef double _utb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2937
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2938
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2939
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2940
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst00b(_uta, _utb)
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2941
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGst00b(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2942
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst00b(_uta, _utb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGst00b(__pyx_v__uta, __pyx_v__utb);
+
+    /* "astropy/_erfa/core.pyx":2943
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst00b(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2944
+ *         _c_retval = eraGst00b(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2931
+ * 
+ * 
+ * def _gst00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2947
+ * 
+ * 
+ * def _gst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_255_gst06(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_255_gst06 = {"_gst06", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_255_gst06, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_255_gst06(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gst06 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_254_gst06(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_254_gst06(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double *__pyx_v__rnpb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gst06", 0);
+
+  /* "astropy/_erfa/core.pyx":2955
+ *     cdef double * _rnpb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2956
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2957
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2958
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2959
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2960
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2961
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _rnpb = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2962
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _rnpb = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2963
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _rnpb = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)
+ *         (<double *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__rnpb = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":2964
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _rnpb = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[5]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGst06(__pyx_v__uta, __pyx_v__utb, __pyx_v__tta, __pyx_v__ttb, __pyx_v__rnpb);
+
+    /* "astropy/_erfa/core.pyx":2965
+ *         _rnpb = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)
+ *         (<double *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2966
+ *         _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)
+ *         (<double *>(dataptrarray[5]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2947
+ * 
+ * 
+ * def _gst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2969
+ * 
+ * 
+ * def _gst06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_257_gst06a(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_257_gst06a = {"_gst06a", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_257_gst06a, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_257_gst06a(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gst06a (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_256_gst06a(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_256_gst06a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__tta;
+  double __pyx_v__ttb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gst06a", 0);
+
+  /* "astropy/_erfa/core.pyx":2976
+ *     cdef double _ttb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2977
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2978
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2979
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2980
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2981
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2982
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)
+ */
+    __pyx_v__tta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2983
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__ttb = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2984
+ *         _tta = (<double *>(dataptrarray[2]))[0]
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGst06a(__pyx_v__uta, __pyx_v__utb, __pyx_v__tta, __pyx_v__ttb);
+
+    /* "astropy/_erfa/core.pyx":2985
+ *         _ttb = (<double *>(dataptrarray[3]))[0]
+ *         _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":2986
+ *         _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)
+ *         (<double *>(dataptrarray[4]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2969
+ * 
+ * 
+ * def _gst06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":2989
+ * 
+ * 
+ * def _gst94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_259_gst94(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_259_gst94 = {"_gst94", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_259_gst94, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_259_gst94(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gst94 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_258_gst94(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_258_gst94(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__uta;
+  double __pyx_v__utb;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_gst94", 0);
+
+  /* "astropy/_erfa/core.pyx":2994
+ *     cdef double _utb
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":2995
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":2996
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":2997
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":2998
+ *     cdef int status = 1
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst94(_uta, _utb)
+ */
+    __pyx_v__uta = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":2999
+ *     while status:
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGst94(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ */
+    __pyx_v__utb = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3000
+ *         _uta = (<double *>(dataptrarray[0]))[0]
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst94(_uta, _utb)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraGst94(__pyx_v__uta, __pyx_v__utb);
+
+    /* "astropy/_erfa/core.pyx":3001
+ *         _utb = (<double *>(dataptrarray[1]))[0]
+ *         _c_retval = eraGst94(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[2]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3002
+ *         _c_retval = eraGst94(_uta, _utb)
+ *         (<double *>(dataptrarray[2]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":2989
+ * 
+ * 
+ * def _gst94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3005
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_261_pmsafe(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_261_pmsafe = {"_pmsafe", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_261_pmsafe, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_261_pmsafe(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pmsafe (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_260_pmsafe(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_260_pmsafe(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ra1;
+  double __pyx_v__dec1;
+  double __pyx_v__pmr1;
+  double __pyx_v__pmd1;
+  double __pyx_v__px1;
+  double __pyx_v__rv1;
+  double __pyx_v__ep1a;
+  double __pyx_v__ep1b;
+  double __pyx_v__ep2a;
+  double __pyx_v__ep2b;
+  double *__pyx_v__ra2;
+  double *__pyx_v__dec2;
+  double *__pyx_v__pmr2;
+  double *__pyx_v__pmd2;
+  double *__pyx_v__px2;
+  double *__pyx_v__rv2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_pmsafe", 0);
+
+  /* "astropy/_erfa/core.pyx":3024
+ *     cdef double * _rv2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3025
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3026
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3027
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3028
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3029
+ *     cdef int status = 1
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ra1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3030
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dec1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3031
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pmr1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3032
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pmd1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3033
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px1 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3034
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv1 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3035
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__ep1a = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3036
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__ep1b = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3037
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__ep2a = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3038
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__ep2b = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3039
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ */
+    __pyx_v__ra2 = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":3040
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ */
+    __pyx_v__dec2 = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":3041
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ */
+    __pyx_v__pmr2 = ((double *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":3042
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))             # <<<<<<<<<<<<<<
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__pmd2 = ((double *)(__pyx_v_dataptrarray[13]));
+
+    /* "astropy/_erfa/core.pyx":3043
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))             # <<<<<<<<<<<<<<
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ */
+    __pyx_v__px2 = ((double *)(__pyx_v_dataptrarray[14]));
+
+    /* "astropy/_erfa/core.pyx":3044
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ */
+    __pyx_v__rv2 = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":3045
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraPmsafe(__pyx_v__ra1, __pyx_v__dec1, __pyx_v__pmr1, __pyx_v__pmd1, __pyx_v__px1, __pyx_v__rv1, __pyx_v__ep1a, __pyx_v__ep1b, __pyx_v__ep2a, __pyx_v__ep2b, __pyx_v__ra2, __pyx_v__dec2, __pyx_v__pmr2, __pyx_v__pmd2, __pyx_v__px2, __pyx_v__rv2);
+
+    /* "astropy/_erfa/core.pyx":3046
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[16]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3047
+ *         _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3048
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3049
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3050
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3005
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._pmsafe", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3053
+ * 
+ * 
+ * def _pvstar(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pv
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_263_pvstar(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_263_pvstar = {"_pvstar", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_263_pvstar, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_263_pvstar(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pvstar (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_262_pvstar(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_262_pvstar(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__pv;
+  double *__pyx_v__ra;
+  double *__pyx_v__dec;
+  double *__pyx_v__pmr;
+  double *__pyx_v__pmd;
+  double *__pyx_v__px;
+  double *__pyx_v__rv;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_pvstar", 0);
+
+  /* "astropy/_erfa/core.pyx":3063
+ *     cdef double * _rv
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3064
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3065
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3066
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _pv = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3067
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[0]))
+ *         _ra = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3068
+ *     cdef int status = 1
+ *     while status:
+ *         _pv = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _ra = (<double *>(dataptrarray[1]))
+ *         _dec = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":3069
+ *     while status:
+ *         _pv = (<double *>(dataptrarray[0]))
+ *         _ra = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _dec = (<double *>(dataptrarray[2]))
+ *         _pmr = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__ra = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":3070
+ *         _pv = (<double *>(dataptrarray[0]))
+ *         _ra = (<double *>(dataptrarray[1]))
+ *         _dec = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _pmr = (<double *>(dataptrarray[3]))
+ *         _pmd = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dec = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3071
+ *         _ra = (<double *>(dataptrarray[1]))
+ *         _dec = (<double *>(dataptrarray[2]))
+ *         _pmr = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _pmd = (<double *>(dataptrarray[4]))
+ *         _px = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__pmr = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3072
+ *         _dec = (<double *>(dataptrarray[2]))
+ *         _pmr = (<double *>(dataptrarray[3]))
+ *         _pmd = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[5]))
+ *         _rv = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__pmd = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3073
+ *         _pmr = (<double *>(dataptrarray[3]))
+ *         _pmd = (<double *>(dataptrarray[4]))
+ *         _px = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)
+ */
+    __pyx_v__px = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3074
+ *         _pmd = (<double *>(dataptrarray[4]))
+ *         _px = (<double *>(dataptrarray[5]))
+ *         _rv = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ */
+    __pyx_v__rv = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3075
+ *         _px = (<double *>(dataptrarray[5]))
+ *         _rv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraPvstar(__pyx_v__pv, __pyx_v__ra, __pyx_v__dec, __pyx_v__pmr, __pyx_v__pmd, __pyx_v__px, __pyx_v__rv);
+
+    /* "astropy/_erfa/core.pyx":3076
+ *         _rv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[7]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3077
+ *         _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3078
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3079
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3080
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3053
+ * 
+ * 
+ * def _pvstar(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pv
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._pvstar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3083
+ * 
+ * 
+ * def _starpv(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_265_starpv(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_265_starpv = {"_starpv", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_265_starpv, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_265_starpv(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_starpv (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_264_starpv(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_264_starpv(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ra;
+  double __pyx_v__dec;
+  double __pyx_v__pmr;
+  double __pyx_v__pmd;
+  double __pyx_v__px;
+  double __pyx_v__rv;
+  double *__pyx_v__pv;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_starpv", 0);
+
+  /* "astropy/_erfa/core.pyx":3093
+ *     cdef double * _pv
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3094
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3095
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3096
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ra = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3097
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ra = (<double *>(dataptrarray[0]))[0]
+ *         _dec = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3098
+ *     cdef int status = 1
+ *     while status:
+ *         _ra = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dec = (<double *>(dataptrarray[1]))[0]
+ *         _pmr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ra = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3099
+ *     while status:
+ *         _ra = (<double *>(dataptrarray[0]))[0]
+ *         _dec = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pmr = (<double *>(dataptrarray[2]))[0]
+ *         _pmd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dec = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3100
+ *         _ra = (<double *>(dataptrarray[0]))[0]
+ *         _dec = (<double *>(dataptrarray[1]))[0]
+ *         _pmr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pmd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pmr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3101
+ *         _dec = (<double *>(dataptrarray[1]))[0]
+ *         _pmr = (<double *>(dataptrarray[2]))[0]
+ *         _pmd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pmd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3102
+ *         _pmr = (<double *>(dataptrarray[2]))[0]
+ *         _pmd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pv = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__px = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3103
+ *         _pmd = (<double *>(dataptrarray[3]))[0]
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)
+ */
+    __pyx_v__rv = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3104
+ *         _px = (<double *>(dataptrarray[4]))[0]
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pv = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3105
+ *         _rv = (<double *>(dataptrarray[5]))[0]
+ *         _pv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraStarpv(__pyx_v__ra, __pyx_v__dec, __pyx_v__pmr, __pyx_v__pmd, __pyx_v__px, __pyx_v__rv, __pyx_v__pv);
+
+    /* "astropy/_erfa/core.pyx":3106
+ *         _pv = (<double *>(dataptrarray[6]))
+ *         _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[7]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3107
+ *         _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3108
+ *         (<int *>(dataptrarray[7]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3109
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3110
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3083
+ * 
+ * 
+ * def _starpv(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._starpv", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3113
+ * 
+ * 
+ * def _fk52h(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_267_fk52h(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_267_fk52h = {"_fk52h", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_267_fk52h, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_267_fk52h(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fk52h (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_266_fk52h(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_266_fk52h(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__r5;
+  double __pyx_v__d5;
+  double __pyx_v__dr5;
+  double __pyx_v__dd5;
+  double __pyx_v__px5;
+  double __pyx_v__rv5;
+  double *__pyx_v__rh;
+  double *__pyx_v__dh;
+  double *__pyx_v__drh;
+  double *__pyx_v__ddh;
+  double *__pyx_v__pxh;
+  double *__pyx_v__rvh;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fk52h", 0);
+
+  /* "astropy/_erfa/core.pyx":3127
+ *     cdef double * _pxh
+ *     cdef double * _rvh
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3128
+ *     cdef double * _rvh
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3129
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3130
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3131
+ *     cdef int status = 1
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _dr5 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__r5 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3132
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dr5 = (<double *>(dataptrarray[2]))[0]
+ *         _dd5 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__d5 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3133
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _dr5 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _dd5 = (<double *>(dataptrarray[3]))[0]
+ *         _px5 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__dr5 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3134
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _dr5 = (<double *>(dataptrarray[2]))[0]
+ *         _dd5 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px5 = (<double *>(dataptrarray[4]))[0]
+ *         _rv5 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__dd5 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3135
+ *         _dr5 = (<double *>(dataptrarray[2]))[0]
+ *         _dd5 = (<double *>(dataptrarray[3]))[0]
+ *         _px5 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv5 = (<double *>(dataptrarray[5]))[0]
+ *         _rh = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__px5 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3136
+ *         _dd5 = (<double *>(dataptrarray[3]))[0]
+ *         _px5 = (<double *>(dataptrarray[4]))[0]
+ *         _rv5 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[6]))
+ *         _dh = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rv5 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3137
+ *         _px5 = (<double *>(dataptrarray[4]))[0]
+ *         _rv5 = (<double *>(dataptrarray[5]))[0]
+ *         _rh = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _dh = (<double *>(dataptrarray[7]))
+ *         _drh = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__rh = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3138
+ *         _rv5 = (<double *>(dataptrarray[5]))[0]
+ *         _rh = (<double *>(dataptrarray[6]))
+ *         _dh = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _drh = (<double *>(dataptrarray[8]))
+ *         _ddh = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__dh = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3139
+ *         _rh = (<double *>(dataptrarray[6]))
+ *         _dh = (<double *>(dataptrarray[7]))
+ *         _drh = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _ddh = (<double *>(dataptrarray[9]))
+ *         _pxh = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__drh = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":3140
+ *         _dh = (<double *>(dataptrarray[7]))
+ *         _drh = (<double *>(dataptrarray[8]))
+ *         _ddh = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         _pxh = (<double *>(dataptrarray[10]))
+ *         _rvh = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__ddh = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":3141
+ *         _drh = (<double *>(dataptrarray[8]))
+ *         _ddh = (<double *>(dataptrarray[9]))
+ *         _pxh = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _rvh = (<double *>(dataptrarray[11]))
+ *         eraFk52h(_r5, _d5, _dr5, _dd5, _px5, _rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh)
+ */
+    __pyx_v__pxh = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":3142
+ *         _ddh = (<double *>(dataptrarray[9]))
+ *         _pxh = (<double *>(dataptrarray[10]))
+ *         _rvh = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         eraFk52h(_r5, _d5, _dr5, _dd5, _px5, _rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rvh = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":3143
+ *         _pxh = (<double *>(dataptrarray[10]))
+ *         _rvh = (<double *>(dataptrarray[11]))
+ *         eraFk52h(_r5, _d5, _dr5, _dd5, _px5, _rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraFk52h(__pyx_v__r5, __pyx_v__d5, __pyx_v__dr5, __pyx_v__dd5, __pyx_v__px5, __pyx_v__rv5, __pyx_v__rh, __pyx_v__dh, __pyx_v__drh, __pyx_v__ddh, __pyx_v__pxh, __pyx_v__rvh);
+
+    /* "astropy/_erfa/core.pyx":3144
+ *         _rvh = (<double *>(dataptrarray[11]))
+ *         eraFk52h(_r5, _d5, _dr5, _dd5, _px5, _rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3113
+ * 
+ * 
+ * def _fk52h(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3147
+ * 
+ * 
+ * def _fk5hip(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _r5h
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_269_fk5hip(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_269_fk5hip = {"_fk5hip", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_269_fk5hip, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_269_fk5hip(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fk5hip (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_268_fk5hip(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_268_fk5hip(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double *__pyx_v__r5h;
+  double *__pyx_v__s5h;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fk5hip", 0);
+
+  /* "astropy/_erfa/core.pyx":3151
+ *     cdef double * _r5h
+ *     cdef double * _s5h
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3152
+ *     cdef double * _s5h
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3153
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _r5h = (<double *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3154
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _r5h = (<double *>(dataptrarray[0]))
+ *         _s5h = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3155
+ *     cdef int status = 1
+ *     while status:
+ *         _r5h = (<double *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _s5h = (<double *>(dataptrarray[1]))
+ *         eraFk5hip(_r5h, _s5h)
+ */
+    __pyx_v__r5h = ((double *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":3156
+ *     while status:
+ *         _r5h = (<double *>(dataptrarray[0]))
+ *         _s5h = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         eraFk5hip(_r5h, _s5h)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__s5h = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":3157
+ *         _r5h = (<double *>(dataptrarray[0]))
+ *         _s5h = (<double *>(dataptrarray[1]))
+ *         eraFk5hip(_r5h, _s5h)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraFk5hip(__pyx_v__r5h, __pyx_v__s5h);
+
+    /* "astropy/_erfa/core.pyx":3158
+ *         _s5h = (<double *>(dataptrarray[1]))
+ *         eraFk5hip(_r5h, _s5h)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3147
+ * 
+ * 
+ * def _fk5hip(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _r5h
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3161
+ * 
+ * 
+ * def _fk5hz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_271_fk5hz(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_271_fk5hz = {"_fk5hz", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_271_fk5hz, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_271_fk5hz(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fk5hz (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_270_fk5hz(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_270_fk5hz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__r5;
+  double __pyx_v__d5;
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__rh;
+  double *__pyx_v__dh;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_fk5hz", 0);
+
+  /* "astropy/_erfa/core.pyx":3169
+ *     cdef double * _rh
+ *     cdef double * _dh
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3170
+ *     cdef double * _dh
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3171
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3172
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3173
+ *     cdef int status = 1
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__r5 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3174
+ *     while status:
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__d5 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3175
+ *         _r5 = (<double *>(dataptrarray[0]))[0]
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rh = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3176
+ *         _d5 = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[4]))
+ *         _dh = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3177
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rh = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _dh = (<double *>(dataptrarray[5]))
+ *         eraFk5hz(_r5, _d5, _date1, _date2, _rh, _dh)
+ */
+    __pyx_v__rh = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3178
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _rh = (<double *>(dataptrarray[4]))
+ *         _dh = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         eraFk5hz(_r5, _d5, _date1, _date2, _rh, _dh)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__dh = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3179
+ *         _rh = (<double *>(dataptrarray[4]))
+ *         _dh = (<double *>(dataptrarray[5]))
+ *         eraFk5hz(_r5, _d5, _date1, _date2, _rh, _dh)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraFk5hz(__pyx_v__r5, __pyx_v__d5, __pyx_v__date1, __pyx_v__date2, __pyx_v__rh, __pyx_v__dh);
+
+    /* "astropy/_erfa/core.pyx":3180
+ *         _dh = (<double *>(dataptrarray[5]))
+ *         eraFk5hz(_r5, _d5, _date1, _date2, _rh, _dh)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3161
+ * 
+ * 
+ * def _fk5hz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3183
+ * 
+ * 
+ * def _h2fk5(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_273_h2fk5(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_273_h2fk5 = {"_h2fk5", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_273_h2fk5, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_273_h2fk5(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_h2fk5 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_272_h2fk5(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_272_h2fk5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rh;
+  double __pyx_v__dh;
+  double __pyx_v__drh;
+  double __pyx_v__ddh;
+  double __pyx_v__pxh;
+  double __pyx_v__rvh;
+  double *__pyx_v__r5;
+  double *__pyx_v__d5;
+  double *__pyx_v__dr5;
+  double *__pyx_v__dd5;
+  double *__pyx_v__px5;
+  double *__pyx_v__rv5;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_h2fk5", 0);
+
+  /* "astropy/_erfa/core.pyx":3197
+ *     cdef double * _px5
+ *     cdef double * _rv5
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3198
+ *     cdef double * _rv5
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3199
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3200
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3201
+ *     cdef int status = 1
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _drh = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3202
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _drh = (<double *>(dataptrarray[2]))[0]
+ *         _ddh = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dh = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3203
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _drh = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ddh = (<double *>(dataptrarray[3]))[0]
+ *         _pxh = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__drh = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3204
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _drh = (<double *>(dataptrarray[2]))[0]
+ *         _ddh = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _pxh = (<double *>(dataptrarray[4]))[0]
+ *         _rvh = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__ddh = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3205
+ *         _drh = (<double *>(dataptrarray[2]))[0]
+ *         _ddh = (<double *>(dataptrarray[3]))[0]
+ *         _pxh = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rvh = (<double *>(dataptrarray[5]))[0]
+ *         _r5 = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__pxh = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3206
+ *         _ddh = (<double *>(dataptrarray[3]))[0]
+ *         _pxh = (<double *>(dataptrarray[4]))[0]
+ *         _rvh = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _r5 = (<double *>(dataptrarray[6]))
+ *         _d5 = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__rvh = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3207
+ *         _pxh = (<double *>(dataptrarray[4]))[0]
+ *         _rvh = (<double *>(dataptrarray[5]))[0]
+ *         _r5 = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _d5 = (<double *>(dataptrarray[7]))
+ *         _dr5 = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__r5 = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3208
+ *         _rvh = (<double *>(dataptrarray[5]))[0]
+ *         _r5 = (<double *>(dataptrarray[6]))
+ *         _d5 = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _dr5 = (<double *>(dataptrarray[8]))
+ *         _dd5 = (<double *>(dataptrarray[9]))
+ */
+    __pyx_v__d5 = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3209
+ *         _r5 = (<double *>(dataptrarray[6]))
+ *         _d5 = (<double *>(dataptrarray[7]))
+ *         _dr5 = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _dd5 = (<double *>(dataptrarray[9]))
+ *         _px5 = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__dr5 = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":3210
+ *         _d5 = (<double *>(dataptrarray[7]))
+ *         _dr5 = (<double *>(dataptrarray[8]))
+ *         _dd5 = (<double *>(dataptrarray[9]))             # <<<<<<<<<<<<<<
+ *         _px5 = (<double *>(dataptrarray[10]))
+ *         _rv5 = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__dd5 = ((double *)(__pyx_v_dataptrarray[9]));
+
+    /* "astropy/_erfa/core.pyx":3211
+ *         _dr5 = (<double *>(dataptrarray[8]))
+ *         _dd5 = (<double *>(dataptrarray[9]))
+ *         _px5 = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _rv5 = (<double *>(dataptrarray[11]))
+ *         eraH2fk5(_rh, _dh, _drh, _ddh, _pxh, _rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5)
+ */
+    __pyx_v__px5 = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":3212
+ *         _dd5 = (<double *>(dataptrarray[9]))
+ *         _px5 = (<double *>(dataptrarray[10]))
+ *         _rv5 = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         eraH2fk5(_rh, _dh, _drh, _ddh, _pxh, _rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__rv5 = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":3213
+ *         _px5 = (<double *>(dataptrarray[10]))
+ *         _rv5 = (<double *>(dataptrarray[11]))
+ *         eraH2fk5(_rh, _dh, _drh, _ddh, _pxh, _rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraH2fk5(__pyx_v__rh, __pyx_v__dh, __pyx_v__drh, __pyx_v__ddh, __pyx_v__pxh, __pyx_v__rvh, __pyx_v__r5, __pyx_v__d5, __pyx_v__dr5, __pyx_v__dd5, __pyx_v__px5, __pyx_v__rv5);
+
+    /* "astropy/_erfa/core.pyx":3214
+ *         _rv5 = (<double *>(dataptrarray[11]))
+ *         eraH2fk5(_rh, _dh, _drh, _ddh, _pxh, _rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3183
+ * 
+ * 
+ * def _h2fk5(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3217
+ * 
+ * 
+ * def _hfk5z(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_275_hfk5z(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_275_hfk5z = {"_hfk5z", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_275_hfk5z, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_275_hfk5z(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_hfk5z (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_274_hfk5z(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_274_hfk5z(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__rh;
+  double __pyx_v__dh;
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double *__pyx_v__r5;
+  double *__pyx_v__d5;
+  double *__pyx_v__dr5;
+  double *__pyx_v__dd5;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_hfk5z", 0);
+
+  /* "astropy/_erfa/core.pyx":3227
+ *     cdef double * _dr5
+ *     cdef double * _dd5
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3228
+ *     cdef double * _dd5
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3229
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3230
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3231
+ *     cdef int status = 1
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__rh = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3232
+ *     while status:
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dh = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3233
+ *         _rh = (<double *>(dataptrarray[0]))[0]
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _r5 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3234
+ *         _dh = (<double *>(dataptrarray[1]))[0]
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _r5 = (<double *>(dataptrarray[4]))
+ *         _d5 = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3235
+ *         _date1 = (<double *>(dataptrarray[2]))[0]
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _r5 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _d5 = (<double *>(dataptrarray[5]))
+ *         _dr5 = (<double *>(dataptrarray[6]))
+ */
+    __pyx_v__r5 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3236
+ *         _date2 = (<double *>(dataptrarray[3]))[0]
+ *         _r5 = (<double *>(dataptrarray[4]))
+ *         _d5 = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _dr5 = (<double *>(dataptrarray[6]))
+ *         _dd5 = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__d5 = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3237
+ *         _r5 = (<double *>(dataptrarray[4]))
+ *         _d5 = (<double *>(dataptrarray[5]))
+ *         _dr5 = (<double *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _dd5 = (<double *>(dataptrarray[7]))
+ *         eraHfk5z(_rh, _dh, _date1, _date2, _r5, _d5, _dr5, _dd5)
+ */
+    __pyx_v__dr5 = ((double *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3238
+ *         _d5 = (<double *>(dataptrarray[5]))
+ *         _dr5 = (<double *>(dataptrarray[6]))
+ *         _dd5 = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         eraHfk5z(_rh, _dh, _date1, _date2, _r5, _d5, _dr5, _dd5)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__dd5 = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3239
+ *         _dr5 = (<double *>(dataptrarray[6]))
+ *         _dd5 = (<double *>(dataptrarray[7]))
+ *         eraHfk5z(_rh, _dh, _date1, _date2, _r5, _d5, _dr5, _dd5)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraHfk5z(__pyx_v__rh, __pyx_v__dh, __pyx_v__date1, __pyx_v__date2, __pyx_v__r5, __pyx_v__d5, __pyx_v__dr5, __pyx_v__dd5);
+
+    /* "astropy/_erfa/core.pyx":3240
+ *         _dd5 = (<double *>(dataptrarray[7]))
+ *         eraHfk5z(_rh, _dh, _date1, _date2, _r5, _d5, _dr5, _dd5)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3217
+ * 
+ * 
+ * def _hfk5z(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3243
+ * 
+ * 
+ * def _starpm(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_277_starpm(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_277_starpm = {"_starpm", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_277_starpm, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_277_starpm(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_starpm (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_276_starpm(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_276_starpm(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ra1;
+  double __pyx_v__dec1;
+  double __pyx_v__pmr1;
+  double __pyx_v__pmd1;
+  double __pyx_v__px1;
+  double __pyx_v__rv1;
+  double __pyx_v__ep1a;
+  double __pyx_v__ep1b;
+  double __pyx_v__ep2a;
+  double __pyx_v__ep2b;
+  double *__pyx_v__ra2;
+  double *__pyx_v__dec2;
+  double *__pyx_v__pmr2;
+  double *__pyx_v__pmd2;
+  double *__pyx_v__px2;
+  double *__pyx_v__rv2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_starpm", 0);
+
+  /* "astropy/_erfa/core.pyx":3262
+ *     cdef double * _rv2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3263
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3264
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3265
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3266
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3267
+ *     cdef int status = 1
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ra1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3268
+ *     while status:
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__dec1 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3269
+ *         _ra1 = (<double *>(dataptrarray[0]))[0]
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__pmr1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3270
+ *         _dec1 = (<double *>(dataptrarray[1]))[0]
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__pmd1 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3271
+ *         _pmr1 = (<double *>(dataptrarray[2]))[0]
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__px1 = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3272
+ *         _pmd1 = (<double *>(dataptrarray[3]))[0]
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ */
+    __pyx_v__rv1 = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3273
+ *         _px1 = (<double *>(dataptrarray[4]))[0]
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ */
+    __pyx_v__ep1a = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3274
+ *         _rv1 = (<double *>(dataptrarray[5]))[0]
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ */
+    __pyx_v__ep1b = (((double *)(__pyx_v_dataptrarray[7]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3275
+ *         _ep1a = (<double *>(dataptrarray[6]))[0]
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]             # <<<<<<<<<<<<<<
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ */
+    __pyx_v__ep2a = (((double *)(__pyx_v_dataptrarray[8]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3276
+ *         _ep1b = (<double *>(dataptrarray[7]))[0]
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]             # <<<<<<<<<<<<<<
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ */
+    __pyx_v__ep2b = (((double *)(__pyx_v_dataptrarray[9]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3277
+ *         _ep2a = (<double *>(dataptrarray[8]))[0]
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))             # <<<<<<<<<<<<<<
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ */
+    __pyx_v__ra2 = ((double *)(__pyx_v_dataptrarray[10]));
+
+    /* "astropy/_erfa/core.pyx":3278
+ *         _ep2b = (<double *>(dataptrarray[9]))[0]
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))             # <<<<<<<<<<<<<<
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ */
+    __pyx_v__dec2 = ((double *)(__pyx_v_dataptrarray[11]));
+
+    /* "astropy/_erfa/core.pyx":3279
+ *         _ra2 = (<double *>(dataptrarray[10]))
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))             # <<<<<<<<<<<<<<
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ */
+    __pyx_v__pmr2 = ((double *)(__pyx_v_dataptrarray[12]));
+
+    /* "astropy/_erfa/core.pyx":3280
+ *         _dec2 = (<double *>(dataptrarray[11]))
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))             # <<<<<<<<<<<<<<
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ */
+    __pyx_v__pmd2 = ((double *)(__pyx_v_dataptrarray[13]));
+
+    /* "astropy/_erfa/core.pyx":3281
+ *         _pmr2 = (<double *>(dataptrarray[12]))
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))             # <<<<<<<<<<<<<<
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ */
+    __pyx_v__px2 = ((double *)(__pyx_v_dataptrarray[14]));
+
+    /* "astropy/_erfa/core.pyx":3282
+ *         _pmd2 = (<double *>(dataptrarray[13]))
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ */
+    __pyx_v__rv2 = ((double *)(__pyx_v_dataptrarray[15]));
+
+    /* "astropy/_erfa/core.pyx":3283
+ *         _px2 = (<double *>(dataptrarray[14]))
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraStarpm(__pyx_v__ra1, __pyx_v__dec1, __pyx_v__pmr1, __pyx_v__pmd1, __pyx_v__px1, __pyx_v__rv1, __pyx_v__ep1a, __pyx_v__ep1b, __pyx_v__ep2a, __pyx_v__ep2b, __pyx_v__ra2, __pyx_v__dec2, __pyx_v__pmr2, __pyx_v__pmd2, __pyx_v__px2, __pyx_v__rv2);
+
+    /* "astropy/_erfa/core.pyx":3284
+ *         _rv2 = (<double *>(dataptrarray[15]))
+ *         _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[16]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3285
+ *         _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3286
+ *         (<int *>(dataptrarray[16]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3287
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3288
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3243
+ * 
+ * 
+ * def _starpm(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._starpm", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3291
+ * 
+ * 
+ * def _eform(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_279_eform(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_279_eform = {"_eform", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_279_eform, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_279_eform(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_eform (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_278_eform(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_278_eform(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__n;
+  double *__pyx_v__a;
+  double *__pyx_v__f;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_eform", 0);
+
+  /* "astropy/_erfa/core.pyx":3297
+ *     cdef double * _f
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3298
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3299
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3300
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3301
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _a = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3302
+ *     cdef int status = 1
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _a = (<double *>(dataptrarray[1]))
+ *         _f = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3303
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _a = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _f = (<double *>(dataptrarray[2]))
+ *         _c_retval = eraEform(_n, _a, _f)
+ */
+    __pyx_v__a = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":3304
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _a = (<double *>(dataptrarray[1]))
+ *         _f = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraEform(_n, _a, _f)
+ *         (<int *>(dataptrarray[3]))[0] = _c_retval
+ */
+    __pyx_v__f = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3305
+ *         _a = (<double *>(dataptrarray[1]))
+ *         _f = (<double *>(dataptrarray[2]))
+ *         _c_retval = eraEform(_n, _a, _f)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[3]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraEform(__pyx_v__n, __pyx_v__a, __pyx_v__f);
+
+    /* "astropy/_erfa/core.pyx":3306
+ *         _f = (<double *>(dataptrarray[2]))
+ *         _c_retval = eraEform(_n, _a, _f)
+ *         (<int *>(dataptrarray[3]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[3]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3307
+ *         _c_retval = eraEform(_n, _a, _f)
+ *         (<int *>(dataptrarray[3]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3308
+ *         (<int *>(dataptrarray[3]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3309
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3310
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3291
+ * 
+ * 
+ * def _eform(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._eform", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3313
+ * 
+ * 
+ * def _gc2gd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_281_gc2gd(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_281_gc2gd = {"_gc2gd", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_281_gc2gd, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_281_gc2gd(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gc2gd (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_280_gc2gd(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_280_gc2gd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__n;
+  double *__pyx_v__xyz;
+  double *__pyx_v__elong;
+  double *__pyx_v__phi;
+  double *__pyx_v__height;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_gc2gd", 0);
+
+  /* "astropy/_erfa/core.pyx":3321
+ *     cdef double * _height
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3322
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3323
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3324
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3325
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _xyz = (<double *>(dataptrarray[1]))
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3326
+ *     cdef int status = 1
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _xyz = (<double *>(dataptrarray[1]))
+ *         _elong = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3327
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _xyz = (<double *>(dataptrarray[1]))             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[2]))
+ *         _phi = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__xyz = ((double *)(__pyx_v_dataptrarray[1]));
+
+    /* "astropy/_erfa/core.pyx":3328
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _xyz = (<double *>(dataptrarray[1]))
+ *         _elong = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[3]))
+ *         _height = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__elong = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3329
+ *         _xyz = (<double *>(dataptrarray[1]))
+ *         _elong = (<double *>(dataptrarray[2]))
+ *         _phi = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _height = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)
+ */
+    __pyx_v__phi = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3330
+ *         _elong = (<double *>(dataptrarray[2]))
+ *         _phi = (<double *>(dataptrarray[3]))
+ *         _height = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__height = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3331
+ *         _phi = (<double *>(dataptrarray[3]))
+ *         _height = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraGc2gd(__pyx_v__n, __pyx_v__xyz, __pyx_v__elong, __pyx_v__phi, __pyx_v__height);
+
+    /* "astropy/_erfa/core.pyx":3332
+ *         _height = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3333
+ *         _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3334
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3335
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3336
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3313
+ * 
+ * 
+ * def _gc2gd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._gc2gd", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3339
+ * 
+ * 
+ * def _gc2gde(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_283_gc2gde(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_283_gc2gde = {"_gc2gde", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_283_gc2gde, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_283_gc2gde(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gc2gde (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_282_gc2gde(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_282_gc2gde(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__a;
+  double __pyx_v__f;
+  double *__pyx_v__xyz;
+  double *__pyx_v__elong;
+  double *__pyx_v__phi;
+  double *__pyx_v__height;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_gc2gde", 0);
+
+  /* "astropy/_erfa/core.pyx":3348
+ *     cdef double * _height
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3349
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3350
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3351
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3352
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3353
+ *     cdef int status = 1
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _xyz = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__a = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3354
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _xyz = (<double *>(dataptrarray[2]))
+ *         _elong = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__f = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3355
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _xyz = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[3]))
+ *         _phi = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__xyz = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3356
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _xyz = (<double *>(dataptrarray[2]))
+ *         _elong = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[4]))
+ *         _height = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__elong = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3357
+ *         _xyz = (<double *>(dataptrarray[2]))
+ *         _elong = (<double *>(dataptrarray[3]))
+ *         _phi = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _height = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)
+ */
+    __pyx_v__phi = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3358
+ *         _elong = (<double *>(dataptrarray[3]))
+ *         _phi = (<double *>(dataptrarray[4]))
+ *         _height = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ */
+    __pyx_v__height = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3359
+ *         _phi = (<double *>(dataptrarray[4]))
+ *         _height = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraGc2gde(__pyx_v__a, __pyx_v__f, __pyx_v__xyz, __pyx_v__elong, __pyx_v__phi, __pyx_v__height);
+
+    /* "astropy/_erfa/core.pyx":3360
+ *         _height = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[6]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3361
+ *         _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3362
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3363
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3364
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3339
+ * 
+ * 
+ * def _gc2gde(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._gc2gde", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3367
+ * 
+ * 
+ * def _gd2gc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_285_gd2gc(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_285_gd2gc = {"_gd2gc", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_285_gd2gc, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_285_gd2gc(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gd2gc (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_284_gd2gc(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_284_gd2gc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__n;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__height;
+  double *__pyx_v__xyz;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_gd2gc", 0);
+
+  /* "astropy/_erfa/core.pyx":3375
+ *     cdef double * _xyz
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3376
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3377
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3378
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3379
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _elong = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3380
+ *     cdef int status = 1
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[1]))[0]
+ *         _phi = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__n = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3381
+ *     while status:
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _elong = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[2]))[0]
+ *         _height = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3382
+ *         _n = (<int *>(dataptrarray[0]))[0]
+ *         _elong = (<double *>(dataptrarray[1]))[0]
+ *         _phi = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _height = (<double *>(dataptrarray[3]))[0]
+ *         _xyz = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3383
+ *         _elong = (<double *>(dataptrarray[1]))[0]
+ *         _phi = (<double *>(dataptrarray[2]))[0]
+ *         _height = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _xyz = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)
+ */
+    __pyx_v__height = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3384
+ *         _phi = (<double *>(dataptrarray[2]))[0]
+ *         _height = (<double *>(dataptrarray[3]))[0]
+ *         _xyz = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__xyz = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3385
+ *         _height = (<double *>(dataptrarray[3]))[0]
+ *         _xyz = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraGd2gc(__pyx_v__n, __pyx_v__elong, __pyx_v__phi, __pyx_v__height, __pyx_v__xyz);
+
+    /* "astropy/_erfa/core.pyx":3386
+ *         _xyz = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3387
+ *         _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3388
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3389
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3390
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3367
+ * 
+ * 
+ * def _gd2gc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._gd2gc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3393
+ * 
+ * 
+ * def _gd2gce(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_287_gd2gce(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_287_gd2gce = {"_gd2gce", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_287_gd2gce, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_287_gd2gce(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_gd2gce (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_286_gd2gce(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_286_gd2gce(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__a;
+  double __pyx_v__f;
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__height;
+  double *__pyx_v__xyz;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_gd2gce", 0);
+
+  /* "astropy/_erfa/core.pyx":3402
+ *     cdef double * _xyz
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3403
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3404
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3405
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3406
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3407
+ *     cdef int status = 1
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__a = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3408
+ *     while status:
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__f = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3409
+ *         _a = (<double *>(dataptrarray[0]))[0]
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _height = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3410
+ *         _f = (<double *>(dataptrarray[1]))[0]
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _height = (<double *>(dataptrarray[4]))[0]
+ *         _xyz = (<double *>(dataptrarray[5]))
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3411
+ *         _elong = (<double *>(dataptrarray[2]))[0]
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _height = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _xyz = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)
+ */
+    __pyx_v__height = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3412
+ *         _phi = (<double *>(dataptrarray[3]))[0]
+ *         _height = (<double *>(dataptrarray[4]))[0]
+ *         _xyz = (<double *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ */
+    __pyx_v__xyz = ((double *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3413
+ *         _height = (<double *>(dataptrarray[4]))[0]
+ *         _xyz = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraGd2gce(__pyx_v__a, __pyx_v__f, __pyx_v__elong, __pyx_v__phi, __pyx_v__height, __pyx_v__xyz);
+
+    /* "astropy/_erfa/core.pyx":3414
+ *         _xyz = (<double *>(dataptrarray[5]))
+ *         _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[6]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3415
+ *         _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3416
+ *         (<int *>(dataptrarray[6]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3417
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3418
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3393
+ * 
+ * 
+ * def _gd2gce(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._gd2gce", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3421
+ * 
+ * 
+ * def _pvtob(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _elong
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_289_pvtob(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_289_pvtob = {"_pvtob", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_289_pvtob, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_289_pvtob(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_pvtob (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_288_pvtob(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_288_pvtob(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__elong;
+  double __pyx_v__phi;
+  double __pyx_v__hm;
+  double __pyx_v__xp;
+  double __pyx_v__yp;
+  double __pyx_v__sp;
+  double __pyx_v__theta;
+  double *__pyx_v__pv;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_pvtob", 0);
+
+  /* "astropy/_erfa/core.pyx":3431
+ *     cdef double _theta
+ *     cdef double * _pv
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3432
+ *     cdef double * _pv
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3433
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _elong = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3434
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[0]))[0]
+ *         _phi = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3435
+ *     cdef int status = 1
+ *     while status:
+ *         _elong = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _phi = (<double *>(dataptrarray[1]))[0]
+ *         _hm = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3436
+ *     while status:
+ *         _elong = (<double *>(dataptrarray[0]))[0]
+ *         _phi = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _hm = (<double *>(dataptrarray[2]))[0]
+ *         _xp = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__phi = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3437
+ *         _elong = (<double *>(dataptrarray[0]))[0]
+ *         _phi = (<double *>(dataptrarray[1]))[0]
+ *         _hm = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _xp = (<double *>(dataptrarray[3]))[0]
+ *         _yp = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__hm = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3438
+ *         _phi = (<double *>(dataptrarray[1]))[0]
+ *         _hm = (<double *>(dataptrarray[2]))[0]
+ *         _xp = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _yp = (<double *>(dataptrarray[4]))[0]
+ *         _sp = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__xp = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3439
+ *         _hm = (<double *>(dataptrarray[2]))[0]
+ *         _xp = (<double *>(dataptrarray[3]))[0]
+ *         _yp = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _sp = (<double *>(dataptrarray[5]))[0]
+ *         _theta = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__yp = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3440
+ *         _xp = (<double *>(dataptrarray[3]))[0]
+ *         _yp = (<double *>(dataptrarray[4]))[0]
+ *         _sp = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _theta = (<double *>(dataptrarray[6]))[0]
+ *         _pv = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__sp = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3441
+ *         _yp = (<double *>(dataptrarray[4]))[0]
+ *         _sp = (<double *>(dataptrarray[5]))[0]
+ *         _theta = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _pv = (<double *>(dataptrarray[7]))
+ *         eraPvtob(_elong, _phi, _hm, _xp, _yp, _sp, _theta, _pv)
+ */
+    __pyx_v__theta = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3442
+ *         _sp = (<double *>(dataptrarray[5]))[0]
+ *         _theta = (<double *>(dataptrarray[6]))[0]
+ *         _pv = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         eraPvtob(_elong, _phi, _hm, _xp, _yp, _sp, _theta, _pv)
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__pv = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3443
+ *         _theta = (<double *>(dataptrarray[6]))[0]
+ *         _pv = (<double *>(dataptrarray[7]))
+ *         eraPvtob(_elong, _phi, _hm, _xp, _yp, _sp, _theta, _pv)             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    eraPvtob(__pyx_v__elong, __pyx_v__phi, __pyx_v__hm, __pyx_v__xp, __pyx_v__yp, __pyx_v__sp, __pyx_v__theta, __pyx_v__pv);
+
+    /* "astropy/_erfa/core.pyx":3444
+ *         _pv = (<double *>(dataptrarray[7]))
+ *         eraPvtob(_elong, _phi, _hm, _xp, _yp, _sp, _theta, _pv)
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3421
+ * 
+ * 
+ * def _pvtob(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _elong
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3447
+ * 
+ * 
+ * def _d2dtf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_291_d2dtf(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_291_d2dtf = {"_d2dtf", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_291_d2dtf, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_291_d2dtf(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_d2dtf (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_290_d2dtf(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_290_d2dtf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  char const *__pyx_v__scale;
+  int __pyx_v__ndp;
+  double __pyx_v__d1;
+  double __pyx_v__d2;
+  int *__pyx_v__iy;
+  int *__pyx_v__im;
+  int *__pyx_v__id;
+  int *__pyx_v__ihmsf;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_d2dtf", 0);
+
+  /* "astropy/_erfa/core.pyx":3458
+ *     cdef int * _ihmsf
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3459
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3460
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3461
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3462
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _ndp = (<int *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3463
+ *     cdef int status = 1
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _ndp = (<int *>(dataptrarray[1]))[0]
+ *         _d1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__scale = ((char const *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":3464
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _ndp = (<int *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _d1 = (<double *>(dataptrarray[2]))[0]
+ *         _d2 = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__ndp = (((int *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3465
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _ndp = (<int *>(dataptrarray[1]))[0]
+ *         _d1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _d2 = (<double *>(dataptrarray[3]))[0]
+ *         _iy = (<int *>(dataptrarray[4]))
+ */
+    __pyx_v__d1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3466
+ *         _ndp = (<int *>(dataptrarray[1]))[0]
+ *         _d1 = (<double *>(dataptrarray[2]))[0]
+ *         _d2 = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _iy = (<int *>(dataptrarray[4]))
+ *         _im = (<int *>(dataptrarray[5]))
+ */
+    __pyx_v__d2 = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3467
+ *         _d1 = (<double *>(dataptrarray[2]))[0]
+ *         _d2 = (<double *>(dataptrarray[3]))[0]
+ *         _iy = (<int *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _im = (<int *>(dataptrarray[5]))
+ *         _id = (<int *>(dataptrarray[6]))
+ */
+    __pyx_v__iy = ((int *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3468
+ *         _d2 = (<double *>(dataptrarray[3]))[0]
+ *         _iy = (<int *>(dataptrarray[4]))
+ *         _im = (<int *>(dataptrarray[5]))             # <<<<<<<<<<<<<<
+ *         _id = (<int *>(dataptrarray[6]))
+ *         _ihmsf = (<int *>(dataptrarray[7]))
+ */
+    __pyx_v__im = ((int *)(__pyx_v_dataptrarray[5]));
+
+    /* "astropy/_erfa/core.pyx":3469
+ *         _iy = (<int *>(dataptrarray[4]))
+ *         _im = (<int *>(dataptrarray[5]))
+ *         _id = (<int *>(dataptrarray[6]))             # <<<<<<<<<<<<<<
+ *         _ihmsf = (<int *>(dataptrarray[7]))
+ *         _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)
+ */
+    __pyx_v__id = ((int *)(__pyx_v_dataptrarray[6]));
+
+    /* "astropy/_erfa/core.pyx":3470
+ *         _im = (<int *>(dataptrarray[5]))
+ *         _id = (<int *>(dataptrarray[6]))
+ *         _ihmsf = (<int *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)
+ *         (<int *>(dataptrarray[8]))[0] = _c_retval
+ */
+    __pyx_v__ihmsf = ((int *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3471
+ *         _id = (<int *>(dataptrarray[6]))
+ *         _ihmsf = (<int *>(dataptrarray[7]))
+ *         _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[8]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraD2dtf(__pyx_v__scale, __pyx_v__ndp, __pyx_v__d1, __pyx_v__d2, __pyx_v__iy, __pyx_v__im, __pyx_v__id, __pyx_v__ihmsf);
+
+    /* "astropy/_erfa/core.pyx":3472
+ *         _ihmsf = (<int *>(dataptrarray[7]))
+ *         _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)
+ *         (<int *>(dataptrarray[8]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[8]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3473
+ *         _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)
+ *         (<int *>(dataptrarray[8]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3474
+ *         (<int *>(dataptrarray[8]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3475
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3476
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3447
+ * 
+ * 
+ * def _d2dtf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._d2dtf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3479
+ * 
+ * 
+ * def _dat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_293_dat(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_293_dat = {"_dat", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_293_dat, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_293_dat(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_dat (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_292_dat(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_292_dat(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  int __pyx_v__iy;
+  int __pyx_v__im;
+  int __pyx_v__id;
+  double __pyx_v__fd;
+  double *__pyx_v__deltat;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_dat", 0);
+
+  /* "astropy/_erfa/core.pyx":3487
+ *     cdef double * _deltat
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3488
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3489
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3490
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3491
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3492
+ *     cdef int status = 1
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__iy = (((int *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3493
+ *     while status:
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _fd = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__im = (((int *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3494
+ *         _iy = (<int *>(dataptrarray[0]))[0]
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _fd = (<double *>(dataptrarray[3]))[0]
+ *         _deltat = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__id = (((int *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3495
+ *         _im = (<int *>(dataptrarray[1]))[0]
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _fd = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _deltat = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)
+ */
+    __pyx_v__fd = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3496
+ *         _id = (<int *>(dataptrarray[2]))[0]
+ *         _fd = (<double *>(dataptrarray[3]))[0]
+ *         _deltat = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__deltat = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3497
+ *         _fd = (<double *>(dataptrarray[3]))[0]
+ *         _deltat = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraDat(__pyx_v__iy, __pyx_v__im, __pyx_v__id, __pyx_v__fd, __pyx_v__deltat);
+
+    /* "astropy/_erfa/core.pyx":3498
+ *         _deltat = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3499
+ *         _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3500
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3501
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3502
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3479
+ * 
+ * 
+ * def _dat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._dat", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3505
+ * 
+ * 
+ * def _dtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_295_dtdb(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_295_dtdb = {"_dtdb", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_295_dtdb, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_295_dtdb(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_dtdb (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_294_dtdb(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_294_dtdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__date1;
+  double __pyx_v__date2;
+  double __pyx_v__ut;
+  double __pyx_v__elong;
+  double __pyx_v__u;
+  double __pyx_v__v;
+  double __pyx_v__c_retval;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_dtdb", 0);
+
+  /* "astropy/_erfa/core.pyx":3514
+ *     cdef double _v
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3515
+ *     cdef double _c_retval
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3516
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3517
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3518
+ *     cdef int status = 1
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ut = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__date1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3519
+ *     while status:
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _ut = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__date2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3520
+ *         _date1 = (<double *>(dataptrarray[0]))[0]
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ut = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _u = (<double *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__ut = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3521
+ *         _date2 = (<double *>(dataptrarray[1]))[0]
+ *         _ut = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _u = (<double *>(dataptrarray[4]))[0]
+ *         _v = (<double *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__elong = (((double *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3522
+ *         _ut = (<double *>(dataptrarray[2]))[0]
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _u = (<double *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _v = (<double *>(dataptrarray[5]))[0]
+ *         _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)
+ */
+    __pyx_v__u = (((double *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3523
+ *         _elong = (<double *>(dataptrarray[3]))[0]
+ *         _u = (<double *>(dataptrarray[4]))[0]
+ *         _v = (<double *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)
+ *         (<double *>(dataptrarray[6]))[0] = _c_retval
+ */
+    __pyx_v__v = (((double *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3524
+ *         _u = (<double *>(dataptrarray[4]))[0]
+ *         _v = (<double *>(dataptrarray[5]))[0]
+ *         _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)             # <<<<<<<<<<<<<<
+ *         (<double *>(dataptrarray[6]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_v__c_retval = eraDtdb(__pyx_v__date1, __pyx_v__date2, __pyx_v__ut, __pyx_v__elong, __pyx_v__u, __pyx_v__v);
+
+    /* "astropy/_erfa/core.pyx":3525
+ *         _v = (<double *>(dataptrarray[5]))[0]
+ *         _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)
+ *         (<double *>(dataptrarray[6]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ * 
+ */
+    (((double *)(__pyx_v_dataptrarray[6]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3526
+ *         _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)
+ *         (<double *>(dataptrarray[6]))[0] = _c_retval
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3505
+ * 
+ * 
+ * def _dtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3529
+ * 
+ * 
+ * def _dtf2d(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_297_dtf2d(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_297_dtf2d = {"_dtf2d", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_297_dtf2d, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_297_dtf2d(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_dtf2d (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_296_dtf2d(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_296_dtf2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  char const *__pyx_v__scale;
+  int __pyx_v__iy;
+  int __pyx_v__im;
+  int __pyx_v__id;
+  int __pyx_v__ihr;
+  int __pyx_v__imn;
+  double __pyx_v__sec;
+  double *__pyx_v__d1;
+  double *__pyx_v__d2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_dtf2d", 0);
+
+  /* "astropy/_erfa/core.pyx":3541
+ *     cdef double * _d2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3542
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3543
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3544
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3545
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _iy = (<int *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3546
+ *     cdef int status = 1
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))             # <<<<<<<<<<<<<<
+ *         _iy = (<int *>(dataptrarray[1]))[0]
+ *         _im = (<int *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__scale = ((char const *)(__pyx_v_dataptrarray[0]));
+
+    /* "astropy/_erfa/core.pyx":3547
+ *     while status:
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _iy = (<int *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _im = (<int *>(dataptrarray[2]))[0]
+ *         _id = (<int *>(dataptrarray[3]))[0]
+ */
+    __pyx_v__iy = (((int *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3548
+ *         _scale = (<const char *>(dataptrarray[0]))
+ *         _iy = (<int *>(dataptrarray[1]))[0]
+ *         _im = (<int *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _id = (<int *>(dataptrarray[3]))[0]
+ *         _ihr = (<int *>(dataptrarray[4]))[0]
+ */
+    __pyx_v__im = (((int *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3549
+ *         _iy = (<int *>(dataptrarray[1]))[0]
+ *         _im = (<int *>(dataptrarray[2]))[0]
+ *         _id = (<int *>(dataptrarray[3]))[0]             # <<<<<<<<<<<<<<
+ *         _ihr = (<int *>(dataptrarray[4]))[0]
+ *         _imn = (<int *>(dataptrarray[5]))[0]
+ */
+    __pyx_v__id = (((int *)(__pyx_v_dataptrarray[3]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3550
+ *         _im = (<int *>(dataptrarray[2]))[0]
+ *         _id = (<int *>(dataptrarray[3]))[0]
+ *         _ihr = (<int *>(dataptrarray[4]))[0]             # <<<<<<<<<<<<<<
+ *         _imn = (<int *>(dataptrarray[5]))[0]
+ *         _sec = (<double *>(dataptrarray[6]))[0]
+ */
+    __pyx_v__ihr = (((int *)(__pyx_v_dataptrarray[4]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3551
+ *         _id = (<int *>(dataptrarray[3]))[0]
+ *         _ihr = (<int *>(dataptrarray[4]))[0]
+ *         _imn = (<int *>(dataptrarray[5]))[0]             # <<<<<<<<<<<<<<
+ *         _sec = (<double *>(dataptrarray[6]))[0]
+ *         _d1 = (<double *>(dataptrarray[7]))
+ */
+    __pyx_v__imn = (((int *)(__pyx_v_dataptrarray[5]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3552
+ *         _ihr = (<int *>(dataptrarray[4]))[0]
+ *         _imn = (<int *>(dataptrarray[5]))[0]
+ *         _sec = (<double *>(dataptrarray[6]))[0]             # <<<<<<<<<<<<<<
+ *         _d1 = (<double *>(dataptrarray[7]))
+ *         _d2 = (<double *>(dataptrarray[8]))
+ */
+    __pyx_v__sec = (((double *)(__pyx_v_dataptrarray[6]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3553
+ *         _imn = (<int *>(dataptrarray[5]))[0]
+ *         _sec = (<double *>(dataptrarray[6]))[0]
+ *         _d1 = (<double *>(dataptrarray[7]))             # <<<<<<<<<<<<<<
+ *         _d2 = (<double *>(dataptrarray[8]))
+ *         _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)
+ */
+    __pyx_v__d1 = ((double *)(__pyx_v_dataptrarray[7]));
+
+    /* "astropy/_erfa/core.pyx":3554
+ *         _sec = (<double *>(dataptrarray[6]))[0]
+ *         _d1 = (<double *>(dataptrarray[7]))
+ *         _d2 = (<double *>(dataptrarray[8]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)
+ *         (<int *>(dataptrarray[9]))[0] = _c_retval
+ */
+    __pyx_v__d2 = ((double *)(__pyx_v_dataptrarray[8]));
+
+    /* "astropy/_erfa/core.pyx":3555
+ *         _d1 = (<double *>(dataptrarray[7]))
+ *         _d2 = (<double *>(dataptrarray[8]))
+ *         _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[9]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraDtf2d(__pyx_v__scale, __pyx_v__iy, __pyx_v__im, __pyx_v__id, __pyx_v__ihr, __pyx_v__imn, __pyx_v__sec, __pyx_v__d1, __pyx_v__d2);
+
+    /* "astropy/_erfa/core.pyx":3556
+ *         _d2 = (<double *>(dataptrarray[8]))
+ *         _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)
+ *         (<int *>(dataptrarray[9]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[9]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3557
+ *         _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)
+ *         (<int *>(dataptrarray[9]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3558
+ *         (<int *>(dataptrarray[9]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3559
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3560
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3529
+ * 
+ * 
+ * def _dtf2d(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._dtf2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3563
+ * 
+ * 
+ * def _taitt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_299_taitt(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_299_taitt = {"_taitt", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_299_taitt, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_299_taitt(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_taitt (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_298_taitt(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_298_taitt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tai1;
+  double __pyx_v__tai2;
+  double *__pyx_v__tt1;
+  double *__pyx_v__tt2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_taitt", 0);
+
+  /* "astropy/_erfa/core.pyx":3570
+ *     cdef double * _tt2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3571
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3572
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3573
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3574
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3575
+ *     cdef int status = 1
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tai1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3576
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tai2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3577
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)
+ */
+    __pyx_v__tt1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3578
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tt2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3579
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTaitt(__pyx_v__tai1, __pyx_v__tai2, __pyx_v__tt1, __pyx_v__tt2);
+
+    /* "astropy/_erfa/core.pyx":3580
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3581
+ *         _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3582
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3583
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3584
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3563
+ * 
+ * 
+ * def _taitt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._taitt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3587
+ * 
+ * 
+ * def _taiut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_301_taiut1(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_301_taiut1 = {"_taiut1", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_301_taiut1, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_301_taiut1(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_taiut1 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_300_taiut1(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_300_taiut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tai1;
+  double __pyx_v__tai2;
+  double __pyx_v__dta;
+  double *__pyx_v__ut11;
+  double *__pyx_v__ut12;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_taiut1", 0);
+
+  /* "astropy/_erfa/core.pyx":3595
+ *     cdef double * _ut12
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3596
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3597
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3598
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3599
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3600
+ *     cdef int status = 1
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tai1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3601
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tai2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3602
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3603
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)
+ */
+    __pyx_v__ut11 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3604
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__ut12 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3605
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTaiut1(__pyx_v__tai1, __pyx_v__tai2, __pyx_v__dta, __pyx_v__ut11, __pyx_v__ut12);
+
+    /* "astropy/_erfa/core.pyx":3606
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3607
+ *         _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3608
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3609
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3610
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3587
+ * 
+ * 
+ * def _taiut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._taiut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3613
+ * 
+ * 
+ * def _taiutc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_303_taiutc(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_303_taiutc = {"_taiutc", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_303_taiutc, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_303_taiutc(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_taiutc (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_302_taiutc(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_302_taiutc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tai1;
+  double __pyx_v__tai2;
+  double *__pyx_v__utc1;
+  double *__pyx_v__utc2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_taiutc", 0);
+
+  /* "astropy/_erfa/core.pyx":3620
+ *     cdef double * _utc2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3621
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3622
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3623
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3624
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3625
+ *     cdef int status = 1
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tai1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3626
+ *     while status:
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[2]))
+ *         _utc2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tai2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3627
+ *         _tai1 = (<double *>(dataptrarray[0]))[0]
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)
+ */
+    __pyx_v__utc1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3628
+ *         _tai2 = (<double *>(dataptrarray[1]))[0]
+ *         _utc1 = (<double *>(dataptrarray[2]))
+ *         _utc2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__utc2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3629
+ *         _utc1 = (<double *>(dataptrarray[2]))
+ *         _utc2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTaiutc(__pyx_v__tai1, __pyx_v__tai2, __pyx_v__utc1, __pyx_v__utc2);
+
+    /* "astropy/_erfa/core.pyx":3630
+ *         _utc2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3631
+ *         _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3632
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3633
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3634
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3634; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3613
+ * 
+ * 
+ * def _taiutc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._taiutc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3637
+ * 
+ * 
+ * def _tcbtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcb1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_305_tcbtdb(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_305_tcbtdb = {"_tcbtdb", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_305_tcbtdb, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_305_tcbtdb(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tcbtdb (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_304_tcbtdb(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_304_tcbtdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tcb1;
+  double __pyx_v__tcb2;
+  double *__pyx_v__tdb1;
+  double *__pyx_v__tdb2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tcbtdb", 0);
+
+  /* "astropy/_erfa/core.pyx":3644
+ *     cdef double * _tdb2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3645
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3646
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3647
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tcb1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3648
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tcb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcb2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3649
+ *     cdef int status = 1
+ *     while status:
+ *         _tcb1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tcb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tcb1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3650
+ *     while status:
+ *         _tcb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcb2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tdb1 = (<double *>(dataptrarray[2]))
+ *         _tdb2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tcb2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3651
+ *         _tcb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tdb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)
+ */
+    __pyx_v__tdb1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3652
+ *         _tcb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[2]))
+ *         _tdb2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tdb2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3653
+ *         _tdb1 = (<double *>(dataptrarray[2]))
+ *         _tdb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTcbtdb(__pyx_v__tcb1, __pyx_v__tcb2, __pyx_v__tdb1, __pyx_v__tdb2);
+
+    /* "astropy/_erfa/core.pyx":3654
+ *         _tdb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3655
+ *         _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3656
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3657
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3658
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3637
+ * 
+ * 
+ * def _tcbtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcb1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tcbtdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3661
+ * 
+ * 
+ * def _tcgtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcg1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_307_tcgtt(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_307_tcgtt = {"_tcgtt", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_307_tcgtt, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_307_tcgtt(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tcgtt (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_306_tcgtt(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_306_tcgtt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tcg1;
+  double __pyx_v__tcg2;
+  double *__pyx_v__tt1;
+  double *__pyx_v__tt2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tcgtt", 0);
+
+  /* "astropy/_erfa/core.pyx":3668
+ *     cdef double * _tt2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3669
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3670
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3671
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tcg1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3672
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tcg1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcg2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3673
+ *     cdef int status = 1
+ *     while status:
+ *         _tcg1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tcg2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tcg1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3674
+ *     while status:
+ *         _tcg1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcg2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tcg2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3675
+ *         _tcg1 = (<double *>(dataptrarray[0]))[0]
+ *         _tcg2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)
+ */
+    __pyx_v__tt1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3676
+ *         _tcg2 = (<double *>(dataptrarray[1]))[0]
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tt2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3677
+ *         _tt1 = (<double *>(dataptrarray[2]))
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTcgtt(__pyx_v__tcg1, __pyx_v__tcg2, __pyx_v__tt1, __pyx_v__tt2);
+
+    /* "astropy/_erfa/core.pyx":3678
+ *         _tt2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3679
+ *         _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3680
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3681
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3682
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3661
+ * 
+ * 
+ * def _tcgtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcg1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tcgtt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3685
+ * 
+ * 
+ * def _tdbtcb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_309_tdbtcb(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_309_tdbtcb = {"_tdbtcb", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_309_tdbtcb, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_309_tdbtcb(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tdbtcb (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_308_tdbtcb(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_308_tdbtcb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tdb1;
+  double __pyx_v__tdb2;
+  double *__pyx_v__tcb1;
+  double *__pyx_v__tcb2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tdbtcb", 0);
+
+  /* "astropy/_erfa/core.pyx":3692
+ *     cdef double * _tcb2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3693
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3694
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3695
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3696
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3697
+ *     cdef int status = 1
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcb1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tdb1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3698
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tcb1 = (<double *>(dataptrarray[2]))
+ *         _tcb2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tdb2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3699
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcb1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tcb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)
+ */
+    __pyx_v__tcb1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3700
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcb1 = (<double *>(dataptrarray[2]))
+ *         _tcb2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tcb2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3701
+ *         _tcb1 = (<double *>(dataptrarray[2]))
+ *         _tcb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTdbtcb(__pyx_v__tdb1, __pyx_v__tdb2, __pyx_v__tcb1, __pyx_v__tcb2);
+
+    /* "astropy/_erfa/core.pyx":3702
+ *         _tcb2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3703
+ *         _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3704
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3705
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3706
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3685
+ * 
+ * 
+ * def _tdbtcb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tdbtcb", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3709
+ * 
+ * 
+ * def _tdbtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_311_tdbtt(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_311_tdbtt = {"_tdbtt", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_311_tdbtt, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_311_tdbtt(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tdbtt (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_310_tdbtt(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_310_tdbtt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tdb1;
+  double __pyx_v__tdb2;
+  double __pyx_v__dtr;
+  double *__pyx_v__tt1;
+  double *__pyx_v__tt2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tdbtt", 0);
+
+  /* "astropy/_erfa/core.pyx":3717
+ *     cdef double * _tt2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3718
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3719
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3720
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3721
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3722
+ *     cdef int status = 1
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tdb1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3723
+ *     while status:
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tdb2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3724
+ *         _tdb1 = (<double *>(dataptrarray[0]))[0]
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dtr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3725
+ *         _tdb2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)
+ */
+    __pyx_v__tt1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3726
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__tt2 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3727
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTdbtt(__pyx_v__tdb1, __pyx_v__tdb2, __pyx_v__dtr, __pyx_v__tt1, __pyx_v__tt2);
+
+    /* "astropy/_erfa/core.pyx":3728
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3729
+ *         _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3730
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3731
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3732
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3709
+ * 
+ * 
+ * def _tdbtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tdbtt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3735
+ * 
+ * 
+ * def _tttai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_313_tttai(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_313_tttai = {"_tttai", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_313_tttai, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_313_tttai(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tttai (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_312_tttai(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_312_tttai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tt1;
+  double __pyx_v__tt2;
+  double *__pyx_v__tai1;
+  double *__pyx_v__tai2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tttai", 0);
+
+  /* "astropy/_erfa/core.pyx":3742
+ *     cdef double * _tai2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3743
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3744
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3745
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3746
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3747
+ *     cdef int status = 1
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tt1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3748
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tt2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3749
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)
+ */
+    __pyx_v__tai1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3750
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tai2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3751
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTttai(__pyx_v__tt1, __pyx_v__tt2, __pyx_v__tai1, __pyx_v__tai2);
+
+    /* "astropy/_erfa/core.pyx":3752
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3753
+ *         _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3754
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3755
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3756
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3735
+ * 
+ * 
+ * def _tttai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tttai", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3759
+ * 
+ * 
+ * def _tttcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_315_tttcg(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_315_tttcg = {"_tttcg", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_315_tttcg, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_315_tttcg(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tttcg (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_314_tttcg(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_314_tttcg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tt1;
+  double __pyx_v__tt2;
+  double *__pyx_v__tcg1;
+  double *__pyx_v__tcg2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tttcg", 0);
+
+  /* "astropy/_erfa/core.pyx":3766
+ *     cdef double * _tcg2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3767
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3768
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3769
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3770
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3771
+ *     cdef int status = 1
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcg1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__tt1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3772
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tcg1 = (<double *>(dataptrarray[2]))
+ *         _tcg2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tt2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3773
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcg1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tcg2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)
+ */
+    __pyx_v__tcg1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3774
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _tcg1 = (<double *>(dataptrarray[2]))
+ *         _tcg2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tcg2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3775
+ *         _tcg1 = (<double *>(dataptrarray[2]))
+ *         _tcg2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTttcg(__pyx_v__tt1, __pyx_v__tt2, __pyx_v__tcg1, __pyx_v__tcg2);
+
+    /* "astropy/_erfa/core.pyx":3776
+ *         _tcg2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3777
+ *         _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3778
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3779
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3780
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3759
+ * 
+ * 
+ * def _tttcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tttcg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3783
+ * 
+ * 
+ * def _tttdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_317_tttdb(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_317_tttdb = {"_tttdb", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_317_tttdb, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_317_tttdb(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_tttdb (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_316_tttdb(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_316_tttdb(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tt1;
+  double __pyx_v__tt2;
+  double __pyx_v__dtr;
+  double *__pyx_v__tdb1;
+  double *__pyx_v__tdb2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_tttdb", 0);
+
+  /* "astropy/_erfa/core.pyx":3791
+ *     cdef double * _tdb2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3792
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3793
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3794
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3795
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3796
+ *     cdef int status = 1
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tt1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3797
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tt2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3798
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _tdb1 = (<double *>(dataptrarray[3]))
+ *         _tdb2 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dtr = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3799
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _tdb2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)
+ */
+    __pyx_v__tdb1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3800
+ *         _dtr = (<double *>(dataptrarray[2]))[0]
+ *         _tdb1 = (<double *>(dataptrarray[3]))
+ *         _tdb2 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__tdb2 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3801
+ *         _tdb1 = (<double *>(dataptrarray[3]))
+ *         _tdb2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTttdb(__pyx_v__tt1, __pyx_v__tt2, __pyx_v__dtr, __pyx_v__tdb1, __pyx_v__tdb2);
+
+    /* "astropy/_erfa/core.pyx":3802
+ *         _tdb2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3803
+ *         _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3804
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3805
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3806
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3783
+ * 
+ * 
+ * def _tttdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._tttdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3809
+ * 
+ * 
+ * def _ttut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_319_ttut1(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_319_ttut1 = {"_ttut1", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_319_ttut1, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_319_ttut1(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ttut1 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_318_ttut1(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_318_ttut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__tt1;
+  double __pyx_v__tt2;
+  double __pyx_v__dt;
+  double *__pyx_v__ut11;
+  double *__pyx_v__ut12;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_ttut1", 0);
+
+  /* "astropy/_erfa/core.pyx":3817
+ *     cdef double * _ut12
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3818
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3819
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3820
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3821
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3822
+ *     cdef int status = 1
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__tt1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3823
+ *     while status:
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__tt2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3824
+ *         _tt1 = (<double *>(dataptrarray[0]))[0]
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dt = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3825
+ *         _tt2 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)
+ */
+    __pyx_v__ut11 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3826
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__ut12 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3827
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraTtut1(__pyx_v__tt1, __pyx_v__tt2, __pyx_v__dt, __pyx_v__ut11, __pyx_v__ut12);
+
+    /* "astropy/_erfa/core.pyx":3828
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3829
+ *         _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3830
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3831
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3832
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3809
+ * 
+ * 
+ * def _ttut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._ttut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3835
+ * 
+ * 
+ * def _ut1tai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_321_ut1tai(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_321_ut1tai = {"_ut1tai", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_321_ut1tai, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_321_ut1tai(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ut1tai (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_320_ut1tai(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_320_ut1tai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ut11;
+  double __pyx_v__ut12;
+  double __pyx_v__dta;
+  double *__pyx_v__tai1;
+  double *__pyx_v__tai2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_ut1tai", 0);
+
+  /* "astropy/_erfa/core.pyx":3843
+ *     cdef double * _tai2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3844
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3845
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3846
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3847
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3848
+ *     cdef int status = 1
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ut11 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3849
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _tai1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__ut12 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3850
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[3]))
+ *         _tai2 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dta = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3851
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _tai1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)
+ */
+    __pyx_v__tai1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3852
+ *         _dta = (<double *>(dataptrarray[2]))[0]
+ *         _tai1 = (<double *>(dataptrarray[3]))
+ *         _tai2 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__tai2 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3853
+ *         _tai1 = (<double *>(dataptrarray[3]))
+ *         _tai2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraUt1tai(__pyx_v__ut11, __pyx_v__ut12, __pyx_v__dta, __pyx_v__tai1, __pyx_v__tai2);
+
+    /* "astropy/_erfa/core.pyx":3854
+ *         _tai2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3855
+ *         _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3856
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3857
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3858
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3835
+ * 
+ * 
+ * def _ut1tai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._ut1tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3861
+ * 
+ * 
+ * def _ut1tt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_323_ut1tt(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_323_ut1tt = {"_ut1tt", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_323_ut1tt, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_323_ut1tt(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ut1tt (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_322_ut1tt(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_322_ut1tt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ut11;
+  double __pyx_v__ut12;
+  double __pyx_v__dt;
+  double *__pyx_v__tt1;
+  double *__pyx_v__tt2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_ut1tt", 0);
+
+  /* "astropy/_erfa/core.pyx":3869
+ *     cdef double * _tt2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3870
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3871
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3872
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3873
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3874
+ *     cdef int status = 1
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ut11 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3875
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__ut12 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3876
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dt = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3877
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)
+ */
+    __pyx_v__tt1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3878
+ *         _dt = (<double *>(dataptrarray[2]))[0]
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__tt2 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3879
+ *         _tt1 = (<double *>(dataptrarray[3]))
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraUt1tt(__pyx_v__ut11, __pyx_v__ut12, __pyx_v__dt, __pyx_v__tt1, __pyx_v__tt2);
+
+    /* "astropy/_erfa/core.pyx":3880
+ *         _tt2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3881
+ *         _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3882
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3883
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3884
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3861
+ * 
+ * 
+ * def _ut1tt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._ut1tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3887
+ * 
+ * 
+ * def _ut1utc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_325_ut1utc(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_325_ut1utc = {"_ut1utc", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_325_ut1utc, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_325_ut1utc(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_ut1utc (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_324_ut1utc(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_324_ut1utc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__ut11;
+  double __pyx_v__ut12;
+  double __pyx_v__dut1;
+  double *__pyx_v__utc1;
+  double *__pyx_v__utc2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_ut1utc", 0);
+
+  /* "astropy/_erfa/core.pyx":3895
+ *     cdef double * _utc2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3896
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3897
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3898
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3899
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3900
+ *     cdef int status = 1
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__ut11 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3901
+ *     while status:
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__ut12 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3902
+ *         _ut11 = (<double *>(dataptrarray[0]))[0]
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[3]))
+ *         _utc2 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3903
+ *         _ut12 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)
+ */
+    __pyx_v__utc1 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3904
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _utc1 = (<double *>(dataptrarray[3]))
+ *         _utc2 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__utc2 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3905
+ *         _utc1 = (<double *>(dataptrarray[3]))
+ *         _utc2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraUt1utc(__pyx_v__ut11, __pyx_v__ut12, __pyx_v__dut1, __pyx_v__utc1, __pyx_v__utc2);
+
+    /* "astropy/_erfa/core.pyx":3906
+ *         _utc2 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3907
+ *         _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3908
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3909
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3910
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3887
+ * 
+ * 
+ * def _ut1utc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._ut1utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3913
+ * 
+ * 
+ * def _utctai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_327_utctai(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_327_utctai = {"_utctai", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_327_utctai, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_327_utctai(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_utctai (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_326_utctai(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_326_utctai(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double *__pyx_v__tai1;
+  double *__pyx_v__tai2;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_utctai", 0);
+
+  /* "astropy/_erfa/core.pyx":3920
+ *     cdef double * _tai2
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3921
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3922
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3923
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3924
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3925
+ *     cdef int status = 1
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3926
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3927
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))             # <<<<<<<<<<<<<<
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)
+ */
+    __pyx_v__tai1 = ((double *)(__pyx_v_dataptrarray[2]));
+
+    /* "astropy/_erfa/core.pyx":3928
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ */
+    __pyx_v__tai2 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3929
+ *         _tai1 = (<double *>(dataptrarray[2]))
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraUtctai(__pyx_v__utc1, __pyx_v__utc2, __pyx_v__tai1, __pyx_v__tai2);
+
+    /* "astropy/_erfa/core.pyx":3930
+ *         _tai2 = (<double *>(dataptrarray[3]))
+ *         _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[4]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3931
+ *         _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3932
+ *         (<int *>(dataptrarray[4]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3933
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3934
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3913
+ * 
+ * 
+ * def _utctai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._utctai", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/_erfa/core.pyx":3937
+ * 
+ * 
+ * def _utcut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_329_utcut1(PyObject *__pyx_self, PyObject *__pyx_v_it); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_5_erfa_5_core_329_utcut1 = {"_utcut1", (PyCFunction)__pyx_pw_7astropy_5_erfa_5_core_329_utcut1, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_5_erfa_5_core_329_utcut1(PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_utcut1 (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_5_erfa_5_core_328_utcut1(__pyx_self, ((PyObject *)__pyx_v_it));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_5_erfa_5_core_328_utcut1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_it) {
+  double __pyx_v__utc1;
+  double __pyx_v__utc2;
+  double __pyx_v__dut1;
+  double *__pyx_v__ut11;
+  double *__pyx_v__ut12;
+  int __pyx_v__c_retval;
+  int __pyx_v_stat_ok;
+  char **__pyx_v_dataptrarray;
+  __pyx_t_7astropy_5_erfa_5_core_IterNextFunc __pyx_v_iternext;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_utcut1", 0);
+
+  /* "astropy/_erfa/core.pyx":3945
+ *     cdef double * _ut12
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True             # <<<<<<<<<<<<<<
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ */
+  __pyx_v_stat_ok = 1;
+
+  /* "astropy/_erfa/core.pyx":3946
+ *     cdef int _c_retval
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ */
+  __pyx_v_dataptrarray = NpyIter_GetDataPtrArray(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+
+  /* "astropy/_erfa/core.pyx":3947
+ *     cdef bint stat_ok = True
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)             # <<<<<<<<<<<<<<
+ *     cdef int status = 1
+ *     while status:
+ */
+  __pyx_v_iternext = NpyIter_GetIterNext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it), NULL);
+
+  /* "astropy/_erfa/core.pyx":3948
+ *     cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1             # <<<<<<<<<<<<<<
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ */
+  __pyx_v_status = 1;
+
+  /* "astropy/_erfa/core.pyx":3949
+ *     cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+ *     cdef int status = 1
+ *     while status:             # <<<<<<<<<<<<<<
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_status != 0);
+    if (!__pyx_t_1) break;
+
+    /* "astropy/_erfa/core.pyx":3950
+ *     cdef int status = 1
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]             # <<<<<<<<<<<<<<
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ */
+    __pyx_v__utc1 = (((double *)(__pyx_v_dataptrarray[0]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3951
+ *     while status:
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]             # <<<<<<<<<<<<<<
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ */
+    __pyx_v__utc2 = (((double *)(__pyx_v_dataptrarray[1]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3952
+ *         _utc1 = (<double *>(dataptrarray[0]))[0]
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]             # <<<<<<<<<<<<<<
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ */
+    __pyx_v__dut1 = (((double *)(__pyx_v_dataptrarray[2]))[0]);
+
+    /* "astropy/_erfa/core.pyx":3953
+ *         _utc2 = (<double *>(dataptrarray[1]))[0]
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))             # <<<<<<<<<<<<<<
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)
+ */
+    __pyx_v__ut11 = ((double *)(__pyx_v_dataptrarray[3]));
+
+    /* "astropy/_erfa/core.pyx":3954
+ *         _dut1 = (<double *>(dataptrarray[2]))[0]
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))             # <<<<<<<<<<<<<<
+ *         _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ */
+    __pyx_v__ut12 = ((double *)(__pyx_v_dataptrarray[4]));
+
+    /* "astropy/_erfa/core.pyx":3955
+ *         _ut11 = (<double *>(dataptrarray[3]))
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)             # <<<<<<<<<<<<<<
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ */
+    __pyx_v__c_retval = eraUtcut1(__pyx_v__utc1, __pyx_v__utc2, __pyx_v__dut1, __pyx_v__ut11, __pyx_v__ut12);
+
+    /* "astropy/_erfa/core.pyx":3956
+ *         _ut12 = (<double *>(dataptrarray[4]))
+ *         _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval             # <<<<<<<<<<<<<<
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ */
+    (((int *)(__pyx_v_dataptrarray[5]))[0]) = __pyx_v__c_retval;
+
+    /* "astropy/_erfa/core.pyx":3957
+ *         _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:             # <<<<<<<<<<<<<<
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ */
+    __pyx_t_1 = ((__pyx_v__c_retval != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/_erfa/core.pyx":3958
+ *         (<int *>(dataptrarray[5]))[0] = _c_retval
+ *         if _c_retval != 0:
+ *             stat_ok = False             # <<<<<<<<<<<<<<
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok
+ */
+      __pyx_v_stat_ok = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "astropy/_erfa/core.pyx":3959
+ *         if _c_retval != 0:
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))             # <<<<<<<<<<<<<<
+ *     return stat_ok
+ * 
+ */
+    __pyx_v_status = __pyx_v_iternext(__pyx_f_7astropy_5_erfa_5_core_GetNpyIter(__pyx_v_it));
+  }
+
+  /* "astropy/_erfa/core.pyx":3960
+ *             stat_ok = False
+ *         status = iternext(GetNpyIter(it))
+ *     return stat_ok             # <<<<<<<<<<<<<<
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_stat_ok); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/_erfa/core.pyx":3937
+ * 
+ * 
+ * def _utcut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("astropy._erfa._core._utcut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L14;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "_core",
+    __pyx_k_This_module_contains_the_Cython, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_n_s_AstropyUserWarning, __pyx_k_AstropyUserWarning, sizeof(__pyx_k_AstropyUserWarning), 0, 0, 1, 1},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_LooseVersion, __pyx_k_LooseVersion, sizeof(__pyx_k_LooseVersion), 0, 0, 1, 1},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s_a, __pyx_k_a, sizeof(__pyx_k_a), 0, 0, 1, 1},
+  {&__pyx_n_s_ab, __pyx_k_ab, sizeof(__pyx_k_ab), 0, 0, 1, 1},
+  {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1},
+  {&__pyx_n_s_aob, __pyx_k_aob, sizeof(__pyx_k_aob), 0, 0, 1, 1},
+  {&__pyx_n_s_apcg, __pyx_k_apcg, sizeof(__pyx_k_apcg), 0, 0, 1, 1},
+  {&__pyx_n_s_apcg13, __pyx_k_apcg13, sizeof(__pyx_k_apcg13), 0, 0, 1, 1},
+  {&__pyx_n_s_apci, __pyx_k_apci, sizeof(__pyx_k_apci), 0, 0, 1, 1},
+  {&__pyx_n_s_apci13, __pyx_k_apci13, sizeof(__pyx_k_apci13), 0, 0, 1, 1},
+  {&__pyx_n_s_apco, __pyx_k_apco, sizeof(__pyx_k_apco), 0, 0, 1, 1},
+  {&__pyx_n_s_apco13, __pyx_k_apco13, sizeof(__pyx_k_apco13), 0, 0, 1, 1},
+  {&__pyx_n_s_apcs, __pyx_k_apcs, sizeof(__pyx_k_apcs), 0, 0, 1, 1},
+  {&__pyx_n_s_apcs13, __pyx_k_apcs13, sizeof(__pyx_k_apcs13), 0, 0, 1, 1},
+  {&__pyx_n_s_aper, __pyx_k_aper, sizeof(__pyx_k_aper), 0, 0, 1, 1},
+  {&__pyx_n_s_aper13, __pyx_k_aper13, sizeof(__pyx_k_aper13), 0, 0, 1, 1},
+  {&__pyx_n_s_apio, __pyx_k_apio, sizeof(__pyx_k_apio), 0, 0, 1, 1},
+  {&__pyx_n_s_apio13, __pyx_k_apio13, sizeof(__pyx_k_apio13), 0, 0, 1, 1},
+  {&__pyx_n_s_astrom, __pyx_k_astrom, sizeof(__pyx_k_astrom), 0, 0, 1, 1},
+  {&__pyx_n_s_astropy__erfa__core, __pyx_k_astropy__erfa__core, sizeof(__pyx_k_astropy__erfa__core), 0, 0, 1, 1},
+  {&__pyx_n_s_atci13, __pyx_k_atci13, sizeof(__pyx_k_atci13), 0, 0, 1, 1},
+  {&__pyx_n_s_atciq, __pyx_k_atciq, sizeof(__pyx_k_atciq), 0, 0, 1, 1},
+  {&__pyx_n_s_atciqn, __pyx_k_atciqn, sizeof(__pyx_k_atciqn), 0, 0, 1, 1},
+  {&__pyx_n_s_atciqz, __pyx_k_atciqz, sizeof(__pyx_k_atciqz), 0, 0, 1, 1},
+  {&__pyx_n_s_atco13, __pyx_k_atco13, sizeof(__pyx_k_atco13), 0, 0, 1, 1},
+  {&__pyx_n_s_atic13, __pyx_k_atic13, sizeof(__pyx_k_atic13), 0, 0, 1, 1},
+  {&__pyx_n_s_aticq, __pyx_k_aticq, sizeof(__pyx_k_aticq), 0, 0, 1, 1},
+  {&__pyx_n_s_aticqn, __pyx_k_aticqn, sizeof(__pyx_k_aticqn), 0, 0, 1, 1},
+  {&__pyx_n_s_atio13, __pyx_k_atio13, sizeof(__pyx_k_atio13), 0, 0, 1, 1},
+  {&__pyx_n_s_atioq, __pyx_k_atioq, sizeof(__pyx_k_atioq), 0, 0, 1, 1},
+  {&__pyx_n_s_atoc13, __pyx_k_atoc13, sizeof(__pyx_k_atoc13), 0, 0, 1, 1},
+  {&__pyx_n_s_atoi13, __pyx_k_atoi13, sizeof(__pyx_k_atoi13), 0, 0, 1, 1},
+  {&__pyx_n_s_atoiq, __pyx_k_atoiq, sizeof(__pyx_k_atoiq), 0, 0, 1, 1},
+  {&__pyx_n_s_b_2, __pyx_k_b_2, sizeof(__pyx_k_b_2), 0, 0, 1, 1},
+  {&__pyx_n_s_bi00, __pyx_k_bi00, sizeof(__pyx_k_bi00), 0, 0, 1, 1},
+  {&__pyx_n_s_bm, __pyx_k_bm, sizeof(__pyx_k_bm), 0, 0, 1, 1},
+  {&__pyx_n_s_bm1, __pyx_k_bm1, sizeof(__pyx_k_bm1), 0, 0, 1, 1},
+  {&__pyx_n_s_bp00, __pyx_k_bp00, sizeof(__pyx_k_bp00), 0, 0, 1, 1},
+  {&__pyx_n_s_bp06, __pyx_k_bp06, sizeof(__pyx_k_bp06), 0, 0, 1, 1},
+  {&__pyx_n_s_bpa, __pyx_k_bpa, sizeof(__pyx_k_bpa), 0, 0, 1, 1},
+  {&__pyx_n_s_bpia, __pyx_k_bpia, sizeof(__pyx_k_bpia), 0, 0, 1, 1},
+  {&__pyx_n_s_bpn2xy, __pyx_k_bpn2xy, sizeof(__pyx_k_bpn2xy), 0, 0, 1, 1},
+  {&__pyx_n_s_bqa, __pyx_k_bqa, sizeof(__pyx_k_bqa), 0, 0, 1, 1},
+  {&__pyx_n_s_btheta, __pyx_k_btheta, sizeof(__pyx_k_btheta), 0, 0, 1, 1},
+  {&__pyx_n_s_bz, __pyx_k_bz, sizeof(__pyx_k_bz), 0, 0, 1, 1},
+  {&__pyx_n_s_bzeta, __pyx_k_bzeta, sizeof(__pyx_k_bzeta), 0, 0, 1, 1},
+  {&__pyx_n_s_c2i00a, __pyx_k_c2i00a, sizeof(__pyx_k_c2i00a), 0, 0, 1, 1},
+  {&__pyx_n_s_c2i00b, __pyx_k_c2i00b, sizeof(__pyx_k_c2i00b), 0, 0, 1, 1},
+  {&__pyx_n_s_c2i06a, __pyx_k_c2i06a, sizeof(__pyx_k_c2i06a), 0, 0, 1, 1},
+  {&__pyx_n_s_c2ibpn, __pyx_k_c2ibpn, sizeof(__pyx_k_c2ibpn), 0, 0, 1, 1},
+  {&__pyx_n_s_c2ixy, __pyx_k_c2ixy, sizeof(__pyx_k_c2ixy), 0, 0, 1, 1},
+  {&__pyx_n_s_c2ixys, __pyx_k_c2ixys, sizeof(__pyx_k_c2ixys), 0, 0, 1, 1},
+  {&__pyx_n_s_c2t00a, __pyx_k_c2t00a, sizeof(__pyx_k_c2t00a), 0, 0, 1, 1},
+  {&__pyx_n_s_c2t00b, __pyx_k_c2t00b, sizeof(__pyx_k_c2t00b), 0, 0, 1, 1},
+  {&__pyx_n_s_c2t06a, __pyx_k_c2t06a, sizeof(__pyx_k_c2t06a), 0, 0, 1, 1},
+  {&__pyx_n_s_c2tcio, __pyx_k_c2tcio, sizeof(__pyx_k_c2tcio), 0, 0, 1, 1},
+  {&__pyx_n_s_c2teqx, __pyx_k_c2teqx, sizeof(__pyx_k_c2teqx), 0, 0, 1, 1},
+  {&__pyx_n_s_c2tpe, __pyx_k_c2tpe, sizeof(__pyx_k_c2tpe), 0, 0, 1, 1},
+  {&__pyx_n_s_c2txy, __pyx_k_c2txy, sizeof(__pyx_k_c2txy), 0, 0, 1, 1},
+  {&__pyx_n_s_c_retval, __pyx_k_c_retval, sizeof(__pyx_k_c_retval), 0, 0, 1, 1},
+  {&__pyx_n_s_cal2jd, __pyx_k_cal2jd, sizeof(__pyx_k_cal2jd), 0, 0, 1, 1},
+  {&__pyx_n_s_chia, __pyx_k_chia, sizeof(__pyx_k_chia), 0, 0, 1, 1},
+  {&__pyx_n_s_d1, __pyx_k_d1, sizeof(__pyx_k_d1), 0, 0, 1, 1},
+  {&__pyx_n_s_d2, __pyx_k_d2, sizeof(__pyx_k_d2), 0, 0, 1, 1},
+  {&__pyx_n_s_d2dtf, __pyx_k_d2dtf, sizeof(__pyx_k_d2dtf), 0, 0, 1, 1},
+  {&__pyx_n_s_d5, __pyx_k_d5, sizeof(__pyx_k_d5), 0, 0, 1, 1},
+  {&__pyx_n_s_dat, __pyx_k_dat, sizeof(__pyx_k_dat), 0, 0, 1, 1},
+  {&__pyx_n_s_dataptrarray, __pyx_k_dataptrarray, sizeof(__pyx_k_dataptrarray), 0, 0, 1, 1},
+  {&__pyx_n_s_date01, __pyx_k_date01, sizeof(__pyx_k_date01), 0, 0, 1, 1},
+  {&__pyx_n_s_date02, __pyx_k_date02, sizeof(__pyx_k_date02), 0, 0, 1, 1},
+  {&__pyx_n_s_date1, __pyx_k_date1, sizeof(__pyx_k_date1), 0, 0, 1, 1},
+  {&__pyx_n_s_date11, __pyx_k_date11, sizeof(__pyx_k_date11), 0, 0, 1, 1},
+  {&__pyx_n_s_date12, __pyx_k_date12, sizeof(__pyx_k_date12), 0, 0, 1, 1},
+  {&__pyx_n_s_date2, __pyx_k_date2, sizeof(__pyx_k_date2), 0, 0, 1, 1},
+  {&__pyx_n_s_dc, __pyx_k_dc, sizeof(__pyx_k_dc), 0, 0, 1, 1},
+  {&__pyx_n_s_dd5, __pyx_k_dd5, sizeof(__pyx_k_dd5), 0, 0, 1, 1},
+  {&__pyx_n_s_ddh, __pyx_k_ddh, sizeof(__pyx_k_ddh), 0, 0, 1, 1},
+  {&__pyx_n_s_dec, __pyx_k_dec, sizeof(__pyx_k_dec), 0, 0, 1, 1},
+  {&__pyx_n_s_dec1, __pyx_k_dec1, sizeof(__pyx_k_dec1), 0, 0, 1, 1},
+  {&__pyx_n_s_dec2, __pyx_k_dec2, sizeof(__pyx_k_dec2), 0, 0, 1, 1},
+  {&__pyx_n_s_deltat, __pyx_k_deltat, sizeof(__pyx_k_deltat), 0, 0, 1, 1},
+  {&__pyx_n_s_deps, __pyx_k_deps, sizeof(__pyx_k_deps), 0, 0, 1, 1},
+  {&__pyx_n_s_depsbi, __pyx_k_depsbi, sizeof(__pyx_k_depsbi), 0, 0, 1, 1},
+  {&__pyx_n_s_depspr, __pyx_k_depspr, sizeof(__pyx_k_depspr), 0, 0, 1, 1},
+  {&__pyx_n_s_dh, __pyx_k_dh, sizeof(__pyx_k_dh), 0, 0, 1, 1},
+  {&__pyx_n_s_di, __pyx_k_di, sizeof(__pyx_k_di), 0, 0, 1, 1},
+  {&__pyx_n_s_distutils_version, __pyx_k_distutils_version, sizeof(__pyx_k_distutils_version), 0, 0, 1, 1},
+  {&__pyx_n_s_dj1, __pyx_k_dj1, sizeof(__pyx_k_dj1), 0, 0, 1, 1},
+  {&__pyx_n_s_dj2, __pyx_k_dj2, sizeof(__pyx_k_dj2), 0, 0, 1, 1},
+  {&__pyx_n_s_djm, __pyx_k_djm, sizeof(__pyx_k_djm), 0, 0, 1, 1},
+  {&__pyx_n_s_djm0, __pyx_k_djm0, sizeof(__pyx_k_djm0), 0, 0, 1, 1},
+  {&__pyx_n_s_dlim, __pyx_k_dlim, sizeof(__pyx_k_dlim), 0, 0, 1, 1},
+  {&__pyx_n_s_dob, __pyx_k_dob, sizeof(__pyx_k_dob), 0, 0, 1, 1},
+  {&__pyx_n_s_dpsi, __pyx_k_dpsi, sizeof(__pyx_k_dpsi), 0, 0, 1, 1},
+  {&__pyx_n_s_dpsibi, __pyx_k_dpsibi, sizeof(__pyx_k_dpsibi), 0, 0, 1, 1},
+  {&__pyx_n_s_dpsipr, __pyx_k_dpsipr, sizeof(__pyx_k_dpsipr), 0, 0, 1, 1},
+  {&__pyx_n_s_dr5, __pyx_k_dr5, sizeof(__pyx_k_dr5), 0, 0, 1, 1},
+  {&__pyx_n_s_dra, __pyx_k_dra, sizeof(__pyx_k_dra), 0, 0, 1, 1},
+  {&__pyx_n_s_drh, __pyx_k_drh, sizeof(__pyx_k_drh), 0, 0, 1, 1},
+  {&__pyx_n_s_dt, __pyx_k_dt, sizeof(__pyx_k_dt), 0, 0, 1, 1},
+  {&__pyx_n_s_dta, __pyx_k_dta, sizeof(__pyx_k_dta), 0, 0, 1, 1},
+  {&__pyx_n_s_dtdb, __pyx_k_dtdb, sizeof(__pyx_k_dtdb), 0, 0, 1, 1},
+  {&__pyx_n_s_dtf2d, __pyx_k_dtf2d, sizeof(__pyx_k_dtf2d), 0, 0, 1, 1},
+  {&__pyx_n_s_dtr, __pyx_k_dtr, sizeof(__pyx_k_dtr), 0, 0, 1, 1},
+  {&__pyx_n_s_dut1, __pyx_k_dut1, sizeof(__pyx_k_dut1), 0, 0, 1, 1},
+  {&__pyx_n_s_e, __pyx_k_e, sizeof(__pyx_k_e), 0, 0, 1, 1},
+  {&__pyx_n_s_ebpv, __pyx_k_ebpv, sizeof(__pyx_k_ebpv), 0, 0, 1, 1},
+  {&__pyx_n_s_ee00, __pyx_k_ee00, sizeof(__pyx_k_ee00), 0, 0, 1, 1},
+  {&__pyx_n_s_ee00a, __pyx_k_ee00a, sizeof(__pyx_k_ee00a), 0, 0, 1, 1},
+  {&__pyx_n_s_ee00b, __pyx_k_ee00b, sizeof(__pyx_k_ee00b), 0, 0, 1, 1},
+  {&__pyx_n_s_ee06a, __pyx_k_ee06a, sizeof(__pyx_k_ee06a), 0, 0, 1, 1},
+  {&__pyx_n_s_eect00, __pyx_k_eect00, sizeof(__pyx_k_eect00), 0, 0, 1, 1},
+  {&__pyx_n_s_eform, __pyx_k_eform, sizeof(__pyx_k_eform), 0, 0, 1, 1},
+  {&__pyx_n_s_ehp, __pyx_k_ehp, sizeof(__pyx_k_ehp), 0, 0, 1, 1},
+  {&__pyx_n_s_elong, __pyx_k_elong, sizeof(__pyx_k_elong), 0, 0, 1, 1},
+  {&__pyx_n_s_em, __pyx_k_em, sizeof(__pyx_k_em), 0, 0, 1, 1},
+  {&__pyx_n_s_eo, __pyx_k_eo, sizeof(__pyx_k_eo), 0, 0, 1, 1},
+  {&__pyx_n_s_eo06a, __pyx_k_eo06a, sizeof(__pyx_k_eo06a), 0, 0, 1, 1},
+  {&__pyx_n_s_eors, __pyx_k_eors, sizeof(__pyx_k_eors), 0, 0, 1, 1},
+  {&__pyx_n_s_ep1a, __pyx_k_ep1a, sizeof(__pyx_k_ep1a), 0, 0, 1, 1},
+  {&__pyx_n_s_ep1b, __pyx_k_ep1b, sizeof(__pyx_k_ep1b), 0, 0, 1, 1},
+  {&__pyx_n_s_ep2a, __pyx_k_ep2a, sizeof(__pyx_k_ep2a), 0, 0, 1, 1},
+  {&__pyx_n_s_ep2b, __pyx_k_ep2b, sizeof(__pyx_k_ep2b), 0, 0, 1, 1},
+  {&__pyx_n_s_epb, __pyx_k_epb, sizeof(__pyx_k_epb), 0, 0, 1, 1},
+  {&__pyx_n_s_epb2jd, __pyx_k_epb2jd, sizeof(__pyx_k_epb2jd), 0, 0, 1, 1},
+  {&__pyx_n_s_epj, __pyx_k_epj, sizeof(__pyx_k_epj), 0, 0, 1, 1},
+  {&__pyx_n_s_epj2jd, __pyx_k_epj2jd, sizeof(__pyx_k_epj2jd), 0, 0, 1, 1},
+  {&__pyx_n_s_eps, __pyx_k_eps, sizeof(__pyx_k_eps), 0, 0, 1, 1},
+  {&__pyx_n_s_eps0, __pyx_k_eps0, sizeof(__pyx_k_eps0), 0, 0, 1, 1},
+  {&__pyx_n_s_epsa, __pyx_k_epsa, sizeof(__pyx_k_epsa), 0, 0, 1, 1},
+  {&__pyx_n_s_epv00, __pyx_k_epv00, sizeof(__pyx_k_epv00), 0, 0, 1, 1},
+  {&__pyx_n_s_eqeq94, __pyx_k_eqeq94, sizeof(__pyx_k_eqeq94), 0, 0, 1, 1},
+  {&__pyx_n_s_era, __pyx_k_era, sizeof(__pyx_k_era), 0, 0, 1, 1},
+  {&__pyx_n_s_era00, __pyx_k_era00, sizeof(__pyx_k_era00), 0, 0, 1, 1},
+  {&__pyx_n_s_f_2, __pyx_k_f_2, sizeof(__pyx_k_f_2), 0, 0, 1, 1},
+  {&__pyx_n_s_fad03, __pyx_k_fad03, sizeof(__pyx_k_fad03), 0, 0, 1, 1},
+  {&__pyx_n_s_fae03, __pyx_k_fae03, sizeof(__pyx_k_fae03), 0, 0, 1, 1},
+  {&__pyx_n_s_faf03, __pyx_k_faf03, sizeof(__pyx_k_faf03), 0, 0, 1, 1},
+  {&__pyx_n_s_faju03, __pyx_k_faju03, sizeof(__pyx_k_faju03), 0, 0, 1, 1},
+  {&__pyx_n_s_fal03, __pyx_k_fal03, sizeof(__pyx_k_fal03), 0, 0, 1, 1},
+  {&__pyx_n_s_falp03, __pyx_k_falp03, sizeof(__pyx_k_falp03), 0, 0, 1, 1},
+  {&__pyx_n_s_fama03, __pyx_k_fama03, sizeof(__pyx_k_fama03), 0, 0, 1, 1},
+  {&__pyx_n_s_fame03, __pyx_k_fame03, sizeof(__pyx_k_fame03), 0, 0, 1, 1},
+  {&__pyx_n_s_fane03, __pyx_k_fane03, sizeof(__pyx_k_fane03), 0, 0, 1, 1},
+  {&__pyx_n_s_faom03, __pyx_k_faom03, sizeof(__pyx_k_faom03), 0, 0, 1, 1},
+  {&__pyx_n_s_fapa03, __pyx_k_fapa03, sizeof(__pyx_k_fapa03), 0, 0, 1, 1},
+  {&__pyx_n_s_fasa03, __pyx_k_fasa03, sizeof(__pyx_k_fasa03), 0, 0, 1, 1},
+  {&__pyx_n_s_faur03, __pyx_k_faur03, sizeof(__pyx_k_faur03), 0, 0, 1, 1},
+  {&__pyx_n_s_fave03, __pyx_k_fave03, sizeof(__pyx_k_fave03), 0, 0, 1, 1},
+  {&__pyx_n_s_fd, __pyx_k_fd, sizeof(__pyx_k_fd), 0, 0, 1, 1},
+  {&__pyx_n_s_fk52h, __pyx_k_fk52h, sizeof(__pyx_k_fk52h), 0, 0, 1, 1},
+  {&__pyx_n_s_fk5hip, __pyx_k_fk5hip, sizeof(__pyx_k_fk5hip), 0, 0, 1, 1},
+  {&__pyx_n_s_fk5hz, __pyx_k_fk5hz, sizeof(__pyx_k_fk5hz), 0, 0, 1, 1},
+  {&__pyx_n_s_fw2m, __pyx_k_fw2m, sizeof(__pyx_k_fw2m), 0, 0, 1, 1},
+  {&__pyx_n_s_fw2xy, __pyx_k_fw2xy, sizeof(__pyx_k_fw2xy), 0, 0, 1, 1},
+  {&__pyx_n_s_gam, __pyx_k_gam, sizeof(__pyx_k_gam), 0, 0, 1, 1},
+  {&__pyx_n_s_gamb, __pyx_k_gamb, sizeof(__pyx_k_gamb), 0, 0, 1, 1},
+  {&__pyx_n_s_gc2gd, __pyx_k_gc2gd, sizeof(__pyx_k_gc2gd), 0, 0, 1, 1},
+  {&__pyx_n_s_gc2gde, __pyx_k_gc2gde, sizeof(__pyx_k_gc2gde), 0, 0, 1, 1},
+  {&__pyx_n_s_gd2gc, __pyx_k_gd2gc, sizeof(__pyx_k_gd2gc), 0, 0, 1, 1},
+  {&__pyx_n_s_gd2gce, __pyx_k_gd2gce, sizeof(__pyx_k_gd2gce), 0, 0, 1, 1},
+  {&__pyx_n_s_gmst00, __pyx_k_gmst00, sizeof(__pyx_k_gmst00), 0, 0, 1, 1},
+  {&__pyx_n_s_gmst06, __pyx_k_gmst06, sizeof(__pyx_k_gmst06), 0, 0, 1, 1},
+  {&__pyx_n_s_gmst82, __pyx_k_gmst82, sizeof(__pyx_k_gmst82), 0, 0, 1, 1},
+  {&__pyx_n_s_gst, __pyx_k_gst, sizeof(__pyx_k_gst), 0, 0, 1, 1},
+  {&__pyx_n_s_gst00a, __pyx_k_gst00a, sizeof(__pyx_k_gst00a), 0, 0, 1, 1},
+  {&__pyx_n_s_gst00b, __pyx_k_gst00b, sizeof(__pyx_k_gst00b), 0, 0, 1, 1},
+  {&__pyx_n_s_gst06, __pyx_k_gst06, sizeof(__pyx_k_gst06), 0, 0, 1, 1},
+  {&__pyx_n_s_gst06a, __pyx_k_gst06a, sizeof(__pyx_k_gst06a), 0, 0, 1, 1},
+  {&__pyx_n_s_gst94, __pyx_k_gst94, sizeof(__pyx_k_gst94), 0, 0, 1, 1},
+  {&__pyx_n_s_h2fk5, __pyx_k_h2fk5, sizeof(__pyx_k_h2fk5), 0, 0, 1, 1},
+  {&__pyx_n_s_height, __pyx_k_height, sizeof(__pyx_k_height), 0, 0, 1, 1},
+  {&__pyx_n_s_hfk5z, __pyx_k_hfk5z, sizeof(__pyx_k_hfk5z), 0, 0, 1, 1},
+  {&__pyx_n_s_hm, __pyx_k_hm, sizeof(__pyx_k_hm), 0, 0, 1, 1},
+  {&__pyx_n_s_hob, __pyx_k_hob, sizeof(__pyx_k_hob), 0, 0, 1, 1},
+  {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+  {&__pyx_n_s_ihmsf, __pyx_k_ihmsf, sizeof(__pyx_k_ihmsf), 0, 0, 1, 1},
+  {&__pyx_n_s_ihr, __pyx_k_ihr, sizeof(__pyx_k_ihr), 0, 0, 1, 1},
+  {&__pyx_n_s_im, __pyx_k_im, sizeof(__pyx_k_im), 0, 0, 1, 1},
+  {&__pyx_n_s_imn, __pyx_k_imn, sizeof(__pyx_k_imn), 0, 0, 1, 1},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_it, __pyx_k_it, sizeof(__pyx_k_it), 0, 0, 1, 1},
+  {&__pyx_n_s_iternext, __pyx_k_iternext, sizeof(__pyx_k_iternext), 0, 0, 1, 1},
+  {&__pyx_n_s_iy, __pyx_k_iy, sizeof(__pyx_k_iy), 0, 0, 1, 1},
+  {&__pyx_n_s_iymdf, __pyx_k_iymdf, sizeof(__pyx_k_iymdf), 0, 0, 1, 1},
+  {&__pyx_n_s_jd2cal, __pyx_k_jd2cal, sizeof(__pyx_k_jd2cal), 0, 0, 1, 1},
+  {&__pyx_n_s_jdcalf, __pyx_k_jdcalf, sizeof(__pyx_k_jdcalf), 0, 0, 1, 1},
+  {&__pyx_n_s_ld, __pyx_k_ld, sizeof(__pyx_k_ld), 0, 0, 1, 1},
+  {&__pyx_n_s_ldn, __pyx_k_ldn, sizeof(__pyx_k_ldn), 0, 0, 1, 1},
+  {&__pyx_n_s_ldsun, __pyx_k_ldsun, sizeof(__pyx_k_ldsun), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_n_s_ndp, __pyx_k_ndp, sizeof(__pyx_k_ndp), 0, 0, 1, 1},
+  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+  {&__pyx_n_s_num00a, __pyx_k_num00a, sizeof(__pyx_k_num00a), 0, 0, 1, 1},
+  {&__pyx_n_s_num00b, __pyx_k_num00b, sizeof(__pyx_k_num00b), 0, 0, 1, 1},
+  {&__pyx_n_s_num06a, __pyx_k_num06a, sizeof(__pyx_k_num06a), 0, 0, 1, 1},
+  {&__pyx_n_s_numat, __pyx_k_numat, sizeof(__pyx_k_numat), 0, 0, 1, 1},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_nut00a, __pyx_k_nut00a, sizeof(__pyx_k_nut00a), 0, 0, 1, 1},
+  {&__pyx_n_s_nut00b, __pyx_k_nut00b, sizeof(__pyx_k_nut00b), 0, 0, 1, 1},
+  {&__pyx_n_s_nut06a, __pyx_k_nut06a, sizeof(__pyx_k_nut06a), 0, 0, 1, 1},
+  {&__pyx_n_s_nut80, __pyx_k_nut80, sizeof(__pyx_k_nut80), 0, 0, 1, 1},
+  {&__pyx_n_s_nutm80, __pyx_k_nutm80, sizeof(__pyx_k_nutm80), 0, 0, 1, 1},
+  {&__pyx_n_s_ob, __pyx_k_ob, sizeof(__pyx_k_ob), 0, 0, 1, 1},
+  {&__pyx_n_s_ob1, __pyx_k_ob1, sizeof(__pyx_k_ob1), 0, 0, 1, 1},
+  {&__pyx_n_s_ob2, __pyx_k_ob2, sizeof(__pyx_k_ob2), 0, 0, 1, 1},
+  {&__pyx_n_s_obl06, __pyx_k_obl06, sizeof(__pyx_k_obl06), 0, 0, 1, 1},
+  {&__pyx_n_s_obl80, __pyx_k_obl80, sizeof(__pyx_k_obl80), 0, 0, 1, 1},
+  {&__pyx_n_s_oma, __pyx_k_oma, sizeof(__pyx_k_oma), 0, 0, 1, 1},
+  {&__pyx_n_s_p, __pyx_k_p, sizeof(__pyx_k_p), 0, 0, 1, 1},
+  {&__pyx_n_s_p06e, __pyx_k_p06e, sizeof(__pyx_k_p06e), 0, 0, 1, 1},
+  {&__pyx_n_s_p1, __pyx_k_p1, sizeof(__pyx_k_p1), 0, 0, 1, 1},
+  {&__pyx_n_s_pa, __pyx_k_pa, sizeof(__pyx_k_pa), 0, 0, 1, 1},
+  {&__pyx_n_s_pb06, __pyx_k_pb06, sizeof(__pyx_k_pb06), 0, 0, 1, 1},
+  {&__pyx_n_s_pco, __pyx_k_pco, sizeof(__pyx_k_pco), 0, 0, 1, 1},
+  {&__pyx_n_s_pd, __pyx_k_pd, sizeof(__pyx_k_pd), 0, 0, 1, 1},
+  {&__pyx_n_s_pfw06, __pyx_k_pfw06, sizeof(__pyx_k_pfw06), 0, 0, 1, 1},
+  {&__pyx_n_s_phi, __pyx_k_phi, sizeof(__pyx_k_phi), 0, 0, 1, 1},
+  {&__pyx_n_s_phib, __pyx_k_phib, sizeof(__pyx_k_phib), 0, 0, 1, 1},
+  {&__pyx_n_s_phpa, __pyx_k_phpa, sizeof(__pyx_k_phpa), 0, 0, 1, 1},
+  {&__pyx_n_s_pia, __pyx_k_pia, sizeof(__pyx_k_pia), 0, 0, 1, 1},
+  {&__pyx_n_s_plan94, __pyx_k_plan94, sizeof(__pyx_k_plan94), 0, 0, 1, 1},
+  {&__pyx_n_s_pmat00, __pyx_k_pmat00, sizeof(__pyx_k_pmat00), 0, 0, 1, 1},
+  {&__pyx_n_s_pmat06, __pyx_k_pmat06, sizeof(__pyx_k_pmat06), 0, 0, 1, 1},
+  {&__pyx_n_s_pmat76, __pyx_k_pmat76, sizeof(__pyx_k_pmat76), 0, 0, 1, 1},
+  {&__pyx_n_s_pmd, __pyx_k_pmd, sizeof(__pyx_k_pmd), 0, 0, 1, 1},
+  {&__pyx_n_s_pmd1, __pyx_k_pmd1, sizeof(__pyx_k_pmd1), 0, 0, 1, 1},
+  {&__pyx_n_s_pmd2, __pyx_k_pmd2, sizeof(__pyx_k_pmd2), 0, 0, 1, 1},
+  {&__pyx_n_s_pmpx, __pyx_k_pmpx, sizeof(__pyx_k_pmpx), 0, 0, 1, 1},
+  {&__pyx_n_s_pmr, __pyx_k_pmr, sizeof(__pyx_k_pmr), 0, 0, 1, 1},
+  {&__pyx_n_s_pmr1, __pyx_k_pmr1, sizeof(__pyx_k_pmr1), 0, 0, 1, 1},
+  {&__pyx_n_s_pmr2, __pyx_k_pmr2, sizeof(__pyx_k_pmr2), 0, 0, 1, 1},
+  {&__pyx_n_s_pmsafe, __pyx_k_pmsafe, sizeof(__pyx_k_pmsafe), 0, 0, 1, 1},
+  {&__pyx_n_s_pmt, __pyx_k_pmt, sizeof(__pyx_k_pmt), 0, 0, 1, 1},
+  {&__pyx_n_s_pn00, __pyx_k_pn00, sizeof(__pyx_k_pn00), 0, 0, 1, 1},
+  {&__pyx_n_s_pn00a, __pyx_k_pn00a, sizeof(__pyx_k_pn00a), 0, 0, 1, 1},
+  {&__pyx_n_s_pn00b, __pyx_k_pn00b, sizeof(__pyx_k_pn00b), 0, 0, 1, 1},
+  {&__pyx_n_s_pn06, __pyx_k_pn06, sizeof(__pyx_k_pn06), 0, 0, 1, 1},
+  {&__pyx_n_s_pn06a, __pyx_k_pn06a, sizeof(__pyx_k_pn06a), 0, 0, 1, 1},
+  {&__pyx_n_s_pnat, __pyx_k_pnat, sizeof(__pyx_k_pnat), 0, 0, 1, 1},
+  {&__pyx_n_s_pnm00a, __pyx_k_pnm00a, sizeof(__pyx_k_pnm00a), 0, 0, 1, 1},
+  {&__pyx_n_s_pnm00b, __pyx_k_pnm00b, sizeof(__pyx_k_pnm00b), 0, 0, 1, 1},
+  {&__pyx_n_s_pnm06a, __pyx_k_pnm06a, sizeof(__pyx_k_pnm06a), 0, 0, 1, 1},
+  {&__pyx_n_s_pnm80, __pyx_k_pnm80, sizeof(__pyx_k_pnm80), 0, 0, 1, 1},
+  {&__pyx_n_s_pob, __pyx_k_pob, sizeof(__pyx_k_pob), 0, 0, 1, 1},
+  {&__pyx_n_s_pom00, __pyx_k_pom00, sizeof(__pyx_k_pom00), 0, 0, 1, 1},
+  {&__pyx_n_s_ppr, __pyx_k_ppr, sizeof(__pyx_k_ppr), 0, 0, 1, 1},
+  {&__pyx_n_s_pr, __pyx_k_pr, sizeof(__pyx_k_pr), 0, 0, 1, 1},
+  {&__pyx_n_s_pr00, __pyx_k_pr00, sizeof(__pyx_k_pr00), 0, 0, 1, 1},
+  {&__pyx_n_s_prec76, __pyx_k_prec76, sizeof(__pyx_k_prec76), 0, 0, 1, 1},
+  {&__pyx_n_s_psi, __pyx_k_psi, sizeof(__pyx_k_psi), 0, 0, 1, 1},
+  {&__pyx_n_s_psia, __pyx_k_psia, sizeof(__pyx_k_psia), 0, 0, 1, 1},
+  {&__pyx_n_s_psib, __pyx_k_psib, sizeof(__pyx_k_psib), 0, 0, 1, 1},
+  {&__pyx_n_s_pv, __pyx_k_pv, sizeof(__pyx_k_pv), 0, 0, 1, 1},
+  {&__pyx_n_s_pvb, __pyx_k_pvb, sizeof(__pyx_k_pvb), 0, 0, 1, 1},
+  {&__pyx_n_s_pvh, __pyx_k_pvh, sizeof(__pyx_k_pvh), 0, 0, 1, 1},
+  {&__pyx_n_s_pvstar, __pyx_k_pvstar, sizeof(__pyx_k_pvstar), 0, 0, 1, 1},
+  {&__pyx_n_s_pvtob, __pyx_k_pvtob, sizeof(__pyx_k_pvtob), 0, 0, 1, 1},
+  {&__pyx_n_s_px, __pyx_k_px, sizeof(__pyx_k_px), 0, 0, 1, 1},
+  {&__pyx_n_s_px1, __pyx_k_px1, sizeof(__pyx_k_px1), 0, 0, 1, 1},
+  {&__pyx_n_s_px2, __pyx_k_px2, sizeof(__pyx_k_px2), 0, 0, 1, 1},
+  {&__pyx_n_s_px5, __pyx_k_px5, sizeof(__pyx_k_px5), 0, 0, 1, 1},
+  {&__pyx_n_s_pxh, __pyx_k_pxh, sizeof(__pyx_k_pxh), 0, 0, 1, 1},
+  {&__pyx_n_s_q_2, __pyx_k_q_2, sizeof(__pyx_k_q_2), 0, 0, 1, 1},
+  {&__pyx_n_s_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 0, 1, 1},
+  {&__pyx_n_s_r5, __pyx_k_r5, sizeof(__pyx_k_r5), 0, 0, 1, 1},
+  {&__pyx_n_s_r5h, __pyx_k_r5h, sizeof(__pyx_k_r5h), 0, 0, 1, 1},
+  {&__pyx_n_s_ra, __pyx_k_ra, sizeof(__pyx_k_ra), 0, 0, 1, 1},
+  {&__pyx_n_s_ra1, __pyx_k_ra1, sizeof(__pyx_k_ra1), 0, 0, 1, 1},
+  {&__pyx_n_s_ra2, __pyx_k_ra2, sizeof(__pyx_k_ra2), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_rb, __pyx_k_rb, sizeof(__pyx_k_rb), 0, 0, 1, 1},
+  {&__pyx_n_s_rbp, __pyx_k_rbp, sizeof(__pyx_k_rbp), 0, 0, 1, 1},
+  {&__pyx_n_s_rbpn, __pyx_k_rbpn, sizeof(__pyx_k_rbpn), 0, 0, 1, 1},
+  {&__pyx_n_s_rc, __pyx_k_rc, sizeof(__pyx_k_rc), 0, 0, 1, 1},
+  {&__pyx_n_s_rc2i, __pyx_k_rc2i, sizeof(__pyx_k_rc2i), 0, 0, 1, 1},
+  {&__pyx_n_s_rc2t, __pyx_k_rc2t, sizeof(__pyx_k_rc2t), 0, 0, 1, 1},
+  {&__pyx_n_s_refa, __pyx_k_refa, sizeof(__pyx_k_refa), 0, 0, 1, 1},
+  {&__pyx_n_s_refb, __pyx_k_refb, sizeof(__pyx_k_refb), 0, 0, 1, 1},
+  {&__pyx_n_s_refco, __pyx_k_refco, sizeof(__pyx_k_refco), 0, 0, 1, 1},
+  {&__pyx_n_s_rh, __pyx_k_rh, sizeof(__pyx_k_rh), 0, 0, 1, 1},
+  {&__pyx_n_s_ri, __pyx_k_ri, sizeof(__pyx_k_ri), 0, 0, 1, 1},
+  {&__pyx_n_s_rmatn, __pyx_k_rmatn, sizeof(__pyx_k_rmatn), 0, 0, 1, 1},
+  {&__pyx_n_s_rmatp, __pyx_k_rmatp, sizeof(__pyx_k_rmatp), 0, 0, 1, 1},
+  {&__pyx_n_s_rmatpn, __pyx_k_rmatpn, sizeof(__pyx_k_rmatpn), 0, 0, 1, 1},
+  {&__pyx_n_s_rn, __pyx_k_rn, sizeof(__pyx_k_rn), 0, 0, 1, 1},
+  {&__pyx_n_s_rnpb, __pyx_k_rnpb, sizeof(__pyx_k_rnpb), 0, 0, 1, 1},
+  {&__pyx_n_s_rob, __pyx_k_rob, sizeof(__pyx_k_rob), 0, 0, 1, 1},
+  {&__pyx_n_s_rp, __pyx_k_rp, sizeof(__pyx_k_rp), 0, 0, 1, 1},
+  {&__pyx_n_s_rpom, __pyx_k_rpom, sizeof(__pyx_k_rpom), 0, 0, 1, 1},
+  {&__pyx_n_s_rv, __pyx_k_rv, sizeof(__pyx_k_rv), 0, 0, 1, 1},
+  {&__pyx_n_s_rv1, __pyx_k_rv1, sizeof(__pyx_k_rv1), 0, 0, 1, 1},
+  {&__pyx_n_s_rv2, __pyx_k_rv2, sizeof(__pyx_k_rv2), 0, 0, 1, 1},
+  {&__pyx_n_s_rv5, __pyx_k_rv5, sizeof(__pyx_k_rv5), 0, 0, 1, 1},
+  {&__pyx_n_s_rvh, __pyx_k_rvh, sizeof(__pyx_k_rvh), 0, 0, 1, 1},
+  {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1},
+  {&__pyx_n_s_s00, __pyx_k_s00, sizeof(__pyx_k_s00), 0, 0, 1, 1},
+  {&__pyx_n_s_s00a, __pyx_k_s00a, sizeof(__pyx_k_s00a), 0, 0, 1, 1},
+  {&__pyx_n_s_s00b, __pyx_k_s00b, sizeof(__pyx_k_s00b), 0, 0, 1, 1},
+  {&__pyx_n_s_s06, __pyx_k_s06, sizeof(__pyx_k_s06), 0, 0, 1, 1},
+  {&__pyx_n_s_s06a, __pyx_k_s06a, sizeof(__pyx_k_s06a), 0, 0, 1, 1},
+  {&__pyx_n_s_s5h, __pyx_k_s5h, sizeof(__pyx_k_s5h), 0, 0, 1, 1},
+  {&__pyx_n_s_sc, __pyx_k_sc, sizeof(__pyx_k_sc), 0, 0, 1, 1},
+  {&__pyx_n_s_scale, __pyx_k_scale, sizeof(__pyx_k_scale), 0, 0, 1, 1},
+  {&__pyx_n_s_sec, __pyx_k_sec, sizeof(__pyx_k_sec), 0, 0, 1, 1},
+  {&__pyx_n_s_sn, __pyx_k_sn, sizeof(__pyx_k_sn), 0, 0, 1, 1},
+  {&__pyx_n_s_sp, __pyx_k_sp, sizeof(__pyx_k_sp), 0, 0, 1, 1},
+  {&__pyx_n_s_sp00, __pyx_k_sp00, sizeof(__pyx_k_sp00), 0, 0, 1, 1},
+  {&__pyx_n_s_starpm, __pyx_k_starpm, sizeof(__pyx_k_starpm), 0, 0, 1, 1},
+  {&__pyx_n_s_starpv, __pyx_k_starpv, sizeof(__pyx_k_starpv), 0, 0, 1, 1},
+  {&__pyx_n_s_stat_ok, __pyx_k_stat_ok, sizeof(__pyx_k_stat_ok), 0, 0, 1, 1},
+  {&__pyx_n_s_status, __pyx_k_status, sizeof(__pyx_k_status), 0, 0, 1, 1},
+  {&__pyx_n_s_t, __pyx_k_t, sizeof(__pyx_k_t), 0, 0, 1, 1},
+  {&__pyx_n_s_tai1, __pyx_k_tai1, sizeof(__pyx_k_tai1), 0, 0, 1, 1},
+  {&__pyx_n_s_tai2, __pyx_k_tai2, sizeof(__pyx_k_tai2), 0, 0, 1, 1},
+  {&__pyx_n_s_taitt, __pyx_k_taitt, sizeof(__pyx_k_taitt), 0, 0, 1, 1},
+  {&__pyx_n_s_taiut1, __pyx_k_taiut1, sizeof(__pyx_k_taiut1), 0, 0, 1, 1},
+  {&__pyx_n_s_taiutc, __pyx_k_taiutc, sizeof(__pyx_k_taiutc), 0, 0, 1, 1},
+  {&__pyx_n_s_tc, __pyx_k_tc, sizeof(__pyx_k_tc), 0, 0, 1, 1},
+  {&__pyx_n_s_tcb1, __pyx_k_tcb1, sizeof(__pyx_k_tcb1), 0, 0, 1, 1},
+  {&__pyx_n_s_tcb2, __pyx_k_tcb2, sizeof(__pyx_k_tcb2), 0, 0, 1, 1},
+  {&__pyx_n_s_tcbtdb, __pyx_k_tcbtdb, sizeof(__pyx_k_tcbtdb), 0, 0, 1, 1},
+  {&__pyx_n_s_tcg1, __pyx_k_tcg1, sizeof(__pyx_k_tcg1), 0, 0, 1, 1},
+  {&__pyx_n_s_tcg2, __pyx_k_tcg2, sizeof(__pyx_k_tcg2), 0, 0, 1, 1},
+  {&__pyx_n_s_tcgtt, __pyx_k_tcgtt, sizeof(__pyx_k_tcgtt), 0, 0, 1, 1},
+  {&__pyx_n_s_tdb1, __pyx_k_tdb1, sizeof(__pyx_k_tdb1), 0, 0, 1, 1},
+  {&__pyx_n_s_tdb2, __pyx_k_tdb2, sizeof(__pyx_k_tdb2), 0, 0, 1, 1},
+  {&__pyx_n_s_tdbtcb, __pyx_k_tdbtcb, sizeof(__pyx_k_tdbtcb), 0, 0, 1, 1},
+  {&__pyx_n_s_tdbtt, __pyx_k_tdbtt, sizeof(__pyx_k_tdbtt), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_n_s_theta, __pyx_k_theta, sizeof(__pyx_k_theta), 0, 0, 1, 1},
+  {&__pyx_n_s_thetaa, __pyx_k_thetaa, sizeof(__pyx_k_thetaa), 0, 0, 1, 1},
+  {&__pyx_n_s_tt1, __pyx_k_tt1, sizeof(__pyx_k_tt1), 0, 0, 1, 1},
+  {&__pyx_n_s_tt2, __pyx_k_tt2, sizeof(__pyx_k_tt2), 0, 0, 1, 1},
+  {&__pyx_n_s_tta, __pyx_k_tta, sizeof(__pyx_k_tta), 0, 0, 1, 1},
+  {&__pyx_n_s_ttb, __pyx_k_ttb, sizeof(__pyx_k_ttb), 0, 0, 1, 1},
+  {&__pyx_n_s_tttai, __pyx_k_tttai, sizeof(__pyx_k_tttai), 0, 0, 1, 1},
+  {&__pyx_n_s_tttcg, __pyx_k_tttcg, sizeof(__pyx_k_tttcg), 0, 0, 1, 1},
+  {&__pyx_n_s_tttdb, __pyx_k_tttdb, sizeof(__pyx_k_tttdb), 0, 0, 1, 1},
+  {&__pyx_n_s_ttut1, __pyx_k_ttut1, sizeof(__pyx_k_ttut1), 0, 0, 1, 1},
+  {&__pyx_n_s_type, __pyx_k_type, sizeof(__pyx_k_type), 0, 0, 1, 1},
+  {&__pyx_n_s_u, __pyx_k_u, sizeof(__pyx_k_u), 0, 0, 1, 1},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_n_s_ut, __pyx_k_ut, sizeof(__pyx_k_ut), 0, 0, 1, 1},
+  {&__pyx_n_s_ut11, __pyx_k_ut11, sizeof(__pyx_k_ut11), 0, 0, 1, 1},
+  {&__pyx_n_s_ut12, __pyx_k_ut12, sizeof(__pyx_k_ut12), 0, 0, 1, 1},
+  {&__pyx_n_s_ut1tai, __pyx_k_ut1tai, sizeof(__pyx_k_ut1tai), 0, 0, 1, 1},
+  {&__pyx_n_s_ut1tt, __pyx_k_ut1tt, sizeof(__pyx_k_ut1tt), 0, 0, 1, 1},
+  {&__pyx_n_s_ut1utc, __pyx_k_ut1utc, sizeof(__pyx_k_ut1utc), 0, 0, 1, 1},
+  {&__pyx_n_s_uta, __pyx_k_uta, sizeof(__pyx_k_uta), 0, 0, 1, 1},
+  {&__pyx_n_s_utb, __pyx_k_utb, sizeof(__pyx_k_utb), 0, 0, 1, 1},
+  {&__pyx_n_s_utc1, __pyx_k_utc1, sizeof(__pyx_k_utc1), 0, 0, 1, 1},
+  {&__pyx_n_s_utc2, __pyx_k_utc2, sizeof(__pyx_k_utc2), 0, 0, 1, 1},
+  {&__pyx_n_s_utctai, __pyx_k_utctai, sizeof(__pyx_k_utctai), 0, 0, 1, 1},
+  {&__pyx_n_s_utcut1, __pyx_k_utcut1, sizeof(__pyx_k_utcut1), 0, 0, 1, 1},
+  {&__pyx_n_s_utils_exceptions, __pyx_k_utils_exceptions, sizeof(__pyx_k_utils_exceptions), 0, 0, 1, 1},
+  {&__pyx_n_s_v, __pyx_k_v, sizeof(__pyx_k_v), 0, 0, 1, 1},
+  {&__pyx_n_s_warnings, __pyx_k_warnings, sizeof(__pyx_k_warnings), 0, 0, 1, 1},
+  {&__pyx_n_s_wl, __pyx_k_wl, sizeof(__pyx_k_wl), 0, 0, 1, 1},
+  {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1},
+  {&__pyx_n_s_xp, __pyx_k_xp, sizeof(__pyx_k_xp), 0, 0, 1, 1},
+  {&__pyx_n_s_xy06, __pyx_k_xy06, sizeof(__pyx_k_xy06), 0, 0, 1, 1},
+  {&__pyx_n_s_xys00a, __pyx_k_xys00a, sizeof(__pyx_k_xys00a), 0, 0, 1, 1},
+  {&__pyx_n_s_xys00b, __pyx_k_xys00b, sizeof(__pyx_k_xys00b), 0, 0, 1, 1},
+  {&__pyx_n_s_xys06a, __pyx_k_xys06a, sizeof(__pyx_k_xys06a), 0, 0, 1, 1},
+  {&__pyx_n_s_xyz, __pyx_k_xyz, sizeof(__pyx_k_xyz), 0, 0, 1, 1},
+  {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1},
+  {&__pyx_n_s_yp, __pyx_k_yp, sizeof(__pyx_k_yp), 0, 0, 1, 1},
+  {&__pyx_n_s_z, __pyx_k_z, sizeof(__pyx_k_z), 0, 0, 1, 1},
+  {&__pyx_n_s_za, __pyx_k_za, sizeof(__pyx_k_za), 0, 0, 1, 1},
+  {&__pyx_n_s_zeta, __pyx_k_zeta, sizeof(__pyx_k_zeta), 0, 0, 1, 1},
+  {&__pyx_n_s_zetaa, __pyx_k_zetaa, sizeof(__pyx_k_zetaa), 0, 0, 1, 1},
+  {&__pyx_n_s_zob, __pyx_k_zob, sizeof(__pyx_k_zob), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple_);
+  __Pyx_GIVEREF(__pyx_tuple_);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__2);
+  __Pyx_GIVEREF(__pyx_tuple__2);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__3);
+  __Pyx_GIVEREF(__pyx_tuple__3);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "astropy/_erfa/core.pyx":225
+ * 
+ * 
+ * def _cal2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+  __pyx_tuple__7 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_djm0, __pyx_n_s_djm, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
+  __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_cal2jd, 225, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":251
+ * 
+ * 
+ * def _epb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_tuple__9 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+  __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_epb, 251, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":267
+ * 
+ * 
+ * def _epb2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epb
+ */
+  __pyx_tuple__11 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_epb, __pyx_n_s_djm0, __pyx_n_s_djm, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__11);
+  __Pyx_GIVEREF(__pyx_tuple__11);
+  __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_epb2jd, 267, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":283
+ * 
+ * 
+ * def _epj(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_tuple__13 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__13);
+  __Pyx_GIVEREF(__pyx_tuple__13);
+  __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_epj, 283, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":299
+ * 
+ * 
+ * def _epj2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epj
+ */
+  __pyx_tuple__15 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_epj, __pyx_n_s_djm0, __pyx_n_s_djm, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__15);
+  __Pyx_GIVEREF(__pyx_tuple__15);
+  __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_epj2jd, 299, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":315
+ * 
+ * 
+ * def _jd2cal(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_tuple__17 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_fd, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__17);
+  __Pyx_GIVEREF(__pyx_tuple__17);
+  __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_jd2cal, 315, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":343
+ * 
+ * 
+ * def _jdcalf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _ndp
+ */
+  __pyx_tuple__19 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_ndp, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_iymdf, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__19);
+  __Pyx_GIVEREF(__pyx_tuple__19);
+  __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_jdcalf, 343, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":367
+ * 
+ * 
+ * def _ab(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pnat
+ */
+  __pyx_tuple__21 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_pnat, __pyx_n_s_v, __pyx_n_s_s, __pyx_n_s_bm1, __pyx_n_s_ppr, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__21);
+  __Pyx_GIVEREF(__pyx_tuple__21);
+  __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ab, 367, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":387
+ * 
+ * 
+ * def _apcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__23 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_ebpv, __pyx_n_s_ehp, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__23);
+  __Pyx_GIVEREF(__pyx_tuple__23);
+  __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apcg, 387, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":407
+ * 
+ * 
+ * def _apcg13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__25 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
+  __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apcg13, 407, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":423
+ * 
+ * 
+ * def _apci(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__27 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_ebpv, __pyx_n_s_ehp, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__27);
+  __Pyx_GIVEREF(__pyx_tuple__27);
+  __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apci, 423, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":449
+ * 
+ * 
+ * def _apci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__29 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_astrom, __pyx_n_s_eo, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__29);
+  __Pyx_GIVEREF(__pyx_tuple__29);
+  __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apci13, 449, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":467
+ * 
+ * 
+ * def _apco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__31 = PyTuple_Pack(21, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_ebpv, __pyx_n_s_ehp, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_theta, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_sp, __pyx_n_s_refa, __pyx_n_s_refb, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_ [...]
+  __Pyx_GOTREF(__pyx_tuple__31);
+  __Pyx_GIVEREF(__pyx_tuple__31);
+  __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(1, 0, 21, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apco, 467, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":511
+ * 
+ * 
+ * def _apco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_tuple__33 = PyTuple_Pack(20, __pyx_n_s_it, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_astrom, __pyx_n_s_eo, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__33);
+  __Pyx_GIVEREF(__pyx_tuple__33);
+  __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(1, 0, 20, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apco13, 511, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":555
+ * 
+ * 
+ * def _apcs(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__35 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_pv, __pyx_n_s_ebpv, __pyx_n_s_ehp, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__35);
+  __Pyx_GIVEREF(__pyx_tuple__35);
+  __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apcs, 555, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":577
+ * 
+ * 
+ * def _apcs13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__37 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_pv, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__37);
+  __Pyx_GIVEREF(__pyx_tuple__37);
+  __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apcs13, 577, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":595
+ * 
+ * 
+ * def _aper(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _theta
+ */
+  __pyx_tuple__39 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_theta, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__39);
+  __Pyx_GIVEREF(__pyx_tuple__39);
+  __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_aper, 595, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":609
+ * 
+ * 
+ * def _aper13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_tuple__41 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__41);
+  __Pyx_GIVEREF(__pyx_tuple__41);
+  __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_aper13, 609, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":625
+ * 
+ * 
+ * def _apio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _sp
+ */
+  __pyx_tuple__43 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_sp, __pyx_n_s_theta, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_refa, __pyx_n_s_refb, __pyx_n_s_astrom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__43);
+  __Pyx_GIVEREF(__pyx_tuple__43);
+  __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apio, 625, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":655
+ * 
+ * 
+ * def _apio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_tuple__45 = PyTuple_Pack(19, __pyx_n_s_it, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_astrom, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__45);
+  __Pyx_GIVEREF(__pyx_tuple__45);
+  __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(1, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_apio13, 655, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":697
+ * 
+ * 
+ * def _atci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__47 = PyTuple_Pack(15, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_pr, __pyx_n_s_pd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_eo, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__47);
+  __Pyx_GIVEREF(__pyx_tuple__47);
+  __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(1, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atci13, 697, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":729
+ * 
+ * 
+ * def _atciq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__49 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_pr, __pyx_n_s_pd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_astrom, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__49);
+  __Pyx_GIVEREF(__pyx_tuple__49);
+  __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atciq, 729, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":757
+ * 
+ * 
+ * def _atciqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__51 = PyTuple_Pack(15, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_pr, __pyx_n_s_pd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_astrom, __pyx_n_s_n, __pyx_n_s_b_2, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__51);
+  __Pyx_GIVEREF(__pyx_tuple__51);
+  __pyx_codeobj__52 = (PyObject*)__Pyx_PyCode_New(1, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__51, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atciqn, 757, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":789
+ * 
+ * 
+ * def _atciqz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__53 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_astrom, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__53);
+  __Pyx_GIVEREF(__pyx_tuple__53);
+  __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atciqz, 789, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":809
+ * 
+ * 
+ * def _atco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__55 = PyTuple_Pack(30, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_pr, __pyx_n_s_pd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_aob, __pyx_n_s_zob, __pyx_n_s_hob, __pyx_n_s_dob, __pyx_n_s_rob, __pyx_n_s_eo, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx [...]
+  __Pyx_GOTREF(__pyx_tuple__55);
+  __Pyx_GIVEREF(__pyx_tuple__55);
+  __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(1, 0, 30, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atco13, 809, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":873
+ * 
+ * 
+ * def _atic13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_tuple__57 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_eo, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 873; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__57);
+  __Pyx_GIVEREF(__pyx_tuple__57);
+  __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atic13, 873, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 873; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":897
+ * 
+ * 
+ * def _aticq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_tuple__59 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_astrom, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__59);
+  __Pyx_GIVEREF(__pyx_tuple__59);
+  __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_aticq, 897, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":917
+ * 
+ * 
+ * def _aticqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_tuple__61 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_astrom, __pyx_n_s_n, __pyx_n_s_b_2, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__61)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__61);
+  __Pyx_GIVEREF(__pyx_tuple__61);
+  __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_aticqn, 917, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":941
+ * 
+ * 
+ * def _atio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_tuple__63 = PyTuple_Pack(25, __pyx_n_s_it, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_aob, __pyx_n_s_zob, __pyx_n_s_hob, __pyx_n_s_dob, __pyx_n_s_rob, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__63)) {__pyx_filename = __pyx_ [...]
+  __Pyx_GOTREF(__pyx_tuple__63);
+  __Pyx_GIVEREF(__pyx_tuple__63);
+  __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(1, 0, 25, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atio13, 941, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":995
+ * 
+ * 
+ * def _atioq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_tuple__65 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_astrom, __pyx_n_s_aob, __pyx_n_s_zob, __pyx_n_s_hob, __pyx_n_s_dob, __pyx_n_s_rob, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__65);
+  __Pyx_GIVEREF(__pyx_tuple__65);
+  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atioq, 995, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1021
+ * 
+ * 
+ * def _atoc13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_tuple__67 = PyTuple_Pack(23, __pyx_n_s_it, __pyx_n_s_type, __pyx_n_s_ob1, __pyx_n_s_ob2, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __ [...]
+  __Pyx_GOTREF(__pyx_tuple__67);
+  __Pyx_GIVEREF(__pyx_tuple__67);
+  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 23, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atoc13, 1021, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1071
+ * 
+ * 
+ * def _atoi13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_tuple__69 = PyTuple_Pack(23, __pyx_n_s_it, __pyx_n_s_type, __pyx_n_s_ob1, __pyx_n_s_ob2, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __ [...]
+  __Pyx_GOTREF(__pyx_tuple__69);
+  __Pyx_GIVEREF(__pyx_tuple__69);
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 23, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atoi13, 1071, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1121
+ * 
+ * 
+ * def _atoiq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_tuple__71 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_type, __pyx_n_s_ob1, __pyx_n_s_ob2, __pyx_n_s_astrom, __pyx_n_s_ri, __pyx_n_s_di, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__71);
+  __Pyx_GIVEREF(__pyx_tuple__71);
+  __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_atoiq, 1121, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1143
+ * 
+ * 
+ * def _ld(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _bm
+ */
+  __pyx_tuple__73 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_bm, __pyx_n_s_p, __pyx_n_s_q_2, __pyx_n_s_e, __pyx_n_s_em, __pyx_n_s_dlim, __pyx_n_s_p1, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__73);
+  __Pyx_GIVEREF(__pyx_tuple__73);
+  __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ld, 1143, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1167
+ * 
+ * 
+ * def _ldn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_tuple__75 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_n, __pyx_n_s_b_2, __pyx_n_s_ob, __pyx_n_s_sc, __pyx_n_s_sn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__75);
+  __Pyx_GIVEREF(__pyx_tuple__75);
+  __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ldn, 1167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1187
+ * 
+ * 
+ * def _ldsun(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _p
+ */
+  __pyx_tuple__77 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_p, __pyx_n_s_e, __pyx_n_s_em, __pyx_n_s_p1, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__77);
+  __Pyx_GIVEREF(__pyx_tuple__77);
+  __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ldsun, 1187, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1205
+ * 
+ * 
+ * def _pmpx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_tuple__79 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_rc, __pyx_n_s_dc, __pyx_n_s_pr, __pyx_n_s_pd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_pmt, __pyx_n_s_pob, __pyx_n_s_pco, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__79);
+  __Pyx_GIVEREF(__pyx_tuple__79);
+  __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmpx, 1205, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1233
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_tuple__81 = PyTuple_Pack(22, __pyx_n_s_it, __pyx_n_s_ra1, __pyx_n_s_dec1, __pyx_n_s_pmr1, __pyx_n_s_pmd1, __pyx_n_s_px1, __pyx_n_s_rv1, __pyx_n_s_ep1a, __pyx_n_s_ep1b, __pyx_n_s_ep2a, __pyx_n_s_ep2b, __pyx_n_s_ra2, __pyx_n_s_dec2, __pyx_n_s_pmr2, __pyx_n_s_pmd2, __pyx_n_s_px2, __pyx_n_s_rv2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1233; __pyx_ [...]
+  __Pyx_GOTREF(__pyx_tuple__81);
+  __Pyx_GIVEREF(__pyx_tuple__81);
+  __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(1, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmsafe, 1233, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1281
+ * 
+ * 
+ * def _refco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _phpa
+ */
+  __pyx_tuple__83 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_phpa, __pyx_n_s_tc, __pyx_n_s_rh, __pyx_n_s_wl, __pyx_n_s_refa, __pyx_n_s_refb, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__83);
+  __Pyx_GIVEREF(__pyx_tuple__83);
+  __pyx_codeobj__84 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__83, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_refco, 1281, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1303
+ * 
+ * 
+ * def _epv00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__85 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_pvh, __pyx_n_s_pvb, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__85);
+  __Pyx_GIVEREF(__pyx_tuple__85);
+  __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_epv00, 1303, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1327
+ * 
+ * 
+ * def _plan94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__87 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_np, __pyx_n_s_pv, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__87);
+  __Pyx_GIVEREF(__pyx_tuple__87);
+  __pyx_codeobj__88 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__87, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_plan94, 1327, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1351
+ * 
+ * 
+ * def _fad03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__89 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__89);
+  __Pyx_GIVEREF(__pyx_tuple__89);
+  __pyx_codeobj__90 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__89, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fad03, 1351, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1365
+ * 
+ * 
+ * def _fae03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__91 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__91);
+  __Pyx_GIVEREF(__pyx_tuple__91);
+  __pyx_codeobj__92 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__91, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fae03, 1365, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1379
+ * 
+ * 
+ * def _faf03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__93 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__93)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__93);
+  __Pyx_GIVEREF(__pyx_tuple__93);
+  __pyx_codeobj__94 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__93, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_faf03, 1379, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__94)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1393
+ * 
+ * 
+ * def _faju03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__95 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__95)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__95);
+  __Pyx_GIVEREF(__pyx_tuple__95);
+  __pyx_codeobj__96 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__95, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_faju03, 1393, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__96)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1407
+ * 
+ * 
+ * def _fal03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__97 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__97)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__97);
+  __Pyx_GIVEREF(__pyx_tuple__97);
+  __pyx_codeobj__98 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__97, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fal03, 1407, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__98)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1421
+ * 
+ * 
+ * def _falp03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__99 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__99)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__99);
+  __Pyx_GIVEREF(__pyx_tuple__99);
+  __pyx_codeobj__100 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__99, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_falp03, 1421, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__100)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1435
+ * 
+ * 
+ * def _fama03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__101 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__101)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__101);
+  __Pyx_GIVEREF(__pyx_tuple__101);
+  __pyx_codeobj__102 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__101, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fama03, 1435, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__102)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1449
+ * 
+ * 
+ * def _fame03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__103 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__103)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__103);
+  __Pyx_GIVEREF(__pyx_tuple__103);
+  __pyx_codeobj__104 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__103, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fame03, 1449, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__104)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1463
+ * 
+ * 
+ * def _fane03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__105 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__105)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__105);
+  __Pyx_GIVEREF(__pyx_tuple__105);
+  __pyx_codeobj__106 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__105, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fane03, 1463, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__106)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1477
+ * 
+ * 
+ * def _faom03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__107 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__107)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__107);
+  __Pyx_GIVEREF(__pyx_tuple__107);
+  __pyx_codeobj__108 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__107, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_faom03, 1477, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__108)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1491
+ * 
+ * 
+ * def _fapa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__109 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__109)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__109);
+  __Pyx_GIVEREF(__pyx_tuple__109);
+  __pyx_codeobj__110 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__109, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fapa03, 1491, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__110)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1505
+ * 
+ * 
+ * def _fasa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__111 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__111)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__111);
+  __Pyx_GIVEREF(__pyx_tuple__111);
+  __pyx_codeobj__112 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__111, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fasa03, 1505, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__112)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1519
+ * 
+ * 
+ * def _faur03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__113 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__113)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__113);
+  __Pyx_GIVEREF(__pyx_tuple__113);
+  __pyx_codeobj__114 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__113, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_faur03, 1519, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__114)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1533
+ * 
+ * 
+ * def _fave03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_tuple__115 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_t, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__115)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__115);
+  __Pyx_GIVEREF(__pyx_tuple__115);
+  __pyx_codeobj__116 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__115, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fave03, 1533, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__116)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1547
+ * 
+ * 
+ * def _bi00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _dpsibi
+ */
+  __pyx_tuple__117 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_dpsibi, __pyx_n_s_depsbi, __pyx_n_s_dra, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__117)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__117);
+  __Pyx_GIVEREF(__pyx_tuple__117);
+  __pyx_codeobj__118 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__117, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_bi00, 1547, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__118)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1563
+ * 
+ * 
+ * def _bp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__119 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__119)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__119);
+  __Pyx_GIVEREF(__pyx_tuple__119);
+  __pyx_codeobj__120 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__119, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_bp00, 1563, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__120)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1583
+ * 
+ * 
+ * def _bp06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__121 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__121)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__121);
+  __Pyx_GIVEREF(__pyx_tuple__121);
+  __pyx_codeobj__122 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__121, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_bp06, 1583, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__122)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1603
+ * 
+ * 
+ * def _bpn2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+  __pyx_tuple__123 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_rbpn, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__123)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__123);
+  __Pyx_GIVEREF(__pyx_tuple__123);
+  __pyx_codeobj__124 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__123, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_bpn2xy, 1603, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__124)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1619
+ * 
+ * 
+ * def _c2i00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__125 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__125)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__125);
+  __Pyx_GIVEREF(__pyx_tuple__125);
+  __pyx_codeobj__126 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__125, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2i00a, 1619, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__126)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1635
+ * 
+ * 
+ * def _c2i00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__127 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__127)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__127);
+  __Pyx_GIVEREF(__pyx_tuple__127);
+  __pyx_codeobj__128 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__127, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2i00b, 1635, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__128)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1651
+ * 
+ * 
+ * def _c2i06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__129 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__129)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__129);
+  __Pyx_GIVEREF(__pyx_tuple__129);
+  __pyx_codeobj__130 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__129, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2i06a, 1651, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__130)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1667
+ * 
+ * 
+ * def _c2ibpn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__131 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rbpn, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__131)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__131);
+  __Pyx_GIVEREF(__pyx_tuple__131);
+  __pyx_codeobj__132 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__131, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2ibpn, 1667, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__132)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1685
+ * 
+ * 
+ * def _c2ixy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__133 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__133)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__133);
+  __Pyx_GIVEREF(__pyx_tuple__133);
+  __pyx_codeobj__134 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__133, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2ixy, 1685, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__134)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1705
+ * 
+ * 
+ * def _c2ixys(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _x
+ */
+  __pyx_tuple__135 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_rc2i, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__135)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__135);
+  __Pyx_GIVEREF(__pyx_tuple__135);
+  __pyx_codeobj__136 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__135, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2ixys, 1705, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__136)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1723
+ * 
+ * 
+ * def _c2t00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_tuple__137 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__137)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__137);
+  __Pyx_GIVEREF(__pyx_tuple__137);
+  __pyx_codeobj__138 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__137, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2t00a, 1723, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__138)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1747
+ * 
+ * 
+ * def _c2t00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_tuple__139 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__139)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__139);
+  __Pyx_GIVEREF(__pyx_tuple__139);
+  __pyx_codeobj__140 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__139, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2t00b, 1747, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__140)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1771
+ * 
+ * 
+ * def _c2t06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_tuple__141 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__141)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__141);
+  __Pyx_GIVEREF(__pyx_tuple__141);
+  __pyx_codeobj__142 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__141, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2t06a, 1771, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__142)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1795
+ * 
+ * 
+ * def _c2tcio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rc2i
+ */
+  __pyx_tuple__143 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_rc2i, __pyx_n_s_era, __pyx_n_s_rpom, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__143)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__143);
+  __Pyx_GIVEREF(__pyx_tuple__143);
+  __pyx_codeobj__144 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__143, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2tcio, 1795, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__144)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1813
+ * 
+ * 
+ * def _c2teqx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+  __pyx_tuple__145 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_rbpn, __pyx_n_s_gst, __pyx_n_s_rpom, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__145)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__145);
+  __Pyx_GIVEREF(__pyx_tuple__145);
+  __pyx_codeobj__146 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__145, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2teqx, 1813, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__146)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1831
+ * 
+ * 
+ * def _c2tpe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_tuple__147 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__147)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__147);
+  __Pyx_GIVEREF(__pyx_tuple__147);
+  __pyx_codeobj__148 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__147, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2tpe, 1831, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__148)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1859
+ * 
+ * 
+ * def _c2txy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_tuple__149 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_rc2t, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__149)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__149);
+  __Pyx_GIVEREF(__pyx_tuple__149);
+  __pyx_codeobj__150 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__149, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_c2txy, 1859, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__150)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1887
+ * 
+ * 
+ * def _eo06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__151 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__151)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__151);
+  __Pyx_GIVEREF(__pyx_tuple__151);
+  __pyx_codeobj__152 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__151, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_eo06a, 1887, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__152)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1903
+ * 
+ * 
+ * def _eors(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rnpb
+ */
+  __pyx_tuple__153 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_rnpb, __pyx_n_s_s, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__153)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__153);
+  __Pyx_GIVEREF(__pyx_tuple__153);
+  __pyx_codeobj__154 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__153, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_eors, 1903, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__154)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1919
+ * 
+ * 
+ * def _fw2m(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+  __pyx_tuple__155 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_gamb, __pyx_n_s_phib, __pyx_n_s_psi, __pyx_n_s_eps, __pyx_n_s_r, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__155)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__155);
+  __Pyx_GIVEREF(__pyx_tuple__155);
+  __pyx_codeobj__156 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__155, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fw2m, 1919, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__156)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1939
+ * 
+ * 
+ * def _fw2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+  __pyx_tuple__157 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_gamb, __pyx_n_s_phib, __pyx_n_s_psi, __pyx_n_s_eps, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__157)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__157);
+  __Pyx_GIVEREF(__pyx_tuple__157);
+  __pyx_codeobj__158 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__157, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fw2xy, 1939, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__158)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1961
+ * 
+ * 
+ * def _num00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__159 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__159)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__159);
+  __Pyx_GIVEREF(__pyx_tuple__159);
+  __pyx_codeobj__160 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__159, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_num00a, 1961, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__160)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1977
+ * 
+ * 
+ * def _num00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__161 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__161)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__161);
+  __Pyx_GIVEREF(__pyx_tuple__161);
+  __pyx_codeobj__162 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__161, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_num00b, 1977, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__162)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":1993
+ * 
+ * 
+ * def _num06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__163 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__163)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__163);
+  __Pyx_GIVEREF(__pyx_tuple__163);
+  __pyx_codeobj__164 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__163, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_num06a, 1993, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__164)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2009
+ * 
+ * 
+ * def _numat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epsa
+ */
+  __pyx_tuple__165 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_epsa, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_rmatn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__165)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__165);
+  __Pyx_GIVEREF(__pyx_tuple__165);
+  __pyx_codeobj__166 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__165, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_numat, 2009, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__166)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2027
+ * 
+ * 
+ * def _nut00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__167 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__167)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__167);
+  __Pyx_GIVEREF(__pyx_tuple__167);
+  __pyx_codeobj__168 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__167, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_nut00a, 2027, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__168)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2045
+ * 
+ * 
+ * def _nut00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__169 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__169)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__169);
+  __Pyx_GIVEREF(__pyx_tuple__169);
+  __pyx_codeobj__170 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__169, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_nut00b, 2045, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__170)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2063
+ * 
+ * 
+ * def _nut06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__171 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__171)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__171);
+  __Pyx_GIVEREF(__pyx_tuple__171);
+  __pyx_codeobj__172 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__171, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_nut06a, 2063, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__172)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2081
+ * 
+ * 
+ * def _nut80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__173 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__173)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__173);
+  __Pyx_GIVEREF(__pyx_tuple__173);
+  __pyx_codeobj__174 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__173, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_nut80, 2081, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__174)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2099
+ * 
+ * 
+ * def _nutm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__175 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__175)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__175);
+  __Pyx_GIVEREF(__pyx_tuple__175);
+  __pyx_codeobj__176 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__175, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_nutm80, 2099, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__176)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2115
+ * 
+ * 
+ * def _obl06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__177 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__177)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__177);
+  __Pyx_GIVEREF(__pyx_tuple__177);
+  __pyx_codeobj__178 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__177, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_obl06, 2115, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__178)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2131
+ * 
+ * 
+ * def _obl80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__179 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__179)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__179);
+  __Pyx_GIVEREF(__pyx_tuple__179);
+  __pyx_codeobj__180 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__179, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_obl80, 2131, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__180)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2147
+ * 
+ * 
+ * def _p06e(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__181 = PyTuple_Pack(22, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_eps0, __pyx_n_s_psia, __pyx_n_s_oma, __pyx_n_s_bpa, __pyx_n_s_bqa, __pyx_n_s_pia, __pyx_n_s_bpia, __pyx_n_s_epsa, __pyx_n_s_chia, __pyx_n_s_za, __pyx_n_s_zetaa, __pyx_n_s_thetaa, __pyx_n_s_pa, __pyx_n_s_gam, __pyx_n_s_phi, __pyx_n_s_psi, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__181)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2147; __pyx_cline [...]
+  __Pyx_GOTREF(__pyx_tuple__181);
+  __Pyx_GIVEREF(__pyx_tuple__181);
+  __pyx_codeobj__182 = (PyObject*)__Pyx_PyCode_New(1, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__181, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_p06e, 2147, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__182)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2193
+ * 
+ * 
+ * def _pb06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__183 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_bzeta, __pyx_n_s_bz, __pyx_n_s_btheta, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__183)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__183);
+  __Pyx_GIVEREF(__pyx_tuple__183);
+  __pyx_codeobj__184 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__183, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pb06, 2193, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__184)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2213
+ * 
+ * 
+ * def _pfw06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__185 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_gamb, __pyx_n_s_phib, __pyx_n_s_psib, __pyx_n_s_epsa, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__185)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__185);
+  __Pyx_GIVEREF(__pyx_tuple__185);
+  __pyx_codeobj__186 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__185, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pfw06, 2213, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__186)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2235
+ * 
+ * 
+ * def _pmat00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__187 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rbp, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__187)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__187);
+  __Pyx_GIVEREF(__pyx_tuple__187);
+  __pyx_codeobj__188 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__187, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmat00, 2235, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__188)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2251
+ * 
+ * 
+ * def _pmat06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__189 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rbp, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__189)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__189);
+  __Pyx_GIVEREF(__pyx_tuple__189);
+  __pyx_codeobj__190 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__189, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmat06, 2251, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__190)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2267
+ * 
+ * 
+ * def _pmat76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__191 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatp, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__191)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__191);
+  __Pyx_GIVEREF(__pyx_tuple__191);
+  __pyx_codeobj__192 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__191, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmat76, 2267, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__192)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2283
+ * 
+ * 
+ * def _pn00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__193 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_epsa, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_rn, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__193)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__193);
+  __Pyx_GIVEREF(__pyx_tuple__193);
+  __pyx_codeobj__194 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__193, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pn00, 2283, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__194)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2313
+ * 
+ * 
+ * def _pn00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__195 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_epsa, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_rn, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__195)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__195);
+  __Pyx_GIVEREF(__pyx_tuple__195);
+  __pyx_codeobj__196 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__195, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pn00a, 2313, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__196)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2343
+ * 
+ * 
+ * def _pn00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__197 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_epsa, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_rn, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__197)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__197);
+  __Pyx_GIVEREF(__pyx_tuple__197);
+  __pyx_codeobj__198 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__197, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pn00b, 2343, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__198)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2373
+ * 
+ * 
+ * def _pn06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__199 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_epsa, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_rn, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__199)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__199);
+  __Pyx_GIVEREF(__pyx_tuple__199);
+  __pyx_codeobj__200 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__199, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pn06, 2373, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__200)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2403
+ * 
+ * 
+ * def _pn06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__201 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsi, __pyx_n_s_deps, __pyx_n_s_epsa, __pyx_n_s_rb, __pyx_n_s_rp, __pyx_n_s_rbp, __pyx_n_s_rn, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__201)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__201);
+  __Pyx_GIVEREF(__pyx_tuple__201);
+  __pyx_codeobj__202 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__201, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pn06a, 2403, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__202)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2433
+ * 
+ * 
+ * def _pnm00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__203 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__203)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__203);
+  __Pyx_GIVEREF(__pyx_tuple__203);
+  __pyx_codeobj__204 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__203, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pnm00a, 2433, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__204)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2449
+ * 
+ * 
+ * def _pnm00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__205 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rbpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__205)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__205);
+  __Pyx_GIVEREF(__pyx_tuple__205);
+  __pyx_codeobj__206 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__205, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pnm00b, 2449, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__206)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2465
+ * 
+ * 
+ * def _pnm06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__207 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rnpb, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__207)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__207);
+  __Pyx_GIVEREF(__pyx_tuple__207);
+  __pyx_codeobj__208 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__207, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pnm06a, 2465, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__208)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2481
+ * 
+ * 
+ * def _pnm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__209 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rmatpn, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__209)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__209);
+  __Pyx_GIVEREF(__pyx_tuple__209);
+  __pyx_codeobj__210 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__209, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pnm80, 2481, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__210)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2497
+ * 
+ * 
+ * def _pom00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _xp
+ */
+  __pyx_tuple__211 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_sp, __pyx_n_s_rpom, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__211)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__211);
+  __Pyx_GIVEREF(__pyx_tuple__211);
+  __pyx_codeobj__212 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__211, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pom00, 2497, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__212)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2515
+ * 
+ * 
+ * def _pr00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__213 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_dpsipr, __pyx_n_s_depspr, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__213)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__213);
+  __Pyx_GIVEREF(__pyx_tuple__213);
+  __pyx_codeobj__214 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__213, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pr00, 2515, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__214)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2533
+ * 
+ * 
+ * def _prec76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date01
+ */
+  __pyx_tuple__215 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_date01, __pyx_n_s_date02, __pyx_n_s_date11, __pyx_n_s_date12, __pyx_n_s_zeta, __pyx_n_s_z, __pyx_n_s_theta, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__215)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__215);
+  __Pyx_GIVEREF(__pyx_tuple__215);
+  __pyx_codeobj__216 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__215, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_prec76, 2533, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__216)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2557
+ * 
+ * 
+ * def _s00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__217 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__217)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__217);
+  __Pyx_GIVEREF(__pyx_tuple__217);
+  __pyx_codeobj__218 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__217, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_s00, 2557, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__218)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2577
+ * 
+ * 
+ * def _s00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__219 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__219)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__219);
+  __Pyx_GIVEREF(__pyx_tuple__219);
+  __pyx_codeobj__220 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__219, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_s00a, 2577, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__220)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2593
+ * 
+ * 
+ * def _s00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__221 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__221)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__221);
+  __Pyx_GIVEREF(__pyx_tuple__221);
+  __pyx_codeobj__222 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__221, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_s00b, 2593, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__222)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2609
+ * 
+ * 
+ * def _s06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__223 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__223)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__223);
+  __Pyx_GIVEREF(__pyx_tuple__223);
+  __pyx_codeobj__224 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__223, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_s06, 2609, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__224)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2629
+ * 
+ * 
+ * def _s06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__225 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__225)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__225);
+  __Pyx_GIVEREF(__pyx_tuple__225);
+  __pyx_codeobj__226 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__225, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_s06a, 2629, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__226)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2645
+ * 
+ * 
+ * def _sp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__227 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__227)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__227);
+  __Pyx_GIVEREF(__pyx_tuple__227);
+  __pyx_codeobj__228 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__227, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_sp00, 2645, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__228)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2661
+ * 
+ * 
+ * def _xy06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__229 = PyTuple_Pack(8, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__229)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__229);
+  __Pyx_GIVEREF(__pyx_tuple__229);
+  __pyx_codeobj__230 = (PyObject*)__Pyx_PyCode_New(1, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__229, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_xy06, 2661, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__230)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2679
+ * 
+ * 
+ * def _xys00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__231 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__231)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__231);
+  __Pyx_GIVEREF(__pyx_tuple__231);
+  __pyx_codeobj__232 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__231, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_xys00a, 2679, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__232)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2699
+ * 
+ * 
+ * def _xys00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__233 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__233)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__233);
+  __Pyx_GIVEREF(__pyx_tuple__233);
+  __pyx_codeobj__234 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__233, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_xys00b, 2699, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__234)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2719
+ * 
+ * 
+ * def _xys06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__235 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_s, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__235)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__235);
+  __Pyx_GIVEREF(__pyx_tuple__235);
+  __pyx_codeobj__236 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__235, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_xys06a, 2719, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__236)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2739
+ * 
+ * 
+ * def _ee00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__237 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_epsa, __pyx_n_s_dpsi, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__237)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__237);
+  __Pyx_GIVEREF(__pyx_tuple__237);
+  __pyx_codeobj__238 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__237, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ee00, 2739, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__238)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2759
+ * 
+ * 
+ * def _ee00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__239 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__239)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__239);
+  __Pyx_GIVEREF(__pyx_tuple__239);
+  __pyx_codeobj__240 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__239, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ee00a, 2759, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__240)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2775
+ * 
+ * 
+ * def _ee00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__241 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__241)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__241);
+  __Pyx_GIVEREF(__pyx_tuple__241);
+  __pyx_codeobj__242 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__241, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ee00b, 2775, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__242)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2791
+ * 
+ * 
+ * def _ee06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__243 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__243)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__243);
+  __Pyx_GIVEREF(__pyx_tuple__243);
+  __pyx_codeobj__244 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__243, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ee06a, 2791, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__244)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2807
+ * 
+ * 
+ * def _eect00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__245 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__245)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__245);
+  __Pyx_GIVEREF(__pyx_tuple__245);
+  __pyx_codeobj__246 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__245, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_eect00, 2807, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__246)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2823
+ * 
+ * 
+ * def _eqeq94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__247 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__247)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__247);
+  __Pyx_GIVEREF(__pyx_tuple__247);
+  __pyx_codeobj__248 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__247, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_eqeq94, 2823, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__248)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2839
+ * 
+ * 
+ * def _era00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_tuple__249 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__249)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__249);
+  __Pyx_GIVEREF(__pyx_tuple__249);
+  __pyx_codeobj__250 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__249, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_era00, 2839, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__250)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2855
+ * 
+ * 
+ * def _gmst00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__251 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__251)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__251);
+  __Pyx_GIVEREF(__pyx_tuple__251);
+  __pyx_codeobj__252 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__251, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gmst00, 2855, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__252)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2875
+ * 
+ * 
+ * def _gmst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__253 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__253)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__253);
+  __Pyx_GIVEREF(__pyx_tuple__253);
+  __pyx_codeobj__254 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__253, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gmst06, 2875, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__254)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2895
+ * 
+ * 
+ * def _gmst82(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_tuple__255 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_dj1, __pyx_n_s_dj2, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__255)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__255);
+  __Pyx_GIVEREF(__pyx_tuple__255);
+  __pyx_codeobj__256 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__255, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gmst82, 2895, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__256)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2911
+ * 
+ * 
+ * def _gst00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__257 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__257)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__257);
+  __Pyx_GIVEREF(__pyx_tuple__257);
+  __pyx_codeobj__258 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__257, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gst00a, 2911, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__258)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2931
+ * 
+ * 
+ * def _gst00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__259 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__259)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__259);
+  __Pyx_GIVEREF(__pyx_tuple__259);
+  __pyx_codeobj__260 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__259, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gst00b, 2931, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__260)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2947
+ * 
+ * 
+ * def _gst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__261 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_rnpb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__261)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__261);
+  __Pyx_GIVEREF(__pyx_tuple__261);
+  __pyx_codeobj__262 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__261, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gst06, 2947, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__262)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2969
+ * 
+ * 
+ * def _gst06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__263 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_tta, __pyx_n_s_ttb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__263)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__263);
+  __Pyx_GIVEREF(__pyx_tuple__263);
+  __pyx_codeobj__264 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__263, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gst06a, 2969, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__264)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":2989
+ * 
+ * 
+ * def _gst94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_tuple__265 = PyTuple_Pack(7, __pyx_n_s_it, __pyx_n_s_uta, __pyx_n_s_utb, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__265)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__265);
+  __Pyx_GIVEREF(__pyx_tuple__265);
+  __pyx_codeobj__266 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__265, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gst94, 2989, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__266)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3005
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_tuple__267 = PyTuple_Pack(22, __pyx_n_s_it, __pyx_n_s_ra1, __pyx_n_s_dec1, __pyx_n_s_pmr1, __pyx_n_s_pmd1, __pyx_n_s_px1, __pyx_n_s_rv1, __pyx_n_s_ep1a, __pyx_n_s_ep1b, __pyx_n_s_ep2a, __pyx_n_s_ep2b, __pyx_n_s_ra2, __pyx_n_s_dec2, __pyx_n_s_pmr2, __pyx_n_s_pmd2, __pyx_n_s_px2, __pyx_n_s_rv2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__267)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3005; __py [...]
+  __Pyx_GOTREF(__pyx_tuple__267);
+  __Pyx_GIVEREF(__pyx_tuple__267);
+  __pyx_codeobj__268 = (PyObject*)__Pyx_PyCode_New(1, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__267, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pmsafe, 3005, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__268)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3053
+ * 
+ * 
+ * def _pvstar(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pv
+ */
+  __pyx_tuple__269 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_pv, __pyx_n_s_ra, __pyx_n_s_dec, __pyx_n_s_pmr, __pyx_n_s_pmd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__269)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__269);
+  __Pyx_GIVEREF(__pyx_tuple__269);
+  __pyx_codeobj__270 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__269, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pvstar, 3053, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__270)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3083
+ * 
+ * 
+ * def _starpv(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra
+ */
+  __pyx_tuple__271 = PyTuple_Pack(13, __pyx_n_s_it, __pyx_n_s_ra, __pyx_n_s_dec, __pyx_n_s_pmr, __pyx_n_s_pmd, __pyx_n_s_px, __pyx_n_s_rv, __pyx_n_s_pv, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__271)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__271);
+  __Pyx_GIVEREF(__pyx_tuple__271);
+  __pyx_codeobj__272 = (PyObject*)__Pyx_PyCode_New(1, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__271, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_starpv, 3083, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__272)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3113
+ * 
+ * 
+ * def _fk52h(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+  __pyx_tuple__273 = PyTuple_Pack(16, __pyx_n_s_it, __pyx_n_s_r5, __pyx_n_s_d5, __pyx_n_s_dr5, __pyx_n_s_dd5, __pyx_n_s_px5, __pyx_n_s_rv5, __pyx_n_s_rh, __pyx_n_s_dh, __pyx_n_s_drh, __pyx_n_s_ddh, __pyx_n_s_pxh, __pyx_n_s_rvh, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__273)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__273);
+  __Pyx_GIVEREF(__pyx_tuple__273);
+  __pyx_codeobj__274 = (PyObject*)__Pyx_PyCode_New(1, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__273, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fk52h, 3113, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__274)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3147
+ * 
+ * 
+ * def _fk5hip(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _r5h
+ */
+  __pyx_tuple__275 = PyTuple_Pack(6, __pyx_n_s_it, __pyx_n_s_r5h, __pyx_n_s_s5h, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__275)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__275);
+  __Pyx_GIVEREF(__pyx_tuple__275);
+  __pyx_codeobj__276 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__275, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fk5hip, 3147, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__276)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3161
+ * 
+ * 
+ * def _fk5hz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+  __pyx_tuple__277 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_r5, __pyx_n_s_d5, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_rh, __pyx_n_s_dh, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__277)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__277);
+  __Pyx_GIVEREF(__pyx_tuple__277);
+  __pyx_codeobj__278 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__277, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_fk5hz, 3161, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__278)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3183
+ * 
+ * 
+ * def _h2fk5(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+  __pyx_tuple__279 = PyTuple_Pack(16, __pyx_n_s_it, __pyx_n_s_rh, __pyx_n_s_dh, __pyx_n_s_drh, __pyx_n_s_ddh, __pyx_n_s_pxh, __pyx_n_s_rvh, __pyx_n_s_r5, __pyx_n_s_d5, __pyx_n_s_dr5, __pyx_n_s_dd5, __pyx_n_s_px5, __pyx_n_s_rv5, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__279)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__279);
+  __Pyx_GIVEREF(__pyx_tuple__279);
+  __pyx_codeobj__280 = (PyObject*)__Pyx_PyCode_New(1, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__279, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_h2fk5, 3183, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__280)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3217
+ * 
+ * 
+ * def _hfk5z(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+  __pyx_tuple__281 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_rh, __pyx_n_s_dh, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_r5, __pyx_n_s_d5, __pyx_n_s_dr5, __pyx_n_s_dd5, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__281)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__281);
+  __Pyx_GIVEREF(__pyx_tuple__281);
+  __pyx_codeobj__282 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__281, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_hfk5z, 3217, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__282)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3243
+ * 
+ * 
+ * def _starpm(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_tuple__283 = PyTuple_Pack(22, __pyx_n_s_it, __pyx_n_s_ra1, __pyx_n_s_dec1, __pyx_n_s_pmr1, __pyx_n_s_pmd1, __pyx_n_s_px1, __pyx_n_s_rv1, __pyx_n_s_ep1a, __pyx_n_s_ep1b, __pyx_n_s_ep2a, __pyx_n_s_ep2b, __pyx_n_s_ra2, __pyx_n_s_dec2, __pyx_n_s_pmr2, __pyx_n_s_pmd2, __pyx_n_s_px2, __pyx_n_s_rv2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__283)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3243; __py [...]
+  __Pyx_GOTREF(__pyx_tuple__283);
+  __Pyx_GIVEREF(__pyx_tuple__283);
+  __pyx_codeobj__284 = (PyObject*)__Pyx_PyCode_New(1, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__283, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_starpm, 3243, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__284)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3291
+ * 
+ * 
+ * def _eform(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_tuple__285 = PyTuple_Pack(9, __pyx_n_s_it, __pyx_n_s_n, __pyx_n_s_a, __pyx_n_s_f_2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__285)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__285);
+  __Pyx_GIVEREF(__pyx_tuple__285);
+  __pyx_codeobj__286 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__285, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_eform, 3291, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__286)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3313
+ * 
+ * 
+ * def _gc2gd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_tuple__287 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_n, __pyx_n_s_xyz, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__287)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__287);
+  __Pyx_GIVEREF(__pyx_tuple__287);
+  __pyx_codeobj__288 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__287, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gc2gd, 3313, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__288)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3339
+ * 
+ * 
+ * def _gc2gde(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+  __pyx_tuple__289 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_a, __pyx_n_s_f_2, __pyx_n_s_xyz, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__289)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3339; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__289);
+  __Pyx_GIVEREF(__pyx_tuple__289);
+  __pyx_codeobj__290 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__289, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gc2gde, 3339, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__290)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3339; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3367
+ * 
+ * 
+ * def _gd2gc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_tuple__291 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_n, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_xyz, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__291)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__291);
+  __Pyx_GIVEREF(__pyx_tuple__291);
+  __pyx_codeobj__292 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__291, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gd2gc, 3367, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__292)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3393
+ * 
+ * 
+ * def _gd2gce(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+  __pyx_tuple__293 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_a, __pyx_n_s_f_2, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_xyz, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__293)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__293);
+  __Pyx_GIVEREF(__pyx_tuple__293);
+  __pyx_codeobj__294 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__293, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_gd2gce, 3393, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__294)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3421
+ * 
+ * 
+ * def _pvtob(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _elong
+ */
+  __pyx_tuple__295 = PyTuple_Pack(12, __pyx_n_s_it, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_hm, __pyx_n_s_xp, __pyx_n_s_yp, __pyx_n_s_sp, __pyx_n_s_theta, __pyx_n_s_pv, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__295)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__295);
+  __Pyx_GIVEREF(__pyx_tuple__295);
+  __pyx_codeobj__296 = (PyObject*)__Pyx_PyCode_New(1, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__295, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_pvtob, 3421, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__296)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3447
+ * 
+ * 
+ * def _d2dtf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+  __pyx_tuple__297 = PyTuple_Pack(14, __pyx_n_s_it, __pyx_n_s_scale, __pyx_n_s_ndp, __pyx_n_s_d1, __pyx_n_s_d2, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_ihmsf, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__297)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__297);
+  __Pyx_GIVEREF(__pyx_tuple__297);
+  __pyx_codeobj__298 = (PyObject*)__Pyx_PyCode_New(1, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__297, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_d2dtf, 3447, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__298)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3479
+ * 
+ * 
+ * def _dat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+  __pyx_tuple__299 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_fd, __pyx_n_s_deltat, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__299)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__299);
+  __Pyx_GIVEREF(__pyx_tuple__299);
+  __pyx_codeobj__300 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__299, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_dat, 3479, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__300)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3505
+ * 
+ * 
+ * def _dtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_tuple__301 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_date1, __pyx_n_s_date2, __pyx_n_s_ut, __pyx_n_s_elong, __pyx_n_s_u, __pyx_n_s_v, __pyx_n_s_c_retval, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__301)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__301);
+  __Pyx_GIVEREF(__pyx_tuple__301);
+  __pyx_codeobj__302 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__301, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_dtdb, 3505, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__302)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3529
+ * 
+ * 
+ * def _dtf2d(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+  __pyx_tuple__303 = PyTuple_Pack(15, __pyx_n_s_it, __pyx_n_s_scale, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_ihr, __pyx_n_s_imn, __pyx_n_s_sec, __pyx_n_s_d1, __pyx_n_s_d2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__303)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__303);
+  __Pyx_GIVEREF(__pyx_tuple__303);
+  __pyx_codeobj__304 = (PyObject*)__Pyx_PyCode_New(1, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__303, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_dtf2d, 3529, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__304)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3563
+ * 
+ * 
+ * def _taitt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_tuple__305 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__305)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__305);
+  __Pyx_GIVEREF(__pyx_tuple__305);
+  __pyx_codeobj__306 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__305, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_taitt, 3563, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__306)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3587
+ * 
+ * 
+ * def _taiut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_tuple__307 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_dta, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__307)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__307);
+  __Pyx_GIVEREF(__pyx_tuple__307);
+  __pyx_codeobj__308 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__307, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_taiut1, 3587, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__308)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3613
+ * 
+ * 
+ * def _taiutc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_tuple__309 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__309)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3613; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__309);
+  __Pyx_GIVEREF(__pyx_tuple__309);
+  __pyx_codeobj__310 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__309, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_taiutc, 3613, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__310)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3613; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3637
+ * 
+ * 
+ * def _tcbtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcb1
+ */
+  __pyx_tuple__311 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tcb1, __pyx_n_s_tcb2, __pyx_n_s_tdb1, __pyx_n_s_tdb2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__311)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__311);
+  __Pyx_GIVEREF(__pyx_tuple__311);
+  __pyx_codeobj__312 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__311, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tcbtdb, 3637, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__312)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3661
+ * 
+ * 
+ * def _tcgtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcg1
+ */
+  __pyx_tuple__313 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tcg1, __pyx_n_s_tcg2, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__313)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__313);
+  __Pyx_GIVEREF(__pyx_tuple__313);
+  __pyx_codeobj__314 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__313, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tcgtt, 3661, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__314)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3685
+ * 
+ * 
+ * def _tdbtcb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+  __pyx_tuple__315 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tdb1, __pyx_n_s_tdb2, __pyx_n_s_tcb1, __pyx_n_s_tcb2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__315)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__315);
+  __Pyx_GIVEREF(__pyx_tuple__315);
+  __pyx_codeobj__316 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__315, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tdbtcb, 3685, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__316)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3709
+ * 
+ * 
+ * def _tdbtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+  __pyx_tuple__317 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tdb1, __pyx_n_s_tdb2, __pyx_n_s_dtr, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__317)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__317);
+  __Pyx_GIVEREF(__pyx_tuple__317);
+  __pyx_codeobj__318 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__317, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tdbtt, 3709, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__318)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3735
+ * 
+ * 
+ * def _tttai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_tuple__319 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__319)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3735; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__319);
+  __Pyx_GIVEREF(__pyx_tuple__319);
+  __pyx_codeobj__320 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__319, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tttai, 3735, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__320)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3735; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3759
+ * 
+ * 
+ * def _tttcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_tuple__321 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_tcg1, __pyx_n_s_tcg2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__321)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__321);
+  __Pyx_GIVEREF(__pyx_tuple__321);
+  __pyx_codeobj__322 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__321, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tttcg, 3759, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__322)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3783
+ * 
+ * 
+ * def _tttdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_tuple__323 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_dtr, __pyx_n_s_tdb1, __pyx_n_s_tdb2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__323)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__323);
+  __Pyx_GIVEREF(__pyx_tuple__323);
+  __pyx_codeobj__324 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__323, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_tttdb, 3783, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__324)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3809
+ * 
+ * 
+ * def _ttut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_tuple__325 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_dt, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__325)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__325);
+  __Pyx_GIVEREF(__pyx_tuple__325);
+  __pyx_codeobj__326 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__325, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ttut1, 3809, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__326)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3835
+ * 
+ * 
+ * def _ut1tai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_tuple__327 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_dta, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__327)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__327);
+  __Pyx_GIVEREF(__pyx_tuple__327);
+  __pyx_codeobj__328 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__327, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ut1tai, 3835, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__328)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3861
+ * 
+ * 
+ * def _ut1tt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_tuple__329 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_dt, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__329)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__329);
+  __Pyx_GIVEREF(__pyx_tuple__329);
+  __pyx_codeobj__330 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__329, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ut1tt, 3861, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__330)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3887
+ * 
+ * 
+ * def _ut1utc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_tuple__331 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_dut1, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__331)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__331);
+  __Pyx_GIVEREF(__pyx_tuple__331);
+  __pyx_codeobj__332 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__331, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_ut1utc, 3887, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__332)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3913
+ * 
+ * 
+ * def _utctai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_tuple__333 = PyTuple_Pack(10, __pyx_n_s_it, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_tai1, __pyx_n_s_tai2, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__333)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__333);
+  __Pyx_GIVEREF(__pyx_tuple__333);
+  __pyx_codeobj__334 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__333, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_utctai, 3913, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__334)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/_erfa/core.pyx":3937
+ * 
+ * 
+ * def _utcut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_tuple__335 = PyTuple_Pack(11, __pyx_n_s_it, __pyx_n_s_utc1, __pyx_n_s_utc2, __pyx_n_s_dut1, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_c_retval, __pyx_n_s_stat_ok, __pyx_n_s_dataptrarray, __pyx_n_s_iternext, __pyx_n_s_status); if (unlikely(!__pyx_tuple__335)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__335);
+  __Pyx_GIVEREF(__pyx_tuple__335);
+  __pyx_codeobj__336 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__335, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_utcut1, 3937, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__336)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_core(void); /*proto*/
+PyMODINIT_FUNC init_core(void)
+#else
+PyMODINIT_FUNC PyInit__core(void); /*proto*/
+PyMODINIT_FUNC PyInit__core(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__core(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("_core", __pyx_methods, __pyx_k_This_module_contains_the_Cython, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_astropy___erfa___core) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "astropy._erfa._core")) {
+      if (unlikely(PyDict_SetItemString(modules, "astropy._erfa._core", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "astropy/_erfa/core.pyx":19
+ * from __future__ import absolute_import, division, print_function
+ * 
+ * import warnings             # <<<<<<<<<<<<<<
+ * from distutils.version import LooseVersion
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_warnings, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":20
+ * 
+ * import warnings
+ * from distutils.version import LooseVersion             # <<<<<<<<<<<<<<
+ * 
+ * from ..utils.exceptions import AstropyUserWarning
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_LooseVersion);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_LooseVersion);
+  __Pyx_GIVEREF(__pyx_n_s_LooseVersion);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_distutils_version, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_LooseVersion); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_LooseVersion, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/_erfa/core.pyx":22
+ * from distutils.version import LooseVersion
+ * 
+ * from ..utils.exceptions import AstropyUserWarning             # <<<<<<<<<<<<<<
+ * 
+ * import numpy
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_AstropyUserWarning);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_AstropyUserWarning);
+  __Pyx_GIVEREF(__pyx_n_s_AstropyUserWarning);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_utils_exceptions, __pyx_t_2, 2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_AstropyUserWarning); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_AstropyUserWarning, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":24
+ * from ..utils.exceptions import AstropyUserWarning
+ * 
+ * import numpy             # <<<<<<<<<<<<<<
+ * cimport numpy
+ * from cpython.ref cimport PyObject
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":28
+ * from cpython.ref cimport PyObject
+ * 
+ * numpy.import_array()             # <<<<<<<<<<<<<<
+ * 
+ * __all__ = ['_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', '_refco', '_epv00', '_plan94', '_fad03', '_fae03', '_faf03', '_faju03', '_fal03', '_falp03', '_f [...]
+ */
+  import_array();
+
+  /* "astropy/_erfa/core.pyx":30
+ * numpy.import_array()
+ * 
+ * __all__ = ['_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', '_refco', '_epv00', '_plan94', '_fad03', '_fae03', '_faf03', '_faju03', '_fal03', '_falp03', '_f [...]
+ * 
+ * #<-----------------------------NpyIter handling------------------------------->
+ */
+  __pyx_t_1 = PyList_New(165); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_cal2jd);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_cal2jd);
+  __Pyx_GIVEREF(__pyx_n_s_cal2jd);
+  __Pyx_INCREF(__pyx_n_s_epb);
+  PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_epb);
+  __Pyx_GIVEREF(__pyx_n_s_epb);
+  __Pyx_INCREF(__pyx_n_s_epb2jd);
+  PyList_SET_ITEM(__pyx_t_1, 2, __pyx_n_s_epb2jd);
+  __Pyx_GIVEREF(__pyx_n_s_epb2jd);
+  __Pyx_INCREF(__pyx_n_s_epj);
+  PyList_SET_ITEM(__pyx_t_1, 3, __pyx_n_s_epj);
+  __Pyx_GIVEREF(__pyx_n_s_epj);
+  __Pyx_INCREF(__pyx_n_s_epj2jd);
+  PyList_SET_ITEM(__pyx_t_1, 4, __pyx_n_s_epj2jd);
+  __Pyx_GIVEREF(__pyx_n_s_epj2jd);
+  __Pyx_INCREF(__pyx_n_s_jd2cal);
+  PyList_SET_ITEM(__pyx_t_1, 5, __pyx_n_s_jd2cal);
+  __Pyx_GIVEREF(__pyx_n_s_jd2cal);
+  __Pyx_INCREF(__pyx_n_s_jdcalf);
+  PyList_SET_ITEM(__pyx_t_1, 6, __pyx_n_s_jdcalf);
+  __Pyx_GIVEREF(__pyx_n_s_jdcalf);
+  __Pyx_INCREF(__pyx_n_s_ab);
+  PyList_SET_ITEM(__pyx_t_1, 7, __pyx_n_s_ab);
+  __Pyx_GIVEREF(__pyx_n_s_ab);
+  __Pyx_INCREF(__pyx_n_s_apcg);
+  PyList_SET_ITEM(__pyx_t_1, 8, __pyx_n_s_apcg);
+  __Pyx_GIVEREF(__pyx_n_s_apcg);
+  __Pyx_INCREF(__pyx_n_s_apcg13);
+  PyList_SET_ITEM(__pyx_t_1, 9, __pyx_n_s_apcg13);
+  __Pyx_GIVEREF(__pyx_n_s_apcg13);
+  __Pyx_INCREF(__pyx_n_s_apci);
+  PyList_SET_ITEM(__pyx_t_1, 10, __pyx_n_s_apci);
+  __Pyx_GIVEREF(__pyx_n_s_apci);
+  __Pyx_INCREF(__pyx_n_s_apci13);
+  PyList_SET_ITEM(__pyx_t_1, 11, __pyx_n_s_apci13);
+  __Pyx_GIVEREF(__pyx_n_s_apci13);
+  __Pyx_INCREF(__pyx_n_s_apco);
+  PyList_SET_ITEM(__pyx_t_1, 12, __pyx_n_s_apco);
+  __Pyx_GIVEREF(__pyx_n_s_apco);
+  __Pyx_INCREF(__pyx_n_s_apco13);
+  PyList_SET_ITEM(__pyx_t_1, 13, __pyx_n_s_apco13);
+  __Pyx_GIVEREF(__pyx_n_s_apco13);
+  __Pyx_INCREF(__pyx_n_s_apcs);
+  PyList_SET_ITEM(__pyx_t_1, 14, __pyx_n_s_apcs);
+  __Pyx_GIVEREF(__pyx_n_s_apcs);
+  __Pyx_INCREF(__pyx_n_s_apcs13);
+  PyList_SET_ITEM(__pyx_t_1, 15, __pyx_n_s_apcs13);
+  __Pyx_GIVEREF(__pyx_n_s_apcs13);
+  __Pyx_INCREF(__pyx_n_s_aper);
+  PyList_SET_ITEM(__pyx_t_1, 16, __pyx_n_s_aper);
+  __Pyx_GIVEREF(__pyx_n_s_aper);
+  __Pyx_INCREF(__pyx_n_s_aper13);
+  PyList_SET_ITEM(__pyx_t_1, 17, __pyx_n_s_aper13);
+  __Pyx_GIVEREF(__pyx_n_s_aper13);
+  __Pyx_INCREF(__pyx_n_s_apio);
+  PyList_SET_ITEM(__pyx_t_1, 18, __pyx_n_s_apio);
+  __Pyx_GIVEREF(__pyx_n_s_apio);
+  __Pyx_INCREF(__pyx_n_s_apio13);
+  PyList_SET_ITEM(__pyx_t_1, 19, __pyx_n_s_apio13);
+  __Pyx_GIVEREF(__pyx_n_s_apio13);
+  __Pyx_INCREF(__pyx_n_s_atci13);
+  PyList_SET_ITEM(__pyx_t_1, 20, __pyx_n_s_atci13);
+  __Pyx_GIVEREF(__pyx_n_s_atci13);
+  __Pyx_INCREF(__pyx_n_s_atciq);
+  PyList_SET_ITEM(__pyx_t_1, 21, __pyx_n_s_atciq);
+  __Pyx_GIVEREF(__pyx_n_s_atciq);
+  __Pyx_INCREF(__pyx_n_s_atciqn);
+  PyList_SET_ITEM(__pyx_t_1, 22, __pyx_n_s_atciqn);
+  __Pyx_GIVEREF(__pyx_n_s_atciqn);
+  __Pyx_INCREF(__pyx_n_s_atciqz);
+  PyList_SET_ITEM(__pyx_t_1, 23, __pyx_n_s_atciqz);
+  __Pyx_GIVEREF(__pyx_n_s_atciqz);
+  __Pyx_INCREF(__pyx_n_s_atco13);
+  PyList_SET_ITEM(__pyx_t_1, 24, __pyx_n_s_atco13);
+  __Pyx_GIVEREF(__pyx_n_s_atco13);
+  __Pyx_INCREF(__pyx_n_s_atic13);
+  PyList_SET_ITEM(__pyx_t_1, 25, __pyx_n_s_atic13);
+  __Pyx_GIVEREF(__pyx_n_s_atic13);
+  __Pyx_INCREF(__pyx_n_s_aticq);
+  PyList_SET_ITEM(__pyx_t_1, 26, __pyx_n_s_aticq);
+  __Pyx_GIVEREF(__pyx_n_s_aticq);
+  __Pyx_INCREF(__pyx_n_s_aticqn);
+  PyList_SET_ITEM(__pyx_t_1, 27, __pyx_n_s_aticqn);
+  __Pyx_GIVEREF(__pyx_n_s_aticqn);
+  __Pyx_INCREF(__pyx_n_s_atio13);
+  PyList_SET_ITEM(__pyx_t_1, 28, __pyx_n_s_atio13);
+  __Pyx_GIVEREF(__pyx_n_s_atio13);
+  __Pyx_INCREF(__pyx_n_s_atioq);
+  PyList_SET_ITEM(__pyx_t_1, 29, __pyx_n_s_atioq);
+  __Pyx_GIVEREF(__pyx_n_s_atioq);
+  __Pyx_INCREF(__pyx_n_s_atoc13);
+  PyList_SET_ITEM(__pyx_t_1, 30, __pyx_n_s_atoc13);
+  __Pyx_GIVEREF(__pyx_n_s_atoc13);
+  __Pyx_INCREF(__pyx_n_s_atoi13);
+  PyList_SET_ITEM(__pyx_t_1, 31, __pyx_n_s_atoi13);
+  __Pyx_GIVEREF(__pyx_n_s_atoi13);
+  __Pyx_INCREF(__pyx_n_s_atoiq);
+  PyList_SET_ITEM(__pyx_t_1, 32, __pyx_n_s_atoiq);
+  __Pyx_GIVEREF(__pyx_n_s_atoiq);
+  __Pyx_INCREF(__pyx_n_s_ld);
+  PyList_SET_ITEM(__pyx_t_1, 33, __pyx_n_s_ld);
+  __Pyx_GIVEREF(__pyx_n_s_ld);
+  __Pyx_INCREF(__pyx_n_s_ldn);
+  PyList_SET_ITEM(__pyx_t_1, 34, __pyx_n_s_ldn);
+  __Pyx_GIVEREF(__pyx_n_s_ldn);
+  __Pyx_INCREF(__pyx_n_s_ldsun);
+  PyList_SET_ITEM(__pyx_t_1, 35, __pyx_n_s_ldsun);
+  __Pyx_GIVEREF(__pyx_n_s_ldsun);
+  __Pyx_INCREF(__pyx_n_s_pmpx);
+  PyList_SET_ITEM(__pyx_t_1, 36, __pyx_n_s_pmpx);
+  __Pyx_GIVEREF(__pyx_n_s_pmpx);
+  __Pyx_INCREF(__pyx_n_s_pmsafe);
+  PyList_SET_ITEM(__pyx_t_1, 37, __pyx_n_s_pmsafe);
+  __Pyx_GIVEREF(__pyx_n_s_pmsafe);
+  __Pyx_INCREF(__pyx_n_s_refco);
+  PyList_SET_ITEM(__pyx_t_1, 38, __pyx_n_s_refco);
+  __Pyx_GIVEREF(__pyx_n_s_refco);
+  __Pyx_INCREF(__pyx_n_s_epv00);
+  PyList_SET_ITEM(__pyx_t_1, 39, __pyx_n_s_epv00);
+  __Pyx_GIVEREF(__pyx_n_s_epv00);
+  __Pyx_INCREF(__pyx_n_s_plan94);
+  PyList_SET_ITEM(__pyx_t_1, 40, __pyx_n_s_plan94);
+  __Pyx_GIVEREF(__pyx_n_s_plan94);
+  __Pyx_INCREF(__pyx_n_s_fad03);
+  PyList_SET_ITEM(__pyx_t_1, 41, __pyx_n_s_fad03);
+  __Pyx_GIVEREF(__pyx_n_s_fad03);
+  __Pyx_INCREF(__pyx_n_s_fae03);
+  PyList_SET_ITEM(__pyx_t_1, 42, __pyx_n_s_fae03);
+  __Pyx_GIVEREF(__pyx_n_s_fae03);
+  __Pyx_INCREF(__pyx_n_s_faf03);
+  PyList_SET_ITEM(__pyx_t_1, 43, __pyx_n_s_faf03);
+  __Pyx_GIVEREF(__pyx_n_s_faf03);
+  __Pyx_INCREF(__pyx_n_s_faju03);
+  PyList_SET_ITEM(__pyx_t_1, 44, __pyx_n_s_faju03);
+  __Pyx_GIVEREF(__pyx_n_s_faju03);
+  __Pyx_INCREF(__pyx_n_s_fal03);
+  PyList_SET_ITEM(__pyx_t_1, 45, __pyx_n_s_fal03);
+  __Pyx_GIVEREF(__pyx_n_s_fal03);
+  __Pyx_INCREF(__pyx_n_s_falp03);
+  PyList_SET_ITEM(__pyx_t_1, 46, __pyx_n_s_falp03);
+  __Pyx_GIVEREF(__pyx_n_s_falp03);
+  __Pyx_INCREF(__pyx_n_s_fama03);
+  PyList_SET_ITEM(__pyx_t_1, 47, __pyx_n_s_fama03);
+  __Pyx_GIVEREF(__pyx_n_s_fama03);
+  __Pyx_INCREF(__pyx_n_s_fame03);
+  PyList_SET_ITEM(__pyx_t_1, 48, __pyx_n_s_fame03);
+  __Pyx_GIVEREF(__pyx_n_s_fame03);
+  __Pyx_INCREF(__pyx_n_s_fane03);
+  PyList_SET_ITEM(__pyx_t_1, 49, __pyx_n_s_fane03);
+  __Pyx_GIVEREF(__pyx_n_s_fane03);
+  __Pyx_INCREF(__pyx_n_s_faom03);
+  PyList_SET_ITEM(__pyx_t_1, 50, __pyx_n_s_faom03);
+  __Pyx_GIVEREF(__pyx_n_s_faom03);
+  __Pyx_INCREF(__pyx_n_s_fapa03);
+  PyList_SET_ITEM(__pyx_t_1, 51, __pyx_n_s_fapa03);
+  __Pyx_GIVEREF(__pyx_n_s_fapa03);
+  __Pyx_INCREF(__pyx_n_s_fasa03);
+  PyList_SET_ITEM(__pyx_t_1, 52, __pyx_n_s_fasa03);
+  __Pyx_GIVEREF(__pyx_n_s_fasa03);
+  __Pyx_INCREF(__pyx_n_s_faur03);
+  PyList_SET_ITEM(__pyx_t_1, 53, __pyx_n_s_faur03);
+  __Pyx_GIVEREF(__pyx_n_s_faur03);
+  __Pyx_INCREF(__pyx_n_s_fave03);
+  PyList_SET_ITEM(__pyx_t_1, 54, __pyx_n_s_fave03);
+  __Pyx_GIVEREF(__pyx_n_s_fave03);
+  __Pyx_INCREF(__pyx_n_s_bi00);
+  PyList_SET_ITEM(__pyx_t_1, 55, __pyx_n_s_bi00);
+  __Pyx_GIVEREF(__pyx_n_s_bi00);
+  __Pyx_INCREF(__pyx_n_s_bp00);
+  PyList_SET_ITEM(__pyx_t_1, 56, __pyx_n_s_bp00);
+  __Pyx_GIVEREF(__pyx_n_s_bp00);
+  __Pyx_INCREF(__pyx_n_s_bp06);
+  PyList_SET_ITEM(__pyx_t_1, 57, __pyx_n_s_bp06);
+  __Pyx_GIVEREF(__pyx_n_s_bp06);
+  __Pyx_INCREF(__pyx_n_s_bpn2xy);
+  PyList_SET_ITEM(__pyx_t_1, 58, __pyx_n_s_bpn2xy);
+  __Pyx_GIVEREF(__pyx_n_s_bpn2xy);
+  __Pyx_INCREF(__pyx_n_s_c2i00a);
+  PyList_SET_ITEM(__pyx_t_1, 59, __pyx_n_s_c2i00a);
+  __Pyx_GIVEREF(__pyx_n_s_c2i00a);
+  __Pyx_INCREF(__pyx_n_s_c2i00b);
+  PyList_SET_ITEM(__pyx_t_1, 60, __pyx_n_s_c2i00b);
+  __Pyx_GIVEREF(__pyx_n_s_c2i00b);
+  __Pyx_INCREF(__pyx_n_s_c2i06a);
+  PyList_SET_ITEM(__pyx_t_1, 61, __pyx_n_s_c2i06a);
+  __Pyx_GIVEREF(__pyx_n_s_c2i06a);
+  __Pyx_INCREF(__pyx_n_s_c2ibpn);
+  PyList_SET_ITEM(__pyx_t_1, 62, __pyx_n_s_c2ibpn);
+  __Pyx_GIVEREF(__pyx_n_s_c2ibpn);
+  __Pyx_INCREF(__pyx_n_s_c2ixy);
+  PyList_SET_ITEM(__pyx_t_1, 63, __pyx_n_s_c2ixy);
+  __Pyx_GIVEREF(__pyx_n_s_c2ixy);
+  __Pyx_INCREF(__pyx_n_s_c2ixys);
+  PyList_SET_ITEM(__pyx_t_1, 64, __pyx_n_s_c2ixys);
+  __Pyx_GIVEREF(__pyx_n_s_c2ixys);
+  __Pyx_INCREF(__pyx_n_s_c2t00a);
+  PyList_SET_ITEM(__pyx_t_1, 65, __pyx_n_s_c2t00a);
+  __Pyx_GIVEREF(__pyx_n_s_c2t00a);
+  __Pyx_INCREF(__pyx_n_s_c2t00b);
+  PyList_SET_ITEM(__pyx_t_1, 66, __pyx_n_s_c2t00b);
+  __Pyx_GIVEREF(__pyx_n_s_c2t00b);
+  __Pyx_INCREF(__pyx_n_s_c2t06a);
+  PyList_SET_ITEM(__pyx_t_1, 67, __pyx_n_s_c2t06a);
+  __Pyx_GIVEREF(__pyx_n_s_c2t06a);
+  __Pyx_INCREF(__pyx_n_s_c2tcio);
+  PyList_SET_ITEM(__pyx_t_1, 68, __pyx_n_s_c2tcio);
+  __Pyx_GIVEREF(__pyx_n_s_c2tcio);
+  __Pyx_INCREF(__pyx_n_s_c2teqx);
+  PyList_SET_ITEM(__pyx_t_1, 69, __pyx_n_s_c2teqx);
+  __Pyx_GIVEREF(__pyx_n_s_c2teqx);
+  __Pyx_INCREF(__pyx_n_s_c2tpe);
+  PyList_SET_ITEM(__pyx_t_1, 70, __pyx_n_s_c2tpe);
+  __Pyx_GIVEREF(__pyx_n_s_c2tpe);
+  __Pyx_INCREF(__pyx_n_s_c2txy);
+  PyList_SET_ITEM(__pyx_t_1, 71, __pyx_n_s_c2txy);
+  __Pyx_GIVEREF(__pyx_n_s_c2txy);
+  __Pyx_INCREF(__pyx_n_s_eo06a);
+  PyList_SET_ITEM(__pyx_t_1, 72, __pyx_n_s_eo06a);
+  __Pyx_GIVEREF(__pyx_n_s_eo06a);
+  __Pyx_INCREF(__pyx_n_s_eors);
+  PyList_SET_ITEM(__pyx_t_1, 73, __pyx_n_s_eors);
+  __Pyx_GIVEREF(__pyx_n_s_eors);
+  __Pyx_INCREF(__pyx_n_s_fw2m);
+  PyList_SET_ITEM(__pyx_t_1, 74, __pyx_n_s_fw2m);
+  __Pyx_GIVEREF(__pyx_n_s_fw2m);
+  __Pyx_INCREF(__pyx_n_s_fw2xy);
+  PyList_SET_ITEM(__pyx_t_1, 75, __pyx_n_s_fw2xy);
+  __Pyx_GIVEREF(__pyx_n_s_fw2xy);
+  __Pyx_INCREF(__pyx_n_s_num00a);
+  PyList_SET_ITEM(__pyx_t_1, 76, __pyx_n_s_num00a);
+  __Pyx_GIVEREF(__pyx_n_s_num00a);
+  __Pyx_INCREF(__pyx_n_s_num00b);
+  PyList_SET_ITEM(__pyx_t_1, 77, __pyx_n_s_num00b);
+  __Pyx_GIVEREF(__pyx_n_s_num00b);
+  __Pyx_INCREF(__pyx_n_s_num06a);
+  PyList_SET_ITEM(__pyx_t_1, 78, __pyx_n_s_num06a);
+  __Pyx_GIVEREF(__pyx_n_s_num06a);
+  __Pyx_INCREF(__pyx_n_s_numat);
+  PyList_SET_ITEM(__pyx_t_1, 79, __pyx_n_s_numat);
+  __Pyx_GIVEREF(__pyx_n_s_numat);
+  __Pyx_INCREF(__pyx_n_s_nut00a);
+  PyList_SET_ITEM(__pyx_t_1, 80, __pyx_n_s_nut00a);
+  __Pyx_GIVEREF(__pyx_n_s_nut00a);
+  __Pyx_INCREF(__pyx_n_s_nut00b);
+  PyList_SET_ITEM(__pyx_t_1, 81, __pyx_n_s_nut00b);
+  __Pyx_GIVEREF(__pyx_n_s_nut00b);
+  __Pyx_INCREF(__pyx_n_s_nut06a);
+  PyList_SET_ITEM(__pyx_t_1, 82, __pyx_n_s_nut06a);
+  __Pyx_GIVEREF(__pyx_n_s_nut06a);
+  __Pyx_INCREF(__pyx_n_s_nut80);
+  PyList_SET_ITEM(__pyx_t_1, 83, __pyx_n_s_nut80);
+  __Pyx_GIVEREF(__pyx_n_s_nut80);
+  __Pyx_INCREF(__pyx_n_s_nutm80);
+  PyList_SET_ITEM(__pyx_t_1, 84, __pyx_n_s_nutm80);
+  __Pyx_GIVEREF(__pyx_n_s_nutm80);
+  __Pyx_INCREF(__pyx_n_s_obl06);
+  PyList_SET_ITEM(__pyx_t_1, 85, __pyx_n_s_obl06);
+  __Pyx_GIVEREF(__pyx_n_s_obl06);
+  __Pyx_INCREF(__pyx_n_s_obl80);
+  PyList_SET_ITEM(__pyx_t_1, 86, __pyx_n_s_obl80);
+  __Pyx_GIVEREF(__pyx_n_s_obl80);
+  __Pyx_INCREF(__pyx_n_s_p06e);
+  PyList_SET_ITEM(__pyx_t_1, 87, __pyx_n_s_p06e);
+  __Pyx_GIVEREF(__pyx_n_s_p06e);
+  __Pyx_INCREF(__pyx_n_s_pb06);
+  PyList_SET_ITEM(__pyx_t_1, 88, __pyx_n_s_pb06);
+  __Pyx_GIVEREF(__pyx_n_s_pb06);
+  __Pyx_INCREF(__pyx_n_s_pfw06);
+  PyList_SET_ITEM(__pyx_t_1, 89, __pyx_n_s_pfw06);
+  __Pyx_GIVEREF(__pyx_n_s_pfw06);
+  __Pyx_INCREF(__pyx_n_s_pmat00);
+  PyList_SET_ITEM(__pyx_t_1, 90, __pyx_n_s_pmat00);
+  __Pyx_GIVEREF(__pyx_n_s_pmat00);
+  __Pyx_INCREF(__pyx_n_s_pmat06);
+  PyList_SET_ITEM(__pyx_t_1, 91, __pyx_n_s_pmat06);
+  __Pyx_GIVEREF(__pyx_n_s_pmat06);
+  __Pyx_INCREF(__pyx_n_s_pmat76);
+  PyList_SET_ITEM(__pyx_t_1, 92, __pyx_n_s_pmat76);
+  __Pyx_GIVEREF(__pyx_n_s_pmat76);
+  __Pyx_INCREF(__pyx_n_s_pn00);
+  PyList_SET_ITEM(__pyx_t_1, 93, __pyx_n_s_pn00);
+  __Pyx_GIVEREF(__pyx_n_s_pn00);
+  __Pyx_INCREF(__pyx_n_s_pn00a);
+  PyList_SET_ITEM(__pyx_t_1, 94, __pyx_n_s_pn00a);
+  __Pyx_GIVEREF(__pyx_n_s_pn00a);
+  __Pyx_INCREF(__pyx_n_s_pn00b);
+  PyList_SET_ITEM(__pyx_t_1, 95, __pyx_n_s_pn00b);
+  __Pyx_GIVEREF(__pyx_n_s_pn00b);
+  __Pyx_INCREF(__pyx_n_s_pn06);
+  PyList_SET_ITEM(__pyx_t_1, 96, __pyx_n_s_pn06);
+  __Pyx_GIVEREF(__pyx_n_s_pn06);
+  __Pyx_INCREF(__pyx_n_s_pn06a);
+  PyList_SET_ITEM(__pyx_t_1, 97, __pyx_n_s_pn06a);
+  __Pyx_GIVEREF(__pyx_n_s_pn06a);
+  __Pyx_INCREF(__pyx_n_s_pnm00a);
+  PyList_SET_ITEM(__pyx_t_1, 98, __pyx_n_s_pnm00a);
+  __Pyx_GIVEREF(__pyx_n_s_pnm00a);
+  __Pyx_INCREF(__pyx_n_s_pnm00b);
+  PyList_SET_ITEM(__pyx_t_1, 99, __pyx_n_s_pnm00b);
+  __Pyx_GIVEREF(__pyx_n_s_pnm00b);
+  __Pyx_INCREF(__pyx_n_s_pnm06a);
+  PyList_SET_ITEM(__pyx_t_1, 100, __pyx_n_s_pnm06a);
+  __Pyx_GIVEREF(__pyx_n_s_pnm06a);
+  __Pyx_INCREF(__pyx_n_s_pnm80);
+  PyList_SET_ITEM(__pyx_t_1, 101, __pyx_n_s_pnm80);
+  __Pyx_GIVEREF(__pyx_n_s_pnm80);
+  __Pyx_INCREF(__pyx_n_s_pom00);
+  PyList_SET_ITEM(__pyx_t_1, 102, __pyx_n_s_pom00);
+  __Pyx_GIVEREF(__pyx_n_s_pom00);
+  __Pyx_INCREF(__pyx_n_s_pr00);
+  PyList_SET_ITEM(__pyx_t_1, 103, __pyx_n_s_pr00);
+  __Pyx_GIVEREF(__pyx_n_s_pr00);
+  __Pyx_INCREF(__pyx_n_s_prec76);
+  PyList_SET_ITEM(__pyx_t_1, 104, __pyx_n_s_prec76);
+  __Pyx_GIVEREF(__pyx_n_s_prec76);
+  __Pyx_INCREF(__pyx_n_s_s00);
+  PyList_SET_ITEM(__pyx_t_1, 105, __pyx_n_s_s00);
+  __Pyx_GIVEREF(__pyx_n_s_s00);
+  __Pyx_INCREF(__pyx_n_s_s00a);
+  PyList_SET_ITEM(__pyx_t_1, 106, __pyx_n_s_s00a);
+  __Pyx_GIVEREF(__pyx_n_s_s00a);
+  __Pyx_INCREF(__pyx_n_s_s00b);
+  PyList_SET_ITEM(__pyx_t_1, 107, __pyx_n_s_s00b);
+  __Pyx_GIVEREF(__pyx_n_s_s00b);
+  __Pyx_INCREF(__pyx_n_s_s06);
+  PyList_SET_ITEM(__pyx_t_1, 108, __pyx_n_s_s06);
+  __Pyx_GIVEREF(__pyx_n_s_s06);
+  __Pyx_INCREF(__pyx_n_s_s06a);
+  PyList_SET_ITEM(__pyx_t_1, 109, __pyx_n_s_s06a);
+  __Pyx_GIVEREF(__pyx_n_s_s06a);
+  __Pyx_INCREF(__pyx_n_s_sp00);
+  PyList_SET_ITEM(__pyx_t_1, 110, __pyx_n_s_sp00);
+  __Pyx_GIVEREF(__pyx_n_s_sp00);
+  __Pyx_INCREF(__pyx_n_s_xy06);
+  PyList_SET_ITEM(__pyx_t_1, 111, __pyx_n_s_xy06);
+  __Pyx_GIVEREF(__pyx_n_s_xy06);
+  __Pyx_INCREF(__pyx_n_s_xys00a);
+  PyList_SET_ITEM(__pyx_t_1, 112, __pyx_n_s_xys00a);
+  __Pyx_GIVEREF(__pyx_n_s_xys00a);
+  __Pyx_INCREF(__pyx_n_s_xys00b);
+  PyList_SET_ITEM(__pyx_t_1, 113, __pyx_n_s_xys00b);
+  __Pyx_GIVEREF(__pyx_n_s_xys00b);
+  __Pyx_INCREF(__pyx_n_s_xys06a);
+  PyList_SET_ITEM(__pyx_t_1, 114, __pyx_n_s_xys06a);
+  __Pyx_GIVEREF(__pyx_n_s_xys06a);
+  __Pyx_INCREF(__pyx_n_s_ee00);
+  PyList_SET_ITEM(__pyx_t_1, 115, __pyx_n_s_ee00);
+  __Pyx_GIVEREF(__pyx_n_s_ee00);
+  __Pyx_INCREF(__pyx_n_s_ee00a);
+  PyList_SET_ITEM(__pyx_t_1, 116, __pyx_n_s_ee00a);
+  __Pyx_GIVEREF(__pyx_n_s_ee00a);
+  __Pyx_INCREF(__pyx_n_s_ee00b);
+  PyList_SET_ITEM(__pyx_t_1, 117, __pyx_n_s_ee00b);
+  __Pyx_GIVEREF(__pyx_n_s_ee00b);
+  __Pyx_INCREF(__pyx_n_s_ee06a);
+  PyList_SET_ITEM(__pyx_t_1, 118, __pyx_n_s_ee06a);
+  __Pyx_GIVEREF(__pyx_n_s_ee06a);
+  __Pyx_INCREF(__pyx_n_s_eect00);
+  PyList_SET_ITEM(__pyx_t_1, 119, __pyx_n_s_eect00);
+  __Pyx_GIVEREF(__pyx_n_s_eect00);
+  __Pyx_INCREF(__pyx_n_s_eqeq94);
+  PyList_SET_ITEM(__pyx_t_1, 120, __pyx_n_s_eqeq94);
+  __Pyx_GIVEREF(__pyx_n_s_eqeq94);
+  __Pyx_INCREF(__pyx_n_s_era00);
+  PyList_SET_ITEM(__pyx_t_1, 121, __pyx_n_s_era00);
+  __Pyx_GIVEREF(__pyx_n_s_era00);
+  __Pyx_INCREF(__pyx_n_s_gmst00);
+  PyList_SET_ITEM(__pyx_t_1, 122, __pyx_n_s_gmst00);
+  __Pyx_GIVEREF(__pyx_n_s_gmst00);
+  __Pyx_INCREF(__pyx_n_s_gmst06);
+  PyList_SET_ITEM(__pyx_t_1, 123, __pyx_n_s_gmst06);
+  __Pyx_GIVEREF(__pyx_n_s_gmst06);
+  __Pyx_INCREF(__pyx_n_s_gmst82);
+  PyList_SET_ITEM(__pyx_t_1, 124, __pyx_n_s_gmst82);
+  __Pyx_GIVEREF(__pyx_n_s_gmst82);
+  __Pyx_INCREF(__pyx_n_s_gst00a);
+  PyList_SET_ITEM(__pyx_t_1, 125, __pyx_n_s_gst00a);
+  __Pyx_GIVEREF(__pyx_n_s_gst00a);
+  __Pyx_INCREF(__pyx_n_s_gst00b);
+  PyList_SET_ITEM(__pyx_t_1, 126, __pyx_n_s_gst00b);
+  __Pyx_GIVEREF(__pyx_n_s_gst00b);
+  __Pyx_INCREF(__pyx_n_s_gst06);
+  PyList_SET_ITEM(__pyx_t_1, 127, __pyx_n_s_gst06);
+  __Pyx_GIVEREF(__pyx_n_s_gst06);
+  __Pyx_INCREF(__pyx_n_s_gst06a);
+  PyList_SET_ITEM(__pyx_t_1, 128, __pyx_n_s_gst06a);
+  __Pyx_GIVEREF(__pyx_n_s_gst06a);
+  __Pyx_INCREF(__pyx_n_s_gst94);
+  PyList_SET_ITEM(__pyx_t_1, 129, __pyx_n_s_gst94);
+  __Pyx_GIVEREF(__pyx_n_s_gst94);
+  __Pyx_INCREF(__pyx_n_s_pmsafe);
+  PyList_SET_ITEM(__pyx_t_1, 130, __pyx_n_s_pmsafe);
+  __Pyx_GIVEREF(__pyx_n_s_pmsafe);
+  __Pyx_INCREF(__pyx_n_s_pvstar);
+  PyList_SET_ITEM(__pyx_t_1, 131, __pyx_n_s_pvstar);
+  __Pyx_GIVEREF(__pyx_n_s_pvstar);
+  __Pyx_INCREF(__pyx_n_s_starpv);
+  PyList_SET_ITEM(__pyx_t_1, 132, __pyx_n_s_starpv);
+  __Pyx_GIVEREF(__pyx_n_s_starpv);
+  __Pyx_INCREF(__pyx_n_s_fk52h);
+  PyList_SET_ITEM(__pyx_t_1, 133, __pyx_n_s_fk52h);
+  __Pyx_GIVEREF(__pyx_n_s_fk52h);
+  __Pyx_INCREF(__pyx_n_s_fk5hip);
+  PyList_SET_ITEM(__pyx_t_1, 134, __pyx_n_s_fk5hip);
+  __Pyx_GIVEREF(__pyx_n_s_fk5hip);
+  __Pyx_INCREF(__pyx_n_s_fk5hz);
+  PyList_SET_ITEM(__pyx_t_1, 135, __pyx_n_s_fk5hz);
+  __Pyx_GIVEREF(__pyx_n_s_fk5hz);
+  __Pyx_INCREF(__pyx_n_s_h2fk5);
+  PyList_SET_ITEM(__pyx_t_1, 136, __pyx_n_s_h2fk5);
+  __Pyx_GIVEREF(__pyx_n_s_h2fk5);
+  __Pyx_INCREF(__pyx_n_s_hfk5z);
+  PyList_SET_ITEM(__pyx_t_1, 137, __pyx_n_s_hfk5z);
+  __Pyx_GIVEREF(__pyx_n_s_hfk5z);
+  __Pyx_INCREF(__pyx_n_s_starpm);
+  PyList_SET_ITEM(__pyx_t_1, 138, __pyx_n_s_starpm);
+  __Pyx_GIVEREF(__pyx_n_s_starpm);
+  __Pyx_INCREF(__pyx_n_s_eform);
+  PyList_SET_ITEM(__pyx_t_1, 139, __pyx_n_s_eform);
+  __Pyx_GIVEREF(__pyx_n_s_eform);
+  __Pyx_INCREF(__pyx_n_s_gc2gd);
+  PyList_SET_ITEM(__pyx_t_1, 140, __pyx_n_s_gc2gd);
+  __Pyx_GIVEREF(__pyx_n_s_gc2gd);
+  __Pyx_INCREF(__pyx_n_s_gc2gde);
+  PyList_SET_ITEM(__pyx_t_1, 141, __pyx_n_s_gc2gde);
+  __Pyx_GIVEREF(__pyx_n_s_gc2gde);
+  __Pyx_INCREF(__pyx_n_s_gd2gc);
+  PyList_SET_ITEM(__pyx_t_1, 142, __pyx_n_s_gd2gc);
+  __Pyx_GIVEREF(__pyx_n_s_gd2gc);
+  __Pyx_INCREF(__pyx_n_s_gd2gce);
+  PyList_SET_ITEM(__pyx_t_1, 143, __pyx_n_s_gd2gce);
+  __Pyx_GIVEREF(__pyx_n_s_gd2gce);
+  __Pyx_INCREF(__pyx_n_s_pvtob);
+  PyList_SET_ITEM(__pyx_t_1, 144, __pyx_n_s_pvtob);
+  __Pyx_GIVEREF(__pyx_n_s_pvtob);
+  __Pyx_INCREF(__pyx_n_s_d2dtf);
+  PyList_SET_ITEM(__pyx_t_1, 145, __pyx_n_s_d2dtf);
+  __Pyx_GIVEREF(__pyx_n_s_d2dtf);
+  __Pyx_INCREF(__pyx_n_s_dat);
+  PyList_SET_ITEM(__pyx_t_1, 146, __pyx_n_s_dat);
+  __Pyx_GIVEREF(__pyx_n_s_dat);
+  __Pyx_INCREF(__pyx_n_s_dtdb);
+  PyList_SET_ITEM(__pyx_t_1, 147, __pyx_n_s_dtdb);
+  __Pyx_GIVEREF(__pyx_n_s_dtdb);
+  __Pyx_INCREF(__pyx_n_s_dtf2d);
+  PyList_SET_ITEM(__pyx_t_1, 148, __pyx_n_s_dtf2d);
+  __Pyx_GIVEREF(__pyx_n_s_dtf2d);
+  __Pyx_INCREF(__pyx_n_s_taitt);
+  PyList_SET_ITEM(__pyx_t_1, 149, __pyx_n_s_taitt);
+  __Pyx_GIVEREF(__pyx_n_s_taitt);
+  __Pyx_INCREF(__pyx_n_s_taiut1);
+  PyList_SET_ITEM(__pyx_t_1, 150, __pyx_n_s_taiut1);
+  __Pyx_GIVEREF(__pyx_n_s_taiut1);
+  __Pyx_INCREF(__pyx_n_s_taiutc);
+  PyList_SET_ITEM(__pyx_t_1, 151, __pyx_n_s_taiutc);
+  __Pyx_GIVEREF(__pyx_n_s_taiutc);
+  __Pyx_INCREF(__pyx_n_s_tcbtdb);
+  PyList_SET_ITEM(__pyx_t_1, 152, __pyx_n_s_tcbtdb);
+  __Pyx_GIVEREF(__pyx_n_s_tcbtdb);
+  __Pyx_INCREF(__pyx_n_s_tcgtt);
+  PyList_SET_ITEM(__pyx_t_1, 153, __pyx_n_s_tcgtt);
+  __Pyx_GIVEREF(__pyx_n_s_tcgtt);
+  __Pyx_INCREF(__pyx_n_s_tdbtcb);
+  PyList_SET_ITEM(__pyx_t_1, 154, __pyx_n_s_tdbtcb);
+  __Pyx_GIVEREF(__pyx_n_s_tdbtcb);
+  __Pyx_INCREF(__pyx_n_s_tdbtt);
+  PyList_SET_ITEM(__pyx_t_1, 155, __pyx_n_s_tdbtt);
+  __Pyx_GIVEREF(__pyx_n_s_tdbtt);
+  __Pyx_INCREF(__pyx_n_s_tttai);
+  PyList_SET_ITEM(__pyx_t_1, 156, __pyx_n_s_tttai);
+  __Pyx_GIVEREF(__pyx_n_s_tttai);
+  __Pyx_INCREF(__pyx_n_s_tttcg);
+  PyList_SET_ITEM(__pyx_t_1, 157, __pyx_n_s_tttcg);
+  __Pyx_GIVEREF(__pyx_n_s_tttcg);
+  __Pyx_INCREF(__pyx_n_s_tttdb);
+  PyList_SET_ITEM(__pyx_t_1, 158, __pyx_n_s_tttdb);
+  __Pyx_GIVEREF(__pyx_n_s_tttdb);
+  __Pyx_INCREF(__pyx_n_s_ttut1);
+  PyList_SET_ITEM(__pyx_t_1, 159, __pyx_n_s_ttut1);
+  __Pyx_GIVEREF(__pyx_n_s_ttut1);
+  __Pyx_INCREF(__pyx_n_s_ut1tai);
+  PyList_SET_ITEM(__pyx_t_1, 160, __pyx_n_s_ut1tai);
+  __Pyx_GIVEREF(__pyx_n_s_ut1tai);
+  __Pyx_INCREF(__pyx_n_s_ut1tt);
+  PyList_SET_ITEM(__pyx_t_1, 161, __pyx_n_s_ut1tt);
+  __Pyx_GIVEREF(__pyx_n_s_ut1tt);
+  __Pyx_INCREF(__pyx_n_s_ut1utc);
+  PyList_SET_ITEM(__pyx_t_1, 162, __pyx_n_s_ut1utc);
+  __Pyx_GIVEREF(__pyx_n_s_ut1utc);
+  __Pyx_INCREF(__pyx_n_s_utctai);
+  PyList_SET_ITEM(__pyx_t_1, 163, __pyx_n_s_utctai);
+  __Pyx_GIVEREF(__pyx_n_s_utctai);
+  __Pyx_INCREF(__pyx_n_s_utcut1);
+  PyList_SET_ITEM(__pyx_t_1, 164, __pyx_n_s_utcut1);
+  __Pyx_GIVEREF(__pyx_n_s_utcut1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":225
+ * 
+ * 
+ * def _cal2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_1_cal2jd, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_cal2jd, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":251
+ * 
+ * 
+ * def _epb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_3_epb, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_epb, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":267
+ * 
+ * 
+ * def _epb2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epb
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_5_epb2jd, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_epb2jd, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":283
+ * 
+ * 
+ * def _epj(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_7_epj, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_epj, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":299
+ * 
+ * 
+ * def _epj2jd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epj
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_9_epj2jd, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_epj2jd, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":315
+ * 
+ * 
+ * def _jd2cal(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_11_jd2cal, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_jd2cal, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":343
+ * 
+ * 
+ * def _jdcalf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _ndp
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_13_jdcalf, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_jdcalf, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":367
+ * 
+ * 
+ * def _ab(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pnat
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_15_ab, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ab, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":387
+ * 
+ * 
+ * def _apcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_17_apcg, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apcg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":407
+ * 
+ * 
+ * def _apcg13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_19_apcg13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apcg13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":423
+ * 
+ * 
+ * def _apci(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_21_apci, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apci, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":449
+ * 
+ * 
+ * def _apci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_23_apci13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apci13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":467
+ * 
+ * 
+ * def _apco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_25_apco, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apco, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":511
+ * 
+ * 
+ * def _apco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_27_apco13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apco13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":555
+ * 
+ * 
+ * def _apcs(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_29_apcs, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apcs, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":577
+ * 
+ * 
+ * def _apcs13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_31_apcs13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apcs13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":595
+ * 
+ * 
+ * def _aper(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _theta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_33_aper, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_aper, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":609
+ * 
+ * 
+ * def _aper13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_35_aper13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_aper13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":625
+ * 
+ * 
+ * def _apio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _sp
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_37_apio, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apio, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":655
+ * 
+ * 
+ * def _apio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_39_apio13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_apio13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":697
+ * 
+ * 
+ * def _atci13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_41_atci13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atci13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":729
+ * 
+ * 
+ * def _atciq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_43_atciq, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atciq, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":757
+ * 
+ * 
+ * def _atciqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_45_atciqn, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atciqn, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":789
+ * 
+ * 
+ * def _atciqz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_47_atciqz, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atciqz, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":809
+ * 
+ * 
+ * def _atco13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_49_atco13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atco13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":873
+ * 
+ * 
+ * def _atic13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_51_atic13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 873; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atic13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 873; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":897
+ * 
+ * 
+ * def _aticq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_53_aticq, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_aticq, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":917
+ * 
+ * 
+ * def _aticqn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_55_aticqn, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_aticqn, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":941
+ * 
+ * 
+ * def _atio13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_57_atio13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atio13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":995
+ * 
+ * 
+ * def _atioq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ri
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_59_atioq, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atioq, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1021
+ * 
+ * 
+ * def _atoc13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_61_atoc13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atoc13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1071
+ * 
+ * 
+ * def _atoi13(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_63_atoi13, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atoi13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1121
+ * 
+ * 
+ * def _atoiq(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _type
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_65_atoiq, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_atoiq, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1143
+ * 
+ * 
+ * def _ld(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _bm
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_67_ld, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ld, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1167
+ * 
+ * 
+ * def _ldn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_69_ldn, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ldn, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1187
+ * 
+ * 
+ * def _ldsun(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _p
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_71_ldsun, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ldsun, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1205
+ * 
+ * 
+ * def _pmpx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rc
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_73_pmpx, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmpx, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1233
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_75_pmsafe, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmsafe, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1281
+ * 
+ * 
+ * def _refco(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _phpa
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_77_refco, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_refco, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1303
+ * 
+ * 
+ * def _epv00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_79_epv00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_epv00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1327
+ * 
+ * 
+ * def _plan94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_81_plan94, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plan94, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1351
+ * 
+ * 
+ * def _fad03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_83_fad03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fad03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1365
+ * 
+ * 
+ * def _fae03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_85_fae03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fae03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1379
+ * 
+ * 
+ * def _faf03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_87_faf03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_faf03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1393
+ * 
+ * 
+ * def _faju03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_89_faju03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_faju03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1407
+ * 
+ * 
+ * def _fal03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_91_fal03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fal03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1421
+ * 
+ * 
+ * def _falp03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_93_falp03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_falp03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1435
+ * 
+ * 
+ * def _fama03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_95_fama03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fama03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1449
+ * 
+ * 
+ * def _fame03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_97_fame03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fame03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1463
+ * 
+ * 
+ * def _fane03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_99_fane03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fane03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1477
+ * 
+ * 
+ * def _faom03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_101_faom03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_faom03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1491
+ * 
+ * 
+ * def _fapa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_103_fapa03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fapa03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1505
+ * 
+ * 
+ * def _fasa03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_105_fasa03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fasa03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1519
+ * 
+ * 
+ * def _faur03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_107_faur03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_faur03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1533
+ * 
+ * 
+ * def _fave03(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _t
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_109_fave03, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fave03, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1547
+ * 
+ * 
+ * def _bi00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _dpsibi
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_111_bi00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_bi00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1563
+ * 
+ * 
+ * def _bp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_113_bp00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_bp00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1583
+ * 
+ * 
+ * def _bp06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_115_bp06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_bp06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1603
+ * 
+ * 
+ * def _bpn2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_117_bpn2xy, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_bpn2xy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1619
+ * 
+ * 
+ * def _c2i00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_119_c2i00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2i00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1635
+ * 
+ * 
+ * def _c2i00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_121_c2i00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2i00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1651
+ * 
+ * 
+ * def _c2i06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_123_c2i06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2i06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1667
+ * 
+ * 
+ * def _c2ibpn(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_125_c2ibpn, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2ibpn, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1685
+ * 
+ * 
+ * def _c2ixy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_127_c2ixy, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2ixy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1705
+ * 
+ * 
+ * def _c2ixys(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _x
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_129_c2ixys, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2ixys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1723
+ * 
+ * 
+ * def _c2t00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_131_c2t00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2t00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1747
+ * 
+ * 
+ * def _c2t00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_133_c2t00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2t00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1771
+ * 
+ * 
+ * def _c2t06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_135_c2t06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2t06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1795
+ * 
+ * 
+ * def _c2tcio(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rc2i
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_137_c2tcio, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2tcio, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1813
+ * 
+ * 
+ * def _c2teqx(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rbpn
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_139_c2teqx, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2teqx, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1831
+ * 
+ * 
+ * def _c2tpe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_141_c2tpe, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2tpe, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1859
+ * 
+ * 
+ * def _c2txy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_143_c2txy, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_c2txy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1887
+ * 
+ * 
+ * def _eo06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_145_eo06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_eo06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1903
+ * 
+ * 
+ * def _eors(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _rnpb
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_147_eors, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_eors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1919
+ * 
+ * 
+ * def _fw2m(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_149_fw2m, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fw2m, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1939
+ * 
+ * 
+ * def _fw2xy(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _gamb
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_151_fw2xy, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fw2xy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1961
+ * 
+ * 
+ * def _num00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_153_num00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_num00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1977
+ * 
+ * 
+ * def _num00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_155_num00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_num00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1993
+ * 
+ * 
+ * def _num06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_157_num06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_num06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2009
+ * 
+ * 
+ * def _numat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _epsa
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_159_numat, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numat, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2027
+ * 
+ * 
+ * def _nut00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_161_nut00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_nut00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2045
+ * 
+ * 
+ * def _nut00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_163_nut00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_nut00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2063
+ * 
+ * 
+ * def _nut06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_165_nut06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_nut06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2081
+ * 
+ * 
+ * def _nut80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_167_nut80, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_nut80, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2099
+ * 
+ * 
+ * def _nutm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_169_nutm80, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_nutm80, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2115
+ * 
+ * 
+ * def _obl06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_171_obl06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_obl06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2131
+ * 
+ * 
+ * def _obl80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_173_obl80, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_obl80, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2147
+ * 
+ * 
+ * def _p06e(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_175_p06e, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_p06e, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2193
+ * 
+ * 
+ * def _pb06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_177_pb06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pb06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2213
+ * 
+ * 
+ * def _pfw06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_179_pfw06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pfw06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2235
+ * 
+ * 
+ * def _pmat00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_181_pmat00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmat00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2251
+ * 
+ * 
+ * def _pmat06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_183_pmat06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmat06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2267
+ * 
+ * 
+ * def _pmat76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_185_pmat76, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmat76, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2283
+ * 
+ * 
+ * def _pn00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_187_pn00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pn00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2313
+ * 
+ * 
+ * def _pn00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_189_pn00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pn00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2343
+ * 
+ * 
+ * def _pn00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_191_pn00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pn00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2373
+ * 
+ * 
+ * def _pn06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_193_pn06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pn06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2403
+ * 
+ * 
+ * def _pn06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_195_pn06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pn06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2433
+ * 
+ * 
+ * def _pnm00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_197_pnm00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pnm00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2449
+ * 
+ * 
+ * def _pnm00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_199_pnm00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pnm00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2465
+ * 
+ * 
+ * def _pnm06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_201_pnm06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pnm06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2481
+ * 
+ * 
+ * def _pnm80(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_203_pnm80, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pnm80, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2497
+ * 
+ * 
+ * def _pom00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _xp
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_205_pom00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pom00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2515
+ * 
+ * 
+ * def _pr00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_207_pr00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pr00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2533
+ * 
+ * 
+ * def _prec76(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date01
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_209_prec76, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_prec76, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2557
+ * 
+ * 
+ * def _s00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_211_s00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_s00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2577
+ * 
+ * 
+ * def _s00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_213_s00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_s00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2577; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2593
+ * 
+ * 
+ * def _s00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_215_s00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_s00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2609
+ * 
+ * 
+ * def _s06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_217_s06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_s06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2629
+ * 
+ * 
+ * def _s06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_219_s06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_s06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2645
+ * 
+ * 
+ * def _sp00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_221_sp00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sp00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2661
+ * 
+ * 
+ * def _xy06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_223_xy06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_xy06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2679
+ * 
+ * 
+ * def _xys00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_225_xys00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_xys00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2699
+ * 
+ * 
+ * def _xys00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_227_xys00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_xys00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2719
+ * 
+ * 
+ * def _xys06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_229_xys06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_xys06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2739
+ * 
+ * 
+ * def _ee00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_231_ee00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ee00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2759
+ * 
+ * 
+ * def _ee00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_233_ee00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ee00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2775
+ * 
+ * 
+ * def _ee00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_235_ee00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ee00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2791
+ * 
+ * 
+ * def _ee06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_237_ee06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ee06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2807
+ * 
+ * 
+ * def _eect00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_239_eect00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_eect00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2823
+ * 
+ * 
+ * def _eqeq94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_241_eqeq94, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_eqeq94, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2839
+ * 
+ * 
+ * def _era00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_243_era00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_era00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2855
+ * 
+ * 
+ * def _gmst00(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_245_gmst00, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst00, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2875
+ * 
+ * 
+ * def _gmst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_247_gmst06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2895
+ * 
+ * 
+ * def _gmst82(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _dj1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_249_gmst82, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst82, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2911
+ * 
+ * 
+ * def _gst00a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_251_gst00a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst00a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2931
+ * 
+ * 
+ * def _gst00b(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_253_gst00b, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst00b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2947
+ * 
+ * 
+ * def _gst06(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_255_gst06, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst06, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2969
+ * 
+ * 
+ * def _gst06a(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_257_gst06a, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst06a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":2989
+ * 
+ * 
+ * def _gst94(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _uta
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_259_gst94, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst94, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3005
+ * 
+ * 
+ * def _pmsafe(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_261_pmsafe, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pmsafe, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3053
+ * 
+ * 
+ * def _pvstar(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _pv
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_263_pvstar, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pvstar, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3083
+ * 
+ * 
+ * def _starpv(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_265_starpv, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_starpv, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3113
+ * 
+ * 
+ * def _fk52h(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_267_fk52h, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fk52h, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3147
+ * 
+ * 
+ * def _fk5hip(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double * _r5h
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_269_fk5hip, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fk5hip, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3161
+ * 
+ * 
+ * def _fk5hz(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _r5
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_271_fk5hz, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fk5hz, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3183
+ * 
+ * 
+ * def _h2fk5(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_273_h2fk5, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_h2fk5, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3217
+ * 
+ * 
+ * def _hfk5z(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _rh
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_275_hfk5z, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_hfk5z, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3243
+ * 
+ * 
+ * def _starpm(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ra1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_277_starpm, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_starpm, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3291
+ * 
+ * 
+ * def _eform(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_279_eform, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_eform, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3313
+ * 
+ * 
+ * def _gc2gd(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_281_gc2gd, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gc2gd, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3339
+ * 
+ * 
+ * def _gc2gde(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_283_gc2gde, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3339; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gc2gde, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3339; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3367
+ * 
+ * 
+ * def _gd2gc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _n
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_285_gd2gc, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gd2gc, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3393
+ * 
+ * 
+ * def _gd2gce(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _a
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_287_gd2gce, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gd2gce, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3421
+ * 
+ * 
+ * def _pvtob(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _elong
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_289_pvtob, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pvtob, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3447
+ * 
+ * 
+ * def _d2dtf(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_291_d2dtf, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_d2dtf, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3479
+ * 
+ * 
+ * def _dat(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef int _iy
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_293_dat, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_dat, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3505
+ * 
+ * 
+ * def _dtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _date1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_295_dtdb, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_dtdb, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3529
+ * 
+ * 
+ * def _dtf2d(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef const char * _scale
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_297_dtf2d, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_dtf2d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3563
+ * 
+ * 
+ * def _taitt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_299_taitt, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_taitt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3587
+ * 
+ * 
+ * def _taiut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_301_taiut1, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_taiut1, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3613
+ * 
+ * 
+ * def _taiutc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tai1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_303_taiutc, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3613; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_taiutc, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3613; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3637
+ * 
+ * 
+ * def _tcbtdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcb1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_305_tcbtdb, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tcbtdb, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3661
+ * 
+ * 
+ * def _tcgtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tcg1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_307_tcgtt, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tcgtt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3685
+ * 
+ * 
+ * def _tdbtcb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_309_tdbtcb, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tdbtcb, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3685; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3709
+ * 
+ * 
+ * def _tdbtt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tdb1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_311_tdbtt, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tdbtt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3735
+ * 
+ * 
+ * def _tttai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_313_tttai, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3735; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tttai, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3735; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3759
+ * 
+ * 
+ * def _tttcg(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_315_tttcg, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tttcg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3783
+ * 
+ * 
+ * def _tttdb(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_317_tttdb, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tttdb, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3809
+ * 
+ * 
+ * def _ttut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _tt1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_319_ttut1, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ttut1, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3835
+ * 
+ * 
+ * def _ut1tai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_321_ut1tai, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1tai, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3861
+ * 
+ * 
+ * def _ut1tt(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_323_ut1tt, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1tt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3887
+ * 
+ * 
+ * def _ut1utc(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _ut11
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_325_ut1utc, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1utc, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3913
+ * 
+ * 
+ * def _utctai(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_327_utctai, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_utctai, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":3937
+ * 
+ * 
+ * def _utcut1(it):             # <<<<<<<<<<<<<<
+ *     #Iterate
+ *     cdef double _utc1
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7astropy_5_erfa_5_core_329_utcut1, NULL, __pyx_n_s_astropy__erfa__core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_utcut1, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/_erfa/core.pyx":1
+ * # Licensed under a 3-clause BSD style license - see LICENSE.rst             # <<<<<<<<<<<<<<
+ * 
+ * # "core.pyx" is auto-generated by erfa_generator.py from the template
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init astropy._erfa._core", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init astropy._erfa._core");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                if (PyObject_IsSubclass(instance_class, type)) {
+                    type = instance_class;
+                } else {
+                    instance_class = NULL;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+#endif
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Format(PyExc_ImportError,
+        #if PY_MAJOR_VERSION < 3
+            "cannot import name %.230s", PyString_AS_STRING(name));
+        #else
+            "cannot import name %S", name);
+        #endif
+    }
+    return value;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
+    }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
+    {                                                                     \
+        func_type value = func_value;                                     \
+        if (sizeof(target_type) < sizeof(func_type)) {                    \
+            if (unlikely(value != (func_type) (target_type) value)) {     \
+                func_type zero = 0;                                       \
+                if (is_unsigned && unlikely(value < zero))                \
+                    goto raise_neg_overflow;                              \
+                else                                                      \
+                    goto raise_overflow;                                  \
+            }                                                             \
+        }                                                                 \
+        return (target_type) value;                                       \
+    }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
+        }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        return PyErr_WarnEx(NULL, message, 1);
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s.%.200s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%.200s.%.200s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_MAJOR_VERSION < 3
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%.4s__ returned non-%.4s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b)))
+      return PyInt_AS_LONG(b);
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+     #if CYTHON_USE_PYLONG_INTERNALS
+       switch (Py_SIZE(b)) {
+       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+       case  0: return 0;
+       case  1: return ((PyLongObject*)b)->ob_digit[0];
+       }
+     #endif
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+    return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/astropy/_erfa/core.py b/astropy/_erfa/core.py
new file mode 100644
index 0000000..3ec95f6
--- /dev/null
+++ b/astropy/_erfa/core.py
@@ -0,0 +1,23230 @@
+# 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.
+
+"""
+This module uses Cython to wrap the ERFA library in numpy-vectorized
+equivalents.
+
+..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 wrappers 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 matricies, the vector/matrix
+dimension(s) are always the *last* dimension(s).  For example, if you
+want to give ten matricies (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 Cython part of these functions are implemented in a separate
+module (compiled as ``_core``), derived from the ``core.pyx`` file.  Splitting
+the wrappers into separate pure-python and Cython portions dramatically reduces
+compilation time without notably impacting performance. (See issue [#3063] on the
+github repository for more about this.)
+"""
+from __future__ import absolute_import, division, print_function
+
+import warnings
+from distutils.version import LooseVersion
+
+from ..utils.exceptions import AstropyUserWarning
+
+import numpy
+from . import _core
+
+NPYLT18 = LooseVersion(numpy.__version__) < LooseVersion('1.8')
+# TODO: remove the above variable and the code using it and make_outputs_scalar when numpy < 1.8 is no longer supported
+
+__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', 'refco', 'epv00', 'plan94', 'fad03', 'fae03', 'faf03', 'faju03', 'fal03', 'falp03', 'fama03', 'fame03', 'fane03', 'faom03', 'fapa03', 'fa [...]
+           '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',
+           'dt_eraASTROM', 'dt_eraLDBODY']
+
+
+#<---------------------------------Error-handling----------------------------->
+
+class ErfaError(ValueError):
+    """
+    A class for errors triggered by ERFA functions (status codes < 0)
+    """
+
+
+class ErfaWarning(AstropyUserWarning):
+    """
+    A class for warnings triggered by ERFA functions (status codes > 0)
+    """
+
+
+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):
+    # 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)
+
+
+#<-------------------------trailing shape verification------------------------>
+
+def check_trailing_shape(arr, shape, name):
+    try:
+        if arr.shape[-len(shape):] != shape:
+            raise Exception()
+    except:
+        raise ValueError("{0} must be of trailing dimensions {1}".format(name, shape))
+
+#<--------------------------Actual ERFA-wrapping code------------------------->
+
+dt_eraASTROM = numpy.dtype([('pmt','d'),
+                         ('eb','d',(3,)),
+                         ('eh','d',(3,)),
+                         ('em','d'),
+                         ('v','d',(3,)),
+                         ('bm1','d'),
+                         ('bpn','d',(3,3)),
+                         ('along','d'),
+                         ('phi','d'),
+                         ('xpl','d'),
+                         ('ypl','d'),
+                         ('sphi','d'),
+                         ('cphi','d'),
+                         ('diurab','d'),
+                         ('eral','d'),
+                         ('refa','d'),
+                         ('refb','d')], align=True)
+
+dt_eraLDBODY = numpy.dtype([('bm','d'),
+                         ('dl','d'),
+                         ('pv','d',(2,3))], align=True)
+
+
+
+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 = (149597870e3)
+"""Astronomical unit (m)"""
+CMPS = 299792458.0
+"""Speed of light (m/s)"""
+AULT = 499.004782
+"""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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    iy_in = numpy.array(iy, dtype=numpy.intc, order="C", copy=False, subok=True)
+    im_in = numpy.array(im, dtype=numpy.intc, order="C", copy=False, subok=True)
+    id_in = numpy.array(id, dtype=numpy.intc, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if iy_in.shape == tuple():
+            iy_in = iy_in.reshape((1,) + iy_in.shape)
+        else:
+            make_outputs_scalar = False
+        if im_in.shape == tuple():
+            im_in = im_in.reshape((1,) + im_in.shape)
+        else:
+            make_outputs_scalar = False
+        if id_in.shape == tuple():
+            id_in = id_in.reshape((1,) + id_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), iy_in, im_in, id_in)
+    djm0_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    djm_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [iy_in, im_in, id_in, djm0_out, djm_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._cal2jd(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'cal2jd')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(djm0_out.shape) > 0 and djm0_out.shape[0] == 1
+        djm0_out = djm0_out.reshape(djm0_out.shape[1:])
+        assert len(djm_out.shape) > 0 and djm_out.shape[0] == 1
+        djm_out = djm_out.reshape(djm_out.shape[1:])
+
+    return djm0_out, djm_out
+STATUS_CODES['cal2jd'] = {0: 'OK', -2: 'bad month  (JD not computed)', -1: 'bad year   (Note 3: 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), dj1_in, dj2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dj1_in, dj2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._epb(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    epb_in = numpy.array(epb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if epb_in.shape == tuple():
+            epb_in = epb_in.reshape((1,) + epb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), epb_in)
+    djm0_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    djm_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [epb_in, djm0_out, djm_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._epb2jd(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(djm0_out.shape) > 0 and djm0_out.shape[0] == 1
+        djm0_out = djm0_out.reshape(djm0_out.shape[1:])
+        assert len(djm_out.shape) > 0 and djm_out.shape[0] == 1
+        djm_out = djm_out.reshape(djm_out.shape[1:])
+
+    return djm0_out, djm_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), dj1_in, dj2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dj1_in, dj2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._epj(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    epj_in = numpy.array(epj, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if epj_in.shape == tuple():
+            epj_in = epj_in.reshape((1,) + epj_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), epj_in)
+    djm0_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    djm_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [epj_in, djm0_out, djm_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._epj2jd(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(djm0_out.shape) > 0 and djm0_out.shape[0] == 1
+        djm0_out = djm0_out.reshape(djm0_out.shape[1:])
+        assert len(djm_out.shape) > 0 and djm_out.shape[0] == 1
+        djm_out = djm_out.reshape(djm_out.shape[1:])
+
+    return djm0_out, djm_out
+
+
+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 3)
+
+    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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), dj1_in, dj2_in)
+    iy_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    im_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    id_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    fd_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dj1_in, dj2_in, iy_out, im_out, id_out, fd_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*5
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._jd2cal(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'jd2cal')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(iy_out.shape) > 0 and iy_out.shape[0] == 1
+        iy_out = iy_out.reshape(iy_out.shape[1:])
+        assert len(im_out.shape) > 0 and im_out.shape[0] == 1
+        im_out = im_out.reshape(im_out.shape[1:])
+        assert len(id_out.shape) > 0 and id_out.shape[0] == 1
+        id_out = id_out.reshape(id_out.shape[1:])
+        assert len(fd_out.shape) > 0 and fd_out.shape[0] == 1
+        fd_out = fd_out.reshape(fd_out.shape[1:])
+
+    return iy_out, im_out, id_out, fd_out
+STATUS_CODES['jd2cal'] = {0: 'OK', -1: 'unacceptable date (Note 3)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ndp_in = numpy.array(ndp, dtype=numpy.intc, order="C", copy=False, subok=True)
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ndp_in.shape == tuple():
+            ndp_in = ndp_in.reshape((1,) + ndp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ndp_in, dj1_in, dj2_in)
+    iymdf_out = numpy.empty(broadcast.shape + (4,), dtype=numpy.intc)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ndp_in, dj1_in, dj2_in, iymdf_out[...,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._jdcalf(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'jdcalf')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(iymdf_out.shape) > 0 and iymdf_out.shape[0] == 1
+        iymdf_out = iymdf_out.reshape(iymdf_out.shape[1:])
+
+    return iymdf_out
+STATUS_CODES['jdcalf'] = {0: 'OK', 1: 'NDP not 0-9 (interpreted as 0)', -1: 'date out of range'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    pnat_in = numpy.array(pnat, dtype=numpy.double, order="C", copy=False, subok=True)
+    v_in = numpy.array(v, dtype=numpy.double, order="C", copy=False, subok=True)
+    s_in = numpy.array(s, dtype=numpy.double, order="C", copy=False, subok=True)
+    bm1_in = numpy.array(bm1, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(pnat_in, (3,), "pnat")
+    check_trailing_shape(v_in, (3,), "v")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if pnat_in[...,0].shape == tuple():
+            pnat_in = pnat_in.reshape((1,) + pnat_in.shape)
+        else:
+            make_outputs_scalar = False
+        if v_in[...,0].shape == tuple():
+            v_in = v_in.reshape((1,) + v_in.shape)
+        else:
+            make_outputs_scalar = False
+        if s_in.shape == tuple():
+            s_in = s_in.reshape((1,) + s_in.shape)
+        else:
+            make_outputs_scalar = False
+        if bm1_in.shape == tuple():
+            bm1_in = bm1_in.reshape((1,) + bm1_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), pnat_in[...,0], v_in[...,0], s_in, bm1_in)
+    ppr_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [pnat_in[...,0], v_in[...,0], s_in, bm1_in, ppr_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ab(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ppr_out.shape) > 0 and ppr_out.shape[0] == 1
+        ppr_out = ppr_out.reshape(ppr_out.shape[1:])
+
+    return ppr_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    ebpv_in = numpy.array(ebpv, dtype=numpy.double, order="C", copy=False, subok=True)
+    ehp_in = numpy.array(ehp, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(ebpv_in, (2, 3), "ebpv")
+    check_trailing_shape(ehp_in, (3,), "ehp")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ebpv_in[...,0,0].shape == tuple():
+            ebpv_in = ebpv_in.reshape((1,) + ebpv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ehp_in[...,0].shape == tuple():
+            ehp_in = ehp_in.reshape((1,) + ehp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0])
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0], astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apcg(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apcg13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    ebpv_in = numpy.array(ebpv, dtype=numpy.double, order="C", copy=False, subok=True)
+    ehp_in = numpy.array(ehp, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    s_in = numpy.array(s, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(ebpv_in, (2, 3), "ebpv")
+    check_trailing_shape(ehp_in, (3,), "ehp")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ebpv_in[...,0,0].shape == tuple():
+            ebpv_in = ebpv_in.reshape((1,) + ebpv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ehp_in[...,0].shape == tuple():
+            ehp_in = ehp_in.reshape((1,) + ehp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+        if s_in.shape == tuple():
+            s_in = s_in.reshape((1,) + s_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0], x_in, y_in, s_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0], x_in, y_in, s_in, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*7 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apci(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    eo_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, astrom_out, eo_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apci13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+        assert len(eo_out.shape) > 0 and eo_out.shape[0] == 1
+        eo_out = eo_out.reshape(eo_out.shape[1:])
+
+    return astrom_out, eo_out
+
+
+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
+    -------
+    refa : double array
+    refb : double array
+    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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    ebpv_in = numpy.array(ebpv, dtype=numpy.double, order="C", copy=False, subok=True)
+    ehp_in = numpy.array(ehp, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    s_in = numpy.array(s, dtype=numpy.double, order="C", copy=False, subok=True)
+    theta_in = numpy.array(theta, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    sp_in = numpy.array(sp, dtype=numpy.double, order="C", copy=False, subok=True)
+    refa_in = numpy.array(refa, dtype=numpy.double, order="C", copy=False, subok=True)
+    refb_in = numpy.array(refb, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(ebpv_in, (2, 3), "ebpv")
+    check_trailing_shape(ehp_in, (3,), "ehp")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ebpv_in[...,0,0].shape == tuple():
+            ebpv_in = ebpv_in.reshape((1,) + ebpv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ehp_in[...,0].shape == tuple():
+            ehp_in = ehp_in.reshape((1,) + ehp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+        if s_in.shape == tuple():
+            s_in = s_in.reshape((1,) + s_in.shape)
+        else:
+            make_outputs_scalar = False
+        if theta_in.shape == tuple():
+            theta_in = theta_in.reshape((1,) + theta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if sp_in.shape == tuple():
+            sp_in = sp_in.reshape((1,) + sp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if refa_in.shape == tuple():
+            refa_in = refa_in.reshape((1,) + refa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if refb_in.shape == tuple():
+            refb_in = refb_in.reshape((1,) + refb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0], x_in, y_in, s_in, theta_in, elong_in, phi_in, hm_in, xp_in, yp_in, sp_in, refa_in, refb_in)
+    refa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    refb_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    numpy.copyto(refa_out, refa_in)
+    numpy.copyto(refb_out, refb_in)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, ebpv_in[...,0,0], ehp_in[...,0], x_in, y_in, s_in, theta_in, elong_in, phi_in, hm_in, xp_in, yp_in, sp_in, refa_out, refb_out, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*14 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apco(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(refa_out.shape) > 0 and refa_out.shape[0] == 1
+        refa_out = refa_out.reshape(refa_out.shape[1:])
+        assert len(refb_out.shape) > 0 and refb_out.shape[0] == 1
+        refb_out = refb_out.reshape(refb_out.shape[1:])
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return refa_out, refb_out, astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    eo_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, astrom_out, eo_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*12 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apco13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'apco13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+        assert len(eo_out.shape) > 0 and eo_out.shape[0] == 1
+        eo_out = eo_out.reshape(eo_out.shape[1:])
+
+    return astrom_out, eo_out
+STATUS_CODES['apco13'] = {0: 'OK', 1: 'dubious year (Note 2)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    pv_in = numpy.array(pv, dtype=numpy.double, order="C", copy=False, subok=True)
+    ebpv_in = numpy.array(ebpv, dtype=numpy.double, order="C", copy=False, subok=True)
+    ehp_in = numpy.array(ehp, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(pv_in, (2, 3), "pv")
+    check_trailing_shape(ebpv_in, (2, 3), "ebpv")
+    check_trailing_shape(ehp_in, (3,), "ehp")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pv_in[...,0,0].shape == tuple():
+            pv_in = pv_in.reshape((1,) + pv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ebpv_in[...,0,0].shape == tuple():
+            ebpv_in = ebpv_in.reshape((1,) + ebpv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ehp_in[...,0].shape == tuple():
+            ehp_in = ehp_in.reshape((1,) + ehp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, pv_in[...,0,0], ebpv_in[...,0,0], ehp_in[...,0])
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, pv_in[...,0,0], ebpv_in[...,0,0], ehp_in[...,0], astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*5 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apcs(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    pv_in = numpy.array(pv, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(pv_in, (2, 3), "pv")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pv_in[...,0,0].shape == tuple():
+            pv_in = pv_in.reshape((1,) + pv_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, pv_in[...,0,0])
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, pv_in[...,0,0], astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apcs13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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.
+
+    - - - - - - - -
+     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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    theta_in = numpy.array(theta, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if theta_in.shape == tuple():
+            theta_in = theta_in.reshape((1,) + theta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), theta_in, astrom_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    numpy.copyto(astrom_out, astrom_in)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [theta_in, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._aper(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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.
+
+    - - - - - - - - - -
+     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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ut11_in = numpy.array(ut11, dtype=numpy.double, order="C", copy=False, subok=True)
+    ut12_in = numpy.array(ut12, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ut11_in.shape == tuple():
+            ut11_in = ut11_in.reshape((1,) + ut11_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ut12_in.shape == tuple():
+            ut12_in = ut12_in.reshape((1,) + ut12_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ut11_in, ut12_in, astrom_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    numpy.copyto(astrom_out, astrom_in)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ut11_in, ut12_in, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._aper13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+
+
+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
+    -------
+    refa : double array
+    refb : double array
+    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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    sp_in = numpy.array(sp, dtype=numpy.double, order="C", copy=False, subok=True)
+    theta_in = numpy.array(theta, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    refa_in = numpy.array(refa, dtype=numpy.double, order="C", copy=False, subok=True)
+    refb_in = numpy.array(refb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if sp_in.shape == tuple():
+            sp_in = sp_in.reshape((1,) + sp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if theta_in.shape == tuple():
+            theta_in = theta_in.reshape((1,) + theta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if refa_in.shape == tuple():
+            refa_in = refa_in.reshape((1,) + refa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if refb_in.shape == tuple():
+            refb_in = refb_in.reshape((1,) + refb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), sp_in, theta_in, elong_in, phi_in, hm_in, xp_in, yp_in, refa_in, refb_in)
+    refa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    refb_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    numpy.copyto(refa_out, refa_in)
+    numpy.copyto(refb_out, refb_in)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [sp_in, theta_in, elong_in, phi_in, hm_in, xp_in, yp_in, refa_out, refb_out, astrom_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*7 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apio(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(refa_out.shape) > 0 and refa_out.shape[0] == 1
+        refa_out = refa_out.reshape(refa_out.shape[1:])
+        assert len(refb_out.shape) > 0 and refb_out.shape[0] == 1
+        refb_out = refb_out.reshape(refb_out.shape[1:])
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return refa_out, refb_out, astrom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    astrom_out = numpy.empty(broadcast.shape + (), dtype=dt_eraASTROM)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, astrom_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*12 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._apio13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'apio13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(astrom_out.shape) > 0 and astrom_out.shape[0] == 1
+        astrom_out = astrom_out.reshape(astrom_out.shape[1:])
+
+    return astrom_out
+STATUS_CODES['apio13'] = {0: 'OK', 1: 'dubious year (Note 2)', -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.8g could be expressed in any of these ways, among
+       others:
+
+              date1          date2
+
+           2450123.8g           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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    pr_in = numpy.array(pr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pd_in = numpy.array(pd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pr_in.shape == tuple():
+            pr_in = pr_in.reshape((1,) + pr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pd_in.shape == tuple():
+            pd_in = pd_in.reshape((1,) + pd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, pr_in, pd_in, px_in, rv_in, date1_in, date2_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    eo_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, pr_in, pd_in, px_in, rv_in, date1_in, date2_in, ri_out, di_out, eo_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*8 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atci13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+        assert len(eo_out.shape) > 0 and eo_out.shape[0] == 1
+        eo_out = eo_out.reshape(eo_out.shape[1:])
+
+    return ri_out, di_out, eo_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    pr_in = numpy.array(pr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pd_in = numpy.array(pd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pr_in.shape == tuple():
+            pr_in = pr_in.reshape((1,) + pr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pd_in.shape == tuple():
+            pd_in = pd_in.reshape((1,) + pd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, pr_in, pd_in, px_in, rv_in, astrom_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, pr_in, pd_in, px_in, rv_in, astrom_in, ri_out, di_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*7 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atciq(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+
+    return ri_out, di_out
+
+
+def atciqn(rc, dc, pr, pd, px, rv, astrom, n, 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
+    n : int 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    pr_in = numpy.array(pr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pd_in = numpy.array(pd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    b_in = numpy.array(b, dtype=dt_eraLDBODY, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pr_in.shape == tuple():
+            pr_in = pr_in.reshape((1,) + pr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pd_in.shape == tuple():
+            pd_in = pd_in.reshape((1,) + pd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+        if b_in.shape == tuple():
+            b_in = b_in.reshape((1,) + b_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, pr_in, pd_in, px_in, rv_in, astrom_in, n_in, b_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, pr_in, pd_in, px_in, rv_in, astrom_in, n_in, b_in, ri_out, di_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*9 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atciqn(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+
+    return ri_out, di_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, astrom_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, astrom_in, ri_out, di_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atciqz(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+
+    return ri_out, di_out
+
+
+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 ICRS to observed
+
+    Copyright (C) 2013-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    pr_in = numpy.array(pr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pd_in = numpy.array(pd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pr_in.shape == tuple():
+            pr_in = pr_in.reshape((1,) + pr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pd_in.shape == tuple():
+            pd_in = pd_in.reshape((1,) + pd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, pr_in, pd_in, px_in, rv_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    aob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    zob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    hob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    eo_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, pr_in, pd_in, px_in, rv_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, aob_out, zob_out, hob_out, dob_out, rob_out, eo_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*18 + [['readwrite']]*7
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atco13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'atco13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(aob_out.shape) > 0 and aob_out.shape[0] == 1
+        aob_out = aob_out.reshape(aob_out.shape[1:])
+        assert len(zob_out.shape) > 0 and zob_out.shape[0] == 1
+        zob_out = zob_out.reshape(zob_out.shape[1:])
+        assert len(hob_out.shape) > 0 and hob_out.shape[0] == 1
+        hob_out = hob_out.reshape(hob_out.shape[1:])
+        assert len(dob_out.shape) > 0 and dob_out.shape[0] == 1
+        dob_out = dob_out.reshape(dob_out.shape[1:])
+        assert len(rob_out.shape) > 0 and rob_out.shape[0] == 1
+        rob_out = rob_out.reshape(rob_out.shape[1:])
+        assert len(eo_out.shape) > 0 and eo_out.shape[0] == 1
+        eo_out = eo_out.reshape(eo_out.shape[1:])
+
+    return aob_out, zob_out, hob_out, dob_out, rob_out, eo_out
+STATUS_CODES['atco13'] = {0: 'OK', 1: 'dubious year (Note 4)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ri_in = numpy.array(ri, dtype=numpy.double, order="C", copy=False, subok=True)
+    di_in = numpy.array(di, dtype=numpy.double, order="C", copy=False, subok=True)
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ri_in.shape == tuple():
+            ri_in = ri_in.reshape((1,) + ri_in.shape)
+        else:
+            make_outputs_scalar = False
+        if di_in.shape == tuple():
+            di_in = di_in.reshape((1,) + di_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ri_in, di_in, date1_in, date2_in)
+    rc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    eo_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ri_in, di_in, date1_in, date2_in, rc_out, dc_out, eo_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atic13(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc_out.shape) > 0 and rc_out.shape[0] == 1
+        rc_out = rc_out.reshape(rc_out.shape[1:])
+        assert len(dc_out.shape) > 0 and dc_out.shape[0] == 1
+        dc_out = dc_out.reshape(dc_out.shape[1:])
+        assert len(eo_out.shape) > 0 and eo_out.shape[0] == 1
+        eo_out = eo_out.reshape(eo_out.shape[1:])
+
+    return rc_out, dc_out, eo_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ri_in = numpy.array(ri, dtype=numpy.double, order="C", copy=False, subok=True)
+    di_in = numpy.array(di, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ri_in.shape == tuple():
+            ri_in = ri_in.reshape((1,) + ri_in.shape)
+        else:
+            make_outputs_scalar = False
+        if di_in.shape == tuple():
+            di_in = di_in.reshape((1,) + di_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ri_in, di_in, astrom_in)
+    rc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ri_in, di_in, astrom_in, rc_out, dc_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._aticq(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc_out.shape) > 0 and rc_out.shape[0] == 1
+        rc_out = rc_out.reshape(rc_out.shape[1:])
+        assert len(dc_out.shape) > 0 and dc_out.shape[0] == 1
+        dc_out = dc_out.reshape(dc_out.shape[1:])
+
+    return rc_out, dc_out
+
+
+def aticqn(ri, di, astrom, n, b):
+    """
+    Wrapper for ERFA function ``eraAticqn``.
+
+    Parameters
+    ----------
+    ri : double array
+    di : double array
+    astrom : eraASTROM array
+    n : int 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ri_in = numpy.array(ri, dtype=numpy.double, order="C", copy=False, subok=True)
+    di_in = numpy.array(di, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    b_in = numpy.array(b, dtype=dt_eraLDBODY, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ri_in.shape == tuple():
+            ri_in = ri_in.reshape((1,) + ri_in.shape)
+        else:
+            make_outputs_scalar = False
+        if di_in.shape == tuple():
+            di_in = di_in.reshape((1,) + di_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+        if b_in.shape == tuple():
+            b_in = b_in.reshape((1,) + b_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ri_in, di_in, astrom_in, n_in, b_in)
+    rc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ri_in, di_in, astrom_in, n_in, b_in, rc_out, dc_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*5 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._aticqn(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc_out.shape) > 0 and rc_out.shape[0] == 1
+        rc_out = rc_out.reshape(rc_out.shape[1:])
+        assert len(dc_out.shape) > 0 and dc_out.shape[0] == 1
+        dc_out = dc_out.reshape(dc_out.shape[1:])
+
+    return rc_out, dc_out
+
+
+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 ICRS to observed
+
+    Copyright (C) 2013-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ri_in = numpy.array(ri, dtype=numpy.double, order="C", copy=False, subok=True)
+    di_in = numpy.array(di, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ri_in.shape == tuple():
+            ri_in = ri_in.reshape((1,) + ri_in.shape)
+        else:
+            make_outputs_scalar = False
+        if di_in.shape == tuple():
+            di_in = di_in.reshape((1,) + di_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ri_in, di_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    aob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    zob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    hob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ri_in, di_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, aob_out, zob_out, hob_out, dob_out, rob_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*14 + [['readwrite']]*6
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atio13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'atio13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(aob_out.shape) > 0 and aob_out.shape[0] == 1
+        aob_out = aob_out.reshape(aob_out.shape[1:])
+        assert len(zob_out.shape) > 0 and zob_out.shape[0] == 1
+        zob_out = zob_out.reshape(zob_out.shape[1:])
+        assert len(hob_out.shape) > 0 and hob_out.shape[0] == 1
+        hob_out = hob_out.reshape(hob_out.shape[1:])
+        assert len(dob_out.shape) > 0 and dob_out.shape[0] == 1
+        dob_out = dob_out.reshape(dob_out.shape[1:])
+        assert len(rob_out.shape) > 0 and rob_out.shape[0] == 1
+        rob_out = rob_out.reshape(rob_out.shape[1:])
+
+    return aob_out, zob_out, hob_out, dob_out, rob_out
+STATUS_CODES['atio13'] = {0: 'OK', 1: 'dubious year (Note 2)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ri_in = numpy.array(ri, dtype=numpy.double, order="C", copy=False, subok=True)
+    di_in = numpy.array(di, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ri_in.shape == tuple():
+            ri_in = ri_in.reshape((1,) + ri_in.shape)
+        else:
+            make_outputs_scalar = False
+        if di_in.shape == tuple():
+            di_in = di_in.reshape((1,) + di_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ri_in, di_in, astrom_in)
+    aob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    zob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    hob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rob_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ri_in, di_in, astrom_in, aob_out, zob_out, hob_out, dob_out, rob_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*5
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atioq(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(aob_out.shape) > 0 and aob_out.shape[0] == 1
+        aob_out = aob_out.reshape(aob_out.shape[1:])
+        assert len(zob_out.shape) > 0 and zob_out.shape[0] == 1
+        zob_out = zob_out.reshape(zob_out.shape[1:])
+        assert len(hob_out.shape) > 0 and hob_out.shape[0] == 1
+        hob_out = hob_out.reshape(hob_out.shape[1:])
+        assert len(dob_out.shape) > 0 and dob_out.shape[0] == 1
+        dob_out = dob_out.reshape(dob_out.shape[1:])
+        assert len(rob_out.shape) > 0 and rob_out.shape[0] == 1
+        rob_out = rob_out.reshape(rob_out.shape[1:])
+
+    return aob_out, zob_out, hob_out, dob_out, rob_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    type_in = numpy.array(type, dtype=numpy.dtype('S16'), order="C", copy=False, subok=True)
+    ob1_in = numpy.array(ob1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ob2_in = numpy.array(ob2, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if type_in.shape == tuple():
+            type_in = type_in.reshape((1,) + type_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob1_in.shape == tuple():
+            ob1_in = ob1_in.reshape((1,) + ob1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob2_in.shape == tuple():
+            ob2_in = ob2_in.reshape((1,) + ob2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), type_in, ob1_in, ob2_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    rc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dc_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [type_in, ob1_in, ob2_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, rc_out, dc_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*15 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atoc13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'atoc13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc_out.shape) > 0 and rc_out.shape[0] == 1
+        rc_out = rc_out.reshape(rc_out.shape[1:])
+        assert len(dc_out.shape) > 0 and dc_out.shape[0] == 1
+        dc_out = dc_out.reshape(dc_out.shape[1:])
+
+    return rc_out, dc_out
+STATUS_CODES['atoc13'] = {0: 'OK', 1: 'dubious year (Note 4)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    type_in = numpy.array(type, dtype=numpy.dtype('S16'), order="C", copy=False, subok=True)
+    ob1_in = numpy.array(ob1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ob2_in = numpy.array(ob2, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if type_in.shape == tuple():
+            type_in = type_in.reshape((1,) + type_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob1_in.shape == tuple():
+            ob1_in = ob1_in.reshape((1,) + ob1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob2_in.shape == tuple():
+            ob2_in = ob2_in.reshape((1,) + ob2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), type_in, ob1_in, ob2_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [type_in, ob1_in, ob2_in, utc1_in, utc2_in, dut1_in, elong_in, phi_in, hm_in, xp_in, yp_in, phpa_in, tc_in, rh_in, wl_in, ri_out, di_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*15 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atoi13(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'atoi13')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+
+    return ri_out, di_out
+STATUS_CODES['atoi13'] = {0: 'OK', 1: 'dubious year (Note 2)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    type_in = numpy.array(type, dtype=numpy.dtype('S16'), order="C", copy=False, subok=True)
+    ob1_in = numpy.array(ob1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ob2_in = numpy.array(ob2, dtype=numpy.double, order="C", copy=False, subok=True)
+    astrom_in = numpy.array(astrom, dtype=dt_eraASTROM, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if type_in.shape == tuple():
+            type_in = type_in.reshape((1,) + type_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob1_in.shape == tuple():
+            ob1_in = ob1_in.reshape((1,) + ob1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob2_in.shape == tuple():
+            ob2_in = ob2_in.reshape((1,) + ob2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if astrom_in.shape == tuple():
+            astrom_in = astrom_in.reshape((1,) + astrom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), type_in, ob1_in, ob2_in, astrom_in)
+    ri_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    di_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [type_in, ob1_in, ob2_in, astrom_in, ri_out, di_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._atoiq(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ri_out.shape) > 0 and ri_out.shape[0] == 1
+        ri_out = ri_out.reshape(ri_out.shape[1:])
+        assert len(di_out.shape) > 0 and di_out.shape[0] == 1
+        di_out = di_out.reshape(di_out.shape[1:])
+
+    return ri_out, di_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    bm_in = numpy.array(bm, dtype=numpy.double, order="C", copy=False, subok=True)
+    p_in = numpy.array(p, dtype=numpy.double, order="C", copy=False, subok=True)
+    q_in = numpy.array(q, dtype=numpy.double, order="C", copy=False, subok=True)
+    e_in = numpy.array(e, dtype=numpy.double, order="C", copy=False, subok=True)
+    em_in = numpy.array(em, dtype=numpy.double, order="C", copy=False, subok=True)
+    dlim_in = numpy.array(dlim, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(p_in, (3,), "p")
+    check_trailing_shape(q_in, (3,), "q")
+    check_trailing_shape(e_in, (3,), "e")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if bm_in.shape == tuple():
+            bm_in = bm_in.reshape((1,) + bm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if p_in[...,0].shape == tuple():
+            p_in = p_in.reshape((1,) + p_in.shape)
+        else:
+            make_outputs_scalar = False
+        if q_in[...,0].shape == tuple():
+            q_in = q_in.reshape((1,) + q_in.shape)
+        else:
+            make_outputs_scalar = False
+        if e_in[...,0].shape == tuple():
+            e_in = e_in.reshape((1,) + e_in.shape)
+        else:
+            make_outputs_scalar = False
+        if em_in.shape == tuple():
+            em_in = em_in.reshape((1,) + em_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dlim_in.shape == tuple():
+            dlim_in = dlim_in.reshape((1,) + dlim_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), bm_in, p_in[...,0], q_in[...,0], e_in[...,0], em_in, dlim_in)
+    p1_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [bm_in, p_in[...,0], q_in[...,0], e_in[...,0], em_in, dlim_in, p1_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ld(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(p1_out.shape) > 0 and p1_out.shape[0] == 1
+        p1_out = p1_out.reshape(p1_out.shape[1:])
+
+    return p1_out
+
+
+def ldn(n, b, ob, sc):
+    """
+    Wrapper for ERFA function ``eraLdn``.
+
+    Parameters
+    ----------
+    n : int array
+    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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    b_in = numpy.array(b, dtype=dt_eraLDBODY, order="C", copy=False, subok=True)
+    ob_in = numpy.array(ob, dtype=numpy.double, order="C", copy=False, subok=True)
+    sc_in = numpy.array(sc, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(ob_in, (3,), "ob")
+    check_trailing_shape(sc_in, (3,), "sc")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+        if b_in.shape == tuple():
+            b_in = b_in.reshape((1,) + b_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ob_in[...,0].shape == tuple():
+            ob_in = ob_in.reshape((1,) + ob_in.shape)
+        else:
+            make_outputs_scalar = False
+        if sc_in[...,0].shape == tuple():
+            sc_in = sc_in.reshape((1,) + sc_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), n_in, b_in, ob_in[...,0], sc_in[...,0])
+    sn_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [n_in, b_in, ob_in[...,0], sc_in[...,0], sn_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ldn(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(sn_out.shape) > 0 and sn_out.shape[0] == 1
+        sn_out = sn_out.reshape(sn_out.shape[1:])
+
+    return sn_out
+
+
+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 about 9 arcsec, falling to
+       zero for zero separation. (The chosen threshold is within the
+       solar limb for all solar-system applications.)
+
+    3) The arguments p and p1 can be the same array.
+
+    Called:
+       eraLd        light deflection by a solar-system body
+
+    Copyright (C) 2013-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    p_in = numpy.array(p, dtype=numpy.double, order="C", copy=False, subok=True)
+    e_in = numpy.array(e, dtype=numpy.double, order="C", copy=False, subok=True)
+    em_in = numpy.array(em, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(p_in, (3,), "p")
+    check_trailing_shape(e_in, (3,), "e")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if p_in[...,0].shape == tuple():
+            p_in = p_in.reshape((1,) + p_in.shape)
+        else:
+            make_outputs_scalar = False
+        if e_in[...,0].shape == tuple():
+            e_in = e_in.reshape((1,) + e_in.shape)
+        else:
+            make_outputs_scalar = False
+        if em_in.shape == tuple():
+            em_in = em_in.reshape((1,) + em_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), p_in[...,0], e_in[...,0], em_in)
+    p1_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [p_in[...,0], e_in[...,0], em_in, p1_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ldsun(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(p1_out.shape) > 0 and p1_out.shape[0] == 1
+        p1_out = p1_out.reshape(p1_out.shape[1:])
+
+    return p1_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc_in = numpy.array(rc, dtype=numpy.double, order="C", copy=False, subok=True)
+    dc_in = numpy.array(dc, dtype=numpy.double, order="C", copy=False, subok=True)
+    pr_in = numpy.array(pr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pd_in = numpy.array(pd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmt_in = numpy.array(pmt, dtype=numpy.double, order="C", copy=False, subok=True)
+    pob_in = numpy.array(pob, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(pob_in, (3,), "pob")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc_in.shape == tuple():
+            rc_in = rc_in.reshape((1,) + rc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dc_in.shape == tuple():
+            dc_in = dc_in.reshape((1,) + dc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pr_in.shape == tuple():
+            pr_in = pr_in.reshape((1,) + pr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pd_in.shape == tuple():
+            pd_in = pd_in.reshape((1,) + pd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmt_in.shape == tuple():
+            pmt_in = pmt_in.reshape((1,) + pmt_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pob_in[...,0].shape == tuple():
+            pob_in = pob_in.reshape((1,) + pob_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc_in, dc_in, pr_in, pd_in, px_in, rv_in, pmt_in, pob_in[...,0])
+    pco_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc_in, dc_in, pr_in, pd_in, px_in, rv_in, pmt_in, pob_in[...,0], pco_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*8 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmpx(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(pco_out.shape) > 0 and pco_out.shape[0] == 1
+        pco_out = pco_out.reshape(pco_out.shape[1:])
+
+    return pco_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ra1_in = numpy.array(ra1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dec1_in = numpy.array(dec1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmr1_in = numpy.array(pmr1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmd1_in = numpy.array(pmd1, dtype=numpy.double, order="C", copy=False, subok=True)
+    px1_in = numpy.array(px1, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv1_in = numpy.array(rv1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1a_in = numpy.array(ep1a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1b_in = numpy.array(ep1b, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2a_in = numpy.array(ep2a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2b_in = numpy.array(ep2b, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ra1_in.shape == tuple():
+            ra1_in = ra1_in.reshape((1,) + ra1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dec1_in.shape == tuple():
+            dec1_in = dec1_in.reshape((1,) + dec1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmr1_in.shape == tuple():
+            pmr1_in = pmr1_in.reshape((1,) + pmr1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmd1_in.shape == tuple():
+            pmd1_in = pmd1_in.reshape((1,) + pmd1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px1_in.shape == tuple():
+            px1_in = px1_in.reshape((1,) + px1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv1_in.shape == tuple():
+            rv1_in = rv1_in.reshape((1,) + rv1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1a_in.shape == tuple():
+            ep1a_in = ep1a_in.reshape((1,) + ep1a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1b_in.shape == tuple():
+            ep1b_in = ep1b_in.reshape((1,) + ep1b_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2a_in.shape == tuple():
+            ep2a_in = ep2a_in.reshape((1,) + ep2a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2b_in.shape == tuple():
+            ep2b_in = ep2b_in.reshape((1,) + ep2b_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in)
+    ra2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dec2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmr2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmd2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    px2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rv2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in, ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*10 + [['readwrite']]*7
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmsafe(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'pmsafe')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ra2_out.shape) > 0 and ra2_out.shape[0] == 1
+        ra2_out = ra2_out.reshape(ra2_out.shape[1:])
+        assert len(dec2_out.shape) > 0 and dec2_out.shape[0] == 1
+        dec2_out = dec2_out.reshape(dec2_out.shape[1:])
+        assert len(pmr2_out.shape) > 0 and pmr2_out.shape[0] == 1
+        pmr2_out = pmr2_out.reshape(pmr2_out.shape[1:])
+        assert len(pmd2_out.shape) > 0 and pmd2_out.shape[0] == 1
+        pmd2_out = pmd2_out.reshape(pmd2_out.shape[1:])
+        assert len(px2_out.shape) > 0 and px2_out.shape[0] == 1
+        px2_out = px2_out.reshape(px2_out.shape[1:])
+        assert len(rv2_out.shape) > 0 and rv2_out.shape[0] == 1
+        rv2_out = rv2_out.reshape(rv2_out.shape[1:])
+
+    return ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out
+STATUS_CODES['pmsafe'] = {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', -1: 'system error (should not occur)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    phpa_in = numpy.array(phpa, dtype=numpy.double, order="C", copy=False, subok=True)
+    tc_in = numpy.array(tc, dtype=numpy.double, order="C", copy=False, subok=True)
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    wl_in = numpy.array(wl, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if phpa_in.shape == tuple():
+            phpa_in = phpa_in.reshape((1,) + phpa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tc_in.shape == tuple():
+            tc_in = tc_in.reshape((1,) + tc_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if wl_in.shape == tuple():
+            wl_in = wl_in.reshape((1,) + wl_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), phpa_in, tc_in, rh_in, wl_in)
+    refa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    refb_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [phpa_in, tc_in, rh_in, wl_in, refa_out, refb_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._refco(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(refa_out.shape) > 0 and refa_out.shape[0] == 1
+        refa_out = refa_out.reshape(refa_out.shape[1:])
+        assert len(refb_out.shape) > 0 and refb_out.shape[0] == 1
+        refb_out = refb_out.reshape(refb_out.shape[1:])
+
+    return refa_out, refb_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    pvh_out = numpy.empty(broadcast.shape + (2, 3), dtype=numpy.double)
+    pvb_out = numpy.empty(broadcast.shape + (2, 3), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, pvh_out[...,0,0], pvb_out[...,0,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._epv00(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'epv00')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(pvh_out.shape) > 0 and pvh_out.shape[0] == 1
+        pvh_out = pvh_out.reshape(pvh_out.shape[1:])
+        assert len(pvb_out.shape) > 0 and pvb_out.shape[0] == 1
+        pvb_out = pvb_out.reshape(pvb_out.shape[1:])
+
+    return pvh_out, pvb_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    np_in = numpy.array(np, dtype=numpy.intc, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if np_in.shape == tuple():
+            np_in = np_in.reshape((1,) + np_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, np_in)
+    pv_out = numpy.empty(broadcast.shape + (2, 3), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, np_in, pv_out[...,0,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._plan94(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'plan94')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(pv_out.shape) > 0 and pv_out.shape[0] == 1
+        pv_out = pv_out.reshape(pv_out.shape[1:])
+
+    return pv_out
+STATUS_CODES['plan94'] = {0: 'OK', 1: 'warning: year outside 1000-3000', 2: 'warning: failed to converge', -1: 'illegal NP (outside 1-8)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fad03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fae03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._faf03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._faju03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fal03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._falp03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fama03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fame03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fane03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._faom03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fapa03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fasa03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._faur03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    t_in = numpy.array(t, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if t_in.shape == tuple():
+            t_in = t_in.reshape((1,) + t_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), t_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [t_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fave03(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), )
+    dpsibi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    depsbi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dra_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dpsibi_out, depsbi_out, dra_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*0 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._bi00(it)
+
+    return dpsibi_out, depsbi_out, dra_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._bp00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+
+    return rb_out, rp_out, rbp_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._bp06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+
+    return rb_out, rp_out, rbp_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rbpn_in = numpy.array(rbpn, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rbpn_in, (3, 3), "rbpn")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rbpn_in[...,0,0].shape == tuple():
+            rbpn_in = rbpn_in.reshape((1,) + rbpn_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rbpn_in[...,0,0])
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rbpn_in[...,0,0], x_out, y_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._bpn2xy(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+
+    return x_out, y_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2i00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2i00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2i06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    rbpn_in = numpy.array(rbpn, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rbpn_in, (3, 3), "rbpn")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rbpn_in[...,0,0].shape == tuple():
+            rbpn_in = rbpn_in.reshape((1,) + rbpn_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, rbpn_in[...,0,0])
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rbpn_in[...,0,0], rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2ibpn(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, x_in, y_in)
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_in, y_in, rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2ixy(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    s_in = numpy.array(s, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+        if s_in.shape == tuple():
+            s_in = s_in.reshape((1,) + s_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), x_in, y_in, s_in)
+    rc2i_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [x_in, y_in, s_in, rc2i_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2ixys(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2i_out.shape) > 0 and rc2i_out.shape[0] == 1
+        rc2i_out = rc2i_out.reshape(rc2i_out.shape[1:])
+
+    return rc2i_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in)
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in, rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2t00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in)
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in, rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2t00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in)
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tta_in, ttb_in, uta_in, utb_in, xp_in, yp_in, rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2t06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rc2i_in = numpy.array(rc2i, dtype=numpy.double, order="C", copy=False, subok=True)
+    era_in = numpy.array(era, dtype=numpy.double, order="C", copy=False, subok=True)
+    rpom_in = numpy.array(rpom, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rc2i_in, (3, 3), "rc2i")
+    check_trailing_shape(rpom_in, (3, 3), "rpom")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rc2i_in[...,0,0].shape == tuple():
+            rc2i_in = rc2i_in.reshape((1,) + rc2i_in.shape)
+        else:
+            make_outputs_scalar = False
+        if era_in.shape == tuple():
+            era_in = era_in.reshape((1,) + era_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rpom_in[...,0,0].shape == tuple():
+            rpom_in = rpom_in.reshape((1,) + rpom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rc2i_in[...,0,0], era_in, rpom_in[...,0,0])
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rc2i_in[...,0,0], era_in, rpom_in[...,0,0], rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2tcio(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rbpn_in = numpy.array(rbpn, dtype=numpy.double, order="C", copy=False, subok=True)
+    gst_in = numpy.array(gst, dtype=numpy.double, order="C", copy=False, subok=True)
+    rpom_in = numpy.array(rpom, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rbpn_in, (3, 3), "rbpn")
+    check_trailing_shape(rpom_in, (3, 3), "rpom")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rbpn_in[...,0,0].shape == tuple():
+            rbpn_in = rbpn_in.reshape((1,) + rbpn_in.shape)
+        else:
+            make_outputs_scalar = False
+        if gst_in.shape == tuple():
+            gst_in = gst_in.reshape((1,) + gst_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rpom_in[...,0,0].shape == tuple():
+            rpom_in = rpom_in.reshape((1,) + rpom_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rbpn_in[...,0,0], gst_in, rpom_in[...,0,0])
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rbpn_in[...,0,0], gst_in, rpom_in[...,0,0], rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2teqx(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    dpsi_in = numpy.array(dpsi, dtype=numpy.double, order="C", copy=False, subok=True)
+    deps_in = numpy.array(deps, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dpsi_in.shape == tuple():
+            dpsi_in = dpsi_in.reshape((1,) + dpsi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if deps_in.shape == tuple():
+            deps_in = deps_in.reshape((1,) + deps_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tta_in, ttb_in, uta_in, utb_in, dpsi_in, deps_in, xp_in, yp_in)
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tta_in, ttb_in, uta_in, utb_in, dpsi_in, deps_in, xp_in, yp_in, rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*8 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2tpe(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tta_in, ttb_in, uta_in, utb_in, x_in, y_in, xp_in, yp_in)
+    rc2t_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tta_in, ttb_in, uta_in, utb_in, x_in, y_in, xp_in, yp_in, rc2t_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*8 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._c2txy(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rc2t_out.shape) > 0 and rc2t_out.shape[0] == 1
+        rc2t_out = rc2t_out.reshape(rc2t_out.shape[1:])
+
+    return rc2t_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._eo06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rnpb_in = numpy.array(rnpb, dtype=numpy.double, order="C", copy=False, subok=True)
+    s_in = numpy.array(s, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rnpb_in, (3, 3), "rnpb")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rnpb_in[...,0,0].shape == tuple():
+            rnpb_in = rnpb_in.reshape((1,) + rnpb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if s_in.shape == tuple():
+            s_in = s_in.reshape((1,) + s_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rnpb_in[...,0,0], s_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rnpb_in[...,0,0], s_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._eors(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    gamb_in = numpy.array(gamb, dtype=numpy.double, order="C", copy=False, subok=True)
+    phib_in = numpy.array(phib, dtype=numpy.double, order="C", copy=False, subok=True)
+    psi_in = numpy.array(psi, dtype=numpy.double, order="C", copy=False, subok=True)
+    eps_in = numpy.array(eps, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if gamb_in.shape == tuple():
+            gamb_in = gamb_in.reshape((1,) + gamb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phib_in.shape == tuple():
+            phib_in = phib_in.reshape((1,) + phib_in.shape)
+        else:
+            make_outputs_scalar = False
+        if psi_in.shape == tuple():
+            psi_in = psi_in.reshape((1,) + psi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if eps_in.shape == tuple():
+            eps_in = eps_in.reshape((1,) + eps_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), gamb_in, phib_in, psi_in, eps_in)
+    r_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [gamb_in, phib_in, psi_in, eps_in, r_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fw2m(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(r_out.shape) > 0 and r_out.shape[0] == 1
+        r_out = r_out.reshape(r_out.shape[1:])
+
+    return r_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    gamb_in = numpy.array(gamb, dtype=numpy.double, order="C", copy=False, subok=True)
+    phib_in = numpy.array(phib, dtype=numpy.double, order="C", copy=False, subok=True)
+    psi_in = numpy.array(psi, dtype=numpy.double, order="C", copy=False, subok=True)
+    eps_in = numpy.array(eps, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if gamb_in.shape == tuple():
+            gamb_in = gamb_in.reshape((1,) + gamb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phib_in.shape == tuple():
+            phib_in = phib_in.reshape((1,) + phib_in.shape)
+        else:
+            make_outputs_scalar = False
+        if psi_in.shape == tuple():
+            psi_in = psi_in.reshape((1,) + psi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if eps_in.shape == tuple():
+            eps_in = eps_in.reshape((1,) + eps_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), gamb_in, phib_in, psi_in, eps_in)
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [gamb_in, phib_in, psi_in, eps_in, x_out, y_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fw2xy(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+
+    return x_out, y_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._num00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatn_out.shape) > 0 and rmatn_out.shape[0] == 1
+        rmatn_out = rmatn_out.reshape(rmatn_out.shape[1:])
+
+    return rmatn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._num00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatn_out.shape) > 0 and rmatn_out.shape[0] == 1
+        rmatn_out = rmatn_out.reshape(rmatn_out.shape[1:])
+
+    return rmatn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._num06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatn_out.shape) > 0 and rmatn_out.shape[0] == 1
+        rmatn_out = rmatn_out.reshape(rmatn_out.shape[1:])
+
+    return rmatn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    epsa_in = numpy.array(epsa, dtype=numpy.double, order="C", copy=False, subok=True)
+    dpsi_in = numpy.array(dpsi, dtype=numpy.double, order="C", copy=False, subok=True)
+    deps_in = numpy.array(deps, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if epsa_in.shape == tuple():
+            epsa_in = epsa_in.reshape((1,) + epsa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dpsi_in.shape == tuple():
+            dpsi_in = dpsi_in.reshape((1,) + dpsi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if deps_in.shape == tuple():
+            deps_in = deps_in.reshape((1,) + deps_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), epsa_in, dpsi_in, deps_in)
+    rmatn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [epsa_in, dpsi_in, deps_in, rmatn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._numat(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatn_out.shape) > 0 and rmatn_out.shape[0] == 1
+        rmatn_out = rmatn_out.reshape(rmatn_out.shape[1:])
+
+    return rmatn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._nut00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+
+    return dpsi_out, deps_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._nut00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+
+    return dpsi_out, deps_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._nut06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+
+    return dpsi_out, deps_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._nut80(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+
+    return dpsi_out, deps_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._nutm80(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatn_out.shape) > 0 and rmatn_out.shape[0] == 1
+        rmatn_out = rmatn_out.reshape(rmatn_out.shape[1:])
+
+    return rmatn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._obl06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._obl80(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    eps0_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    psia_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    oma_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    bpa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    bqa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pia_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    bpia_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    chia_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    za_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    zetaa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    thetaa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    gam_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    phi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    psi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, eps0_out, psia_out, oma_out, bpa_out, bqa_out, pia_out, bpia_out, epsa_out, chia_out, za_out, zetaa_out, thetaa_out, pa_out, gam_out, phi_out, psi_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*16
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._p06e(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(eps0_out.shape) > 0 and eps0_out.shape[0] == 1
+        eps0_out = eps0_out.reshape(eps0_out.shape[1:])
+        assert len(psia_out.shape) > 0 and psia_out.shape[0] == 1
+        psia_out = psia_out.reshape(psia_out.shape[1:])
+        assert len(oma_out.shape) > 0 and oma_out.shape[0] == 1
+        oma_out = oma_out.reshape(oma_out.shape[1:])
+        assert len(bpa_out.shape) > 0 and bpa_out.shape[0] == 1
+        bpa_out = bpa_out.reshape(bpa_out.shape[1:])
+        assert len(bqa_out.shape) > 0 and bqa_out.shape[0] == 1
+        bqa_out = bqa_out.reshape(bqa_out.shape[1:])
+        assert len(pia_out.shape) > 0 and pia_out.shape[0] == 1
+        pia_out = pia_out.reshape(pia_out.shape[1:])
+        assert len(bpia_out.shape) > 0 and bpia_out.shape[0] == 1
+        bpia_out = bpia_out.reshape(bpia_out.shape[1:])
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(chia_out.shape) > 0 and chia_out.shape[0] == 1
+        chia_out = chia_out.reshape(chia_out.shape[1:])
+        assert len(za_out.shape) > 0 and za_out.shape[0] == 1
+        za_out = za_out.reshape(za_out.shape[1:])
+        assert len(zetaa_out.shape) > 0 and zetaa_out.shape[0] == 1
+        zetaa_out = zetaa_out.reshape(zetaa_out.shape[1:])
+        assert len(thetaa_out.shape) > 0 and thetaa_out.shape[0] == 1
+        thetaa_out = thetaa_out.reshape(thetaa_out.shape[1:])
+        assert len(pa_out.shape) > 0 and pa_out.shape[0] == 1
+        pa_out = pa_out.reshape(pa_out.shape[1:])
+        assert len(gam_out.shape) > 0 and gam_out.shape[0] == 1
+        gam_out = gam_out.reshape(gam_out.shape[1:])
+        assert len(phi_out.shape) > 0 and phi_out.shape[0] == 1
+        phi_out = phi_out.reshape(phi_out.shape[1:])
+        assert len(psi_out.shape) > 0 and psi_out.shape[0] == 1
+        psi_out = psi_out.reshape(psi_out.shape[1:])
+
+    return eps0_out, psia_out, oma_out, bpa_out, bqa_out, pia_out, bpia_out, epsa_out, chia_out, za_out, zetaa_out, thetaa_out, pa_out, gam_out, phi_out, psi_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    bzeta_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    bz_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    btheta_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, bzeta_out, bz_out, btheta_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pb06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(bzeta_out.shape) > 0 and bzeta_out.shape[0] == 1
+        bzeta_out = bzeta_out.reshape(bzeta_out.shape[1:])
+        assert len(bz_out.shape) > 0 and bz_out.shape[0] == 1
+        bz_out = bz_out.reshape(bz_out.shape[1:])
+        assert len(btheta_out.shape) > 0 and btheta_out.shape[0] == 1
+        btheta_out = btheta_out.reshape(btheta_out.shape[1:])
+
+    return bzeta_out, bz_out, btheta_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    gamb_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    phib_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    psib_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, gamb_out, phib_out, psib_out, epsa_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*4
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pfw06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(gamb_out.shape) > 0 and gamb_out.shape[0] == 1
+        gamb_out = gamb_out.reshape(gamb_out.shape[1:])
+        assert len(phib_out.shape) > 0 and phib_out.shape[0] == 1
+        phib_out = phib_out.reshape(phib_out.shape[1:])
+        assert len(psib_out.shape) > 0 and psib_out.shape[0] == 1
+        psib_out = psib_out.reshape(psib_out.shape[1:])
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+
+    return gamb_out, phib_out, psib_out, epsa_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rbp_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmat00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+
+    return rbp_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rbp_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmat06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+
+    return rbp_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatp_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmat76(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatp_out.shape) > 0 and rmatp_out.shape[0] == 1
+        rmatp_out = rmatp_out.reshape(rmatp_out.shape[1:])
+
+    return rmatp_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dpsi_in = numpy.array(dpsi, dtype=numpy.double, order="C", copy=False, subok=True)
+    deps_in = numpy.array(deps, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dpsi_in.shape == tuple():
+            dpsi_in = dpsi_in.reshape((1,) + dpsi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if deps_in.shape == tuple():
+            deps_in = deps_in.reshape((1,) + deps_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, dpsi_in, deps_in)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_in, deps_in, epsa_out, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0], rn_out[...,0,0], rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*6
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pn00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+        assert len(rn_out.shape) > 0 and rn_out.shape[0] == 1
+        rn_out = rn_out.reshape(rn_out.shape[1:])
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return epsa_out, rb_out, rp_out, rbp_out, rn_out, rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out, epsa_out, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0], rn_out[...,0,0], rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*8
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pn00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+        assert len(rn_out.shape) > 0 and rn_out.shape[0] == 1
+        rn_out = rn_out.reshape(rn_out.shape[1:])
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return dpsi_out, deps_out, epsa_out, rb_out, rp_out, rbp_out, rn_out, rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out, epsa_out, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0], rn_out[...,0,0], rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*8
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pn00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+        assert len(rn_out.shape) > 0 and rn_out.shape[0] == 1
+        rn_out = rn_out.reshape(rn_out.shape[1:])
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return dpsi_out, deps_out, epsa_out, rb_out, rp_out, rbp_out, rn_out, rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dpsi_in = numpy.array(dpsi, dtype=numpy.double, order="C", copy=False, subok=True)
+    deps_in = numpy.array(deps, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dpsi_in.shape == tuple():
+            dpsi_in = dpsi_in.reshape((1,) + dpsi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if deps_in.shape == tuple():
+            deps_in = deps_in.reshape((1,) + deps_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, dpsi_in, deps_in)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_in, deps_in, epsa_out, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0], rn_out[...,0,0], rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*6
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pn06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+        assert len(rn_out.shape) > 0 and rn_out.shape[0] == 1
+        rn_out = rn_out.reshape(rn_out.shape[1:])
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return epsa_out, rb_out, rp_out, rbp_out, rn_out, rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    deps_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    epsa_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbp_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsi_out, deps_out, epsa_out, rb_out[...,0,0], rp_out[...,0,0], rbp_out[...,0,0], rn_out[...,0,0], rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*8
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pn06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsi_out.shape) > 0 and dpsi_out.shape[0] == 1
+        dpsi_out = dpsi_out.reshape(dpsi_out.shape[1:])
+        assert len(deps_out.shape) > 0 and deps_out.shape[0] == 1
+        deps_out = deps_out.reshape(deps_out.shape[1:])
+        assert len(epsa_out.shape) > 0 and epsa_out.shape[0] == 1
+        epsa_out = epsa_out.reshape(epsa_out.shape[1:])
+        assert len(rb_out.shape) > 0 and rb_out.shape[0] == 1
+        rb_out = rb_out.reshape(rb_out.shape[1:])
+        assert len(rp_out.shape) > 0 and rp_out.shape[0] == 1
+        rp_out = rp_out.reshape(rp_out.shape[1:])
+        assert len(rbp_out.shape) > 0 and rbp_out.shape[0] == 1
+        rbp_out = rbp_out.reshape(rbp_out.shape[1:])
+        assert len(rn_out.shape) > 0 and rn_out.shape[0] == 1
+        rn_out = rn_out.reshape(rn_out.shape[1:])
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return dpsi_out, deps_out, epsa_out, rb_out, rp_out, rbp_out, rn_out, rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pnm00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rbpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rbpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pnm00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rbpn_out.shape) > 0 and rbpn_out.shape[0] == 1
+        rbpn_out = rbpn_out.reshape(rbpn_out.shape[1:])
+
+    return rbpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rnpb_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rnpb_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pnm06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rnpb_out.shape) > 0 and rnpb_out.shape[0] == 1
+        rnpb_out = rnpb_out.reshape(rnpb_out.shape[1:])
+
+    return rnpb_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    rmatpn_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, rmatpn_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pnm80(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rmatpn_out.shape) > 0 and rmatpn_out.shape[0] == 1
+        rmatpn_out = rmatpn_out.reshape(rmatpn_out.shape[1:])
+
+    return rmatpn_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    sp_in = numpy.array(sp, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if sp_in.shape == tuple():
+            sp_in = sp_in.reshape((1,) + sp_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), xp_in, yp_in, sp_in)
+    rpom_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [xp_in, yp_in, sp_in, rpom_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pom00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rpom_out.shape) > 0 and rpom_out.shape[0] == 1
+        rpom_out = rpom_out.reshape(rpom_out.shape[1:])
+
+    return rpom_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    dpsipr_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    depspr_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, dpsipr_out, depspr_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pr00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(dpsipr_out.shape) > 0 and dpsipr_out.shape[0] == 1
+        dpsipr_out = dpsipr_out.reshape(dpsipr_out.shape[1:])
+        assert len(depspr_out.shape) > 0 and depspr_out.shape[0] == 1
+        depspr_out = depspr_out.reshape(depspr_out.shape[1:])
+
+    return dpsipr_out, depspr_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date01_in = numpy.array(date01, dtype=numpy.double, order="C", copy=False, subok=True)
+    date02_in = numpy.array(date02, dtype=numpy.double, order="C", copy=False, subok=True)
+    date11_in = numpy.array(date11, dtype=numpy.double, order="C", copy=False, subok=True)
+    date12_in = numpy.array(date12, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date01_in.shape == tuple():
+            date01_in = date01_in.reshape((1,) + date01_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date02_in.shape == tuple():
+            date02_in = date02_in.reshape((1,) + date02_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date11_in.shape == tuple():
+            date11_in = date11_in.reshape((1,) + date11_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date12_in.shape == tuple():
+            date12_in = date12_in.reshape((1,) + date12_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date01_in, date02_in, date11_in, date12_in)
+    zeta_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    z_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    theta_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date01_in, date02_in, date11_in, date12_in, zeta_out, z_out, theta_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._prec76(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(zeta_out.shape) > 0 and zeta_out.shape[0] == 1
+        zeta_out = zeta_out.reshape(zeta_out.shape[1:])
+        assert len(z_out.shape) > 0 and z_out.shape[0] == 1
+        z_out = z_out.reshape(z_out.shape[1:])
+        assert len(theta_out.shape) > 0 and theta_out.shape[0] == 1
+        theta_out = theta_out.reshape(theta_out.shape[1:])
+
+    return zeta_out, z_out, theta_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, x_in, y_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_in, y_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._s00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._s00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._s00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    x_in = numpy.array(x, dtype=numpy.double, order="C", copy=False, subok=True)
+    y_in = numpy.array(y, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if x_in.shape == tuple():
+            x_in = x_in.reshape((1,) + x_in.shape)
+        else:
+            make_outputs_scalar = False
+        if y_in.shape == tuple():
+            y_in = y_in.reshape((1,) + y_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, x_in, y_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_in, y_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._s06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._s06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._sp00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_out, y_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._xy06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+
+    return x_out, y_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    s_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_out, y_out, s_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._xys00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+        assert len(s_out.shape) > 0 and s_out.shape[0] == 1
+        s_out = s_out.reshape(s_out.shape[1:])
+
+    return x_out, y_out, s_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    s_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_out, y_out, s_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._xys00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+        assert len(s_out.shape) > 0 and s_out.shape[0] == 1
+        s_out = s_out.reshape(s_out.shape[1:])
+
+    return x_out, y_out, s_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    x_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    y_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    s_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, x_out, y_out, s_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._xys06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(x_out.shape) > 0 and x_out.shape[0] == 1
+        x_out = x_out.reshape(x_out.shape[1:])
+        assert len(y_out.shape) > 0 and y_out.shape[0] == 1
+        y_out = y_out.reshape(y_out.shape[1:])
+        assert len(s_out.shape) > 0 and s_out.shape[0] == 1
+        s_out = s_out.reshape(s_out.shape[1:])
+
+    return x_out, y_out, s_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    epsa_in = numpy.array(epsa, dtype=numpy.double, order="C", copy=False, subok=True)
+    dpsi_in = numpy.array(dpsi, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if epsa_in.shape == tuple():
+            epsa_in = epsa_in.reshape((1,) + epsa_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dpsi_in.shape == tuple():
+            dpsi_in = dpsi_in.reshape((1,) + dpsi_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, epsa_in, dpsi_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, epsa_in, dpsi_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ee00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ee00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ee00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ee06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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", Astronomy &
+       Astrophysics, 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._eect00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._eqeq94(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), dj1_in, dj2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dj1_in, dj2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._era00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in, tta_in, ttb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, tta_in, ttb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gmst00(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in, tta_in, ttb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, tta_in, ttb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gmst06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    dj1_in = numpy.array(dj1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dj2_in = numpy.array(dj2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if dj1_in.shape == tuple():
+            dj1_in = dj1_in.reshape((1,) + dj1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dj2_in.shape == tuple():
+            dj2_in = dj2_in.reshape((1,) + dj2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), dj1_in, dj2_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [dj1_in, dj2_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gmst82(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in, tta_in, ttb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, tta_in, ttb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gst00a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gst00b(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    rnpb_in = numpy.array(rnpb, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(rnpb_in, (3, 3), "rnpb")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rnpb_in[...,0,0].shape == tuple():
+            rnpb_in = rnpb_in.reshape((1,) + rnpb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in, tta_in, ttb_in, rnpb_in[...,0,0])
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, tta_in, ttb_in, rnpb_in[...,0,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*5 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gst06(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    tta_in = numpy.array(tta, dtype=numpy.double, order="C", copy=False, subok=True)
+    ttb_in = numpy.array(ttb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tta_in.shape == tuple():
+            tta_in = tta_in.reshape((1,) + tta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ttb_in.shape == tuple():
+            ttb_in = ttb_in.reshape((1,) + ttb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in, tta_in, ttb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, tta_in, ttb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gst06a(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    uta_in = numpy.array(uta, dtype=numpy.double, order="C", copy=False, subok=True)
+    utb_in = numpy.array(utb, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if uta_in.shape == tuple():
+            uta_in = uta_in.reshape((1,) + uta_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utb_in.shape == tuple():
+            utb_in = utb_in.reshape((1,) + utb_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), uta_in, utb_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [uta_in, utb_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gst94(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ra1_in = numpy.array(ra1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dec1_in = numpy.array(dec1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmr1_in = numpy.array(pmr1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmd1_in = numpy.array(pmd1, dtype=numpy.double, order="C", copy=False, subok=True)
+    px1_in = numpy.array(px1, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv1_in = numpy.array(rv1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1a_in = numpy.array(ep1a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1b_in = numpy.array(ep1b, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2a_in = numpy.array(ep2a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2b_in = numpy.array(ep2b, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ra1_in.shape == tuple():
+            ra1_in = ra1_in.reshape((1,) + ra1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dec1_in.shape == tuple():
+            dec1_in = dec1_in.reshape((1,) + dec1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmr1_in.shape == tuple():
+            pmr1_in = pmr1_in.reshape((1,) + pmr1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmd1_in.shape == tuple():
+            pmd1_in = pmd1_in.reshape((1,) + pmd1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px1_in.shape == tuple():
+            px1_in = px1_in.reshape((1,) + px1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv1_in.shape == tuple():
+            rv1_in = rv1_in.reshape((1,) + rv1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1a_in.shape == tuple():
+            ep1a_in = ep1a_in.reshape((1,) + ep1a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1b_in.shape == tuple():
+            ep1b_in = ep1b_in.reshape((1,) + ep1b_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2a_in.shape == tuple():
+            ep2a_in = ep2a_in.reshape((1,) + ep2a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2b_in.shape == tuple():
+            ep2b_in = ep2b_in.reshape((1,) + ep2b_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in)
+    ra2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dec2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmr2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmd2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    px2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rv2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in, ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*10 + [['readwrite']]*7
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pmsafe(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'pmsafe')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ra2_out.shape) > 0 and ra2_out.shape[0] == 1
+        ra2_out = ra2_out.reshape(ra2_out.shape[1:])
+        assert len(dec2_out.shape) > 0 and dec2_out.shape[0] == 1
+        dec2_out = dec2_out.reshape(dec2_out.shape[1:])
+        assert len(pmr2_out.shape) > 0 and pmr2_out.shape[0] == 1
+        pmr2_out = pmr2_out.reshape(pmr2_out.shape[1:])
+        assert len(pmd2_out.shape) > 0 and pmd2_out.shape[0] == 1
+        pmd2_out = pmd2_out.reshape(pmd2_out.shape[1:])
+        assert len(px2_out.shape) > 0 and px2_out.shape[0] == 1
+        px2_out = px2_out.reshape(px2_out.shape[1:])
+        assert len(rv2_out.shape) > 0 and rv2_out.shape[0] == 1
+        rv2_out = rv2_out.reshape(rv2_out.shape[1:])
+
+    return ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out
+STATUS_CODES['pmsafe'] = {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', -1: 'system error (should not occur)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    pv_in = numpy.array(pv, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(pv_in, (2, 3), "pv")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if pv_in[...,0,0].shape == tuple():
+            pv_in = pv_in.reshape((1,) + pv_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), pv_in[...,0,0])
+    ra_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dec_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmr_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmd_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    px_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rv_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [pv_in[...,0,0], ra_out, dec_out, pmr_out, pmd_out, px_out, rv_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*7
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pvstar(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'pvstar')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ra_out.shape) > 0 and ra_out.shape[0] == 1
+        ra_out = ra_out.reshape(ra_out.shape[1:])
+        assert len(dec_out.shape) > 0 and dec_out.shape[0] == 1
+        dec_out = dec_out.reshape(dec_out.shape[1:])
+        assert len(pmr_out.shape) > 0 and pmr_out.shape[0] == 1
+        pmr_out = pmr_out.reshape(pmr_out.shape[1:])
+        assert len(pmd_out.shape) > 0 and pmd_out.shape[0] == 1
+        pmd_out = pmd_out.reshape(pmd_out.shape[1:])
+        assert len(px_out.shape) > 0 and px_out.shape[0] == 1
+        px_out = px_out.reshape(px_out.shape[1:])
+        assert len(rv_out.shape) > 0 and rv_out.shape[0] == 1
+        rv_out = rv_out.reshape(rv_out.shape[1:])
+
+    return ra_out, dec_out, pmr_out, pmd_out, px_out, rv_out
+STATUS_CODES['pvstar'] = {0: 'OK', -2: 'null position vector', -1: 'superluminal speed (Note 5)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ra_in = numpy.array(ra, dtype=numpy.double, order="C", copy=False, subok=True)
+    dec_in = numpy.array(dec, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmr_in = numpy.array(pmr, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmd_in = numpy.array(pmd, dtype=numpy.double, order="C", copy=False, subok=True)
+    px_in = numpy.array(px, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv_in = numpy.array(rv, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ra_in.shape == tuple():
+            ra_in = ra_in.reshape((1,) + ra_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dec_in.shape == tuple():
+            dec_in = dec_in.reshape((1,) + dec_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmr_in.shape == tuple():
+            pmr_in = pmr_in.reshape((1,) + pmr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmd_in.shape == tuple():
+            pmd_in = pmd_in.reshape((1,) + pmd_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px_in.shape == tuple():
+            px_in = px_in.reshape((1,) + px_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv_in.shape == tuple():
+            rv_in = rv_in.reshape((1,) + rv_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ra_in, dec_in, pmr_in, pmd_in, px_in, rv_in)
+    pv_out = numpy.empty(broadcast.shape + (2, 3), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ra_in, dec_in, pmr_in, pmd_in, px_in, rv_in, pv_out[...,0,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._starpv(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'starpv')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(pv_out.shape) > 0 and pv_out.shape[0] == 1
+        pv_out = pv_out.reshape(pv_out.shape[1:])
+
+    return pv_out
+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 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    r5_in = numpy.array(r5, dtype=numpy.double, order="C", copy=False, subok=True)
+    d5_in = numpy.array(d5, dtype=numpy.double, order="C", copy=False, subok=True)
+    dr5_in = numpy.array(dr5, dtype=numpy.double, order="C", copy=False, subok=True)
+    dd5_in = numpy.array(dd5, dtype=numpy.double, order="C", copy=False, subok=True)
+    px5_in = numpy.array(px5, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv5_in = numpy.array(rv5, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if r5_in.shape == tuple():
+            r5_in = r5_in.reshape((1,) + r5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if d5_in.shape == tuple():
+            d5_in = d5_in.reshape((1,) + d5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dr5_in.shape == tuple():
+            dr5_in = dr5_in.reshape((1,) + dr5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dd5_in.shape == tuple():
+            dd5_in = dd5_in.reshape((1,) + dd5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px5_in.shape == tuple():
+            px5_in = px5_in.reshape((1,) + px5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv5_in.shape == tuple():
+            rv5_in = rv5_in.reshape((1,) + rv5_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), r5_in, d5_in, dr5_in, dd5_in, px5_in, rv5_in)
+    rh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    drh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    ddh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pxh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rvh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [r5_in, d5_in, dr5_in, dd5_in, px5_in, rv5_in, rh_out, dh_out, drh_out, ddh_out, pxh_out, rvh_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*6
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fk52h(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rh_out.shape) > 0 and rh_out.shape[0] == 1
+        rh_out = rh_out.reshape(rh_out.shape[1:])
+        assert len(dh_out.shape) > 0 and dh_out.shape[0] == 1
+        dh_out = dh_out.reshape(dh_out.shape[1:])
+        assert len(drh_out.shape) > 0 and drh_out.shape[0] == 1
+        drh_out = drh_out.reshape(drh_out.shape[1:])
+        assert len(ddh_out.shape) > 0 and ddh_out.shape[0] == 1
+        ddh_out = ddh_out.reshape(ddh_out.shape[1:])
+        assert len(pxh_out.shape) > 0 and pxh_out.shape[0] == 1
+        pxh_out = pxh_out.reshape(pxh_out.shape[1:])
+        assert len(rvh_out.shape) > 0 and rvh_out.shape[0] == 1
+        rvh_out = rvh_out.reshape(rvh_out.shape[1:])
+
+    return rh_out, dh_out, drh_out, ddh_out, pxh_out, rvh_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), )
+    r5h_out = numpy.empty(broadcast.shape + (3, 3), dtype=numpy.double)
+    s5h_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [r5h_out[...,0,0], s5h_out[...,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*0 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fk5hip(it)
+
+    return r5h_out, s5h_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    r5_in = numpy.array(r5, dtype=numpy.double, order="C", copy=False, subok=True)
+    d5_in = numpy.array(d5, dtype=numpy.double, order="C", copy=False, subok=True)
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if r5_in.shape == tuple():
+            r5_in = r5_in.reshape((1,) + r5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if d5_in.shape == tuple():
+            d5_in = d5_in.reshape((1,) + d5_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), r5_in, d5_in, date1_in, date2_in)
+    rh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dh_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [r5_in, d5_in, date1_in, date2_in, rh_out, dh_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._fk5hz(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(rh_out.shape) > 0 and rh_out.shape[0] == 1
+        rh_out = rh_out.reshape(rh_out.shape[1:])
+        assert len(dh_out.shape) > 0 and dh_out.shape[0] == 1
+        dh_out = dh_out.reshape(dh_out.shape[1:])
+
+    return rh_out, dh_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    dh_in = numpy.array(dh, dtype=numpy.double, order="C", copy=False, subok=True)
+    drh_in = numpy.array(drh, dtype=numpy.double, order="C", copy=False, subok=True)
+    ddh_in = numpy.array(ddh, dtype=numpy.double, order="C", copy=False, subok=True)
+    pxh_in = numpy.array(pxh, dtype=numpy.double, order="C", copy=False, subok=True)
+    rvh_in = numpy.array(rvh, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dh_in.shape == tuple():
+            dh_in = dh_in.reshape((1,) + dh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if drh_in.shape == tuple():
+            drh_in = drh_in.reshape((1,) + drh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ddh_in.shape == tuple():
+            ddh_in = ddh_in.reshape((1,) + ddh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pxh_in.shape == tuple():
+            pxh_in = pxh_in.reshape((1,) + pxh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rvh_in.shape == tuple():
+            rvh_in = rvh_in.reshape((1,) + rvh_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rh_in, dh_in, drh_in, ddh_in, pxh_in, rvh_in)
+    r5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    d5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dr5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dd5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    px5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rv5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rh_in, dh_in, drh_in, ddh_in, pxh_in, rvh_in, r5_out, d5_out, dr5_out, dd5_out, px5_out, rv5_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*6
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._h2fk5(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(r5_out.shape) > 0 and r5_out.shape[0] == 1
+        r5_out = r5_out.reshape(r5_out.shape[1:])
+        assert len(d5_out.shape) > 0 and d5_out.shape[0] == 1
+        d5_out = d5_out.reshape(d5_out.shape[1:])
+        assert len(dr5_out.shape) > 0 and dr5_out.shape[0] == 1
+        dr5_out = dr5_out.reshape(dr5_out.shape[1:])
+        assert len(dd5_out.shape) > 0 and dd5_out.shape[0] == 1
+        dd5_out = dd5_out.reshape(dd5_out.shape[1:])
+        assert len(px5_out.shape) > 0 and px5_out.shape[0] == 1
+        px5_out = px5_out.reshape(px5_out.shape[1:])
+        assert len(rv5_out.shape) > 0 and rv5_out.shape[0] == 1
+        rv5_out = rv5_out.reshape(rv5_out.shape[1:])
+
+    return r5_out, d5_out, dr5_out, dd5_out, px5_out, rv5_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    rh_in = numpy.array(rh, dtype=numpy.double, order="C", copy=False, subok=True)
+    dh_in = numpy.array(dh, dtype=numpy.double, order="C", copy=False, subok=True)
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if rh_in.shape == tuple():
+            rh_in = rh_in.reshape((1,) + rh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dh_in.shape == tuple():
+            dh_in = dh_in.reshape((1,) + dh_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), rh_in, dh_in, date1_in, date2_in)
+    r5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    d5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dr5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dd5_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [rh_in, dh_in, date1_in, date2_in, r5_out, d5_out, dr5_out, dd5_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*4
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._hfk5z(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(r5_out.shape) > 0 and r5_out.shape[0] == 1
+        r5_out = r5_out.reshape(r5_out.shape[1:])
+        assert len(d5_out.shape) > 0 and d5_out.shape[0] == 1
+        d5_out = d5_out.reshape(d5_out.shape[1:])
+        assert len(dr5_out.shape) > 0 and dr5_out.shape[0] == 1
+        dr5_out = dr5_out.reshape(dr5_out.shape[1:])
+        assert len(dd5_out.shape) > 0 and dd5_out.shape[0] == 1
+        dd5_out = dd5_out.reshape(dd5_out.shape[1:])
+
+    return r5_out, d5_out, dr5_out, dd5_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ra1_in = numpy.array(ra1, dtype=numpy.double, order="C", copy=False, subok=True)
+    dec1_in = numpy.array(dec1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmr1_in = numpy.array(pmr1, dtype=numpy.double, order="C", copy=False, subok=True)
+    pmd1_in = numpy.array(pmd1, dtype=numpy.double, order="C", copy=False, subok=True)
+    px1_in = numpy.array(px1, dtype=numpy.double, order="C", copy=False, subok=True)
+    rv1_in = numpy.array(rv1, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1a_in = numpy.array(ep1a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep1b_in = numpy.array(ep1b, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2a_in = numpy.array(ep2a, dtype=numpy.double, order="C", copy=False, subok=True)
+    ep2b_in = numpy.array(ep2b, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ra1_in.shape == tuple():
+            ra1_in = ra1_in.reshape((1,) + ra1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dec1_in.shape == tuple():
+            dec1_in = dec1_in.reshape((1,) + dec1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmr1_in.shape == tuple():
+            pmr1_in = pmr1_in.reshape((1,) + pmr1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if pmd1_in.shape == tuple():
+            pmd1_in = pmd1_in.reshape((1,) + pmd1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if px1_in.shape == tuple():
+            px1_in = px1_in.reshape((1,) + px1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if rv1_in.shape == tuple():
+            rv1_in = rv1_in.reshape((1,) + rv1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1a_in.shape == tuple():
+            ep1a_in = ep1a_in.reshape((1,) + ep1a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep1b_in.shape == tuple():
+            ep1b_in = ep1b_in.reshape((1,) + ep1b_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2a_in.shape == tuple():
+            ep2a_in = ep2a_in.reshape((1,) + ep2a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ep2b_in.shape == tuple():
+            ep2b_in = ep2b_in.reshape((1,) + ep2b_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in)
+    ra2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    dec2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmr2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    pmd2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    px2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    rv2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ra1_in, dec1_in, pmr1_in, pmd1_in, px1_in, rv1_in, ep1a_in, ep1b_in, ep2a_in, ep2b_in, ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*10 + [['readwrite']]*7
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._starpm(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'starpm')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ra2_out.shape) > 0 and ra2_out.shape[0] == 1
+        ra2_out = ra2_out.reshape(ra2_out.shape[1:])
+        assert len(dec2_out.shape) > 0 and dec2_out.shape[0] == 1
+        dec2_out = dec2_out.reshape(dec2_out.shape[1:])
+        assert len(pmr2_out.shape) > 0 and pmr2_out.shape[0] == 1
+        pmr2_out = pmr2_out.reshape(pmr2_out.shape[1:])
+        assert len(pmd2_out.shape) > 0 and pmd2_out.shape[0] == 1
+        pmd2_out = pmd2_out.reshape(pmd2_out.shape[1:])
+        assert len(px2_out.shape) > 0 and px2_out.shape[0] == 1
+        px2_out = px2_out.reshape(px2_out.shape[1:])
+        assert len(rv2_out.shape) > 0 and rv2_out.shape[0] == 1
+        rv2_out = rv2_out.reshape(rv2_out.shape[1:])
+
+    return ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out
+STATUS_CODES['starpm'] = {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', -1: 'system error (should not occur)'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), n_in)
+    a_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    f_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [n_in, a_out, f_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*1 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._eform(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'eform')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(a_out.shape) > 0 and a_out.shape[0] == 1
+        a_out = a_out.reshape(a_out.shape[1:])
+        assert len(f_out.shape) > 0 and f_out.shape[0] == 1
+        f_out = f_out.reshape(f_out.shape[1:])
+
+    return a_out, f_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    xyz_in = numpy.array(xyz, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(xyz_in, (3,), "xyz")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xyz_in[...,0].shape == tuple():
+            xyz_in = xyz_in.reshape((1,) + xyz_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), n_in, xyz_in[...,0])
+    elong_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    phi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    height_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [n_in, xyz_in[...,0], elong_out, phi_out, height_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*4
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gc2gd(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'gc2gd')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(elong_out.shape) > 0 and elong_out.shape[0] == 1
+        elong_out = elong_out.reshape(elong_out.shape[1:])
+        assert len(phi_out.shape) > 0 and phi_out.shape[0] == 1
+        phi_out = phi_out.reshape(phi_out.shape[1:])
+        assert len(height_out.shape) > 0 and height_out.shape[0] == 1
+        height_out = height_out.reshape(height_out.shape[1:])
+
+    return elong_out, phi_out, height_out
+STATUS_CODES['gc2gd'] = {0: 'OK', -2: 'internal error (Note 3)', -1: 'illegal identifier (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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    a_in = numpy.array(a, dtype=numpy.double, order="C", copy=False, subok=True)
+    f_in = numpy.array(f, dtype=numpy.double, order="C", copy=False, subok=True)
+    xyz_in = numpy.array(xyz, dtype=numpy.double, order="C", copy=False, subok=True)
+    check_trailing_shape(xyz_in, (3,), "xyz")
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if a_in.shape == tuple():
+            a_in = a_in.reshape((1,) + a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if f_in.shape == tuple():
+            f_in = f_in.reshape((1,) + f_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xyz_in[...,0].shape == tuple():
+            xyz_in = xyz_in.reshape((1,) + xyz_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), a_in, f_in, xyz_in[...,0])
+    elong_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    phi_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    height_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [a_in, f_in, xyz_in[...,0], elong_out, phi_out, height_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*4
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gc2gde(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'gc2gde')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(elong_out.shape) > 0 and elong_out.shape[0] == 1
+        elong_out = elong_out.reshape(elong_out.shape[1:])
+        assert len(phi_out.shape) > 0 and phi_out.shape[0] == 1
+        phi_out = phi_out.reshape(phi_out.shape[1:])
+        assert len(height_out.shape) > 0 and height_out.shape[0] == 1
+        height_out = height_out.reshape(height_out.shape[1:])
+
+    return elong_out, phi_out, height_out
+STATUS_CODES['gc2gde'] = {0: 'OK', -2: 'illegal a', -1: 'illegal f'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    n_in = numpy.array(n, dtype=numpy.intc, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    height_in = numpy.array(height, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if n_in.shape == tuple():
+            n_in = n_in.reshape((1,) + n_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if height_in.shape == tuple():
+            height_in = height_in.reshape((1,) + height_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), n_in, elong_in, phi_in, height_in)
+    xyz_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [n_in, elong_in, phi_in, height_in, xyz_out[...,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gd2gc(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'gd2gc')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(xyz_out.shape) > 0 and xyz_out.shape[0] == 1
+        xyz_out = xyz_out.reshape(xyz_out.shape[1:])
+
+    return xyz_out
+STATUS_CODES['gd2gc'] = {0: 'OK', -2: 'illegal case (Note 3)', -1: 'illegal identifier (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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    a_in = numpy.array(a, dtype=numpy.double, order="C", copy=False, subok=True)
+    f_in = numpy.array(f, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    height_in = numpy.array(height, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if a_in.shape == tuple():
+            a_in = a_in.reshape((1,) + a_in.shape)
+        else:
+            make_outputs_scalar = False
+        if f_in.shape == tuple():
+            f_in = f_in.reshape((1,) + f_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if height_in.shape == tuple():
+            height_in = height_in.reshape((1,) + height_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), a_in, f_in, elong_in, phi_in, height_in)
+    xyz_out = numpy.empty(broadcast.shape + (3,), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [a_in, f_in, elong_in, phi_in, height_in, xyz_out[...,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*5 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._gd2gce(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'gd2gce')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(xyz_out.shape) > 0 and xyz_out.shape[0] == 1
+        xyz_out = xyz_out.reshape(xyz_out.shape[1:])
+
+    return xyz_out
+STATUS_CODES['gd2gce'] = {0: 'OK', -1: 'illegal case (Note 4)Notes:'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    phi_in = numpy.array(phi, dtype=numpy.double, order="C", copy=False, subok=True)
+    hm_in = numpy.array(hm, dtype=numpy.double, order="C", copy=False, subok=True)
+    xp_in = numpy.array(xp, dtype=numpy.double, order="C", copy=False, subok=True)
+    yp_in = numpy.array(yp, dtype=numpy.double, order="C", copy=False, subok=True)
+    sp_in = numpy.array(sp, dtype=numpy.double, order="C", copy=False, subok=True)
+    theta_in = numpy.array(theta, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if phi_in.shape == tuple():
+            phi_in = phi_in.reshape((1,) + phi_in.shape)
+        else:
+            make_outputs_scalar = False
+        if hm_in.shape == tuple():
+            hm_in = hm_in.reshape((1,) + hm_in.shape)
+        else:
+            make_outputs_scalar = False
+        if xp_in.shape == tuple():
+            xp_in = xp_in.reshape((1,) + xp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if yp_in.shape == tuple():
+            yp_in = yp_in.reshape((1,) + yp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if sp_in.shape == tuple():
+            sp_in = sp_in.reshape((1,) + sp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if theta_in.shape == tuple():
+            theta_in = theta_in.reshape((1,) + theta_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), elong_in, phi_in, hm_in, xp_in, yp_in, sp_in, theta_in)
+    pv_out = numpy.empty(broadcast.shape + (2, 3), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [elong_in, phi_in, hm_in, xp_in, yp_in, sp_in, theta_in, pv_out[...,0,0]]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*7 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._pvtob(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(pv_out.shape) > 0 and pv_out.shape[0] == 1
+        pv_out = pv_out.reshape(pv_out.shape[1:])
+
+    return pv_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    scale_in = numpy.array(scale, dtype=numpy.dtype('S16'), order="C", copy=False, subok=True)
+    ndp_in = numpy.array(ndp, dtype=numpy.intc, order="C", copy=False, subok=True)
+    d1_in = numpy.array(d1, dtype=numpy.double, order="C", copy=False, subok=True)
+    d2_in = numpy.array(d2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if scale_in.shape == tuple():
+            scale_in = scale_in.reshape((1,) + scale_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ndp_in.shape == tuple():
+            ndp_in = ndp_in.reshape((1,) + ndp_in.shape)
+        else:
+            make_outputs_scalar = False
+        if d1_in.shape == tuple():
+            d1_in = d1_in.reshape((1,) + d1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if d2_in.shape == tuple():
+            d2_in = d2_in.reshape((1,) + d2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), scale_in, ndp_in, d1_in, d2_in)
+    iy_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    im_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    id_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+    ihmsf_out = numpy.empty(broadcast.shape + (4,), dtype=numpy.intc)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [scale_in, ndp_in, d1_in, d2_in, iy_out, im_out, id_out, ihmsf_out[...,0], c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*5
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._d2dtf(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'd2dtf')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(iy_out.shape) > 0 and iy_out.shape[0] == 1
+        iy_out = iy_out.reshape(iy_out.shape[1:])
+        assert len(im_out.shape) > 0 and im_out.shape[0] == 1
+        im_out = im_out.reshape(im_out.shape[1:])
+        assert len(id_out.shape) > 0 and id_out.shape[0] == 1
+        id_out = id_out.reshape(id_out.shape[1:])
+        assert len(ihmsf_out.shape) > 0 and ihmsf_out.shape[0] == 1
+        ihmsf_out = ihmsf_out.reshape(ihmsf_out.shape[1:])
+
+    return iy_out, im_out, id_out, ihmsf_out
+STATUS_CODES['d2dtf'] = {0: 'OK', 1: 'dubious year (Note 5)', -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:  2012 June 30       :
+       :                                          :
+       :__________________________________________:
+
+    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
+
+    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 UTC-TAI 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 UTC-TAI 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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    iy_in = numpy.array(iy, dtype=numpy.intc, order="C", copy=False, subok=True)
+    im_in = numpy.array(im, dtype=numpy.intc, order="C", copy=False, subok=True)
+    id_in = numpy.array(id, dtype=numpy.intc, order="C", copy=False, subok=True)
+    fd_in = numpy.array(fd, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if iy_in.shape == tuple():
+            iy_in = iy_in.reshape((1,) + iy_in.shape)
+        else:
+            make_outputs_scalar = False
+        if im_in.shape == tuple():
+            im_in = im_in.reshape((1,) + im_in.shape)
+        else:
+            make_outputs_scalar = False
+        if id_in.shape == tuple():
+            id_in = id_in.reshape((1,) + id_in.shape)
+        else:
+            make_outputs_scalar = False
+        if fd_in.shape == tuple():
+            fd_in = fd_in.reshape((1,) + fd_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), iy_in, im_in, id_in, fd_in)
+    deltat_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [iy_in, im_in, id_in, fd_in, deltat_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*4 + [['readwrite']]*2
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._dat(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'dat')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(deltat_out.shape) > 0 and deltat_out.shape[0] == 1
+        deltat_out = deltat_out.reshape(deltat_out.shape[1:])
+
+    return deltat_out
+STATUS_CODES['dat'] = {0: 'OK', 1: 'dubious year (Note 1)', -1: 'bad year', -5: 'internal error', -4: 'bad fraction (Note 4)', -3: 'bad day (Note 3)', -2: 'bad month'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    date1_in = numpy.array(date1, dtype=numpy.double, order="C", copy=False, subok=True)
+    date2_in = numpy.array(date2, dtype=numpy.double, order="C", copy=False, subok=True)
+    ut_in = numpy.array(ut, dtype=numpy.double, order="C", copy=False, subok=True)
+    elong_in = numpy.array(elong, dtype=numpy.double, order="C", copy=False, subok=True)
+    u_in = numpy.array(u, dtype=numpy.double, order="C", copy=False, subok=True)
+    v_in = numpy.array(v, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if date1_in.shape == tuple():
+            date1_in = date1_in.reshape((1,) + date1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if date2_in.shape == tuple():
+            date2_in = date2_in.reshape((1,) + date2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ut_in.shape == tuple():
+            ut_in = ut_in.reshape((1,) + ut_in.shape)
+        else:
+            make_outputs_scalar = False
+        if elong_in.shape == tuple():
+            elong_in = elong_in.reshape((1,) + elong_in.shape)
+        else:
+            make_outputs_scalar = False
+        if u_in.shape == tuple():
+            u_in = u_in.reshape((1,) + u_in.shape)
+        else:
+            make_outputs_scalar = False
+        if v_in.shape == tuple():
+            v_in = v_in.reshape((1,) + v_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), date1_in, date2_in, ut_in, elong_in, u_in, v_in)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [date1_in, date2_in, ut_in, elong_in, u_in, v_in, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*6 + [['readwrite']]*1
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._dtdb(it)
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(c_retval_out.shape) > 0 and c_retval_out.shape[0] == 1
+        c_retval_out = c_retval_out.reshape(c_retval_out.shape[1:])
+
+    return c_retval_out
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    scale_in = numpy.array(scale, dtype=numpy.dtype('S16'), order="C", copy=False, subok=True)
+    iy_in = numpy.array(iy, dtype=numpy.intc, order="C", copy=False, subok=True)
+    im_in = numpy.array(im, dtype=numpy.intc, order="C", copy=False, subok=True)
+    id_in = numpy.array(id, dtype=numpy.intc, order="C", copy=False, subok=True)
+    ihr_in = numpy.array(ihr, dtype=numpy.intc, order="C", copy=False, subok=True)
+    imn_in = numpy.array(imn, dtype=numpy.intc, order="C", copy=False, subok=True)
+    sec_in = numpy.array(sec, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if scale_in.shape == tuple():
+            scale_in = scale_in.reshape((1,) + scale_in.shape)
+        else:
+            make_outputs_scalar = False
+        if iy_in.shape == tuple():
+            iy_in = iy_in.reshape((1,) + iy_in.shape)
+        else:
+            make_outputs_scalar = False
+        if im_in.shape == tuple():
+            im_in = im_in.reshape((1,) + im_in.shape)
+        else:
+            make_outputs_scalar = False
+        if id_in.shape == tuple():
+            id_in = id_in.reshape((1,) + id_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ihr_in.shape == tuple():
+            ihr_in = ihr_in.reshape((1,) + ihr_in.shape)
+        else:
+            make_outputs_scalar = False
+        if imn_in.shape == tuple():
+            imn_in = imn_in.reshape((1,) + imn_in.shape)
+        else:
+            make_outputs_scalar = False
+        if sec_in.shape == tuple():
+            sec_in = sec_in.reshape((1,) + sec_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), scale_in, iy_in, im_in, id_in, ihr_in, imn_in, sec_in)
+    d1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    d2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [scale_in, iy_in, im_in, id_in, ihr_in, imn_in, sec_in, d1_out, d2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*7 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._dtf2d(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'dtf2d')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(d1_out.shape) > 0 and d1_out.shape[0] == 1
+        d1_out = d1_out.reshape(d1_out.shape[1:])
+        assert len(d2_out.shape) > 0 and d2_out.shape[0] == 1
+        d2_out = d2_out.reshape(d2_out.shape[1:])
+
+    return d1_out, d2_out
+STATUS_CODES['dtf2d'] = {0: 'OK', 1: 'dubious year (Note 6)', 2: 'time is after end of day (Note 5)', 3: 'both of next two', -1: 'bad year', -6: 'bad second (<0)', -5: 'bad minute', -4: 'bad hour', -3: 'bad day', -2: 'bad month'}
+
+
+
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tai1_in = numpy.array(tai1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tai2_in = numpy.array(tai2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tai1_in.shape == tuple():
+            tai1_in = tai1_in.reshape((1,) + tai1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tai2_in.shape == tuple():
+            tai2_in = tai2_in.reshape((1,) + tai2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tai1_in, tai2_in)
+    tt1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tt2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tai1_in, tai2_in, tt1_out, tt2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._taitt(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'taitt')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tt1_out.shape) > 0 and tt1_out.shape[0] == 1
+        tt1_out = tt1_out.reshape(tt1_out.shape[1:])
+        assert len(tt2_out.shape) > 0 and tt2_out.shape[0] == 1
+        tt2_out = tt2_out.reshape(tt2_out.shape[1:])
+
+    return tt1_out, tt2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tai1_in = numpy.array(tai1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tai2_in = numpy.array(tai2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dta_in = numpy.array(dta, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tai1_in.shape == tuple():
+            tai1_in = tai1_in.reshape((1,) + tai1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tai2_in.shape == tuple():
+            tai2_in = tai2_in.reshape((1,) + tai2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dta_in.shape == tuple():
+            dta_in = dta_in.reshape((1,) + dta_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tai1_in, tai2_in, dta_in)
+    ut11_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    ut12_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tai1_in, tai2_in, dta_in, ut11_out, ut12_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._taiut1(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'taiut1')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ut11_out.shape) > 0 and ut11_out.shape[0] == 1
+        ut11_out = ut11_out.reshape(ut11_out.shape[1:])
+        assert len(ut12_out.shape) > 0 and ut12_out.shape[0] == 1
+        ut12_out = ut12_out.reshape(ut12_out.shape[1:])
+
+    return ut11_out, ut12_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tai1_in = numpy.array(tai1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tai2_in = numpy.array(tai2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tai1_in.shape == tuple():
+            tai1_in = tai1_in.reshape((1,) + tai1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tai2_in.shape == tuple():
+            tai2_in = tai2_in.reshape((1,) + tai2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tai1_in, tai2_in)
+    utc1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    utc2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tai1_in, tai2_in, utc1_out, utc2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._taiutc(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'taiutc')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(utc1_out.shape) > 0 and utc1_out.shape[0] == 1
+        utc1_out = utc1_out.reshape(utc1_out.shape[1:])
+        assert len(utc2_out.shape) > 0 and utc2_out.shape[0] == 1
+        utc2_out = utc2_out.reshape(utc2_out.shape[1:])
+
+    return utc1_out, utc2_out
+STATUS_CODES['taiutc'] = {0: 'OK', 1: 'dubious year (Note 4)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tcb1_in = numpy.array(tcb1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tcb2_in = numpy.array(tcb2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tcb1_in.shape == tuple():
+            tcb1_in = tcb1_in.reshape((1,) + tcb1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tcb2_in.shape == tuple():
+            tcb2_in = tcb2_in.reshape((1,) + tcb2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tcb1_in, tcb2_in)
+    tdb1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tdb2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tcb1_in, tcb2_in, tdb1_out, tdb2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tcbtdb(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tcbtdb')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tdb1_out.shape) > 0 and tdb1_out.shape[0] == 1
+        tdb1_out = tdb1_out.reshape(tdb1_out.shape[1:])
+        assert len(tdb2_out.shape) > 0 and tdb2_out.shape[0] == 1
+        tdb2_out = tdb2_out.reshape(tdb2_out.shape[1:])
+
+    return tdb1_out, tdb2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tcg1_in = numpy.array(tcg1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tcg2_in = numpy.array(tcg2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tcg1_in.shape == tuple():
+            tcg1_in = tcg1_in.reshape((1,) + tcg1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tcg2_in.shape == tuple():
+            tcg2_in = tcg2_in.reshape((1,) + tcg2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tcg1_in, tcg2_in)
+    tt1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tt2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tcg1_in, tcg2_in, tt1_out, tt2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tcgtt(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tcgtt')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tt1_out.shape) > 0 and tt1_out.shape[0] == 1
+        tt1_out = tt1_out.reshape(tt1_out.shape[1:])
+        assert len(tt2_out.shape) > 0 and tt2_out.shape[0] == 1
+        tt2_out = tt2_out.reshape(tt2_out.shape[1:])
+
+    return tt1_out, tt2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tdb1_in = numpy.array(tdb1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tdb2_in = numpy.array(tdb2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tdb1_in.shape == tuple():
+            tdb1_in = tdb1_in.reshape((1,) + tdb1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tdb2_in.shape == tuple():
+            tdb2_in = tdb2_in.reshape((1,) + tdb2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tdb1_in, tdb2_in)
+    tcb1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tcb2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tdb1_in, tdb2_in, tcb1_out, tcb2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tdbtcb(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tdbtcb')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tcb1_out.shape) > 0 and tcb1_out.shape[0] == 1
+        tcb1_out = tcb1_out.reshape(tcb1_out.shape[1:])
+        assert len(tcb2_out.shape) > 0 and tcb2_out.shape[0] == 1
+        tcb2_out = tcb2_out.reshape(tcb2_out.shape[1:])
+
+    return tcb1_out, tcb2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tdb1_in = numpy.array(tdb1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tdb2_in = numpy.array(tdb2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dtr_in = numpy.array(dtr, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tdb1_in.shape == tuple():
+            tdb1_in = tdb1_in.reshape((1,) + tdb1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tdb2_in.shape == tuple():
+            tdb2_in = tdb2_in.reshape((1,) + tdb2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dtr_in.shape == tuple():
+            dtr_in = dtr_in.reshape((1,) + dtr_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tdb1_in, tdb2_in, dtr_in)
+    tt1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tt2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tdb1_in, tdb2_in, dtr_in, tt1_out, tt2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tdbtt(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tdbtt')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tt1_out.shape) > 0 and tt1_out.shape[0] == 1
+        tt1_out = tt1_out.reshape(tt1_out.shape[1:])
+        assert len(tt2_out.shape) > 0 and tt2_out.shape[0] == 1
+        tt2_out = tt2_out.reshape(tt2_out.shape[1:])
+
+    return tt1_out, tt2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tt1_in = numpy.array(tt1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tt2_in = numpy.array(tt2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tt1_in.shape == tuple():
+            tt1_in = tt1_in.reshape((1,) + tt1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tt2_in.shape == tuple():
+            tt2_in = tt2_in.reshape((1,) + tt2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tt1_in, tt2_in)
+    tai1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tai2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tt1_in, tt2_in, tai1_out, tai2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tttai(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tttai')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tai1_out.shape) > 0 and tai1_out.shape[0] == 1
+        tai1_out = tai1_out.reshape(tai1_out.shape[1:])
+        assert len(tai2_out.shape) > 0 and tai2_out.shape[0] == 1
+        tai2_out = tai2_out.reshape(tai2_out.shape[1:])
+
+    return tai1_out, tai2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tt1_in = numpy.array(tt1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tt2_in = numpy.array(tt2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tt1_in.shape == tuple():
+            tt1_in = tt1_in.reshape((1,) + tt1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tt2_in.shape == tuple():
+            tt2_in = tt2_in.reshape((1,) + tt2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tt1_in, tt2_in)
+    tcg1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tcg2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tt1_in, tt2_in, tcg1_out, tcg2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tttcg(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tttcg')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tcg1_out.shape) > 0 and tcg1_out.shape[0] == 1
+        tcg1_out = tcg1_out.reshape(tcg1_out.shape[1:])
+        assert len(tcg2_out.shape) > 0 and tcg2_out.shape[0] == 1
+        tcg2_out = tcg2_out.reshape(tcg2_out.shape[1:])
+
+    return tcg1_out, tcg2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tt1_in = numpy.array(tt1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tt2_in = numpy.array(tt2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dtr_in = numpy.array(dtr, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tt1_in.shape == tuple():
+            tt1_in = tt1_in.reshape((1,) + tt1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tt2_in.shape == tuple():
+            tt2_in = tt2_in.reshape((1,) + tt2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dtr_in.shape == tuple():
+            dtr_in = dtr_in.reshape((1,) + dtr_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tt1_in, tt2_in, dtr_in)
+    tdb1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tdb2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tt1_in, tt2_in, dtr_in, tdb1_out, tdb2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._tttdb(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'tttdb')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tdb1_out.shape) > 0 and tdb1_out.shape[0] == 1
+        tdb1_out = tdb1_out.reshape(tdb1_out.shape[1:])
+        assert len(tdb2_out.shape) > 0 and tdb2_out.shape[0] == 1
+        tdb2_out = tdb2_out.reshape(tdb2_out.shape[1:])
+
+    return tdb1_out, tdb2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    tt1_in = numpy.array(tt1, dtype=numpy.double, order="C", copy=False, subok=True)
+    tt2_in = numpy.array(tt2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dt_in = numpy.array(dt, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if tt1_in.shape == tuple():
+            tt1_in = tt1_in.reshape((1,) + tt1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if tt2_in.shape == tuple():
+            tt2_in = tt2_in.reshape((1,) + tt2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dt_in.shape == tuple():
+            dt_in = dt_in.reshape((1,) + dt_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), tt1_in, tt2_in, dt_in)
+    ut11_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    ut12_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [tt1_in, tt2_in, dt_in, ut11_out, ut12_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ttut1(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'ttut1')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ut11_out.shape) > 0 and ut11_out.shape[0] == 1
+        ut11_out = ut11_out.reshape(ut11_out.shape[1:])
+        assert len(ut12_out.shape) > 0 and ut12_out.shape[0] == 1
+        ut12_out = ut12_out.reshape(ut12_out.shape[1:])
+
+    return ut11_out, ut12_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ut11_in = numpy.array(ut11, dtype=numpy.double, order="C", copy=False, subok=True)
+    ut12_in = numpy.array(ut12, dtype=numpy.double, order="C", copy=False, subok=True)
+    dta_in = numpy.array(dta, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ut11_in.shape == tuple():
+            ut11_in = ut11_in.reshape((1,) + ut11_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ut12_in.shape == tuple():
+            ut12_in = ut12_in.reshape((1,) + ut12_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dta_in.shape == tuple():
+            dta_in = dta_in.reshape((1,) + dta_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ut11_in, ut12_in, dta_in)
+    tai1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tai2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ut11_in, ut12_in, dta_in, tai1_out, tai2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ut1tai(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'ut1tai')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tai1_out.shape) > 0 and tai1_out.shape[0] == 1
+        tai1_out = tai1_out.reshape(tai1_out.shape[1:])
+        assert len(tai2_out.shape) > 0 and tai2_out.shape[0] == 1
+        tai2_out = tai2_out.reshape(tai2_out.shape[1:])
+
+    return tai1_out, tai2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ut11_in = numpy.array(ut11, dtype=numpy.double, order="C", copy=False, subok=True)
+    ut12_in = numpy.array(ut12, dtype=numpy.double, order="C", copy=False, subok=True)
+    dt_in = numpy.array(dt, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ut11_in.shape == tuple():
+            ut11_in = ut11_in.reshape((1,) + ut11_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ut12_in.shape == tuple():
+            ut12_in = ut12_in.reshape((1,) + ut12_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dt_in.shape == tuple():
+            dt_in = dt_in.reshape((1,) + dt_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ut11_in, ut12_in, dt_in)
+    tt1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tt2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ut11_in, ut12_in, dt_in, tt1_out, tt2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ut1tt(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'ut1tt')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tt1_out.shape) > 0 and tt1_out.shape[0] == 1
+        tt1_out = tt1_out.reshape(tt1_out.shape[1:])
+        assert len(tt2_out.shape) > 0 and tt2_out.shape[0] == 1
+        tt2_out = tt2_out.reshape(tt2_out.shape[1:])
+
+    return tt1_out, tt2_out
+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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    ut11_in = numpy.array(ut11, dtype=numpy.double, order="C", copy=False, subok=True)
+    ut12_in = numpy.array(ut12, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if ut11_in.shape == tuple():
+            ut11_in = ut11_in.reshape((1,) + ut11_in.shape)
+        else:
+            make_outputs_scalar = False
+        if ut12_in.shape == tuple():
+            ut12_in = ut12_in.reshape((1,) + ut12_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), ut11_in, ut12_in, dut1_in)
+    utc1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    utc2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [ut11_in, ut12_in, dut1_in, utc1_out, utc2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._ut1utc(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'ut1utc')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(utc1_out.shape) > 0 and utc1_out.shape[0] == 1
+        utc1_out = utc1_out.reshape(utc1_out.shape[1:])
+        assert len(utc2_out.shape) > 0 and utc2_out.shape[0] == 1
+        utc2_out = utc2_out.reshape(utc2_out.shape[1:])
+
+    return utc1_out, utc2_out
+STATUS_CODES['ut1utc'] = {0: 'OK', 1: 'dubious year (Note 5)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), utc1_in, utc2_in)
+    tai1_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    tai2_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [utc1_in, utc2_in, tai1_out, tai2_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*2 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._utctai(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'utctai')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(tai1_out.shape) > 0 and tai1_out.shape[0] == 1
+        tai1_out = tai1_out.reshape(tai1_out.shape[1:])
+        assert len(tai2_out.shape) > 0 and tai2_out.shape[0] == 1
+        tai2_out = tai2_out.reshape(tai2_out.shape[1:])
+
+    return tai1_out, tai2_out
+STATUS_CODES['utctai'] = {0: 'OK', 1: 'dubious year (Note 3)', -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-2014, NumFOCUS Foundation.
+    Derived, with permission, from the SOFA library.  See notes at end of file.
+
+    """
+
+    #Turn all inputs into arrays
+    utc1_in = numpy.array(utc1, dtype=numpy.double, order="C", copy=False, subok=True)
+    utc2_in = numpy.array(utc2, dtype=numpy.double, order="C", copy=False, subok=True)
+    dut1_in = numpy.array(dut1, dtype=numpy.double, order="C", copy=False, subok=True)
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        if utc1_in.shape == tuple():
+            utc1_in = utc1_in.reshape((1,) + utc1_in.shape)
+        else:
+            make_outputs_scalar = False
+        if utc2_in.shape == tuple():
+            utc2_in = utc2_in.reshape((1,) + utc2_in.shape)
+        else:
+            make_outputs_scalar = False
+        if dut1_in.shape == tuple():
+            dut1_in = dut1_in.reshape((1,) + dut1_in.shape)
+        else:
+            make_outputs_scalar = False
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), utc1_in, utc2_in, dut1_in)
+    ut11_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    ut12_out = numpy.empty(broadcast.shape + (), dtype=numpy.double)
+    c_retval_out = numpy.empty(broadcast.shape + (), dtype=numpy.intc)
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [utc1_in, utc2_in, dut1_in, ut11_out, ut12_out, c_retval_out]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*3 + [['readwrite']]*3
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._utcut1(it)
+
+    if not stat_ok:
+        check_errwarn(c_retval_out, 'utcut1')
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        assert len(ut11_out.shape) > 0 and ut11_out.shape[0] == 1
+        ut11_out = ut11_out.reshape(ut11_out.shape[1:])
+        assert len(ut12_out.shape) > 0 and ut12_out.shape[0] == 1
+        ut12_out = ut12_out.reshape(ut12_out.shape[1:])
+
+    return ut11_out, ut12_out
+STATUS_CODES['utcut1'] = {0: 'OK', 1: 'dubious year (Note 3)', -1: 'unacceptable date'}
+
+
diff --git a/astropy/_erfa/core.py.templ b/astropy/_erfa/core.py.templ
new file mode 100644
index 0000000..128bd0a
--- /dev/null
+++ b/astropy/_erfa/core.py.templ
@@ -0,0 +1,250 @@
+# 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.
+
+"""
+This module uses Cython to wrap the ERFA library in numpy-vectorized
+equivalents.
+
+..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 wrappers 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 matricies, the vector/matrix
+dimension(s) are always the *last* dimension(s).  For example, if you
+want to give ten matricies (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 Cython part of these functions are implemented in a separate
+module (compiled as ``_core``), derived from the ``core.pyx`` file.  Splitting
+the wrappers into separate pure-python and Cython portions dramatically reduces
+compilation time without notably impacting performance. (See issue [#3063] on the
+github repository for more about this.)
+"""
+from __future__ import absolute_import, division, print_function
+
+import warnings
+from distutils.version import LooseVersion
+
+from ..utils.exceptions import AstropyUserWarning
+
+import numpy
+from . import _core
+
+NPYLT18 = LooseVersion(numpy.__version__) < LooseVersion('1.8')
+# TODO: remove the above variable and the code using it and make_outputs_scalar when numpy < 1.8 is no longer supported
+
+__all__ = ['ErfaError', 'ErfaWarning',
+           {{ funcs|map(attribute='pyname')|surround("'","'")|join(", ") }},
+           {{ constants|map(attribute='name')|surround("'","'")|join(", ") }},
+           'dt_eraASTROM', 'dt_eraLDBODY']
+
+
+#<---------------------------------Error-handling----------------------------->
+
+class ErfaError(ValueError):
+    """
+    A class for errors triggered by ERFA functions (status codes < 0)
+    """
+
+
+class ErfaWarning(AstropyUserWarning):
+    """
+    A class for warnings triggered by ERFA functions (status codes > 0)
+    """
+
+
+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):
+    # 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)
+
+
+#<-------------------------trailing shape verification------------------------>
+
+def check_trailing_shape(arr, shape, name):
+    try:
+        if arr.shape[-len(shape):] != shape:
+            raise Exception()
+    except:
+        raise ValueError("{0} must be of trailing dimensions {1}".format(name, shape))
+
+#<--------------------------Actual ERFA-wrapping code------------------------->
+
+dt_eraASTROM = numpy.dtype([('pmt','d'),
+                         ('eb','d',(3,)),
+                         ('eh','d',(3,)),
+                         ('em','d'),
+                         ('v','d',(3,)),
+                         ('bm1','d'),
+                         ('bpn','d',(3,3)),
+                         ('along','d'),
+                         ('phi','d'),
+                         ('xpl','d'),
+                         ('ypl','d'),
+                         ('sphi','d'),
+                         ('cphi','d'),
+                         ('diurab','d'),
+                         ('eral','d'),
+                         ('refa','d'),
+                         ('refb','d')], align=True)
+
+dt_eraLDBODY = numpy.dtype([('bm','d'),
+                         ('dl','d'),
+                         ('pv','d',(2,3))], align=True)
+
+
+{% 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.
+
+{{ func.doc }}
+    """
+
+    #Turn all inputs into arrays
+    {%- for arg in func.args_by_inout('in|inout') %}
+    {{ arg.name }}_in = numpy.array({{ arg.name }}, dtype={{ arg.dtype }}, order="C", copy=False, subok=True)
+    {%- endfor %}
+    {%- for arg in func.args_by_inout('in|inout') %}
+    {%- if arg.ndim > 0 %}
+    check_trailing_shape({{ arg.name }}_in, {{ arg.shape }}, "{{arg.name}}")
+    {%- endif %}
+    {%- endfor %}
+
+    {%- if func.args_by_inout('in|inout') %}
+    make_outputs_scalar = False
+    if NPYLT18:
+        # in numpy < 1.8, the iterator used below doesn't work with 0d/scalar arrays
+        # so we replace all scalars with 1d arrays
+        make_outputs_scalar = True
+        {%- for arg in func.args_by_inout('in|inout') %}
+        if {{ arg.name_in_broadcast }}.shape == tuple():
+            {{ arg.name }}_in = {{ arg.name }}_in.reshape((1,) + {{ arg.name }}_in.shape)
+        else:
+            make_outputs_scalar = False
+        {%- endfor %}
+    {%- endif %}
+
+    #Create the output array, based on the broadcasted shape, adding the generated dimensions if needed
+    broadcast = numpy.broadcast(numpy.int32(0.0), numpy.int32(0.0), {{ func.args_by_inout('in|inout')|map(attribute='name_in_broadcast')|join(', ') }})
+    {%- for arg in func.args_by_inout('inout|out|ret|stat') %}
+    {{ arg.name }}_out = numpy.empty(broadcast.shape + {{ arg.shape }}, dtype={{ arg.dtype }})
+    {%- endfor %}
+    {%- for arg in func.args_by_inout('inout') %}
+    numpy.copyto({{ arg.name }}_out, {{ arg.name }}_in)
+    {%- endfor %}
+
+    #Create the iterator, broadcasting on all but the consumed dimensions
+    arrs = [{{ (func.args_by_inout('in')|map(attribute='name_in_broadcast')|list + func.args_by_inout('inout|out|ret|stat')|map(attribute='name_out_broadcast')|list)|join(', ') }}]
+    op_axes = [[-1]*(broadcast.nd-arr.ndim) + list(range(arr.ndim)) for arr in arrs]
+    op_flags = [['readonly']]*{{ func.args_by_inout('in')|count }} + [['readwrite']]*{{ func.args_by_inout('inout|out|ret|stat')|count }}
+    it = numpy.nditer(arrs, op_axes=op_axes, op_flags=op_flags)
+
+    #Iterate
+    stat_ok = _core._{{ func.pyname }}(it)
+
+    {%- for arg in func.args_by_inout('stat') %}
+
+    if not stat_ok:
+        check_errwarn({{ arg.name }}_out, '{{ func.pyname }}')
+    {%- endfor %}
+
+    {%- if func.args_by_inout('in|inout') %}
+    #need to convert the outputs back to scalars if all the inputs were scalars but we made them 1d
+    if make_outputs_scalar:
+        {%- for arg in func.args_by_inout('inout|out|ret') %}
+        assert len({{ arg.name }}_out.shape) > 0 and {{ arg.name }}_out.shape[0] == 1
+        {{ arg.name }}_out = {{ arg.name }}_out.reshape({{ arg.name }}_out.shape[1:])
+        {%- else %}
+        pass
+        {%- endfor %}
+    {%- endif %}
+
+    return {{ func.args_by_inout('inout|out|ret')|map(attribute='name')|postfix('_out')|join(', ') }}
+
+{%- for stat in func.args_by_inout('stat') %}
+{%- if stat.doc_info.statuscodes %}
+STATUS_CODES['{{ func.pyname }}'] = {{ stat.doc_info.statuscodes|string }}
+{% endif %}
+{%- endfor %}
+
+{% endfor %}
\ No newline at end of file
diff --git a/astropy/_erfa/core.pyx b/astropy/_erfa/core.pyx
new file mode 100644
index 0000000..01381a4
--- /dev/null
+++ b/astropy/_erfa/core.pyx
@@ -0,0 +1,3961 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+# "core.pyx" is auto-generated by erfa_generator.py from the template
+# "core.pyx.templ". Do *not* edit "core.pyx" directly, instead edit
+# "core.pyx.templ" and run erfa_generator.py from the source directory to
+# update it.
+
+"""
+This module contains the Cython parts of the ERFA python wrappers.
+This is separated from the python code in ``core.py`` because putting it all in
+Cython results in very long compile times.  By having only the vectorized core
+in Cython, the compilation time is kept short without sacrificing much (if any)
+performance.
+
+For more about the module and how to use it, see the ``core.py`` docstrings.
+"""
+from __future__ import absolute_import, division, print_function
+
+import warnings
+from distutils.version import LooseVersion
+
+from ..utils.exceptions import AstropyUserWarning
+
+import numpy
+cimport numpy
+from cpython.ref cimport PyObject
+
+numpy.import_array()
+
+__all__ = ['_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', '_refco', '_epv00', '_plan94', '_fad03', '_fae03', '_faf03', '_faju03', '_fal03', '_falp03', '_fama [...]
+
+#<-----------------------------NpyIter handling------------------------------->
+
+ctypedef void NpyIter
+ctypedef int (*IterNextFunc)(NpyIter * iter) nogil
+
+cdef extern from "numpy/arrayobject.h":
+    IterNextFunc GetIterNext "NpyIter_GetIterNext" (NpyIter *iter, char **)
+    char** GetDataPtrArray "NpyIter_GetDataPtrArray" (NpyIter* iter)
+
+ctypedef struct NewNpyArrayIterObject:
+    PyObject base
+    NpyIter *iter
+
+cdef inline NpyIter* GetNpyIter(object iter):
+    return (<NewNpyArrayIterObject*>iter).iter
+
+
+#<--------------------------Actual ERFA-wrapping code------------------------->
+
+cdef extern from "erfam.h":
+    struct eraASTROM:
+        pass
+    struct eraLDBODY:
+        pass
+
+cdef extern from "erfa.h":
+    int eraCal2jd(int, int, int, double *, double *)
+    double eraEpb(double, double)
+    void eraEpb2jd(double, double *, double *)
+    double eraEpj(double, double)
+    void eraEpj2jd(double, double *, double *)
+    int eraJd2cal(double, double, int *, int *, int *, double *)
+    int eraJdcalf(int, double, double, int *)
+    void eraAb(double *, double *, double, double, double *)
+    void eraApcg(double, double, double *, double *, eraASTROM *)
+    void eraApcg13(double, double, eraASTROM *)
+    void eraApci(double, double, double *, double *, double, double, double, eraASTROM *)
+    void eraApci13(double, double, eraASTROM *, double *)
+    void eraApco(double, double, double *, double *, double, double, double, double, double, double, double, double, double, double, double, double, eraASTROM *)
+    int eraApco13(double, double, double, double, double, double, double, double, double, double, double, double, eraASTROM *, double *)
+    void eraApcs(double, double, double *, double *, double *, eraASTROM *)
+    void eraApcs13(double, double, double *, eraASTROM *)
+    void eraAper(double, eraASTROM *)
+    void eraAper13(double, double, eraASTROM *)
+    void eraApio(double, double, double, double, double, double, double, double, double, eraASTROM *)
+    int eraApio13(double, double, double, double, double, double, double, double, double, double, double, double, eraASTROM *)
+    void eraAtci13(double, double, double, double, double, double, double, double, double *, double *, double *)
+    void eraAtciq(double, double, double, double, double, double, eraASTROM *, double *, double *)
+    void eraAtciqn(double, double, double, double, double, double, eraASTROM *, int, eraLDBODY *, double *, double *)
+    void eraAtciqz(double, double, eraASTROM *, double *, double *)
+    int eraAtco13(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraAtic13(double, double, double, double, double *, double *, double *)
+    void eraAticq(double, double, eraASTROM *, double *, double *)
+    void eraAticqn(double, double, eraASTROM *, int, eraLDBODY *, double *, double *)
+    int eraAtio13(double, double, double, double, double, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, double *)
+    void eraAtioq(double, double, eraASTROM *, double *, double *, double *, double *, double *)
+    int eraAtoc13(const char *, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double *, double *)
+    int eraAtoi13(const char *, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double *, double *)
+    void eraAtoiq(const char *, double, double, eraASTROM *, double *, double *)
+    void eraLd(double, double *, double *, double *, double, double, double *)
+    void eraLdn(int, eraLDBODY *, double *, double *, double *)
+    void eraLdsun(double *, double *, double, double *)
+    void eraPmpx(double, double, double, double, double, double, double, double *, double *)
+    int eraPmsafe(double, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraRefco(double, double, double, double, double *, double *)
+    int eraEpv00(double, double, double *, double *)
+    int eraPlan94(double, double, int, double *)
+    double eraFad03(double)
+    double eraFae03(double)
+    double eraFaf03(double)
+    double eraFaju03(double)
+    double eraFal03(double)
+    double eraFalp03(double)
+    double eraFama03(double)
+    double eraFame03(double)
+    double eraFane03(double)
+    double eraFaom03(double)
+    double eraFapa03(double)
+    double eraFasa03(double)
+    double eraFaur03(double)
+    double eraFave03(double)
+    void eraBi00(double *, double *, double *)
+    void eraBp00(double, double, double *, double *, double *)
+    void eraBp06(double, double, double *, double *, double *)
+    void eraBpn2xy(double *, double *, double *)
+    void eraC2i00a(double, double, double *)
+    void eraC2i00b(double, double, double *)
+    void eraC2i06a(double, double, double *)
+    void eraC2ibpn(double, double, double *, double *)
+    void eraC2ixy(double, double, double, double, double *)
+    void eraC2ixys(double, double, double, double *)
+    void eraC2t00a(double, double, double, double, double, double, double *)
+    void eraC2t00b(double, double, double, double, double, double, double *)
+    void eraC2t06a(double, double, double, double, double, double, double *)
+    void eraC2tcio(double *, double, double *, double *)
+    void eraC2teqx(double *, double, double *, double *)
+    void eraC2tpe(double, double, double, double, double, double, double, double, double *)
+    void eraC2txy(double, double, double, double, double, double, double, double, double *)
+    double eraEo06a(double, double)
+    double eraEors(double *, double)
+    void eraFw2m(double, double, double, double, double *)
+    void eraFw2xy(double, double, double, double, double *, double *)
+    void eraNum00a(double, double, double *)
+    void eraNum00b(double, double, double *)
+    void eraNum06a(double, double, double *)
+    void eraNumat(double, double, double, double *)
+    void eraNut00a(double, double, double *, double *)
+    void eraNut00b(double, double, double *, double *)
+    void eraNut06a(double, double, double *, double *)
+    void eraNut80(double, double, double *, double *)
+    void eraNutm80(double, double, double *)
+    double eraObl06(double, double)
+    double eraObl80(double, double)
+    void eraP06e(double, double, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *)
+    void eraPb06(double, double, double *, double *, double *)
+    void eraPfw06(double, double, double *, double *, double *, double *)
+    void eraPmat00(double, double, double *)
+    void eraPmat06(double, double, double *)
+    void eraPmat76(double, double, double *)
+    void eraPn00(double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraPn00a(double, double, double *, double *, double *, double *, double *, double *, double *, double *)
+    void eraPn00b(double, double, double *, double *, double *, double *, double *, double *, double *, double *)
+    void eraPn06(double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraPn06a(double, double, double *, double *, double *, double *, double *, double *, double *, double *)
+    void eraPnm00a(double, double, double *)
+    void eraPnm00b(double, double, double *)
+    void eraPnm06a(double, double, double *)
+    void eraPnm80(double, double, double *)
+    void eraPom00(double, double, double, double *)
+    void eraPr00(double, double, double *, double *)
+    void eraPrec76(double, double, double, double, double *, double *, double *)
+    double eraS00(double, double, double, double)
+    double eraS00a(double, double)
+    double eraS00b(double, double)
+    double eraS06(double, double, double, double)
+    double eraS06a(double, double)
+    double eraSp00(double, double)
+    void eraXy06(double, double, double *, double *)
+    void eraXys00a(double, double, double *, double *, double *)
+    void eraXys00b(double, double, double *, double *, double *)
+    void eraXys06a(double, double, double *, double *, double *)
+    double eraEe00(double, double, double, double)
+    double eraEe00a(double, double)
+    double eraEe00b(double, double)
+    double eraEe06a(double, double)
+    double eraEect00(double, double)
+    double eraEqeq94(double, double)
+    double eraEra00(double, double)
+    double eraGmst00(double, double, double, double)
+    double eraGmst06(double, double, double, double)
+    double eraGmst82(double, double)
+    double eraGst00a(double, double, double, double)
+    double eraGst00b(double, double)
+    double eraGst06(double, double, double, double, double *)
+    double eraGst06a(double, double, double, double)
+    double eraGst94(double, double)
+    int eraPmsafe(double, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    int eraPvstar(double *, double *, double *, double *, double *, double *, double *)
+    int eraStarpv(double, double, double, double, double, double, double *)
+    void eraFk52h(double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraFk5hip(double *, double *)
+    void eraFk5hz(double, double, double, double, double *, double *)
+    void eraH2fk5(double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    void eraHfk5z(double, double, double, double, double *, double *, double *, double *)
+    int eraStarpm(double, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *)
+    int eraEform(int, double *, double *)
+    int eraGc2gd(int, double *, double *, double *, double *)
+    int eraGc2gde(double, double, double *, double *, double *, double *)
+    int eraGd2gc(int, double, double, double, double *)
+    int eraGd2gce(double, double, double, double, double, double *)
+    void eraPvtob(double, double, double, double, double, double, double, double *)
+    int eraD2dtf(const char *, int, double, double, int *, int *, int *, int *)
+    int eraDat(int, int, int, double, double *)
+    double eraDtdb(double, double, double, double, double, double)
+    int eraDtf2d(const char *, int, int, int, int, int, double, double *, double *)
+    int eraTaitt(double, double, double *, double *)
+    int eraTaiut1(double, double, double, double *, double *)
+    int eraTaiutc(double, double, double *, double *)
+    int eraTcbtdb(double, double, double *, double *)
+    int eraTcgtt(double, double, double *, double *)
+    int eraTdbtcb(double, double, double *, double *)
+    int eraTdbtt(double, double, double, double *, double *)
+    int eraTttai(double, double, double *, double *)
+    int eraTttcg(double, double, double *, double *)
+    int eraTttdb(double, double, double, double *, double *)
+    int eraTtut1(double, double, double, double *, double *)
+    int eraUt1tai(double, double, double, double *, double *)
+    int eraUt1tt(double, double, double, double *, double *)
+    int eraUt1utc(double, double, double, double *, double *)
+    int eraUtctai(double, double, double *, double *)
+    int eraUtcut1(double, double, double, double *, double *)
+
+
+def _cal2jd(it):
+    #Iterate
+    cdef int _iy
+    cdef int _im
+    cdef int _id
+    cdef double * _djm0
+    cdef double * _djm
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _iy = (<int *>(dataptrarray[0]))[0]
+        _im = (<int *>(dataptrarray[1]))[0]
+        _id = (<int *>(dataptrarray[2]))[0]
+        _djm0 = (<double *>(dataptrarray[3]))
+        _djm = (<double *>(dataptrarray[4]))
+        _c_retval = eraCal2jd(_iy, _im, _id, _djm0, _djm)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _epb(it):
+    #Iterate
+    cdef double _dj1
+    cdef double _dj2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dj1 = (<double *>(dataptrarray[0]))[0]
+        _dj2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEpb(_dj1, _dj2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _epb2jd(it):
+    #Iterate
+    cdef double _epb
+    cdef double * _djm0
+    cdef double * _djm
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _epb = (<double *>(dataptrarray[0]))[0]
+        _djm0 = (<double *>(dataptrarray[1]))
+        _djm = (<double *>(dataptrarray[2]))
+        eraEpb2jd(_epb, _djm0, _djm)
+        status = iternext(GetNpyIter(it))
+
+
+def _epj(it):
+    #Iterate
+    cdef double _dj1
+    cdef double _dj2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dj1 = (<double *>(dataptrarray[0]))[0]
+        _dj2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEpj(_dj1, _dj2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _epj2jd(it):
+    #Iterate
+    cdef double _epj
+    cdef double * _djm0
+    cdef double * _djm
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _epj = (<double *>(dataptrarray[0]))[0]
+        _djm0 = (<double *>(dataptrarray[1]))
+        _djm = (<double *>(dataptrarray[2]))
+        eraEpj2jd(_epj, _djm0, _djm)
+        status = iternext(GetNpyIter(it))
+
+
+def _jd2cal(it):
+    #Iterate
+    cdef double _dj1
+    cdef double _dj2
+    cdef int * _iy
+    cdef int * _im
+    cdef int * _id
+    cdef double * _fd
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dj1 = (<double *>(dataptrarray[0]))[0]
+        _dj2 = (<double *>(dataptrarray[1]))[0]
+        _iy = (<int *>(dataptrarray[2]))
+        _im = (<int *>(dataptrarray[3]))
+        _id = (<int *>(dataptrarray[4]))
+        _fd = (<double *>(dataptrarray[5]))
+        _c_retval = eraJd2cal(_dj1, _dj2, _iy, _im, _id, _fd)
+        (<int *>(dataptrarray[6]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _jdcalf(it):
+    #Iterate
+    cdef int _ndp
+    cdef double _dj1
+    cdef double _dj2
+    cdef int * _iymdf
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ndp = (<int *>(dataptrarray[0]))[0]
+        _dj1 = (<double *>(dataptrarray[1]))[0]
+        _dj2 = (<double *>(dataptrarray[2]))[0]
+        _iymdf = (<int *>(dataptrarray[3]))
+        _c_retval = eraJdcalf(_ndp, _dj1, _dj2, _iymdf)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _ab(it):
+    #Iterate
+    cdef double * _pnat
+    cdef double * _v
+    cdef double _s
+    cdef double _bm1
+    cdef double * _ppr
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _pnat = (<double *>(dataptrarray[0]))
+        _v = (<double *>(dataptrarray[1]))
+        _s = (<double *>(dataptrarray[2]))[0]
+        _bm1 = (<double *>(dataptrarray[3]))[0]
+        _ppr = (<double *>(dataptrarray[4]))
+        eraAb(_pnat, _v, _s, _bm1, _ppr)
+        status = iternext(GetNpyIter(it))
+
+
+def _apcg(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _ebpv
+    cdef double * _ehp
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _ebpv = (<double *>(dataptrarray[2]))
+        _ehp = (<double *>(dataptrarray[3]))
+        _astrom = (<eraASTROM *>(dataptrarray[4]))
+        eraApcg(_date1, _date2, _ebpv, _ehp, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apcg13(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        eraApcg13(_date1, _date2, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apci(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _ebpv
+    cdef double * _ehp
+    cdef double _x
+    cdef double _y
+    cdef double _s
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _ebpv = (<double *>(dataptrarray[2]))
+        _ehp = (<double *>(dataptrarray[3]))
+        _x = (<double *>(dataptrarray[4]))[0]
+        _y = (<double *>(dataptrarray[5]))[0]
+        _s = (<double *>(dataptrarray[6]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[7]))
+        eraApci(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apci13(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef eraASTROM * _astrom
+    cdef double * _eo
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        _eo = (<double *>(dataptrarray[3]))
+        eraApci13(_date1, _date2, _astrom, _eo)
+        status = iternext(GetNpyIter(it))
+
+
+def _apco(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _ebpv
+    cdef double * _ehp
+    cdef double _x
+    cdef double _y
+    cdef double _s
+    cdef double _theta
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _sp
+    cdef double _refa
+    cdef double _refb
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _ebpv = (<double *>(dataptrarray[2]))
+        _ehp = (<double *>(dataptrarray[3]))
+        _x = (<double *>(dataptrarray[4]))[0]
+        _y = (<double *>(dataptrarray[5]))[0]
+        _s = (<double *>(dataptrarray[6]))[0]
+        _theta = (<double *>(dataptrarray[7]))[0]
+        _elong = (<double *>(dataptrarray[8]))[0]
+        _phi = (<double *>(dataptrarray[9]))[0]
+        _hm = (<double *>(dataptrarray[10]))[0]
+        _xp = (<double *>(dataptrarray[11]))[0]
+        _yp = (<double *>(dataptrarray[12]))[0]
+        _sp = (<double *>(dataptrarray[13]))[0]
+        _refa = (<double *>(dataptrarray[14]))[0]
+        _refb = (<double *>(dataptrarray[15]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[16]))
+        eraApco(_date1, _date2, _ebpv, _ehp, _x, _y, _s, _theta, _elong, _phi, _hm, _xp, _yp, _sp, _refa, _refb, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apco13(it):
+    #Iterate
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef eraASTROM * _astrom
+    cdef double * _eo
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _utc1 = (<double *>(dataptrarray[0]))[0]
+        _utc2 = (<double *>(dataptrarray[1]))[0]
+        _dut1 = (<double *>(dataptrarray[2]))[0]
+        _elong = (<double *>(dataptrarray[3]))[0]
+        _phi = (<double *>(dataptrarray[4]))[0]
+        _hm = (<double *>(dataptrarray[5]))[0]
+        _xp = (<double *>(dataptrarray[6]))[0]
+        _yp = (<double *>(dataptrarray[7]))[0]
+        _phpa = (<double *>(dataptrarray[8]))[0]
+        _tc = (<double *>(dataptrarray[9]))[0]
+        _rh = (<double *>(dataptrarray[10]))[0]
+        _wl = (<double *>(dataptrarray[11]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[12]))
+        _eo = (<double *>(dataptrarray[13]))
+        _c_retval = eraApco13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom, _eo)
+        (<int *>(dataptrarray[14]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _apcs(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _pv
+    cdef double * _ebpv
+    cdef double * _ehp
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _pv = (<double *>(dataptrarray[2]))
+        _ebpv = (<double *>(dataptrarray[3]))
+        _ehp = (<double *>(dataptrarray[4]))
+        _astrom = (<eraASTROM *>(dataptrarray[5]))
+        eraApcs(_date1, _date2, _pv, _ebpv, _ehp, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apcs13(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _pv
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _pv = (<double *>(dataptrarray[2]))
+        _astrom = (<eraASTROM *>(dataptrarray[3]))
+        eraApcs13(_date1, _date2, _pv, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _aper(it):
+    #Iterate
+    cdef double _theta
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _theta = (<double *>(dataptrarray[0]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[1]))
+        eraAper(_theta, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _aper13(it):
+    #Iterate
+    cdef double _ut11
+    cdef double _ut12
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ut11 = (<double *>(dataptrarray[0]))[0]
+        _ut12 = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        eraAper13(_ut11, _ut12, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apio(it):
+    #Iterate
+    cdef double _sp
+    cdef double _theta
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _refa
+    cdef double _refb
+    cdef eraASTROM * _astrom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _sp = (<double *>(dataptrarray[0]))[0]
+        _theta = (<double *>(dataptrarray[1]))[0]
+        _elong = (<double *>(dataptrarray[2]))[0]
+        _phi = (<double *>(dataptrarray[3]))[0]
+        _hm = (<double *>(dataptrarray[4]))[0]
+        _xp = (<double *>(dataptrarray[5]))[0]
+        _yp = (<double *>(dataptrarray[6]))[0]
+        _refa = (<double *>(dataptrarray[7]))[0]
+        _refb = (<double *>(dataptrarray[8]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[9]))
+        eraApio(_sp, _theta, _elong, _phi, _hm, _xp, _yp, _refa, _refb, _astrom)
+        status = iternext(GetNpyIter(it))
+
+
+def _apio13(it):
+    #Iterate
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef eraASTROM * _astrom
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _utc1 = (<double *>(dataptrarray[0]))[0]
+        _utc2 = (<double *>(dataptrarray[1]))[0]
+        _dut1 = (<double *>(dataptrarray[2]))[0]
+        _elong = (<double *>(dataptrarray[3]))[0]
+        _phi = (<double *>(dataptrarray[4]))[0]
+        _hm = (<double *>(dataptrarray[5]))[0]
+        _xp = (<double *>(dataptrarray[6]))[0]
+        _yp = (<double *>(dataptrarray[7]))[0]
+        _phpa = (<double *>(dataptrarray[8]))[0]
+        _tc = (<double *>(dataptrarray[9]))[0]
+        _rh = (<double *>(dataptrarray[10]))[0]
+        _wl = (<double *>(dataptrarray[11]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[12]))
+        _c_retval = eraApio13(_utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _astrom)
+        (<int *>(dataptrarray[13]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _atci13(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef double _pr
+    cdef double _pd
+    cdef double _px
+    cdef double _rv
+    cdef double _date1
+    cdef double _date2
+    cdef double * _ri
+    cdef double * _di
+    cdef double * _eo
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _pr = (<double *>(dataptrarray[2]))[0]
+        _pd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _date1 = (<double *>(dataptrarray[6]))[0]
+        _date2 = (<double *>(dataptrarray[7]))[0]
+        _ri = (<double *>(dataptrarray[8]))
+        _di = (<double *>(dataptrarray[9]))
+        _eo = (<double *>(dataptrarray[10]))
+        eraAtci13(_rc, _dc, _pr, _pd, _px, _rv, _date1, _date2, _ri, _di, _eo)
+        status = iternext(GetNpyIter(it))
+
+
+def _atciq(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef double _pr
+    cdef double _pd
+    cdef double _px
+    cdef double _rv
+    cdef eraASTROM * _astrom
+    cdef double * _ri
+    cdef double * _di
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _pr = (<double *>(dataptrarray[2]))[0]
+        _pd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[6]))
+        _ri = (<double *>(dataptrarray[7]))
+        _di = (<double *>(dataptrarray[8]))
+        eraAtciq(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _ri, _di)
+        status = iternext(GetNpyIter(it))
+
+
+def _atciqn(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef double _pr
+    cdef double _pd
+    cdef double _px
+    cdef double _rv
+    cdef eraASTROM * _astrom
+    cdef int _n
+    cdef eraLDBODY * _b
+    cdef double * _ri
+    cdef double * _di
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _pr = (<double *>(dataptrarray[2]))[0]
+        _pd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[6]))
+        _n = (<int *>(dataptrarray[7]))[0]
+        _b = (<eraLDBODY *>(dataptrarray[8]))
+        _ri = (<double *>(dataptrarray[9]))
+        _di = (<double *>(dataptrarray[10]))
+        eraAtciqn(_rc, _dc, _pr, _pd, _px, _rv, _astrom, _n, _b, _ri, _di)
+        status = iternext(GetNpyIter(it))
+
+
+def _atciqz(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef eraASTROM * _astrom
+    cdef double * _ri
+    cdef double * _di
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        _ri = (<double *>(dataptrarray[3]))
+        _di = (<double *>(dataptrarray[4]))
+        eraAtciqz(_rc, _dc, _astrom, _ri, _di)
+        status = iternext(GetNpyIter(it))
+
+
+def _atco13(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef double _pr
+    cdef double _pd
+    cdef double _px
+    cdef double _rv
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef double * _aob
+    cdef double * _zob
+    cdef double * _hob
+    cdef double * _dob
+    cdef double * _rob
+    cdef double * _eo
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _pr = (<double *>(dataptrarray[2]))[0]
+        _pd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _utc1 = (<double *>(dataptrarray[6]))[0]
+        _utc2 = (<double *>(dataptrarray[7]))[0]
+        _dut1 = (<double *>(dataptrarray[8]))[0]
+        _elong = (<double *>(dataptrarray[9]))[0]
+        _phi = (<double *>(dataptrarray[10]))[0]
+        _hm = (<double *>(dataptrarray[11]))[0]
+        _xp = (<double *>(dataptrarray[12]))[0]
+        _yp = (<double *>(dataptrarray[13]))[0]
+        _phpa = (<double *>(dataptrarray[14]))[0]
+        _tc = (<double *>(dataptrarray[15]))[0]
+        _rh = (<double *>(dataptrarray[16]))[0]
+        _wl = (<double *>(dataptrarray[17]))[0]
+        _aob = (<double *>(dataptrarray[18]))
+        _zob = (<double *>(dataptrarray[19]))
+        _hob = (<double *>(dataptrarray[20]))
+        _dob = (<double *>(dataptrarray[21]))
+        _rob = (<double *>(dataptrarray[22]))
+        _eo = (<double *>(dataptrarray[23]))
+        _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 *>(dataptrarray[24]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _atic13(it):
+    #Iterate
+    cdef double _ri
+    cdef double _di
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rc
+    cdef double * _dc
+    cdef double * _eo
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ri = (<double *>(dataptrarray[0]))[0]
+        _di = (<double *>(dataptrarray[1]))[0]
+        _date1 = (<double *>(dataptrarray[2]))[0]
+        _date2 = (<double *>(dataptrarray[3]))[0]
+        _rc = (<double *>(dataptrarray[4]))
+        _dc = (<double *>(dataptrarray[5]))
+        _eo = (<double *>(dataptrarray[6]))
+        eraAtic13(_ri, _di, _date1, _date2, _rc, _dc, _eo)
+        status = iternext(GetNpyIter(it))
+
+
+def _aticq(it):
+    #Iterate
+    cdef double _ri
+    cdef double _di
+    cdef eraASTROM * _astrom
+    cdef double * _rc
+    cdef double * _dc
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ri = (<double *>(dataptrarray[0]))[0]
+        _di = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        _rc = (<double *>(dataptrarray[3]))
+        _dc = (<double *>(dataptrarray[4]))
+        eraAticq(_ri, _di, _astrom, _rc, _dc)
+        status = iternext(GetNpyIter(it))
+
+
+def _aticqn(it):
+    #Iterate
+    cdef double _ri
+    cdef double _di
+    cdef eraASTROM * _astrom
+    cdef int _n
+    cdef eraLDBODY * _b
+    cdef double * _rc
+    cdef double * _dc
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ri = (<double *>(dataptrarray[0]))[0]
+        _di = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        _n = (<int *>(dataptrarray[3]))[0]
+        _b = (<eraLDBODY *>(dataptrarray[4]))
+        _rc = (<double *>(dataptrarray[5]))
+        _dc = (<double *>(dataptrarray[6]))
+        eraAticqn(_ri, _di, _astrom, _n, _b, _rc, _dc)
+        status = iternext(GetNpyIter(it))
+
+
+def _atio13(it):
+    #Iterate
+    cdef double _ri
+    cdef double _di
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef double * _aob
+    cdef double * _zob
+    cdef double * _hob
+    cdef double * _dob
+    cdef double * _rob
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ri = (<double *>(dataptrarray[0]))[0]
+        _di = (<double *>(dataptrarray[1]))[0]
+        _utc1 = (<double *>(dataptrarray[2]))[0]
+        _utc2 = (<double *>(dataptrarray[3]))[0]
+        _dut1 = (<double *>(dataptrarray[4]))[0]
+        _elong = (<double *>(dataptrarray[5]))[0]
+        _phi = (<double *>(dataptrarray[6]))[0]
+        _hm = (<double *>(dataptrarray[7]))[0]
+        _xp = (<double *>(dataptrarray[8]))[0]
+        _yp = (<double *>(dataptrarray[9]))[0]
+        _phpa = (<double *>(dataptrarray[10]))[0]
+        _tc = (<double *>(dataptrarray[11]))[0]
+        _rh = (<double *>(dataptrarray[12]))[0]
+        _wl = (<double *>(dataptrarray[13]))[0]
+        _aob = (<double *>(dataptrarray[14]))
+        _zob = (<double *>(dataptrarray[15]))
+        _hob = (<double *>(dataptrarray[16]))
+        _dob = (<double *>(dataptrarray[17]))
+        _rob = (<double *>(dataptrarray[18]))
+        _c_retval = eraAtio13(_ri, _di, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _aob, _zob, _hob, _dob, _rob)
+        (<int *>(dataptrarray[19]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _atioq(it):
+    #Iterate
+    cdef double _ri
+    cdef double _di
+    cdef eraASTROM * _astrom
+    cdef double * _aob
+    cdef double * _zob
+    cdef double * _hob
+    cdef double * _dob
+    cdef double * _rob
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ri = (<double *>(dataptrarray[0]))[0]
+        _di = (<double *>(dataptrarray[1]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[2]))
+        _aob = (<double *>(dataptrarray[3]))
+        _zob = (<double *>(dataptrarray[4]))
+        _hob = (<double *>(dataptrarray[5]))
+        _dob = (<double *>(dataptrarray[6]))
+        _rob = (<double *>(dataptrarray[7]))
+        eraAtioq(_ri, _di, _astrom, _aob, _zob, _hob, _dob, _rob)
+        status = iternext(GetNpyIter(it))
+
+
+def _atoc13(it):
+    #Iterate
+    cdef const char * _type
+    cdef double _ob1
+    cdef double _ob2
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef double * _rc
+    cdef double * _dc
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _type = (<const char *>(dataptrarray[0]))
+        _ob1 = (<double *>(dataptrarray[1]))[0]
+        _ob2 = (<double *>(dataptrarray[2]))[0]
+        _utc1 = (<double *>(dataptrarray[3]))[0]
+        _utc2 = (<double *>(dataptrarray[4]))[0]
+        _dut1 = (<double *>(dataptrarray[5]))[0]
+        _elong = (<double *>(dataptrarray[6]))[0]
+        _phi = (<double *>(dataptrarray[7]))[0]
+        _hm = (<double *>(dataptrarray[8]))[0]
+        _xp = (<double *>(dataptrarray[9]))[0]
+        _yp = (<double *>(dataptrarray[10]))[0]
+        _phpa = (<double *>(dataptrarray[11]))[0]
+        _tc = (<double *>(dataptrarray[12]))[0]
+        _rh = (<double *>(dataptrarray[13]))[0]
+        _wl = (<double *>(dataptrarray[14]))[0]
+        _rc = (<double *>(dataptrarray[15]))
+        _dc = (<double *>(dataptrarray[16]))
+        _c_retval = eraAtoc13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _rc, _dc)
+        (<int *>(dataptrarray[17]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _atoi13(it):
+    #Iterate
+    cdef const char * _type
+    cdef double _ob1
+    cdef double _ob2
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef double * _ri
+    cdef double * _di
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _type = (<const char *>(dataptrarray[0]))
+        _ob1 = (<double *>(dataptrarray[1]))[0]
+        _ob2 = (<double *>(dataptrarray[2]))[0]
+        _utc1 = (<double *>(dataptrarray[3]))[0]
+        _utc2 = (<double *>(dataptrarray[4]))[0]
+        _dut1 = (<double *>(dataptrarray[5]))[0]
+        _elong = (<double *>(dataptrarray[6]))[0]
+        _phi = (<double *>(dataptrarray[7]))[0]
+        _hm = (<double *>(dataptrarray[8]))[0]
+        _xp = (<double *>(dataptrarray[9]))[0]
+        _yp = (<double *>(dataptrarray[10]))[0]
+        _phpa = (<double *>(dataptrarray[11]))[0]
+        _tc = (<double *>(dataptrarray[12]))[0]
+        _rh = (<double *>(dataptrarray[13]))[0]
+        _wl = (<double *>(dataptrarray[14]))[0]
+        _ri = (<double *>(dataptrarray[15]))
+        _di = (<double *>(dataptrarray[16]))
+        _c_retval = eraAtoi13(_type, _ob1, _ob2, _utc1, _utc2, _dut1, _elong, _phi, _hm, _xp, _yp, _phpa, _tc, _rh, _wl, _ri, _di)
+        (<int *>(dataptrarray[17]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _atoiq(it):
+    #Iterate
+    cdef const char * _type
+    cdef double _ob1
+    cdef double _ob2
+    cdef eraASTROM * _astrom
+    cdef double * _ri
+    cdef double * _di
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _type = (<const char *>(dataptrarray[0]))
+        _ob1 = (<double *>(dataptrarray[1]))[0]
+        _ob2 = (<double *>(dataptrarray[2]))[0]
+        _astrom = (<eraASTROM *>(dataptrarray[3]))
+        _ri = (<double *>(dataptrarray[4]))
+        _di = (<double *>(dataptrarray[5]))
+        eraAtoiq(_type, _ob1, _ob2, _astrom, _ri, _di)
+        status = iternext(GetNpyIter(it))
+
+
+def _ld(it):
+    #Iterate
+    cdef double _bm
+    cdef double * _p
+    cdef double * _q
+    cdef double * _e
+    cdef double _em
+    cdef double _dlim
+    cdef double * _p1
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _bm = (<double *>(dataptrarray[0]))[0]
+        _p = (<double *>(dataptrarray[1]))
+        _q = (<double *>(dataptrarray[2]))
+        _e = (<double *>(dataptrarray[3]))
+        _em = (<double *>(dataptrarray[4]))[0]
+        _dlim = (<double *>(dataptrarray[5]))[0]
+        _p1 = (<double *>(dataptrarray[6]))
+        eraLd(_bm, _p, _q, _e, _em, _dlim, _p1)
+        status = iternext(GetNpyIter(it))
+
+
+def _ldn(it):
+    #Iterate
+    cdef int _n
+    cdef eraLDBODY * _b
+    cdef double * _ob
+    cdef double * _sc
+    cdef double * _sn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _n = (<int *>(dataptrarray[0]))[0]
+        _b = (<eraLDBODY *>(dataptrarray[1]))
+        _ob = (<double *>(dataptrarray[2]))
+        _sc = (<double *>(dataptrarray[3]))
+        _sn = (<double *>(dataptrarray[4]))
+        eraLdn(_n, _b, _ob, _sc, _sn)
+        status = iternext(GetNpyIter(it))
+
+
+def _ldsun(it):
+    #Iterate
+    cdef double * _p
+    cdef double * _e
+    cdef double _em
+    cdef double * _p1
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _p = (<double *>(dataptrarray[0]))
+        _e = (<double *>(dataptrarray[1]))
+        _em = (<double *>(dataptrarray[2]))[0]
+        _p1 = (<double *>(dataptrarray[3]))
+        eraLdsun(_p, _e, _em, _p1)
+        status = iternext(GetNpyIter(it))
+
+
+def _pmpx(it):
+    #Iterate
+    cdef double _rc
+    cdef double _dc
+    cdef double _pr
+    cdef double _pd
+    cdef double _px
+    cdef double _rv
+    cdef double _pmt
+    cdef double * _pob
+    cdef double * _pco
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc = (<double *>(dataptrarray[0]))[0]
+        _dc = (<double *>(dataptrarray[1]))[0]
+        _pr = (<double *>(dataptrarray[2]))[0]
+        _pd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _pmt = (<double *>(dataptrarray[6]))[0]
+        _pob = (<double *>(dataptrarray[7]))
+        _pco = (<double *>(dataptrarray[8]))
+        eraPmpx(_rc, _dc, _pr, _pd, _px, _rv, _pmt, _pob, _pco)
+        status = iternext(GetNpyIter(it))
+
+
+def _pmsafe(it):
+    #Iterate
+    cdef double _ra1
+    cdef double _dec1
+    cdef double _pmr1
+    cdef double _pmd1
+    cdef double _px1
+    cdef double _rv1
+    cdef double _ep1a
+    cdef double _ep1b
+    cdef double _ep2a
+    cdef double _ep2b
+    cdef double * _ra2
+    cdef double * _dec2
+    cdef double * _pmr2
+    cdef double * _pmd2
+    cdef double * _px2
+    cdef double * _rv2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ra1 = (<double *>(dataptrarray[0]))[0]
+        _dec1 = (<double *>(dataptrarray[1]))[0]
+        _pmr1 = (<double *>(dataptrarray[2]))[0]
+        _pmd1 = (<double *>(dataptrarray[3]))[0]
+        _px1 = (<double *>(dataptrarray[4]))[0]
+        _rv1 = (<double *>(dataptrarray[5]))[0]
+        _ep1a = (<double *>(dataptrarray[6]))[0]
+        _ep1b = (<double *>(dataptrarray[7]))[0]
+        _ep2a = (<double *>(dataptrarray[8]))[0]
+        _ep2b = (<double *>(dataptrarray[9]))[0]
+        _ra2 = (<double *>(dataptrarray[10]))
+        _dec2 = (<double *>(dataptrarray[11]))
+        _pmr2 = (<double *>(dataptrarray[12]))
+        _pmd2 = (<double *>(dataptrarray[13]))
+        _px2 = (<double *>(dataptrarray[14]))
+        _rv2 = (<double *>(dataptrarray[15]))
+        _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+        (<int *>(dataptrarray[16]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _refco(it):
+    #Iterate
+    cdef double _phpa
+    cdef double _tc
+    cdef double _rh
+    cdef double _wl
+    cdef double * _refa
+    cdef double * _refb
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _phpa = (<double *>(dataptrarray[0]))[0]
+        _tc = (<double *>(dataptrarray[1]))[0]
+        _rh = (<double *>(dataptrarray[2]))[0]
+        _wl = (<double *>(dataptrarray[3]))[0]
+        _refa = (<double *>(dataptrarray[4]))
+        _refb = (<double *>(dataptrarray[5]))
+        eraRefco(_phpa, _tc, _rh, _wl, _refa, _refb)
+        status = iternext(GetNpyIter(it))
+
+
+def _epv00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _pvh
+    cdef double * _pvb
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _pvh = (<double *>(dataptrarray[2]))
+        _pvb = (<double *>(dataptrarray[3]))
+        _c_retval = eraEpv00(_date1, _date2, _pvh, _pvb)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _plan94(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef int _np
+    cdef double * _pv
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _np = (<int *>(dataptrarray[2]))[0]
+        _pv = (<double *>(dataptrarray[3]))
+        _c_retval = eraPlan94(_date1, _date2, _np, _pv)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _fad03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFad03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fae03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFae03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _faf03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFaf03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _faju03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFaju03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fal03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFal03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _falp03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFalp03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fama03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFama03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fame03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFame03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fane03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFane03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _faom03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFaom03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fapa03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFapa03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fasa03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFasa03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _faur03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFaur03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fave03(it):
+    #Iterate
+    cdef double _t
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _t = (<double *>(dataptrarray[0]))[0]
+        _c_retval = eraFave03(_t)
+        (<double *>(dataptrarray[1]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _bi00(it):
+    #Iterate
+    cdef double * _dpsibi
+    cdef double * _depsbi
+    cdef double * _dra
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dpsibi = (<double *>(dataptrarray[0]))
+        _depsbi = (<double *>(dataptrarray[1]))
+        _dra = (<double *>(dataptrarray[2]))
+        eraBi00(_dpsibi, _depsbi, _dra)
+        status = iternext(GetNpyIter(it))
+
+
+def _bp00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rb = (<double *>(dataptrarray[2]))
+        _rp = (<double *>(dataptrarray[3]))
+        _rbp = (<double *>(dataptrarray[4]))
+        eraBp00(_date1, _date2, _rb, _rp, _rbp)
+        status = iternext(GetNpyIter(it))
+
+
+def _bp06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rb = (<double *>(dataptrarray[2]))
+        _rp = (<double *>(dataptrarray[3]))
+        _rbp = (<double *>(dataptrarray[4]))
+        eraBp06(_date1, _date2, _rb, _rp, _rbp)
+        status = iternext(GetNpyIter(it))
+
+
+def _bpn2xy(it):
+    #Iterate
+    cdef double * _rbpn
+    cdef double * _x
+    cdef double * _y
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rbpn = (<double *>(dataptrarray[0]))
+        _x = (<double *>(dataptrarray[1]))
+        _y = (<double *>(dataptrarray[2]))
+        eraBpn2xy(_rbpn, _x, _y)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2i00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rc2i = (<double *>(dataptrarray[2]))
+        eraC2i00a(_date1, _date2, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2i00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rc2i = (<double *>(dataptrarray[2]))
+        eraC2i00b(_date1, _date2, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2i06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rc2i = (<double *>(dataptrarray[2]))
+        eraC2i06a(_date1, _date2, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2ibpn(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rbpn
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rbpn = (<double *>(dataptrarray[2]))
+        _rc2i = (<double *>(dataptrarray[3]))
+        eraC2ibpn(_date1, _date2, _rbpn, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2ixy(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _x
+    cdef double _y
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))[0]
+        _y = (<double *>(dataptrarray[3]))[0]
+        _rc2i = (<double *>(dataptrarray[4]))
+        eraC2ixy(_date1, _date2, _x, _y, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2ixys(it):
+    #Iterate
+    cdef double _x
+    cdef double _y
+    cdef double _s
+    cdef double * _rc2i
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _x = (<double *>(dataptrarray[0]))[0]
+        _y = (<double *>(dataptrarray[1]))[0]
+        _s = (<double *>(dataptrarray[2]))[0]
+        _rc2i = (<double *>(dataptrarray[3]))
+        eraC2ixys(_x, _y, _s, _rc2i)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2t00a(it):
+    #Iterate
+    cdef double _tta
+    cdef double _ttb
+    cdef double _uta
+    cdef double _utb
+    cdef double _xp
+    cdef double _yp
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tta = (<double *>(dataptrarray[0]))[0]
+        _ttb = (<double *>(dataptrarray[1]))[0]
+        _uta = (<double *>(dataptrarray[2]))[0]
+        _utb = (<double *>(dataptrarray[3]))[0]
+        _xp = (<double *>(dataptrarray[4]))[0]
+        _yp = (<double *>(dataptrarray[5]))[0]
+        _rc2t = (<double *>(dataptrarray[6]))
+        eraC2t00a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2t00b(it):
+    #Iterate
+    cdef double _tta
+    cdef double _ttb
+    cdef double _uta
+    cdef double _utb
+    cdef double _xp
+    cdef double _yp
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tta = (<double *>(dataptrarray[0]))[0]
+        _ttb = (<double *>(dataptrarray[1]))[0]
+        _uta = (<double *>(dataptrarray[2]))[0]
+        _utb = (<double *>(dataptrarray[3]))[0]
+        _xp = (<double *>(dataptrarray[4]))[0]
+        _yp = (<double *>(dataptrarray[5]))[0]
+        _rc2t = (<double *>(dataptrarray[6]))
+        eraC2t00b(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2t06a(it):
+    #Iterate
+    cdef double _tta
+    cdef double _ttb
+    cdef double _uta
+    cdef double _utb
+    cdef double _xp
+    cdef double _yp
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tta = (<double *>(dataptrarray[0]))[0]
+        _ttb = (<double *>(dataptrarray[1]))[0]
+        _uta = (<double *>(dataptrarray[2]))[0]
+        _utb = (<double *>(dataptrarray[3]))[0]
+        _xp = (<double *>(dataptrarray[4]))[0]
+        _yp = (<double *>(dataptrarray[5]))[0]
+        _rc2t = (<double *>(dataptrarray[6]))
+        eraC2t06a(_tta, _ttb, _uta, _utb, _xp, _yp, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2tcio(it):
+    #Iterate
+    cdef double * _rc2i
+    cdef double _era
+    cdef double * _rpom
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rc2i = (<double *>(dataptrarray[0]))
+        _era = (<double *>(dataptrarray[1]))[0]
+        _rpom = (<double *>(dataptrarray[2]))
+        _rc2t = (<double *>(dataptrarray[3]))
+        eraC2tcio(_rc2i, _era, _rpom, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2teqx(it):
+    #Iterate
+    cdef double * _rbpn
+    cdef double _gst
+    cdef double * _rpom
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rbpn = (<double *>(dataptrarray[0]))
+        _gst = (<double *>(dataptrarray[1]))[0]
+        _rpom = (<double *>(dataptrarray[2]))
+        _rc2t = (<double *>(dataptrarray[3]))
+        eraC2teqx(_rbpn, _gst, _rpom, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2tpe(it):
+    #Iterate
+    cdef double _tta
+    cdef double _ttb
+    cdef double _uta
+    cdef double _utb
+    cdef double _dpsi
+    cdef double _deps
+    cdef double _xp
+    cdef double _yp
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tta = (<double *>(dataptrarray[0]))[0]
+        _ttb = (<double *>(dataptrarray[1]))[0]
+        _uta = (<double *>(dataptrarray[2]))[0]
+        _utb = (<double *>(dataptrarray[3]))[0]
+        _dpsi = (<double *>(dataptrarray[4]))[0]
+        _deps = (<double *>(dataptrarray[5]))[0]
+        _xp = (<double *>(dataptrarray[6]))[0]
+        _yp = (<double *>(dataptrarray[7]))[0]
+        _rc2t = (<double *>(dataptrarray[8]))
+        eraC2tpe(_tta, _ttb, _uta, _utb, _dpsi, _deps, _xp, _yp, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _c2txy(it):
+    #Iterate
+    cdef double _tta
+    cdef double _ttb
+    cdef double _uta
+    cdef double _utb
+    cdef double _x
+    cdef double _y
+    cdef double _xp
+    cdef double _yp
+    cdef double * _rc2t
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tta = (<double *>(dataptrarray[0]))[0]
+        _ttb = (<double *>(dataptrarray[1]))[0]
+        _uta = (<double *>(dataptrarray[2]))[0]
+        _utb = (<double *>(dataptrarray[3]))[0]
+        _x = (<double *>(dataptrarray[4]))[0]
+        _y = (<double *>(dataptrarray[5]))[0]
+        _xp = (<double *>(dataptrarray[6]))[0]
+        _yp = (<double *>(dataptrarray[7]))[0]
+        _rc2t = (<double *>(dataptrarray[8]))
+        eraC2txy(_tta, _ttb, _uta, _utb, _x, _y, _xp, _yp, _rc2t)
+        status = iternext(GetNpyIter(it))
+
+
+def _eo06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEo06a(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _eors(it):
+    #Iterate
+    cdef double * _rnpb
+    cdef double _s
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rnpb = (<double *>(dataptrarray[0]))
+        _s = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEors(_rnpb, _s)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _fw2m(it):
+    #Iterate
+    cdef double _gamb
+    cdef double _phib
+    cdef double _psi
+    cdef double _eps
+    cdef double * _r
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _gamb = (<double *>(dataptrarray[0]))[0]
+        _phib = (<double *>(dataptrarray[1]))[0]
+        _psi = (<double *>(dataptrarray[2]))[0]
+        _eps = (<double *>(dataptrarray[3]))[0]
+        _r = (<double *>(dataptrarray[4]))
+        eraFw2m(_gamb, _phib, _psi, _eps, _r)
+        status = iternext(GetNpyIter(it))
+
+
+def _fw2xy(it):
+    #Iterate
+    cdef double _gamb
+    cdef double _phib
+    cdef double _psi
+    cdef double _eps
+    cdef double * _x
+    cdef double * _y
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _gamb = (<double *>(dataptrarray[0]))[0]
+        _phib = (<double *>(dataptrarray[1]))[0]
+        _psi = (<double *>(dataptrarray[2]))[0]
+        _eps = (<double *>(dataptrarray[3]))[0]
+        _x = (<double *>(dataptrarray[4]))
+        _y = (<double *>(dataptrarray[5]))
+        eraFw2xy(_gamb, _phib, _psi, _eps, _x, _y)
+        status = iternext(GetNpyIter(it))
+
+
+def _num00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatn = (<double *>(dataptrarray[2]))
+        eraNum00a(_date1, _date2, _rmatn)
+        status = iternext(GetNpyIter(it))
+
+
+def _num00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatn = (<double *>(dataptrarray[2]))
+        eraNum00b(_date1, _date2, _rmatn)
+        status = iternext(GetNpyIter(it))
+
+
+def _num06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatn = (<double *>(dataptrarray[2]))
+        eraNum06a(_date1, _date2, _rmatn)
+        status = iternext(GetNpyIter(it))
+
+
+def _numat(it):
+    #Iterate
+    cdef double _epsa
+    cdef double _dpsi
+    cdef double _deps
+    cdef double * _rmatn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _epsa = (<double *>(dataptrarray[0]))[0]
+        _dpsi = (<double *>(dataptrarray[1]))[0]
+        _deps = (<double *>(dataptrarray[2]))[0]
+        _rmatn = (<double *>(dataptrarray[3]))
+        eraNumat(_epsa, _dpsi, _deps, _rmatn)
+        status = iternext(GetNpyIter(it))
+
+
+def _nut00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        eraNut00a(_date1, _date2, _dpsi, _deps)
+        status = iternext(GetNpyIter(it))
+
+
+def _nut00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        eraNut00b(_date1, _date2, _dpsi, _deps)
+        status = iternext(GetNpyIter(it))
+
+
+def _nut06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        eraNut06a(_date1, _date2, _dpsi, _deps)
+        status = iternext(GetNpyIter(it))
+
+
+def _nut80(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        eraNut80(_date1, _date2, _dpsi, _deps)
+        status = iternext(GetNpyIter(it))
+
+
+def _nutm80(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatn = (<double *>(dataptrarray[2]))
+        eraNutm80(_date1, _date2, _rmatn)
+        status = iternext(GetNpyIter(it))
+
+
+def _obl06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraObl06(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _obl80(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraObl80(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _p06e(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _eps0
+    cdef double * _psia
+    cdef double * _oma
+    cdef double * _bpa
+    cdef double * _bqa
+    cdef double * _pia
+    cdef double * _bpia
+    cdef double * _epsa
+    cdef double * _chia
+    cdef double * _za
+    cdef double * _zetaa
+    cdef double * _thetaa
+    cdef double * _pa
+    cdef double * _gam
+    cdef double * _phi
+    cdef double * _psi
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _eps0 = (<double *>(dataptrarray[2]))
+        _psia = (<double *>(dataptrarray[3]))
+        _oma = (<double *>(dataptrarray[4]))
+        _bpa = (<double *>(dataptrarray[5]))
+        _bqa = (<double *>(dataptrarray[6]))
+        _pia = (<double *>(dataptrarray[7]))
+        _bpia = (<double *>(dataptrarray[8]))
+        _epsa = (<double *>(dataptrarray[9]))
+        _chia = (<double *>(dataptrarray[10]))
+        _za = (<double *>(dataptrarray[11]))
+        _zetaa = (<double *>(dataptrarray[12]))
+        _thetaa = (<double *>(dataptrarray[13]))
+        _pa = (<double *>(dataptrarray[14]))
+        _gam = (<double *>(dataptrarray[15]))
+        _phi = (<double *>(dataptrarray[16]))
+        _psi = (<double *>(dataptrarray[17]))
+        eraP06e(_date1, _date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi)
+        status = iternext(GetNpyIter(it))
+
+
+def _pb06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _bzeta
+    cdef double * _bz
+    cdef double * _btheta
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _bzeta = (<double *>(dataptrarray[2]))
+        _bz = (<double *>(dataptrarray[3]))
+        _btheta = (<double *>(dataptrarray[4]))
+        eraPb06(_date1, _date2, _bzeta, _bz, _btheta)
+        status = iternext(GetNpyIter(it))
+
+
+def _pfw06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _gamb
+    cdef double * _phib
+    cdef double * _psib
+    cdef double * _epsa
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _gamb = (<double *>(dataptrarray[2]))
+        _phib = (<double *>(dataptrarray[3]))
+        _psib = (<double *>(dataptrarray[4]))
+        _epsa = (<double *>(dataptrarray[5]))
+        eraPfw06(_date1, _date2, _gamb, _phib, _psib, _epsa)
+        status = iternext(GetNpyIter(it))
+
+
+def _pmat00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rbp
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rbp = (<double *>(dataptrarray[2]))
+        eraPmat00(_date1, _date2, _rbp)
+        status = iternext(GetNpyIter(it))
+
+
+def _pmat06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rbp
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rbp = (<double *>(dataptrarray[2]))
+        eraPmat06(_date1, _date2, _rbp)
+        status = iternext(GetNpyIter(it))
+
+
+def _pmat76(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatp
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatp = (<double *>(dataptrarray[2]))
+        eraPmat76(_date1, _date2, _rmatp)
+        status = iternext(GetNpyIter(it))
+
+
+def _pn00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _dpsi
+    cdef double _deps
+    cdef double * _epsa
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef double * _rn
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))[0]
+        _deps = (<double *>(dataptrarray[3]))[0]
+        _epsa = (<double *>(dataptrarray[4]))
+        _rb = (<double *>(dataptrarray[5]))
+        _rp = (<double *>(dataptrarray[6]))
+        _rbp = (<double *>(dataptrarray[7]))
+        _rn = (<double *>(dataptrarray[8]))
+        _rbpn = (<double *>(dataptrarray[9]))
+        eraPn00(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pn00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef double * _epsa
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef double * _rn
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        _epsa = (<double *>(dataptrarray[4]))
+        _rb = (<double *>(dataptrarray[5]))
+        _rp = (<double *>(dataptrarray[6]))
+        _rbp = (<double *>(dataptrarray[7]))
+        _rn = (<double *>(dataptrarray[8]))
+        _rbpn = (<double *>(dataptrarray[9]))
+        eraPn00a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pn00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef double * _epsa
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef double * _rn
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        _epsa = (<double *>(dataptrarray[4]))
+        _rb = (<double *>(dataptrarray[5]))
+        _rp = (<double *>(dataptrarray[6]))
+        _rbp = (<double *>(dataptrarray[7]))
+        _rn = (<double *>(dataptrarray[8]))
+        _rbpn = (<double *>(dataptrarray[9]))
+        eraPn00b(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pn06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _dpsi
+    cdef double _deps
+    cdef double * _epsa
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef double * _rn
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))[0]
+        _deps = (<double *>(dataptrarray[3]))[0]
+        _epsa = (<double *>(dataptrarray[4]))
+        _rb = (<double *>(dataptrarray[5]))
+        _rp = (<double *>(dataptrarray[6]))
+        _rbp = (<double *>(dataptrarray[7]))
+        _rn = (<double *>(dataptrarray[8]))
+        _rbpn = (<double *>(dataptrarray[9]))
+        eraPn06(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pn06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsi
+    cdef double * _deps
+    cdef double * _epsa
+    cdef double * _rb
+    cdef double * _rp
+    cdef double * _rbp
+    cdef double * _rn
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsi = (<double *>(dataptrarray[2]))
+        _deps = (<double *>(dataptrarray[3]))
+        _epsa = (<double *>(dataptrarray[4]))
+        _rb = (<double *>(dataptrarray[5]))
+        _rp = (<double *>(dataptrarray[6]))
+        _rbp = (<double *>(dataptrarray[7]))
+        _rn = (<double *>(dataptrarray[8]))
+        _rbpn = (<double *>(dataptrarray[9]))
+        eraPn06a(_date1, _date2, _dpsi, _deps, _epsa, _rb, _rp, _rbp, _rn, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pnm00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rbpn = (<double *>(dataptrarray[2]))
+        eraPnm00a(_date1, _date2, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pnm00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rbpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rbpn = (<double *>(dataptrarray[2]))
+        eraPnm00b(_date1, _date2, _rbpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pnm06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rnpb
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rnpb = (<double *>(dataptrarray[2]))
+        eraPnm06a(_date1, _date2, _rnpb)
+        status = iternext(GetNpyIter(it))
+
+
+def _pnm80(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rmatpn
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _rmatpn = (<double *>(dataptrarray[2]))
+        eraPnm80(_date1, _date2, _rmatpn)
+        status = iternext(GetNpyIter(it))
+
+
+def _pom00(it):
+    #Iterate
+    cdef double _xp
+    cdef double _yp
+    cdef double _sp
+    cdef double * _rpom
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _xp = (<double *>(dataptrarray[0]))[0]
+        _yp = (<double *>(dataptrarray[1]))[0]
+        _sp = (<double *>(dataptrarray[2]))[0]
+        _rpom = (<double *>(dataptrarray[3]))
+        eraPom00(_xp, _yp, _sp, _rpom)
+        status = iternext(GetNpyIter(it))
+
+
+def _pr00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _dpsipr
+    cdef double * _depspr
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _dpsipr = (<double *>(dataptrarray[2]))
+        _depspr = (<double *>(dataptrarray[3]))
+        eraPr00(_date1, _date2, _dpsipr, _depspr)
+        status = iternext(GetNpyIter(it))
+
+
+def _prec76(it):
+    #Iterate
+    cdef double _date01
+    cdef double _date02
+    cdef double _date11
+    cdef double _date12
+    cdef double * _zeta
+    cdef double * _z
+    cdef double * _theta
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date01 = (<double *>(dataptrarray[0]))[0]
+        _date02 = (<double *>(dataptrarray[1]))[0]
+        _date11 = (<double *>(dataptrarray[2]))[0]
+        _date12 = (<double *>(dataptrarray[3]))[0]
+        _zeta = (<double *>(dataptrarray[4]))
+        _z = (<double *>(dataptrarray[5]))
+        _theta = (<double *>(dataptrarray[6]))
+        eraPrec76(_date01, _date02, _date11, _date12, _zeta, _z, _theta)
+        status = iternext(GetNpyIter(it))
+
+
+def _s00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _x
+    cdef double _y
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))[0]
+        _y = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraS00(_date1, _date2, _x, _y)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _s00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraS00a(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _s00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraS00b(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _s06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _x
+    cdef double _y
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))[0]
+        _y = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraS06(_date1, _date2, _x, _y)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _s06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraS06a(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _sp00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraSp00(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _xy06(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _x
+    cdef double * _y
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))
+        _y = (<double *>(dataptrarray[3]))
+        eraXy06(_date1, _date2, _x, _y)
+        status = iternext(GetNpyIter(it))
+
+
+def _xys00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _x
+    cdef double * _y
+    cdef double * _s
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))
+        _y = (<double *>(dataptrarray[3]))
+        _s = (<double *>(dataptrarray[4]))
+        eraXys00a(_date1, _date2, _x, _y, _s)
+        status = iternext(GetNpyIter(it))
+
+
+def _xys00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _x
+    cdef double * _y
+    cdef double * _s
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))
+        _y = (<double *>(dataptrarray[3]))
+        _s = (<double *>(dataptrarray[4]))
+        eraXys00b(_date1, _date2, _x, _y, _s)
+        status = iternext(GetNpyIter(it))
+
+
+def _xys06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double * _x
+    cdef double * _y
+    cdef double * _s
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _x = (<double *>(dataptrarray[2]))
+        _y = (<double *>(dataptrarray[3]))
+        _s = (<double *>(dataptrarray[4]))
+        eraXys06a(_date1, _date2, _x, _y, _s)
+        status = iternext(GetNpyIter(it))
+
+
+def _ee00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _epsa
+    cdef double _dpsi
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _epsa = (<double *>(dataptrarray[2]))[0]
+        _dpsi = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraEe00(_date1, _date2, _epsa, _dpsi)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _ee00a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEe00a(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _ee00b(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEe00b(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _ee06a(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEe06a(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _eect00(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEect00(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _eqeq94(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEqeq94(_date1, _date2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _era00(it):
+    #Iterate
+    cdef double _dj1
+    cdef double _dj2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dj1 = (<double *>(dataptrarray[0]))[0]
+        _dj2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraEra00(_dj1, _dj2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gmst00(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _tta
+    cdef double _ttb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _tta = (<double *>(dataptrarray[2]))[0]
+        _ttb = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraGmst00(_uta, _utb, _tta, _ttb)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gmst06(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _tta
+    cdef double _ttb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _tta = (<double *>(dataptrarray[2]))[0]
+        _ttb = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraGmst06(_uta, _utb, _tta, _ttb)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gmst82(it):
+    #Iterate
+    cdef double _dj1
+    cdef double _dj2
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _dj1 = (<double *>(dataptrarray[0]))[0]
+        _dj2 = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraGmst82(_dj1, _dj2)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gst00a(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _tta
+    cdef double _ttb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _tta = (<double *>(dataptrarray[2]))[0]
+        _ttb = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraGst00a(_uta, _utb, _tta, _ttb)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gst00b(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraGst00b(_uta, _utb)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gst06(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _tta
+    cdef double _ttb
+    cdef double * _rnpb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _tta = (<double *>(dataptrarray[2]))[0]
+        _ttb = (<double *>(dataptrarray[3]))[0]
+        _rnpb = (<double *>(dataptrarray[4]))
+        _c_retval = eraGst06(_uta, _utb, _tta, _ttb, _rnpb)
+        (<double *>(dataptrarray[5]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gst06a(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _tta
+    cdef double _ttb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _tta = (<double *>(dataptrarray[2]))[0]
+        _ttb = (<double *>(dataptrarray[3]))[0]
+        _c_retval = eraGst06a(_uta, _utb, _tta, _ttb)
+        (<double *>(dataptrarray[4]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _gst94(it):
+    #Iterate
+    cdef double _uta
+    cdef double _utb
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _uta = (<double *>(dataptrarray[0]))[0]
+        _utb = (<double *>(dataptrarray[1]))[0]
+        _c_retval = eraGst94(_uta, _utb)
+        (<double *>(dataptrarray[2]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _pmsafe(it):
+    #Iterate
+    cdef double _ra1
+    cdef double _dec1
+    cdef double _pmr1
+    cdef double _pmd1
+    cdef double _px1
+    cdef double _rv1
+    cdef double _ep1a
+    cdef double _ep1b
+    cdef double _ep2a
+    cdef double _ep2b
+    cdef double * _ra2
+    cdef double * _dec2
+    cdef double * _pmr2
+    cdef double * _pmd2
+    cdef double * _px2
+    cdef double * _rv2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ra1 = (<double *>(dataptrarray[0]))[0]
+        _dec1 = (<double *>(dataptrarray[1]))[0]
+        _pmr1 = (<double *>(dataptrarray[2]))[0]
+        _pmd1 = (<double *>(dataptrarray[3]))[0]
+        _px1 = (<double *>(dataptrarray[4]))[0]
+        _rv1 = (<double *>(dataptrarray[5]))[0]
+        _ep1a = (<double *>(dataptrarray[6]))[0]
+        _ep1b = (<double *>(dataptrarray[7]))[0]
+        _ep2a = (<double *>(dataptrarray[8]))[0]
+        _ep2b = (<double *>(dataptrarray[9]))[0]
+        _ra2 = (<double *>(dataptrarray[10]))
+        _dec2 = (<double *>(dataptrarray[11]))
+        _pmr2 = (<double *>(dataptrarray[12]))
+        _pmd2 = (<double *>(dataptrarray[13]))
+        _px2 = (<double *>(dataptrarray[14]))
+        _rv2 = (<double *>(dataptrarray[15]))
+        _c_retval = eraPmsafe(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+        (<int *>(dataptrarray[16]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _pvstar(it):
+    #Iterate
+    cdef double * _pv
+    cdef double * _ra
+    cdef double * _dec
+    cdef double * _pmr
+    cdef double * _pmd
+    cdef double * _px
+    cdef double * _rv
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _pv = (<double *>(dataptrarray[0]))
+        _ra = (<double *>(dataptrarray[1]))
+        _dec = (<double *>(dataptrarray[2]))
+        _pmr = (<double *>(dataptrarray[3]))
+        _pmd = (<double *>(dataptrarray[4]))
+        _px = (<double *>(dataptrarray[5]))
+        _rv = (<double *>(dataptrarray[6]))
+        _c_retval = eraPvstar(_pv, _ra, _dec, _pmr, _pmd, _px, _rv)
+        (<int *>(dataptrarray[7]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _starpv(it):
+    #Iterate
+    cdef double _ra
+    cdef double _dec
+    cdef double _pmr
+    cdef double _pmd
+    cdef double _px
+    cdef double _rv
+    cdef double * _pv
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ra = (<double *>(dataptrarray[0]))[0]
+        _dec = (<double *>(dataptrarray[1]))[0]
+        _pmr = (<double *>(dataptrarray[2]))[0]
+        _pmd = (<double *>(dataptrarray[3]))[0]
+        _px = (<double *>(dataptrarray[4]))[0]
+        _rv = (<double *>(dataptrarray[5]))[0]
+        _pv = (<double *>(dataptrarray[6]))
+        _c_retval = eraStarpv(_ra, _dec, _pmr, _pmd, _px, _rv, _pv)
+        (<int *>(dataptrarray[7]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _fk52h(it):
+    #Iterate
+    cdef double _r5
+    cdef double _d5
+    cdef double _dr5
+    cdef double _dd5
+    cdef double _px5
+    cdef double _rv5
+    cdef double * _rh
+    cdef double * _dh
+    cdef double * _drh
+    cdef double * _ddh
+    cdef double * _pxh
+    cdef double * _rvh
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _r5 = (<double *>(dataptrarray[0]))[0]
+        _d5 = (<double *>(dataptrarray[1]))[0]
+        _dr5 = (<double *>(dataptrarray[2]))[0]
+        _dd5 = (<double *>(dataptrarray[3]))[0]
+        _px5 = (<double *>(dataptrarray[4]))[0]
+        _rv5 = (<double *>(dataptrarray[5]))[0]
+        _rh = (<double *>(dataptrarray[6]))
+        _dh = (<double *>(dataptrarray[7]))
+        _drh = (<double *>(dataptrarray[8]))
+        _ddh = (<double *>(dataptrarray[9]))
+        _pxh = (<double *>(dataptrarray[10]))
+        _rvh = (<double *>(dataptrarray[11]))
+        eraFk52h(_r5, _d5, _dr5, _dd5, _px5, _rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh)
+        status = iternext(GetNpyIter(it))
+
+
+def _fk5hip(it):
+    #Iterate
+    cdef double * _r5h
+    cdef double * _s5h
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _r5h = (<double *>(dataptrarray[0]))
+        _s5h = (<double *>(dataptrarray[1]))
+        eraFk5hip(_r5h, _s5h)
+        status = iternext(GetNpyIter(it))
+
+
+def _fk5hz(it):
+    #Iterate
+    cdef double _r5
+    cdef double _d5
+    cdef double _date1
+    cdef double _date2
+    cdef double * _rh
+    cdef double * _dh
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _r5 = (<double *>(dataptrarray[0]))[0]
+        _d5 = (<double *>(dataptrarray[1]))[0]
+        _date1 = (<double *>(dataptrarray[2]))[0]
+        _date2 = (<double *>(dataptrarray[3]))[0]
+        _rh = (<double *>(dataptrarray[4]))
+        _dh = (<double *>(dataptrarray[5]))
+        eraFk5hz(_r5, _d5, _date1, _date2, _rh, _dh)
+        status = iternext(GetNpyIter(it))
+
+
+def _h2fk5(it):
+    #Iterate
+    cdef double _rh
+    cdef double _dh
+    cdef double _drh
+    cdef double _ddh
+    cdef double _pxh
+    cdef double _rvh
+    cdef double * _r5
+    cdef double * _d5
+    cdef double * _dr5
+    cdef double * _dd5
+    cdef double * _px5
+    cdef double * _rv5
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rh = (<double *>(dataptrarray[0]))[0]
+        _dh = (<double *>(dataptrarray[1]))[0]
+        _drh = (<double *>(dataptrarray[2]))[0]
+        _ddh = (<double *>(dataptrarray[3]))[0]
+        _pxh = (<double *>(dataptrarray[4]))[0]
+        _rvh = (<double *>(dataptrarray[5]))[0]
+        _r5 = (<double *>(dataptrarray[6]))
+        _d5 = (<double *>(dataptrarray[7]))
+        _dr5 = (<double *>(dataptrarray[8]))
+        _dd5 = (<double *>(dataptrarray[9]))
+        _px5 = (<double *>(dataptrarray[10]))
+        _rv5 = (<double *>(dataptrarray[11]))
+        eraH2fk5(_rh, _dh, _drh, _ddh, _pxh, _rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5)
+        status = iternext(GetNpyIter(it))
+
+
+def _hfk5z(it):
+    #Iterate
+    cdef double _rh
+    cdef double _dh
+    cdef double _date1
+    cdef double _date2
+    cdef double * _r5
+    cdef double * _d5
+    cdef double * _dr5
+    cdef double * _dd5
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _rh = (<double *>(dataptrarray[0]))[0]
+        _dh = (<double *>(dataptrarray[1]))[0]
+        _date1 = (<double *>(dataptrarray[2]))[0]
+        _date2 = (<double *>(dataptrarray[3]))[0]
+        _r5 = (<double *>(dataptrarray[4]))
+        _d5 = (<double *>(dataptrarray[5]))
+        _dr5 = (<double *>(dataptrarray[6]))
+        _dd5 = (<double *>(dataptrarray[7]))
+        eraHfk5z(_rh, _dh, _date1, _date2, _r5, _d5, _dr5, _dd5)
+        status = iternext(GetNpyIter(it))
+
+
+def _starpm(it):
+    #Iterate
+    cdef double _ra1
+    cdef double _dec1
+    cdef double _pmr1
+    cdef double _pmd1
+    cdef double _px1
+    cdef double _rv1
+    cdef double _ep1a
+    cdef double _ep1b
+    cdef double _ep2a
+    cdef double _ep2b
+    cdef double * _ra2
+    cdef double * _dec2
+    cdef double * _pmr2
+    cdef double * _pmd2
+    cdef double * _px2
+    cdef double * _rv2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ra1 = (<double *>(dataptrarray[0]))[0]
+        _dec1 = (<double *>(dataptrarray[1]))[0]
+        _pmr1 = (<double *>(dataptrarray[2]))[0]
+        _pmd1 = (<double *>(dataptrarray[3]))[0]
+        _px1 = (<double *>(dataptrarray[4]))[0]
+        _rv1 = (<double *>(dataptrarray[5]))[0]
+        _ep1a = (<double *>(dataptrarray[6]))[0]
+        _ep1b = (<double *>(dataptrarray[7]))[0]
+        _ep2a = (<double *>(dataptrarray[8]))[0]
+        _ep2b = (<double *>(dataptrarray[9]))[0]
+        _ra2 = (<double *>(dataptrarray[10]))
+        _dec2 = (<double *>(dataptrarray[11]))
+        _pmr2 = (<double *>(dataptrarray[12]))
+        _pmd2 = (<double *>(dataptrarray[13]))
+        _px2 = (<double *>(dataptrarray[14]))
+        _rv2 = (<double *>(dataptrarray[15]))
+        _c_retval = eraStarpm(_ra1, _dec1, _pmr1, _pmd1, _px1, _rv1, _ep1a, _ep1b, _ep2a, _ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2)
+        (<int *>(dataptrarray[16]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _eform(it):
+    #Iterate
+    cdef int _n
+    cdef double * _a
+    cdef double * _f
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _n = (<int *>(dataptrarray[0]))[0]
+        _a = (<double *>(dataptrarray[1]))
+        _f = (<double *>(dataptrarray[2]))
+        _c_retval = eraEform(_n, _a, _f)
+        (<int *>(dataptrarray[3]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _gc2gd(it):
+    #Iterate
+    cdef int _n
+    cdef double * _xyz
+    cdef double * _elong
+    cdef double * _phi
+    cdef double * _height
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _n = (<int *>(dataptrarray[0]))[0]
+        _xyz = (<double *>(dataptrarray[1]))
+        _elong = (<double *>(dataptrarray[2]))
+        _phi = (<double *>(dataptrarray[3]))
+        _height = (<double *>(dataptrarray[4]))
+        _c_retval = eraGc2gd(_n, _xyz, _elong, _phi, _height)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _gc2gde(it):
+    #Iterate
+    cdef double _a
+    cdef double _f
+    cdef double * _xyz
+    cdef double * _elong
+    cdef double * _phi
+    cdef double * _height
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _a = (<double *>(dataptrarray[0]))[0]
+        _f = (<double *>(dataptrarray[1]))[0]
+        _xyz = (<double *>(dataptrarray[2]))
+        _elong = (<double *>(dataptrarray[3]))
+        _phi = (<double *>(dataptrarray[4]))
+        _height = (<double *>(dataptrarray[5]))
+        _c_retval = eraGc2gde(_a, _f, _xyz, _elong, _phi, _height)
+        (<int *>(dataptrarray[6]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _gd2gc(it):
+    #Iterate
+    cdef int _n
+    cdef double _elong
+    cdef double _phi
+    cdef double _height
+    cdef double * _xyz
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _n = (<int *>(dataptrarray[0]))[0]
+        _elong = (<double *>(dataptrarray[1]))[0]
+        _phi = (<double *>(dataptrarray[2]))[0]
+        _height = (<double *>(dataptrarray[3]))[0]
+        _xyz = (<double *>(dataptrarray[4]))
+        _c_retval = eraGd2gc(_n, _elong, _phi, _height, _xyz)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _gd2gce(it):
+    #Iterate
+    cdef double _a
+    cdef double _f
+    cdef double _elong
+    cdef double _phi
+    cdef double _height
+    cdef double * _xyz
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _a = (<double *>(dataptrarray[0]))[0]
+        _f = (<double *>(dataptrarray[1]))[0]
+        _elong = (<double *>(dataptrarray[2]))[0]
+        _phi = (<double *>(dataptrarray[3]))[0]
+        _height = (<double *>(dataptrarray[4]))[0]
+        _xyz = (<double *>(dataptrarray[5]))
+        _c_retval = eraGd2gce(_a, _f, _elong, _phi, _height, _xyz)
+        (<int *>(dataptrarray[6]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _pvtob(it):
+    #Iterate
+    cdef double _elong
+    cdef double _phi
+    cdef double _hm
+    cdef double _xp
+    cdef double _yp
+    cdef double _sp
+    cdef double _theta
+    cdef double * _pv
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _elong = (<double *>(dataptrarray[0]))[0]
+        _phi = (<double *>(dataptrarray[1]))[0]
+        _hm = (<double *>(dataptrarray[2]))[0]
+        _xp = (<double *>(dataptrarray[3]))[0]
+        _yp = (<double *>(dataptrarray[4]))[0]
+        _sp = (<double *>(dataptrarray[5]))[0]
+        _theta = (<double *>(dataptrarray[6]))[0]
+        _pv = (<double *>(dataptrarray[7]))
+        eraPvtob(_elong, _phi, _hm, _xp, _yp, _sp, _theta, _pv)
+        status = iternext(GetNpyIter(it))
+
+
+def _d2dtf(it):
+    #Iterate
+    cdef const char * _scale
+    cdef int _ndp
+    cdef double _d1
+    cdef double _d2
+    cdef int * _iy
+    cdef int * _im
+    cdef int * _id
+    cdef int * _ihmsf
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _scale = (<const char *>(dataptrarray[0]))
+        _ndp = (<int *>(dataptrarray[1]))[0]
+        _d1 = (<double *>(dataptrarray[2]))[0]
+        _d2 = (<double *>(dataptrarray[3]))[0]
+        _iy = (<int *>(dataptrarray[4]))
+        _im = (<int *>(dataptrarray[5]))
+        _id = (<int *>(dataptrarray[6]))
+        _ihmsf = (<int *>(dataptrarray[7]))
+        _c_retval = eraD2dtf(_scale, _ndp, _d1, _d2, _iy, _im, _id, _ihmsf)
+        (<int *>(dataptrarray[8]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _dat(it):
+    #Iterate
+    cdef int _iy
+    cdef int _im
+    cdef int _id
+    cdef double _fd
+    cdef double * _deltat
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _iy = (<int *>(dataptrarray[0]))[0]
+        _im = (<int *>(dataptrarray[1]))[0]
+        _id = (<int *>(dataptrarray[2]))[0]
+        _fd = (<double *>(dataptrarray[3]))[0]
+        _deltat = (<double *>(dataptrarray[4]))
+        _c_retval = eraDat(_iy, _im, _id, _fd, _deltat)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _dtdb(it):
+    #Iterate
+    cdef double _date1
+    cdef double _date2
+    cdef double _ut
+    cdef double _elong
+    cdef double _u
+    cdef double _v
+    cdef double _c_retval
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _date1 = (<double *>(dataptrarray[0]))[0]
+        _date2 = (<double *>(dataptrarray[1]))[0]
+        _ut = (<double *>(dataptrarray[2]))[0]
+        _elong = (<double *>(dataptrarray[3]))[0]
+        _u = (<double *>(dataptrarray[4]))[0]
+        _v = (<double *>(dataptrarray[5]))[0]
+        _c_retval = eraDtdb(_date1, _date2, _ut, _elong, _u, _v)
+        (<double *>(dataptrarray[6]))[0] = _c_retval
+        status = iternext(GetNpyIter(it))
+
+
+def _dtf2d(it):
+    #Iterate
+    cdef const char * _scale
+    cdef int _iy
+    cdef int _im
+    cdef int _id
+    cdef int _ihr
+    cdef int _imn
+    cdef double _sec
+    cdef double * _d1
+    cdef double * _d2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _scale = (<const char *>(dataptrarray[0]))
+        _iy = (<int *>(dataptrarray[1]))[0]
+        _im = (<int *>(dataptrarray[2]))[0]
+        _id = (<int *>(dataptrarray[3]))[0]
+        _ihr = (<int *>(dataptrarray[4]))[0]
+        _imn = (<int *>(dataptrarray[5]))[0]
+        _sec = (<double *>(dataptrarray[6]))[0]
+        _d1 = (<double *>(dataptrarray[7]))
+        _d2 = (<double *>(dataptrarray[8]))
+        _c_retval = eraDtf2d(_scale, _iy, _im, _id, _ihr, _imn, _sec, _d1, _d2)
+        (<int *>(dataptrarray[9]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _taitt(it):
+    #Iterate
+    cdef double _tai1
+    cdef double _tai2
+    cdef double * _tt1
+    cdef double * _tt2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tai1 = (<double *>(dataptrarray[0]))[0]
+        _tai2 = (<double *>(dataptrarray[1]))[0]
+        _tt1 = (<double *>(dataptrarray[2]))
+        _tt2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTaitt(_tai1, _tai2, _tt1, _tt2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _taiut1(it):
+    #Iterate
+    cdef double _tai1
+    cdef double _tai2
+    cdef double _dta
+    cdef double * _ut11
+    cdef double * _ut12
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tai1 = (<double *>(dataptrarray[0]))[0]
+        _tai2 = (<double *>(dataptrarray[1]))[0]
+        _dta = (<double *>(dataptrarray[2]))[0]
+        _ut11 = (<double *>(dataptrarray[3]))
+        _ut12 = (<double *>(dataptrarray[4]))
+        _c_retval = eraTaiut1(_tai1, _tai2, _dta, _ut11, _ut12)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _taiutc(it):
+    #Iterate
+    cdef double _tai1
+    cdef double _tai2
+    cdef double * _utc1
+    cdef double * _utc2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tai1 = (<double *>(dataptrarray[0]))[0]
+        _tai2 = (<double *>(dataptrarray[1]))[0]
+        _utc1 = (<double *>(dataptrarray[2]))
+        _utc2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTaiutc(_tai1, _tai2, _utc1, _utc2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tcbtdb(it):
+    #Iterate
+    cdef double _tcb1
+    cdef double _tcb2
+    cdef double * _tdb1
+    cdef double * _tdb2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tcb1 = (<double *>(dataptrarray[0]))[0]
+        _tcb2 = (<double *>(dataptrarray[1]))[0]
+        _tdb1 = (<double *>(dataptrarray[2]))
+        _tdb2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTcbtdb(_tcb1, _tcb2, _tdb1, _tdb2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tcgtt(it):
+    #Iterate
+    cdef double _tcg1
+    cdef double _tcg2
+    cdef double * _tt1
+    cdef double * _tt2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tcg1 = (<double *>(dataptrarray[0]))[0]
+        _tcg2 = (<double *>(dataptrarray[1]))[0]
+        _tt1 = (<double *>(dataptrarray[2]))
+        _tt2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTcgtt(_tcg1, _tcg2, _tt1, _tt2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tdbtcb(it):
+    #Iterate
+    cdef double _tdb1
+    cdef double _tdb2
+    cdef double * _tcb1
+    cdef double * _tcb2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tdb1 = (<double *>(dataptrarray[0]))[0]
+        _tdb2 = (<double *>(dataptrarray[1]))[0]
+        _tcb1 = (<double *>(dataptrarray[2]))
+        _tcb2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTdbtcb(_tdb1, _tdb2, _tcb1, _tcb2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tdbtt(it):
+    #Iterate
+    cdef double _tdb1
+    cdef double _tdb2
+    cdef double _dtr
+    cdef double * _tt1
+    cdef double * _tt2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tdb1 = (<double *>(dataptrarray[0]))[0]
+        _tdb2 = (<double *>(dataptrarray[1]))[0]
+        _dtr = (<double *>(dataptrarray[2]))[0]
+        _tt1 = (<double *>(dataptrarray[3]))
+        _tt2 = (<double *>(dataptrarray[4]))
+        _c_retval = eraTdbtt(_tdb1, _tdb2, _dtr, _tt1, _tt2)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tttai(it):
+    #Iterate
+    cdef double _tt1
+    cdef double _tt2
+    cdef double * _tai1
+    cdef double * _tai2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tt1 = (<double *>(dataptrarray[0]))[0]
+        _tt2 = (<double *>(dataptrarray[1]))[0]
+        _tai1 = (<double *>(dataptrarray[2]))
+        _tai2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTttai(_tt1, _tt2, _tai1, _tai2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tttcg(it):
+    #Iterate
+    cdef double _tt1
+    cdef double _tt2
+    cdef double * _tcg1
+    cdef double * _tcg2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tt1 = (<double *>(dataptrarray[0]))[0]
+        _tt2 = (<double *>(dataptrarray[1]))[0]
+        _tcg1 = (<double *>(dataptrarray[2]))
+        _tcg2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraTttcg(_tt1, _tt2, _tcg1, _tcg2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _tttdb(it):
+    #Iterate
+    cdef double _tt1
+    cdef double _tt2
+    cdef double _dtr
+    cdef double * _tdb1
+    cdef double * _tdb2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tt1 = (<double *>(dataptrarray[0]))[0]
+        _tt2 = (<double *>(dataptrarray[1]))[0]
+        _dtr = (<double *>(dataptrarray[2]))[0]
+        _tdb1 = (<double *>(dataptrarray[3]))
+        _tdb2 = (<double *>(dataptrarray[4]))
+        _c_retval = eraTttdb(_tt1, _tt2, _dtr, _tdb1, _tdb2)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _ttut1(it):
+    #Iterate
+    cdef double _tt1
+    cdef double _tt2
+    cdef double _dt
+    cdef double * _ut11
+    cdef double * _ut12
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _tt1 = (<double *>(dataptrarray[0]))[0]
+        _tt2 = (<double *>(dataptrarray[1]))[0]
+        _dt = (<double *>(dataptrarray[2]))[0]
+        _ut11 = (<double *>(dataptrarray[3]))
+        _ut12 = (<double *>(dataptrarray[4]))
+        _c_retval = eraTtut1(_tt1, _tt2, _dt, _ut11, _ut12)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _ut1tai(it):
+    #Iterate
+    cdef double _ut11
+    cdef double _ut12
+    cdef double _dta
+    cdef double * _tai1
+    cdef double * _tai2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ut11 = (<double *>(dataptrarray[0]))[0]
+        _ut12 = (<double *>(dataptrarray[1]))[0]
+        _dta = (<double *>(dataptrarray[2]))[0]
+        _tai1 = (<double *>(dataptrarray[3]))
+        _tai2 = (<double *>(dataptrarray[4]))
+        _c_retval = eraUt1tai(_ut11, _ut12, _dta, _tai1, _tai2)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _ut1tt(it):
+    #Iterate
+    cdef double _ut11
+    cdef double _ut12
+    cdef double _dt
+    cdef double * _tt1
+    cdef double * _tt2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ut11 = (<double *>(dataptrarray[0]))[0]
+        _ut12 = (<double *>(dataptrarray[1]))[0]
+        _dt = (<double *>(dataptrarray[2]))[0]
+        _tt1 = (<double *>(dataptrarray[3]))
+        _tt2 = (<double *>(dataptrarray[4]))
+        _c_retval = eraUt1tt(_ut11, _ut12, _dt, _tt1, _tt2)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _ut1utc(it):
+    #Iterate
+    cdef double _ut11
+    cdef double _ut12
+    cdef double _dut1
+    cdef double * _utc1
+    cdef double * _utc2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _ut11 = (<double *>(dataptrarray[0]))[0]
+        _ut12 = (<double *>(dataptrarray[1]))[0]
+        _dut1 = (<double *>(dataptrarray[2]))[0]
+        _utc1 = (<double *>(dataptrarray[3]))
+        _utc2 = (<double *>(dataptrarray[4]))
+        _c_retval = eraUt1utc(_ut11, _ut12, _dut1, _utc1, _utc2)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _utctai(it):
+    #Iterate
+    cdef double _utc1
+    cdef double _utc2
+    cdef double * _tai1
+    cdef double * _tai2
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _utc1 = (<double *>(dataptrarray[0]))[0]
+        _utc2 = (<double *>(dataptrarray[1]))[0]
+        _tai1 = (<double *>(dataptrarray[2]))
+        _tai2 = (<double *>(dataptrarray[3]))
+        _c_retval = eraUtctai(_utc1, _utc2, _tai1, _tai2)
+        (<int *>(dataptrarray[4]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
+
+def _utcut1(it):
+    #Iterate
+    cdef double _utc1
+    cdef double _utc2
+    cdef double _dut1
+    cdef double * _ut11
+    cdef double * _ut12
+    cdef int _c_retval
+    cdef bint stat_ok = True
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        _utc1 = (<double *>(dataptrarray[0]))[0]
+        _utc2 = (<double *>(dataptrarray[1]))[0]
+        _dut1 = (<double *>(dataptrarray[2]))[0]
+        _ut11 = (<double *>(dataptrarray[3]))
+        _ut12 = (<double *>(dataptrarray[4]))
+        _c_retval = eraUtcut1(_utc1, _utc2, _dut1, _ut11, _ut12)
+        (<int *>(dataptrarray[5]))[0] = _c_retval
+        if _c_retval != 0:
+            stat_ok = False
+        status = iternext(GetNpyIter(it))
+    return stat_ok
+
diff --git a/astropy/_erfa/core.pyx.templ b/astropy/_erfa/core.pyx.templ
new file mode 100644
index 0000000..76b87b1
--- /dev/null
+++ b/astropy/_erfa/core.pyx.templ
@@ -0,0 +1,91 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+# "core.pyx" is auto-generated by erfa_generator.py from the template
+# "core.pyx.templ". Do *not* edit "core.pyx" directly, instead edit
+# "core.pyx.templ" and run erfa_generator.py from the source directory to
+# update it.
+
+"""
+This module contains the Cython parts of the ERFA python wrappers.
+This is separated from the python code in ``core.py`` because putting it all in
+Cython results in very long compile times.  By having only the vectorized core
+in Cython, the compilation time is kept short without sacrificing much (if any)
+performance.
+
+For more about the module and how to use it, see the ``core.py`` docstrings.
+"""
+from __future__ import absolute_import, division, print_function
+
+import warnings
+from distutils.version import LooseVersion
+
+from ..utils.exceptions import AstropyUserWarning
+
+import numpy
+cimport numpy
+from cpython.ref cimport PyObject
+
+numpy.import_array()
+
+__all__ = [{{ funcs|map(attribute='pyname')|surround("'_","'")|join(", ") }}]
+
+#<-----------------------------NpyIter handling------------------------------->
+
+ctypedef void NpyIter
+ctypedef int (*IterNextFunc)(NpyIter * iter) nogil
+
+cdef extern from "numpy/arrayobject.h":
+    IterNextFunc GetIterNext "NpyIter_GetIterNext" (NpyIter *iter, char **)
+    char** GetDataPtrArray "NpyIter_GetDataPtrArray" (NpyIter* iter)
+
+ctypedef struct NewNpyArrayIterObject:
+    PyObject base
+    NpyIter *iter
+
+cdef inline NpyIter* GetNpyIter(object iter):
+    return (<NewNpyArrayIterObject*>iter).iter
+
+
+#<--------------------------Actual ERFA-wrapping code------------------------->
+
+cdef extern from "erfam.h":
+    struct eraASTROM:
+        pass
+    struct eraLDBODY:
+        pass
+
+cdef extern from "erfa.h":
+{%- for func in funcs %}
+    {{ func.ret }} {{ func.name }}({{ func.args_by_inout('in|inout|out')|map(attribute='ctype_ptr')|join(', ') }})
+{%- endfor %}
+
+{% for func in funcs %}
+def _{{ func.pyname }}(it):
+    #Iterate
+    {%- for arg in func.args_by_inout('in|inout|out|ret|stat') %}
+    cdef {{ arg.ctype_ptr }} _{{ arg.name }}
+    {%- endfor %}
+    {%- if func.args_by_inout('stat')|length > 0 %}
+    cdef bint stat_ok = True
+    {%- endif %}
+    cdef char** dataptrarray = GetDataPtrArray(GetNpyIter(it))
+    cdef IterNextFunc iternext = GetIterNext(GetNpyIter(it), NULL)
+    cdef int status = 1
+    while status:
+        {%- for arg in func.args_by_inout('in|inout|out') %}
+        _{{ arg.name }} = (<{{ arg.ctype }} *>(dataptrarray[{{ func.args.index(arg) }}])){%- if arg.ctype_ptr[-1] != '*' %}[0]{% endif %}
+        {%- endfor %}
+        {{ func.args_by_inout('ret|stat')|map(attribute='name')|surround('_',' = ')|join }}{{ func.name }}({{ func.args_by_inout('in|inout|out')|map(attribute='name')|prefix('_')|join(', ') }})
+        {%- for arg in func.args_by_inout('ret|stat') %}
+        (<{{ arg.ctype }} *>(dataptrarray[{{ func.args.index(arg) }}]))[0] = _{{ arg.name }}
+        {%- endfor %}
+        {%- for arg in func.args_by_inout('stat') %}
+        if _{{ arg.name }} != 0:
+            stat_ok = False
+        {%- endfor %}
+        status = iternext(GetNpyIter(it))
+    {%- if func.args_by_inout('stat')|length > 0 %}
+    return stat_ok
+    {%- endif %}
+
+{% endfor %}
diff --git a/astropy/_erfa/erfa_generator.py b/astropy/_erfa/erfa_generator.py
new file mode 100644
index 0000000..efe00ca
--- /dev/null
+++ b/astropy/_erfa/erfa_generator.py
@@ -0,0 +1,468 @@
+# 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 erfa.pyx when ERFA is updated (or this generator is enhanced).
+
+`Jinja2 <http://jinja.pocoo.org/>`_ 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.
+"""
+from __future__ import absolute_import, division, print_function
+# note that we do *not* use unicode_literals here, because that makes the
+# generated code's strings have u'' in them on py 2.x
+
+import re
+import os.path
+
+
+ctype_to_dtype = {'double'     : "numpy.double",
+                  'int'        : "numpy.intc",
+                  'eraASTROM'  : "dt_eraASTROM",
+                  'eraLDBODY'  : "dt_eraLDBODY",
+                  'char'       : "numpy.dtype('S16')",
+                  'const char' : "numpy.dtype('S16')",
+                  }
+
+
+NDIMS_REX = re.compile(re.escape("numpy.dtype([('fi0', '.*', <(.*)>)])").replace(r'\.\*','.*').replace(r'\<', '(').replace(r'\>',')'))
+
+
+class FunctionDoc(object):
+
+    def __init__(self, doc):
+        self.doc = doc.replace("**", "  ").replace("/*\n", "").replace("*/", "")
+        self.__input = None
+        self.__output = None
+        self.__ret_info = None
+
+    @property
+    def input(self):
+        if self.__input is None:
+            self.__input = []
+            result = re.search("Given([^\n]*):\n(.+?)  \n", self.doc, re.DOTALL)
+            if result is not None:
+                __input = result.group(2)
+                for i in __input.split("\n"):
+                    arg_doc = ArgumentDoc(i)
+                    if arg_doc.name is not None:
+                        self.__input.append(arg_doc)
+            result = re.search("Given and returned([^\n]*):\n(.+?)  \n", self.doc, re.DOTALL)
+            if result is not None:
+                __input = result.group(2)
+                for i in __input.split("\n"):
+                    arg_doc = ArgumentDoc(i)
+                    if arg_doc.name is not None:
+                        self.__input.append(arg_doc)
+        return self.__input
+
+    @property
+    def output(self):
+        if self.__output is None:
+            self.__output = []
+            result = re.search("Returned([^\n]*):\n(.+?)  \n", self.doc, re.DOTALL)
+            if result is not None:
+                __output = result.group(2)
+                for i in __output.split("\n"):
+                    arg_doc = ArgumentDoc(i)
+                    if arg_doc.name is not None:
+                        self.__output.append(arg_doc)
+            result = re.search("Given and returned([^\n]*):\n(.+?)  \n", self.doc, re.DOTALL)
+            if result is not None:
+                __output = result.group(2)
+                for i in __output.split("\n"):
+                    arg_doc = ArgumentDoc(i)
+                    if arg_doc.name is not None:
+                        self.__output.append(arg_doc)
+        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(object):
+
+    def __init__(self, doc):
+        match = re.search("^ +([^ ]+)[ ]+([^ ]+)[ ]+(.+)", doc)
+        if match is not None:
+            self.name = match.group(1)
+            self.type = match.group(2)
+            self.doc = match.group(3)
+        else:
+            self.name = None
+            self.type = None
+            self.doc = None
+
+    def __repr__(self):
+        return "    {0:15} {1:15} {2}".format(self.name, self.type, self.doc)
+
+
+class Argument(object):
+
+    def __init__(self, definition, doc):
+        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 ctype_ptr(self):
+        if (self.is_ptr) | (len(self.shape)>0):
+            return self.ctype+" *"
+        else:
+            return self.ctype
+
+    @property
+    def name_in_broadcast(self):
+        if len(self.shape)>0:
+            return "{0}_in[...{1}]".format(self.name, ",0"*len(self.shape))
+        else:
+            return "{0}_in".format(self.name)
+
+    @property
+    def name_out_broadcast(self):
+        if len(self.shape)>0:
+            return "{0}_out[...{1}]".format(self.name, ",0"*len(self.shape))
+        else:
+            return "{0}_out".format(self.name)
+
+    @property
+    def dtype(self):
+        return ctype_to_dtype[self.ctype]
+
+    @property
+    def ndim(self):
+        return len(self.shape)
+
+    def __repr__(self):
+        return "Argument('{0}', name='{1}', ctype='{2}', inout_state='{3}')".format(self.definition, self.name, self.ctype, self.inout_state)
+
+
+class ReturnDoc(object):
+
+    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 "Return value, type={0:15}, {1}, {2}".format(self.type, self.descr, self.doc)
+
+
+class Return(object):
+
+    def __init__(self, ctype, doc):
+        self.name = 'c_retval'
+        self.name_out_broadcast = self.name+"_out"
+        self.inout_state = 'stat' if ctype == 'int' else 'ret'
+        self.ctype = ctype
+        self.ctype_ptr = ctype
+        self.shape = ()
+        self.doc = doc
+
+    def __repr__(self):
+        return "Return(name='{0}', ctype='{1}', inout_state='{2}')".format(self.name, self.ctype, self.inout_state)
+
+    @property
+    def dtype(self):
+        return ctype_to_dtype[self.ctype]
+
+    @property
+    def nd_dtype(self):
+        """
+        This if the return type has a multi-dimensional output, like
+        double[3][3]
+        """
+        return "'fi0'" in self.dtype
+
+    @property
+    def doc_info(self):
+        return self.doc.ret_info
+
+
+class Function(object):
+    """
+    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 = "\n([^\n]+{0} ?\([^)]+\)).+?(/\*.+?\*/)".format(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("\(([^)]+)\)", self.cfunc).group(1).split(', '):
+            self.args.append(Argument(arg, self.doc))
+        self.ret = re.search("^(.*){0}".format(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
+
+    def __repr__(self):
+        return "Function(name='{0}', pyname='{1}', filename='{2}', filepath='{3}')".format(self.name, self.pyname, self.filename, self.filepath)
+
+
+class Constant(object):
+
+    def __init__(self, name, value, doc):
+        self.name = name.replace("ERFA_","")
+        self.value = value.replace("ERFA_","")
+        self.doc = doc
+
+
+def main(srcdir, outfn, templateloc, 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+'{0}'.format(an_element) for an_element in a_list]
+    def postfix(a_list, post):
+        return ['{0}'.format(an_element)+post for an_element in a_list]
+    def surround(a_list, pre, post):
+        return [pre+'{0}'.format(an_element)+post for an_element in a_list]
+    env.filters['prefix'] = prefix
+    env.filters['postfix'] = postfix
+    env.filters['surround'] = surround
+
+    erfa_pyx_in = env.get_template('core.pyx.templ')
+    erfa_py_in = env.get_template('core.py.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()
+
+    funcs = []
+    section_subsection_functions = re.findall('/\* (\w*)/(\w*) \*/\n(.*?)\n\n',
+                                              erfa_h, flags=re.DOTALL|re.MULTILINE)
+    for section, subsection, functions in section_subsection_functions:
+        print_("{0}.{1}".format(section, subsection))
+        if section == "Astronomy":
+            func_names = re.findall(' (\w+)\(.*?\);', functions, flags=re.DOTALL)
+            for name in func_names:
+                print_("{0}.{1}.{2}...".format(section, subsection, name))
+                if multifilserc:
+                    # easy because it just looks in the file itself
+                    funcs.append(Function(name, srcdir))
+                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('\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.append(Function(name, srcdir, 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!")
+
+    #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("#define (ERFA_\w+?) (.+?)$", chunk, flags=re.DOTALL|re.MULTILINE)
+        if result:
+            doc = re.findall("/\* (.+?) \*/\n", chunk, flags=re.DOTALL)
+            for (name, value) in result:
+                constants.append(Constant(name, value, doc))
+
+    print_("Rendering template")
+    erfa_pyx = erfa_pyx_in.render(funcs=funcs)
+    erfa_py = erfa_py_in.render(funcs=funcs, constants=constants)
+
+    if outfn is not None:
+        outfnx = outfn + "x"
+        print_("Saving to", outfn, 'and', outfnx)
+        with open(outfn, "w") as f:
+            f.write(erfa_py)
+        with open(outfnx, "w") as f:
+            f.write(erfa_pyx)
+
+    print_("Done!")
+
+    return erfa_pyx, erfa_py, funcs
+
+DEFAULT_ERFA_LOC = os.path.join(os.path.split(__file__)[0],
+                                '../../cextern/erfa')
+DEFAULT_TEMPLATE_LOC = os.path.split(__file__)[0]
+
+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: "{0}"'.format(DEFAULT_ERFA_LOC))
+    ap.add_argument('-o', '--output', default='core.py',
+                    help='The output filename.  This is the name for only the '
+                         'pure-python output, the Cython part will have the '
+                         'same name but with an "x" appended.')
+    ap.add_argument('-t', '--template-loc',
+                    default=DEFAULT_TEMPLATE_LOC,
+                    help='the location where the "erfa.pyx.templ" '
+                         'template can be found.')
+    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.template_loc)
diff --git a/astropy/_erfa/setup_package.py b/astropy/_erfa/setup_package.py
new file mode 100644
index 0000000..e6d9961
--- /dev/null
+++ b/astropy/_erfa/setup_package.py
@@ -0,0 +1,108 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import absolute_import
+
+import os
+import glob
+import warnings
+
+from distutils.extension import Extension
+
+from astropy_helpers import setup_helpers
+
+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 ['core.py.templ', 'core.pyx.templ', 'erfa_generator.py']]
+
+GEN_FILES = [os.path.join(ERFAPKGDIR, 'core.py'), os.path.join(ERFAPKGDIR, 'core.pyx')]
+
+
+def pre_build_py_hook(cmd_obj):
+    preprocess_source()
+
+
+def pre_build_ext_hook(cmd_obj):
+    preprocess_source()
+
+
+def pre_sdist_hook(cmd_obj):
+    preprocess_source()
+
+
+def preprocess_source():
+
+    # Generating the ERFA wrappers should only be done if needed. This also
+    # ensures that it is not done for any release tarball since those will
+    # include core.py and core.pyx.
+    if all(os.path.exists(filename) for filename in GEN_FILES):
+
+        # Determine modification times
+        erfa_mtime = max(os.path.getmtime(filename) for filename in SRC_FILES)
+        gen_mtime = min(os.path.getmtime(filename) for filename in GEN_FILES)
+
+        # If generated source is recent enough, don't update
+        if gen_mtime > erfa_mtime:
+            return
+
+        # If jinja2 isn't present, then print a warning and use existing files
+        try:
+            import jinja2
+        except:
+            warnings.warn("jinja2 could not be imported, so the existing ERFA "
+                          "core.py and core.pyx files will be used")
+            return
+
+    name = 'erfa_generator'
+    filename = os.path.join(ERFAPKGDIR, 'erfa_generator.py')
+
+    try:
+        from importlib import machinery as import_machinery
+        loader = import_machinery.SourceFileLoader(name, filename)
+        gen = loader.load_module()
+    except ImportError:
+        import imp
+        gen = imp.load_source(name, filename)
+
+    gen.main(gen.DEFAULT_ERFA_LOC,
+             os.path.join(ERFAPKGDIR, 'core.py'),
+             gen.DEFAULT_TEMPLATE_LOC,
+             verbose=False)
+
+
+def get_extensions():
+    sources = [os.path.join(ERFAPKGDIR, "core.pyx")]
+    include_dirs = ['numpy']
+    libraries = []
+
+    if setup_helpers.use_system_library('erfa'):
+        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._core",
+        sources=sources,
+        include_dirs=include_dirs,
+        libraries=libraries,
+        language="c",)
+
+    return [erfa_ext]
+
+
+def get_external_libraries():
+    return ['erfa']
+
+
+def requires_2to3():
+    return False
+
+
+def get_package_data():
+    return {'astropy._erfa': ['core.py.templ', 'core.pyx.templ']}
diff --git a/astropy/_erfa/tests/__init__.py b/astropy/_erfa/tests/__init__.py
new file mode 100644
index 0000000..9dce85d
--- /dev/null
+++ b/astropy/_erfa/tests/__init__.py
@@ -0,0 +1 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
diff --git a/astropy/_erfa/tests/test_erfa.py b/astropy/_erfa/tests/test_erfa.py
new file mode 100644
index 0000000..92a600c
--- /dev/null
+++ b/astropy/_erfa/tests/test_erfa.py
@@ -0,0 +1,169 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+from .. import core as erfa
+
+
+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, 4)
+    assert ihmsf.dtype == np.dtype('i4')
+
+    iy, im, id, ihmsf = erfa.d2dtf("UTC", 3, jd[0], 0.0)
+    assert iy.shape == ()
+    assert ihmsf.shape == (4,)
+    assert ihmsf.dtype == np.dtype('i4')
+
+
+def test_errwarn_reporting(recwarn):
+    """
+    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
+    erfa.dat(100, 1, 1, 0.5)
+    w = recwarn.pop(erfa.ErfaWarning)
+    assert '1 of "dubious year (Note 1)"' in str(w.message)
+
+    # and that the count is right for a vector.
+    erfa.dat([100, 200, 1990], 1, 1, 0.5)
+    w = recwarn.pop(erfa.ErfaWarning)
+    assert '2 of "dubious year (Note 1)"' in str(w.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_matrix_in():
+    jd1 = 2456165.5
+    jd2 = 0.401182685
+
+    pvmat = np.empty((2, 3))
+    pvmat[0][0] = -6241497.16
+    pvmat[0][1] = 401346.896
+    pvmat[0][2] = -1251136.04
+    pvmat[1][0] = -29.264597
+    pvmat[1][1] = -455.021831
+    pvmat[1][2] = 0.0266151194
+
+    astrom = erfa.apcs13(jd1, jd2, pvmat)
+    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'], [.9012691529023298391,
+                                             -.4173999812023068781,
+                                             -.1809906511146821008])
+    np.testing.assert_allclose(astrom['bpn'], np.eye(3))
+
+    #first make sure it *fails* if we mess with the input orders
+    pvmatbad = np.roll(pvmat.ravel(), 1).reshape((2, 3))
+    astrombad = erfa.apcs13(jd1, jd2, pvmatbad)
+    assert not np.allclose(astrombad['em'], 1.010428384373318379)
+
+    pvmatarr = np.array([pvmat]*3)
+    astrom2 = erfa.apcs13(jd1, jd2, pvmatarr)
+    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([pvmat]*9)[::3]
+    astrom3 = erfa.apcs13(jd1, jd2, pvmatarr)
+    assert astrom3.shape == (3,)
+    np.testing.assert_allclose(astrom3['em'], 1.010428384373318379)
+
+    #try fortran-order
+    pvmatarr = np.array([pvmat]*3, order='F')
+    astrom4 = erfa.apcs13(jd1, jd2, pvmatarr)
+    assert astrom4.shape == (3,)
+    np.testing.assert_allclose(astrom4['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)
diff --git a/astropy/analytic_functions/__init__.py b/astropy/analytic_functions/__init__.py
new file mode 100644
index 0000000..439fcd0
--- /dev/null
+++ b/astropy/analytic_functions/__init__.py
@@ -0,0 +1,10 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""This package contains analytic functions useful for astronomy.
+
+In future versions of ``astropy``, many of these might be
+accessible as `~astropy.modeling.core.Model`.
+
+"""
+
+# Shortcuts for most commonly used blackbody functions
+from .blackbody import blackbody_nu, blackbody_lambda
diff --git a/astropy/analytic_functions/blackbody.py b/astropy/analytic_functions/blackbody.py
new file mode 100644
index 0000000..eda7c31
--- /dev/null
+++ b/astropy/analytic_functions/blackbody.py
@@ -0,0 +1,107 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Functions related to blackbody radiation."""
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+# STDLIB
+import warnings
+
+# THIRD-PARTY
+import numpy as np
+
+# LOCAL
+from .. import constants as const
+from .. import units as u
+from ..utils.exceptions import AstropyUserWarning
+
+
+__all__ = ['blackbody_nu', 'blackbody_lambda']
+
+# Units
+FNU = u.erg / (u.cm**2 * u.s * u.Hz)
+FLAM = u.erg / (u.cm**2 * u.s * u.AA)
+
+
+def blackbody_nu(in_x, temperature):
+    """Calculate blackbody flux per steradian, :math:`B_{\\nu}(T)`.
+
+    .. note::
+
+        Use `numpy.errstate` to suppress Numpy warnings, if desired.
+
+    .. warning::
+
+        Output values might contain ``nan`` and ``inf``.
+
+    Parameters
+    ----------
+    in_x : number, array-like, or `~astropy.units.Quantity`
+        Frequency, wavelength, or wave number.
+        If not a Quantity, it is assumed to be in Hz.
+
+    temperature : number or `~astropy.units.Quantity`
+        Blackbody temperature.
+        If not a Quantity, it is assumed to be in Kelvin.
+
+    Returns
+    -------
+    flux : `~astropy.units.Quantity`
+        Blackbody monochromatic flux in
+        :math:`erg \\; cm^{-2} s^{-1} Hz^{-1} sr^{-1}`.
+
+    Raises
+    ------
+    ValueError
+        Invalid temperature.
+
+    ZeroDivisionError
+        Wavelength is zero (when converting to frequency).
+
+    """
+    # Convert to units for calculations, also force double precision
+    with u.add_enabled_equivalencies(u.spectral() + u.temperature()):
+        freq = u.Quantity(in_x, u.Hz, dtype=np.float64)
+        temp = u.Quantity(temperature, u.K, dtype=np.float64)
+
+    # Check if input values are physically possible
+    if temp < 0:
+        raise ValueError('Invalid temperature {0}'.format(temp))
+    if np.any(freq <= 0):  # pragma: no cover
+        warnings.warn('Input contains invalid wavelength/frequency value(s)',
+                      AstropyUserWarning)
+
+    # Calculate blackbody flux
+    bb_nu = (2.0 * const.h * freq ** 3 /
+             (const.c ** 2 * np.expm1(const.h * freq / (const.k_B * temp))))
+    flux = bb_nu.to(FNU, u.spectral_density(freq))
+
+    return flux / u.sr  # Add per steradian to output flux unit
+
+
+def blackbody_lambda(in_x, temperature):
+    """Like :func:`blackbody_nu` but for :math:`B_{\\lambda}(T)`.
+
+    Parameters
+    ----------
+    in_x : number, array-like, or `~astropy.units.Quantity`
+        Frequency, wavelength, or wave number.
+        If not a Quantity, it is assumed to be in Angstrom.
+
+    temperature : number or `~astropy.units.Quantity`
+        Blackbody temperature.
+        If not a Quantity, it is assumed to be in Kelvin.
+
+    Returns
+    -------
+    flux : `~astropy.units.Quantity`
+        Blackbody monochromatic flux in
+        :math:`erg \\; cm^{-2} s^{-1} \\AA^{-1} sr^{-1}`.
+
+    """
+    if getattr(in_x, 'unit', None) is None:
+        in_x = u.Quantity(in_x, u.AA)
+
+    bb_nu = blackbody_nu(in_x, temperature) * u.sr  # Remove sr for conversion
+    flux = bb_nu.to(FLAM, u.spectral_density(in_x))
+
+    return flux / u.sr  # Add per steradian to output flux unit
diff --git a/astropy/analytic_functions/tests/__init__.py b/astropy/analytic_functions/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy/analytic_functions/tests/test_blackbody.py b/astropy/analytic_functions/tests/test_blackbody.py
new file mode 100644
index 0000000..39a1011
--- /dev/null
+++ b/astropy/analytic_functions/tests/test_blackbody.py
@@ -0,0 +1,97 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Tests for blackbody functions."""
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import os
+# THIRD-PARTY
+import numpy as np
+
+# LOCAL
+from ..blackbody import blackbody_nu, blackbody_lambda, FNU
+from ... import units as u
+from ... import constants as const
+from ...tests.helper import pytest
+
+try:
+    from scipy import integrate  # pylint: disable=W0611
+except ImportError:
+    HAS_SCIPY = False
+else:
+    HAS_SCIPY = True
+
+
+__doctest_skip__ = ['*']
+
+
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
+ at pytest.mark.skipif('not HAS_SCIPY')
+def test_blackbody_scipy():
+    """Test Planck function.
+
+    .. note:: Needs ``scipy`` to work.
+
+    """
+    flux_unit = u.Watt / (u.m ** 2 * u.um)
+    wave = np.logspace(0, 8, 1e6) * u.AA
+    temp = 100. * u.K
+    with np.errstate(all='ignore'):
+        bb_nu = blackbody_nu(wave, temp) * u.sr
+    flux = bb_nu.to(flux_unit, u.spectral_density(wave)) / u.sr
+
+    lum = wave.to(u.um)
+    intflux = integrate.trapz(flux.value, x=lum.value)
+    ans = const.sigma_sb * temp**4 / np.pi
+    np.testing.assert_allclose(intflux, ans.value, rtol=0.01)  # 1% accuracy
+
+
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
+def test_blackbody_overflow():
+    """Test Planck function with overflow."""
+    photlam = u.photon / (u.cm**2 * u.s * u.AA)
+    wave = [0, 1000.0, 100000.0, 1e55]  # Angstrom
+    temp = 10000.0  # Kelvin
+    with np.errstate(all='ignore'):
+        bb_lam = blackbody_lambda(wave, temp) * u.sr
+    flux = bb_lam.to(photlam, u.spectral_density(wave * u.AA)) / u.sr
+
+    # First element is NaN, last element is very small, others normal
+    assert np.isnan(flux[0])
+    assert np.log10(flux[-1].value) < -134
+    np.testing.assert_allclose(
+        flux.value[1:-1], [3.38131732e+16, 3.87451317e+15],
+        rtol=1e-3)  # 0.1% accuracy in PHOTLAM/sr
+
+    with np.errstate(all='ignore'):
+        flux = blackbody_lambda(1, 1e4)
+    assert flux.value == 0
+
+
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
+def test_blackbody_synphot():
+    """Test that it is consistent with IRAF SYNPHOT BBFUNC."""
+    # Solid angle of solar radius at 1 kpc
+    fac = np.pi * (const.R_sun / const.kpc) ** 2 * u.sr
+
+    with np.errstate(all='ignore'):
+        flux = blackbody_nu([100, 1, 1000, 1e4, 1e5] * u.AA, 5000) * fac
+    assert flux.unit == FNU
+
+    # Special check for overflow value (SYNPHOT gives 0)
+    assert np.log10(flux[0].value) < -143
+
+    np.testing.assert_allclose(
+        flux.value[1:], [0, 2.01950807e-34, 3.78584515e-26, 1.90431881e-27],
+        rtol=0.01)  # 1% accuracy
+
+
+def test_blackbody_exceptions():
+    """Test exceptions."""
+
+    # Negative temperature
+    with pytest.raises(ValueError):
+        flux = blackbody_nu(1000 * u.AA, -100)
+
+    # Zero wavelength given for conversion to Hz
+    with pytest.raises(ZeroDivisionError):
+        flux = blackbody_nu(0 * u.AA, 5000)
diff --git a/astropy/config/tests/test_configs.py b/astropy/config/tests/test_configs.py
index 81193bc..3956616 100644
--- a/astropy/config/tests/test_configs.py
+++ b/astropy/config/tests/test_configs.py
@@ -25,7 +25,7 @@ def test_paths():
 
 
 def test_config_file():
-    from ..configuration import get_config, reload_config, save_config
+    from ..configuration import get_config, reload_config
 
     apycfg = get_config('astropy')
     assert apycfg.filename.endswith('astropy.cfg')
@@ -107,7 +107,7 @@ def test_configitem_options(tmpdir):
     while apycfg.parent is not apycfg:
         apycfg = apycfg.parent
     f = tmpdir.join('astropy.cfg')
-    with io.open(f.strpath, 'w', encoding='utf-8') as fd:
+    with io.open(f.strpath, 'wb') as fd:
         apycfg.write(fd)
     with io.open(f.strpath, 'rU', encoding='utf-8') as fd:
         lns = [x.strip() for x in f.readlines()]
@@ -121,7 +121,7 @@ def test_config_noastropy_fallback(monkeypatch):
     there's a problem accessing the astropy directory
     """
     from ...tests.helper import pytest
-    from .. import paths, configuration
+    from .. import paths
 
     # make sure the config directory is not searched
     monkeypatch.setenv(str('XDG_CONFIG_HOME'), 'foo')
diff --git a/astropy/conftest.py b/astropy/conftest.py
index ef05070..33dcc65 100644
--- a/astropy/conftest.py
+++ b/astropy/conftest.py
@@ -4,4 +4,11 @@
 
 from .tests.pytest_plugins import *
 
-enable_deprecations_as_exceptions()
+try:
+    import matplotlib
+except ImportError:
+    pass
+else:
+    matplotlib.use('Agg')
+
+enable_deprecations_as_exceptions(include_astropy_deprecations=False)
diff --git a/astropy/constants/tests/test_pickle.py b/astropy/constants/tests/test_pickle.py
new file mode 100644
index 0000000..4109f22
--- /dev/null
+++ b/astropy/constants/tests/test_pickle.py
@@ -0,0 +1,17 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import absolute_import, division, print_function, unicode_literals
+from ... import constants as const
+from ...tests.helper import pytest, pickle_protocol, check_pickling_recovery
+
+originals = [const.Constant('h_fake', 'Not Planck',
+                            0.0, 'J s', 0.0, 'fakeref',
+                            system='si'),
+             const.h,
+             const.e]
+xfails = [True, True, True]
+
+ at pytest.mark.parametrize("original,xfail", zip(originals, xfails))
+def test_new_constant(pickle_protocol, original, xfail):
+    if xfail:
+        pytest.xfail()
+    check_pickling_recovery(original, pickle_protocol)
diff --git a/astropy/convolution/boundary_extend.c b/astropy/convolution/boundary_extend.c
index 90ae14c..3413230 100644
--- a/astropy/convolution/boundary_extend.c
+++ b/astropy/convolution/boundary_extend.c
@@ -482,7 +482,7 @@ typedef struct {
 } __Pyx_BufFmt_Context;
 
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -491,7 +491,7 @@ typedef struct {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -500,7 +500,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -509,7 +509,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -518,7 +518,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -527,7 +527,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -536,7 +536,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -545,7 +545,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -554,7 +554,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -563,7 +563,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -572,7 +572,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -581,7 +581,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -590,7 +590,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -599,7 +599,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -608,7 +608,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -617,7 +617,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -626,7 +626,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -635,7 +635,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -644,7 +644,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -653,7 +653,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -662,7 +662,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -702,7 +702,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_15boundary_extend_
 
 /*--- Type declarations ---*/
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -711,7 +711,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_15boundary_extend_
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -720,7 +720,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -729,7 +729,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -1140,7 +1140,7 @@ static char __pyx_k_convolve1d_boundary_extend[] = "convolve1d_boundary_extend";
 static char __pyx_k_convolve2d_boundary_extend[] = "convolve2d_boundary_extend";
 static char __pyx_k_convolve3d_boundary_extend[] = "convolve3d_boundary_extend";
 static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/convolution/boundary_extend.pyx";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/convolution/boundary_extend.pyx";
 static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_Convolution_kernel_must_have_odd[] = "Convolution kernel must have odd dimensions";
 static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
@@ -1154,6 +1154,7 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
 static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
 static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
 static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s_astropy_convolution_boundary_ext;
 static PyObject *__pyx_n_s_bot;
@@ -1173,7 +1174,6 @@ static PyObject *__pyx_n_s_iii;
 static PyObject *__pyx_n_s_iimax;
 static PyObject *__pyx_n_s_iimin;
 static PyObject *__pyx_n_s_import;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
 static PyObject *__pyx_n_s_j;
 static PyObject *__pyx_n_s_jj;
 static PyObject *__pyx_n_s_jjj;
@@ -4200,7 +4200,7 @@ static PyObject *__pyx_pf_7astropy_11convolution_15boundary_extend_4convolve3d_b
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -4250,7 +4250,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __Pyx_GIVEREF(__pyx_v_info->obj);
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
  *             # of flags
  * 
  *             if info == NULL: return             # <<<<<<<<<<<<<<
@@ -4263,7 +4263,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
  * 
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -4272,7 +4272,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -4281,7 +4281,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
  *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
@@ -4290,7 +4290,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
  *             ndim = PyArray_NDIM(self)
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -4300,7 +4300,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 copy_shape = 1             # <<<<<<<<<<<<<<
@@ -4312,7 +4312,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
  *                 copy_shape = 1
  *             else:
  *                 copy_shape = 0             # <<<<<<<<<<<<<<
@@ -4323,7 +4323,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
  *                 copy_shape = 0
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4337,7 +4337,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L6_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4349,7 +4349,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L6_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -4363,7 +4363,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4377,7 +4377,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L9_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4389,7 +4389,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L9_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -4403,7 +4403,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
@@ -4412,7 +4412,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
  * 
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim             # <<<<<<<<<<<<<<
@@ -4421,7 +4421,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->ndim = __pyx_v_ndim;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim
  *             if copy_shape:             # <<<<<<<<<<<<<<
@@ -4431,7 +4431,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (__pyx_v_copy_shape != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
@@ -4440,7 +4440,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
@@ -4449,7 +4449,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):             # <<<<<<<<<<<<<<
@@ -4460,7 +4460,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
       __pyx_v_i = __pyx_t_5;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
@@ -4469,7 +4469,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
       (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]
  *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
@@ -4482,7 +4482,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
  *                     info.shape[i] = PyArray_DIMS(self)[i]
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
@@ -4491,7 +4491,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
@@ -4502,7 +4502,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L11:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
@@ -4511,7 +4511,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->suboffsets = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
@@ -4520,7 +4520,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)
  *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
@@ -4529,7 +4529,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
  * 
  *             cdef int t
  *             cdef char* f = NULL             # <<<<<<<<<<<<<<
@@ -4538,7 +4538,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_f = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
  *             cdef int t
  *             cdef char* f = NULL
  *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
@@ -4550,7 +4550,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
  *             cdef int offset
  * 
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
@@ -4559,7 +4559,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
  * 
  *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
@@ -4577,7 +4577,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L15_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
  *             if not hasfields and not copy_shape:
  *                 # do not call releasebuffer
  *                 info.obj = None             # <<<<<<<<<<<<<<
@@ -4593,7 +4593,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
  *             else:
  *                 # need to call releasebuffer
  *                 info.obj = self             # <<<<<<<<<<<<<<
@@ -4608,7 +4608,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L14:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
  *                 info.obj = self
  * 
  *             if not hasfields:             # <<<<<<<<<<<<<<
@@ -4618,7 +4618,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
  * 
  *             if not hasfields:
  *                 t = descr.type_num             # <<<<<<<<<<<<<<
@@ -4628,7 +4628,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_4 = __pyx_v_descr->type_num;
     __pyx_v_t = __pyx_t_4;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
  *             if not hasfields:
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -4648,7 +4648,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L20_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -4666,7 +4666,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_L19_bool_binop_done:;
     if (__pyx_t_1) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4680,7 +4680,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4689,7 +4689,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     switch (__pyx_v_t) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
@@ -4700,7 +4700,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_b;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
@@ -4711,7 +4711,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_B;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
@@ -4722,7 +4722,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_h;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
@@ -4733,7 +4733,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_H;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
@@ -4744,7 +4744,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_i;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
@@ -4755,7 +4755,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_I;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
@@ -4766,7 +4766,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_l;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
@@ -4777,7 +4777,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_L;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
@@ -4788,7 +4788,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
@@ -4799,7 +4799,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
@@ -4810,7 +4810,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_f;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
@@ -4821,7 +4821,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_d;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
@@ -4832,7 +4832,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_g;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
@@ -4843,7 +4843,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zf;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
@@ -4854,7 +4854,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zd;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
@@ -4865,7 +4865,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zg;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4877,7 +4877,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
       default:
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -4903,7 +4903,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f             # <<<<<<<<<<<<<<
@@ -4912,7 +4912,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = __pyx_v_f;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f
  *                 return             # <<<<<<<<<<<<<<
@@ -4924,7 +4924,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
  *                 return
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
@@ -4933,7 +4933,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = ((char *)malloc(255));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
@@ -4942,7 +4942,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     (__pyx_v_info->format[0]) = '^';
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0             # <<<<<<<<<<<<<<
@@ -4951,7 +4951,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_offset = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0
  *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
@@ -4961,7 +4961,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_f = __pyx_t_7;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
  *                                       info.format + _buffer_format_string_len,
  *                                       &offset)
  *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
@@ -4971,7 +4971,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     (__pyx_v_f[0]) = '\x00';
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -5003,7 +5003,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5027,7 +5027,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
@@ -5037,7 +5037,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
@@ -5049,7 +5049,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -5059,7 +5059,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
@@ -5071,7 +5071,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5083,7 +5083,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5100,7 +5100,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
  * 
  * cdef inline object PyArray_MultiIterNew1(a):
  *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
@@ -5114,7 +5114,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5133,7 +5133,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5150,7 +5150,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
@@ -5164,7 +5164,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5183,7 +5183,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5200,7 +5200,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
@@ -5214,7 +5214,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5233,7 +5233,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5250,7 +5250,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
@@ -5264,7 +5264,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5283,7 +5283,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5300,7 +5300,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
@@ -5314,7 +5314,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5333,7 +5333,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -5365,7 +5365,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_util_dtypestring", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
  *     cdef int delta_offset
  *     cdef tuple i
  *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -5374,7 +5374,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
  *     cdef tuple i
  *     cdef int endian_detector = 1
  *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -5383,7 +5383,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -5405,7 +5405,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
  * 
  *     for childname in descr.names:
  *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
@@ -5418,7 +5418,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
  *     for childname in descr.names:
  *         fields = descr.fields[childname]
  *         child, new_offset = fields             # <<<<<<<<<<<<<<
@@ -5457,7 +5457,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
  *         child, new_offset = fields
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
@@ -5474,7 +5474,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -5488,7 +5488,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
  * 
  *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -5508,7 +5508,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L8_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -5526,7 +5526,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_L7_bool_binop_done:;
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -5540,7 +5540,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
  * 
  *         # Output padding bytes
  *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
@@ -5556,7 +5556,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (!__pyx_t_6) break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
  *         # Output padding bytes
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
@@ -5565,7 +5565,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       (__pyx_v_f[0]) = 120;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5574,7 +5574,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       __pyx_v_f = (__pyx_v_f + 1);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
  *             f[0] = 120 # "x"; pad byte
  *             f += 1
  *             offset[0] += 1             # <<<<<<<<<<<<<<
@@ -5585,7 +5585,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
  *             offset[0] += 1
  * 
  *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
@@ -5595,7 +5595,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_8 = 0;
     (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
  *         offset[0] += child.itemsize
  * 
  *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
@@ -5605,7 +5605,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
  * 
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num             # <<<<<<<<<<<<<<
@@ -5617,7 +5617,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num
  *             if end - f < 5:             # <<<<<<<<<<<<<<
@@ -5627,7 +5627,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_6) {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -5641,7 +5641,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
@@ -5659,7 +5659,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
@@ -5677,7 +5677,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
@@ -5695,7 +5695,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
@@ -5713,7 +5713,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
@@ -5731,7 +5731,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
@@ -5749,7 +5749,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
@@ -5767,7 +5767,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
@@ -5785,7 +5785,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
@@ -5803,7 +5803,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
@@ -5821,7 +5821,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
@@ -5839,7 +5839,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
@@ -5857,7 +5857,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
@@ -5875,7 +5875,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
@@ -5895,7 +5895,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
@@ -5915,7 +5915,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
@@ -5935,7 +5935,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
@@ -5954,7 +5954,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       /*else*/ {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -5977,7 +5977,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       __pyx_L15:;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5989,7 +5989,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     /*else*/ {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
  *             # Cython ignores struct boundary information ("T{...}"),
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
@@ -6001,7 +6001,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L13:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -6011,7 +6011,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)
  *     return f             # <<<<<<<<<<<<<<
@@ -6021,7 +6021,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   __pyx_r = __pyx_v_f;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -6046,7 +6046,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6061,7 +6061,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
  * cdef inline void set_array_base(ndarray arr, object base):
  *      cdef PyObject* baseptr
  *      if base is None:             # <<<<<<<<<<<<<<
@@ -6072,7 +6072,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
  *      cdef PyObject* baseptr
  *      if base is None:
  *          baseptr = NULL             # <<<<<<<<<<<<<<
@@ -6084,7 +6084,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
  *          baseptr = NULL
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
@@ -6093,7 +6093,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
     Py_INCREF(__pyx_v_base);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
@@ -6104,7 +6104,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
@@ -6113,7 +6113,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   Py_XDECREF(__pyx_v_arr->base);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)
  *      arr.base = baseptr             # <<<<<<<<<<<<<<
@@ -6122,7 +6122,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   __pyx_v_arr->base = __pyx_v_baseptr;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6134,7 +6134,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6148,7 +6148,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("get_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
  * 
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:             # <<<<<<<<<<<<<<
@@ -6158,7 +6158,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:
  *         return None             # <<<<<<<<<<<<<<
@@ -6172,7 +6172,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
  *         return None
  *     else:
  *         return <object>arr.base             # <<<<<<<<<<<<<<
@@ -6183,7 +6183,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6227,6 +6227,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
   {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s_astropy_convolution_boundary_ext, __pyx_k_astropy_convolution_boundary_ext, sizeof(__pyx_k_astropy_convolution_boundary_ext), 0, 0, 1, 1},
   {&__pyx_n_s_bot, __pyx_k_bot, sizeof(__pyx_k_bot), 0, 0, 1, 1},
@@ -6246,7 +6247,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_iimax, __pyx_k_iimax, sizeof(__pyx_k_iimax), 0, 0, 1, 1},
   {&__pyx_n_s_iimin, __pyx_k_iimin, sizeof(__pyx_k_iimin), 0, 0, 1, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
   {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},
   {&__pyx_n_s_jj, __pyx_k_jj, sizeof(__pyx_k_jj), 0, 0, 1, 1},
   {&__pyx_n_s_jjj, __pyx_k_jjj, sizeof(__pyx_k_jjj), 0, 0, 1, 1},
@@ -6325,7 +6325,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -6336,7 +6336,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__4);
   __Pyx_GIVEREF(__pyx_tuple__4);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -6347,7 +6347,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6358,7 +6358,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__6);
   __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -6369,7 +6369,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__7);
   __Pyx_GIVEREF(__pyx_tuple__7);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6380,7 +6380,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -6401,7 +6401,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__10 = PyTuple_Pack(16, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_nkx, __pyx_n_s_wkx, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_iii, __pyx_n_s_ii, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
-  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve1d_boundary_extend, 19, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve1d_boundary_extend, 19, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_extend.pyx":87
  * 
@@ -6413,7 +6413,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__12 = PyTuple_Pack(24, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno  [...]
   __Pyx_GOTREF(__pyx_tuple__12);
   __Pyx_GIVEREF(__pyx_tuple__12);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve2d_boundary_extend, 87, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve2d_boundary_extend, 87, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_extend.pyx":170
  * 
@@ -6425,7 +6425,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__14 = PyTuple_Pack(32, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_nkz, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_wkz, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_kkk, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_kk, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_kkmin, __pyx_n_s_kkmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_ [...]
   __Pyx_GOTREF(__pyx_tuple__14);
   __Pyx_GIVEREF(__pyx_tuple__14);
-  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 32, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve3d_boundary_extend, 170, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 32, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve3d_boundary_extend, 170, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -6611,7 +6611,7 @@ PyMODINIT_FUNC PyInit_boundary_extend(void)
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
diff --git a/astropy/convolution/boundary_fill.c b/astropy/convolution/boundary_fill.c
index 22144bb..f699d49 100644
--- a/astropy/convolution/boundary_fill.c
+++ b/astropy/convolution/boundary_fill.c
@@ -482,7 +482,7 @@ typedef struct {
 } __Pyx_BufFmt_Context;
 
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -491,7 +491,7 @@ typedef struct {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -500,7 +500,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -509,7 +509,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -518,7 +518,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -527,7 +527,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -536,7 +536,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -545,7 +545,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -554,7 +554,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -563,7 +563,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -572,7 +572,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -581,7 +581,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -590,7 +590,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -599,7 +599,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -608,7 +608,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -617,7 +617,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -626,7 +626,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -635,7 +635,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -644,7 +644,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -653,7 +653,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -662,7 +662,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -702,7 +702,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_fill_DT
 
 /*--- Type declarations ---*/
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -711,7 +711,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_fill_DT
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -720,7 +720,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -729,7 +729,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -1139,7 +1139,7 @@ static char __pyx_k_convolve1d_boundary_fill[] = "convolve1d_boundary_fill";
 static char __pyx_k_convolve2d_boundary_fill[] = "convolve2d_boundary_fill";
 static char __pyx_k_convolve3d_boundary_fill[] = "convolve3d_boundary_fill";
 static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/convolution/boundary_fill.pyx";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/convolution/boundary_fill.pyx";
 static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_Convolution_kernel_must_have_odd[] = "Convolution kernel must have odd dimensions";
 static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
@@ -1153,6 +1153,7 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
 static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
 static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
 static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s_astropy_convolution_boundary_fil;
 static PyObject *__pyx_n_s_bot;
@@ -1173,7 +1174,6 @@ static PyObject *__pyx_n_s_iii;
 static PyObject *__pyx_n_s_iimax;
 static PyObject *__pyx_n_s_iimin;
 static PyObject *__pyx_n_s_import;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
 static PyObject *__pyx_n_s_j;
 static PyObject *__pyx_n_s_jj;
 static PyObject *__pyx_n_s_jjj;
@@ -4335,7 +4335,7 @@ static PyObject *__pyx_pf_7astropy_11convolution_13boundary_fill_4convolve3d_bou
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -4385,7 +4385,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __Pyx_GIVEREF(__pyx_v_info->obj);
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
  *             # of flags
  * 
  *             if info == NULL: return             # <<<<<<<<<<<<<<
@@ -4398,7 +4398,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
  * 
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -4407,7 +4407,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -4416,7 +4416,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
  *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
@@ -4425,7 +4425,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
  *             ndim = PyArray_NDIM(self)
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -4435,7 +4435,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 copy_shape = 1             # <<<<<<<<<<<<<<
@@ -4447,7 +4447,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
  *                 copy_shape = 1
  *             else:
  *                 copy_shape = 0             # <<<<<<<<<<<<<<
@@ -4458,7 +4458,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
  *                 copy_shape = 0
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4472,7 +4472,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L6_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4484,7 +4484,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L6_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -4498,7 +4498,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4512,7 +4512,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L9_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4524,7 +4524,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L9_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -4538,7 +4538,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
@@ -4547,7 +4547,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
  * 
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim             # <<<<<<<<<<<<<<
@@ -4556,7 +4556,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->ndim = __pyx_v_ndim;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim
  *             if copy_shape:             # <<<<<<<<<<<<<<
@@ -4566,7 +4566,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (__pyx_v_copy_shape != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
@@ -4575,7 +4575,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
@@ -4584,7 +4584,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):             # <<<<<<<<<<<<<<
@@ -4595,7 +4595,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
       __pyx_v_i = __pyx_t_5;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
@@ -4604,7 +4604,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
       (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]
  *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
@@ -4617,7 +4617,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
  *                     info.shape[i] = PyArray_DIMS(self)[i]
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
@@ -4626,7 +4626,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
@@ -4637,7 +4637,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L11:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
@@ -4646,7 +4646,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->suboffsets = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
@@ -4655,7 +4655,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)
  *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
@@ -4664,7 +4664,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
  * 
  *             cdef int t
  *             cdef char* f = NULL             # <<<<<<<<<<<<<<
@@ -4673,7 +4673,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_f = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
  *             cdef int t
  *             cdef char* f = NULL
  *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
@@ -4685,7 +4685,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
  *             cdef int offset
  * 
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
@@ -4694,7 +4694,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
  * 
  *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
@@ -4712,7 +4712,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L15_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
  *             if not hasfields and not copy_shape:
  *                 # do not call releasebuffer
  *                 info.obj = None             # <<<<<<<<<<<<<<
@@ -4728,7 +4728,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
  *             else:
  *                 # need to call releasebuffer
  *                 info.obj = self             # <<<<<<<<<<<<<<
@@ -4743,7 +4743,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L14:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
  *                 info.obj = self
  * 
  *             if not hasfields:             # <<<<<<<<<<<<<<
@@ -4753,7 +4753,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
  * 
  *             if not hasfields:
  *                 t = descr.type_num             # <<<<<<<<<<<<<<
@@ -4763,7 +4763,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_4 = __pyx_v_descr->type_num;
     __pyx_v_t = __pyx_t_4;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
  *             if not hasfields:
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -4783,7 +4783,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L20_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -4801,7 +4801,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_L19_bool_binop_done:;
     if (__pyx_t_1) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4815,7 +4815,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4824,7 +4824,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     switch (__pyx_v_t) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
@@ -4835,7 +4835,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_b;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
@@ -4846,7 +4846,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_B;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
@@ -4857,7 +4857,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_h;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
@@ -4868,7 +4868,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_H;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
@@ -4879,7 +4879,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_i;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
@@ -4890,7 +4890,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_I;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
@@ -4901,7 +4901,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_l;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
@@ -4912,7 +4912,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_L;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
@@ -4923,7 +4923,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
@@ -4934,7 +4934,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
@@ -4945,7 +4945,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_f;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
@@ -4956,7 +4956,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_d;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
@@ -4967,7 +4967,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_g;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
@@ -4978,7 +4978,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zf;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
@@ -4989,7 +4989,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zd;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
@@ -5000,7 +5000,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zg;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -5012,7 +5012,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
       default:
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -5038,7 +5038,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f             # <<<<<<<<<<<<<<
@@ -5047,7 +5047,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = __pyx_v_f;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f
  *                 return             # <<<<<<<<<<<<<<
@@ -5059,7 +5059,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
  *                 return
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
@@ -5068,7 +5068,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = ((char *)malloc(255));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
@@ -5077,7 +5077,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     (__pyx_v_info->format[0]) = '^';
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0             # <<<<<<<<<<<<<<
@@ -5086,7 +5086,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_offset = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0
  *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
@@ -5096,7 +5096,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_f = __pyx_t_7;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
  *                                       info.format + _buffer_format_string_len,
  *                                       &offset)
  *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
@@ -5106,7 +5106,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     (__pyx_v_f[0]) = '\x00';
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -5138,7 +5138,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5162,7 +5162,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
@@ -5172,7 +5172,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
@@ -5184,7 +5184,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -5194,7 +5194,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
@@ -5206,7 +5206,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5218,7 +5218,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5235,7 +5235,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
  * 
  * cdef inline object PyArray_MultiIterNew1(a):
  *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
@@ -5249,7 +5249,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5268,7 +5268,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5285,7 +5285,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
@@ -5299,7 +5299,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5318,7 +5318,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5335,7 +5335,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
@@ -5349,7 +5349,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5368,7 +5368,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5385,7 +5385,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
@@ -5399,7 +5399,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5418,7 +5418,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5435,7 +5435,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
@@ -5449,7 +5449,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5468,7 +5468,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -5500,7 +5500,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_util_dtypestring", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
  *     cdef int delta_offset
  *     cdef tuple i
  *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -5509,7 +5509,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
  *     cdef tuple i
  *     cdef int endian_detector = 1
  *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -5518,7 +5518,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -5540,7 +5540,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
  * 
  *     for childname in descr.names:
  *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
@@ -5553,7 +5553,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
  *     for childname in descr.names:
  *         fields = descr.fields[childname]
  *         child, new_offset = fields             # <<<<<<<<<<<<<<
@@ -5592,7 +5592,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
  *         child, new_offset = fields
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
@@ -5609,7 +5609,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -5623,7 +5623,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
  * 
  *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -5643,7 +5643,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L8_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -5661,7 +5661,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_L7_bool_binop_done:;
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -5675,7 +5675,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
  * 
  *         # Output padding bytes
  *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
@@ -5691,7 +5691,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (!__pyx_t_6) break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
  *         # Output padding bytes
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
@@ -5700,7 +5700,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       (__pyx_v_f[0]) = 120;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5709,7 +5709,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       __pyx_v_f = (__pyx_v_f + 1);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
  *             f[0] = 120 # "x"; pad byte
  *             f += 1
  *             offset[0] += 1             # <<<<<<<<<<<<<<
@@ -5720,7 +5720,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
  *             offset[0] += 1
  * 
  *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
@@ -5730,7 +5730,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_8 = 0;
     (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
  *         offset[0] += child.itemsize
  * 
  *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
@@ -5740,7 +5740,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
  * 
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num             # <<<<<<<<<<<<<<
@@ -5752,7 +5752,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num
  *             if end - f < 5:             # <<<<<<<<<<<<<<
@@ -5762,7 +5762,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_6) {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -5776,7 +5776,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
@@ -5794,7 +5794,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
@@ -5812,7 +5812,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
@@ -5830,7 +5830,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
@@ -5848,7 +5848,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
@@ -5866,7 +5866,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
@@ -5884,7 +5884,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
@@ -5902,7 +5902,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
@@ -5920,7 +5920,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
@@ -5938,7 +5938,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
@@ -5956,7 +5956,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
@@ -5974,7 +5974,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
@@ -5992,7 +5992,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
@@ -6010,7 +6010,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
@@ -6030,7 +6030,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
@@ -6050,7 +6050,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
@@ -6070,7 +6070,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
@@ -6089,7 +6089,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       /*else*/ {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -6112,7 +6112,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       __pyx_L15:;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *             f += 1             # <<<<<<<<<<<<<<
@@ -6124,7 +6124,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     /*else*/ {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
  *             # Cython ignores struct boundary information ("T{...}"),
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
@@ -6136,7 +6136,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L13:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -6146,7 +6146,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)
  *     return f             # <<<<<<<<<<<<<<
@@ -6156,7 +6156,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   __pyx_r = __pyx_v_f;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -6181,7 +6181,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6196,7 +6196,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
  * cdef inline void set_array_base(ndarray arr, object base):
  *      cdef PyObject* baseptr
  *      if base is None:             # <<<<<<<<<<<<<<
@@ -6207,7 +6207,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
  *      cdef PyObject* baseptr
  *      if base is None:
  *          baseptr = NULL             # <<<<<<<<<<<<<<
@@ -6219,7 +6219,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
  *          baseptr = NULL
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
@@ -6228,7 +6228,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
     Py_INCREF(__pyx_v_base);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
@@ -6239,7 +6239,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
@@ -6248,7 +6248,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   Py_XDECREF(__pyx_v_arr->base);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)
  *      arr.base = baseptr             # <<<<<<<<<<<<<<
@@ -6257,7 +6257,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   __pyx_v_arr->base = __pyx_v_baseptr;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6269,7 +6269,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6283,7 +6283,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("get_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
  * 
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:             # <<<<<<<<<<<<<<
@@ -6293,7 +6293,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:
  *         return None             # <<<<<<<<<<<<<<
@@ -6307,7 +6307,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
  *         return None
  *     else:
  *         return <object>arr.base             # <<<<<<<<<<<<<<
@@ -6318,7 +6318,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6362,6 +6362,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
   {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s_astropy_convolution_boundary_fil, __pyx_k_astropy_convolution_boundary_fil, sizeof(__pyx_k_astropy_convolution_boundary_fil), 0, 0, 1, 1},
   {&__pyx_n_s_bot, __pyx_k_bot, sizeof(__pyx_k_bot), 0, 0, 1, 1},
@@ -6382,7 +6383,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_iimax, __pyx_k_iimax, sizeof(__pyx_k_iimax), 0, 0, 1, 1},
   {&__pyx_n_s_iimin, __pyx_k_iimin, sizeof(__pyx_k_iimin), 0, 0, 1, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
   {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},
   {&__pyx_n_s_jj, __pyx_k_jj, sizeof(__pyx_k_jj), 0, 0, 1, 1},
   {&__pyx_n_s_jjj, __pyx_k_jjj, sizeof(__pyx_k_jjj), 0, 0, 1, 1},
@@ -6461,7 +6461,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -6472,7 +6472,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__4);
   __Pyx_GIVEREF(__pyx_tuple__4);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -6483,7 +6483,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6494,7 +6494,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__6);
   __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -6505,7 +6505,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__7);
   __Pyx_GIVEREF(__pyx_tuple__7);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6516,7 +6516,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -6537,7 +6537,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__10 = PyTuple_Pack(17, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_fill_value, __pyx_n_s_nx, __pyx_n_s_nkx, __pyx_n_s_wkx, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_iii, __pyx_n_s_ii, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
-  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(3, 0, 17, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve1d_boundary_fill, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(3, 0, 17, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve1d_boundary_fill, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_fill.pyx":88
  * 
@@ -6549,7 +6549,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__12 = PyTuple_Pack(25, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_fill_value, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_linen [...]
   __Pyx_GOTREF(__pyx_tuple__12);
   __Pyx_GIVEREF(__pyx_tuple__12);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(3, 0, 25, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve2d_boundary_fill, 88, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(3, 0, 25, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve2d_boundary_fill, 88, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_fill.pyx":173
  * 
@@ -6561,7 +6561,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__14 = PyTuple_Pack(33, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_fill_value, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_nkz, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_wkz, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_kkk, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_kk, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_kkmin, __pyx_n_s_kkmax, __pyx_n_s_top, [...]
   __Pyx_GOTREF(__pyx_tuple__14);
   __Pyx_GIVEREF(__pyx_tuple__14);
-  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(3, 0, 33, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve3d_boundary_fill, 173, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(3, 0, 33, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve3d_boundary_fill, 173, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -6747,7 +6747,7 @@ PyMODINIT_FUNC PyInit_boundary_fill(void)
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
diff --git a/astropy/convolution/boundary_none.c b/astropy/convolution/boundary_none.c
index 064b08e..6be9693 100644
--- a/astropy/convolution/boundary_none.c
+++ b/astropy/convolution/boundary_none.c
@@ -482,7 +482,7 @@ typedef struct {
 } __Pyx_BufFmt_Context;
 
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -491,7 +491,7 @@ typedef struct {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -500,7 +500,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -509,7 +509,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -518,7 +518,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -527,7 +527,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -536,7 +536,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -545,7 +545,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -554,7 +554,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -563,7 +563,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -572,7 +572,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -581,7 +581,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -590,7 +590,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -599,7 +599,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -608,7 +608,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -617,7 +617,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -626,7 +626,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -635,7 +635,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -644,7 +644,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -653,7 +653,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -662,7 +662,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -702,7 +702,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_none_DT
 
 /*--- Type declarations ---*/
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -711,7 +711,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_none_DT
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -720,7 +720,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -729,7 +729,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -1137,7 +1137,7 @@ static char __pyx_k_convolve1d_boundary_none[] = "convolve1d_boundary_none";
 static char __pyx_k_convolve2d_boundary_none[] = "convolve2d_boundary_none";
 static char __pyx_k_convolve3d_boundary_none[] = "convolve3d_boundary_none";
 static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/convolution/boundary_none.pyx";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/convolution/boundary_none.pyx";
 static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_Convolution_kernel_must_have_odd[] = "Convolution kernel must have odd dimensions";
 static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
@@ -1151,6 +1151,7 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
 static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
 static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
 static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s_astropy_convolution_boundary_non;
 static PyObject *__pyx_n_s_bot;
@@ -1168,7 +1169,6 @@ static PyObject *__pyx_n_s_ii;
 static PyObject *__pyx_n_s_iimax;
 static PyObject *__pyx_n_s_iimin;
 static PyObject *__pyx_n_s_import;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
 static PyObject *__pyx_n_s_j;
 static PyObject *__pyx_n_s_jj;
 static PyObject *__pyx_n_s_jjmax;
@@ -3886,7 +3886,7 @@ static PyObject *__pyx_pf_7astropy_11convolution_13boundary_none_4convolve3d_bou
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -3936,7 +3936,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __Pyx_GIVEREF(__pyx_v_info->obj);
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
  *             # of flags
  * 
  *             if info == NULL: return             # <<<<<<<<<<<<<<
@@ -3949,7 +3949,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
  * 
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -3958,7 +3958,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -3967,7 +3967,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
  *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
@@ -3976,7 +3976,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
  *             ndim = PyArray_NDIM(self)
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -3986,7 +3986,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 copy_shape = 1             # <<<<<<<<<<<<<<
@@ -3998,7 +3998,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
  *                 copy_shape = 1
  *             else:
  *                 copy_shape = 0             # <<<<<<<<<<<<<<
@@ -4009,7 +4009,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
  *                 copy_shape = 0
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4023,7 +4023,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L6_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4035,7 +4035,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L6_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -4049,7 +4049,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4063,7 +4063,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L9_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4075,7 +4075,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L9_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -4089,7 +4089,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
@@ -4098,7 +4098,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
  * 
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim             # <<<<<<<<<<<<<<
@@ -4107,7 +4107,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->ndim = __pyx_v_ndim;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim
  *             if copy_shape:             # <<<<<<<<<<<<<<
@@ -4117,7 +4117,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (__pyx_v_copy_shape != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
@@ -4126,7 +4126,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
@@ -4135,7 +4135,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):             # <<<<<<<<<<<<<<
@@ -4146,7 +4146,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
       __pyx_v_i = __pyx_t_5;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
@@ -4155,7 +4155,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
       (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]
  *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
@@ -4168,7 +4168,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
  *                     info.shape[i] = PyArray_DIMS(self)[i]
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
@@ -4177,7 +4177,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
@@ -4188,7 +4188,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L11:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
@@ -4197,7 +4197,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->suboffsets = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
@@ -4206,7 +4206,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)
  *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
@@ -4215,7 +4215,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
  * 
  *             cdef int t
  *             cdef char* f = NULL             # <<<<<<<<<<<<<<
@@ -4224,7 +4224,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_f = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
  *             cdef int t
  *             cdef char* f = NULL
  *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
@@ -4236,7 +4236,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
  *             cdef int offset
  * 
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
@@ -4245,7 +4245,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
  * 
  *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
@@ -4263,7 +4263,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L15_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
  *             if not hasfields and not copy_shape:
  *                 # do not call releasebuffer
  *                 info.obj = None             # <<<<<<<<<<<<<<
@@ -4279,7 +4279,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
  *             else:
  *                 # need to call releasebuffer
  *                 info.obj = self             # <<<<<<<<<<<<<<
@@ -4294,7 +4294,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L14:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
  *                 info.obj = self
  * 
  *             if not hasfields:             # <<<<<<<<<<<<<<
@@ -4304,7 +4304,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
  * 
  *             if not hasfields:
  *                 t = descr.type_num             # <<<<<<<<<<<<<<
@@ -4314,7 +4314,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_4 = __pyx_v_descr->type_num;
     __pyx_v_t = __pyx_t_4;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
  *             if not hasfields:
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -4334,7 +4334,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L20_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -4352,7 +4352,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_L19_bool_binop_done:;
     if (__pyx_t_1) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4366,7 +4366,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4375,7 +4375,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     switch (__pyx_v_t) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
@@ -4386,7 +4386,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_b;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
@@ -4397,7 +4397,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_B;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
@@ -4408,7 +4408,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_h;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
@@ -4419,7 +4419,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_H;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
@@ -4430,7 +4430,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_i;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
@@ -4441,7 +4441,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_I;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
@@ -4452,7 +4452,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_l;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
@@ -4463,7 +4463,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_L;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
@@ -4474,7 +4474,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
@@ -4485,7 +4485,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
@@ -4496,7 +4496,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_f;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
@@ -4507,7 +4507,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_d;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
@@ -4518,7 +4518,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_g;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
@@ -4529,7 +4529,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zf;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
@@ -4540,7 +4540,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zd;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
@@ -4551,7 +4551,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zg;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4563,7 +4563,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
       default:
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -4589,7 +4589,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f             # <<<<<<<<<<<<<<
@@ -4598,7 +4598,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = __pyx_v_f;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f
  *                 return             # <<<<<<<<<<<<<<
@@ -4610,7 +4610,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
  *                 return
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
@@ -4619,7 +4619,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = ((char *)malloc(255));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
@@ -4628,7 +4628,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     (__pyx_v_info->format[0]) = '^';
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0             # <<<<<<<<<<<<<<
@@ -4637,7 +4637,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_offset = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0
  *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
@@ -4647,7 +4647,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_f = __pyx_t_7;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
  *                                       info.format + _buffer_format_string_len,
  *                                       &offset)
  *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
@@ -4657,7 +4657,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     (__pyx_v_f[0]) = '\x00';
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -4689,7 +4689,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -4713,7 +4713,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
@@ -4723,7 +4723,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
@@ -4735,7 +4735,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -4745,7 +4745,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
@@ -4757,7 +4757,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -4769,7 +4769,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -4786,7 +4786,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
  * 
  * cdef inline object PyArray_MultiIterNew1(a):
  *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
@@ -4800,7 +4800,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -4819,7 +4819,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -4836,7 +4836,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
@@ -4850,7 +4850,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -4869,7 +4869,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -4886,7 +4886,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
@@ -4900,7 +4900,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -4919,7 +4919,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -4936,7 +4936,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
@@ -4950,7 +4950,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -4969,7 +4969,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -4986,7 +4986,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
@@ -5000,7 +5000,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5019,7 +5019,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -5051,7 +5051,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_util_dtypestring", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
  *     cdef int delta_offset
  *     cdef tuple i
  *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -5060,7 +5060,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
  *     cdef tuple i
  *     cdef int endian_detector = 1
  *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -5069,7 +5069,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -5091,7 +5091,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
  * 
  *     for childname in descr.names:
  *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
@@ -5104,7 +5104,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
  *     for childname in descr.names:
  *         fields = descr.fields[childname]
  *         child, new_offset = fields             # <<<<<<<<<<<<<<
@@ -5143,7 +5143,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
  *         child, new_offset = fields
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
@@ -5160,7 +5160,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -5174,7 +5174,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
  * 
  *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -5194,7 +5194,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L8_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -5212,7 +5212,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_L7_bool_binop_done:;
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -5226,7 +5226,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
  * 
  *         # Output padding bytes
  *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
@@ -5242,7 +5242,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (!__pyx_t_6) break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
  *         # Output padding bytes
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
@@ -5251,7 +5251,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       (__pyx_v_f[0]) = 120;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5260,7 +5260,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       __pyx_v_f = (__pyx_v_f + 1);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
  *             f[0] = 120 # "x"; pad byte
  *             f += 1
  *             offset[0] += 1             # <<<<<<<<<<<<<<
@@ -5271,7 +5271,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
  *             offset[0] += 1
  * 
  *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
@@ -5281,7 +5281,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_8 = 0;
     (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
  *         offset[0] += child.itemsize
  * 
  *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
@@ -5291,7 +5291,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
  * 
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num             # <<<<<<<<<<<<<<
@@ -5303,7 +5303,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num
  *             if end - f < 5:             # <<<<<<<<<<<<<<
@@ -5313,7 +5313,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_6) {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -5327,7 +5327,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
@@ -5345,7 +5345,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
@@ -5363,7 +5363,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
@@ -5381,7 +5381,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
@@ -5399,7 +5399,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
@@ -5417,7 +5417,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
@@ -5435,7 +5435,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
@@ -5453,7 +5453,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
@@ -5471,7 +5471,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
@@ -5489,7 +5489,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
@@ -5507,7 +5507,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
@@ -5525,7 +5525,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
@@ -5543,7 +5543,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
@@ -5561,7 +5561,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
@@ -5581,7 +5581,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
@@ -5601,7 +5601,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
@@ -5621,7 +5621,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
@@ -5640,7 +5640,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       /*else*/ {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -5663,7 +5663,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       __pyx_L15:;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5675,7 +5675,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     /*else*/ {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
  *             # Cython ignores struct boundary information ("T{...}"),
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
@@ -5687,7 +5687,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L13:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -5697,7 +5697,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)
  *     return f             # <<<<<<<<<<<<<<
@@ -5707,7 +5707,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   __pyx_r = __pyx_v_f;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -5732,7 +5732,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -5747,7 +5747,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
  * cdef inline void set_array_base(ndarray arr, object base):
  *      cdef PyObject* baseptr
  *      if base is None:             # <<<<<<<<<<<<<<
@@ -5758,7 +5758,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
  *      cdef PyObject* baseptr
  *      if base is None:
  *          baseptr = NULL             # <<<<<<<<<<<<<<
@@ -5770,7 +5770,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
  *          baseptr = NULL
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
@@ -5779,7 +5779,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
     Py_INCREF(__pyx_v_base);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
@@ -5790,7 +5790,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
@@ -5799,7 +5799,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   Py_XDECREF(__pyx_v_arr->base);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)
  *      arr.base = baseptr             # <<<<<<<<<<<<<<
@@ -5808,7 +5808,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   __pyx_v_arr->base = __pyx_v_baseptr;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -5820,7 +5820,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -5834,7 +5834,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("get_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
  * 
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:             # <<<<<<<<<<<<<<
@@ -5844,7 +5844,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:
  *         return None             # <<<<<<<<<<<<<<
@@ -5858,7 +5858,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
  *         return None
  *     else:
  *         return <object>arr.base             # <<<<<<<<<<<<<<
@@ -5869,7 +5869,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -5913,6 +5913,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
   {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s_astropy_convolution_boundary_non, __pyx_k_astropy_convolution_boundary_non, sizeof(__pyx_k_astropy_convolution_boundary_non), 0, 0, 1, 1},
   {&__pyx_n_s_bot, __pyx_k_bot, sizeof(__pyx_k_bot), 0, 0, 1, 1},
@@ -5930,7 +5931,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_iimax, __pyx_k_iimax, sizeof(__pyx_k_iimax), 0, 0, 1, 1},
   {&__pyx_n_s_iimin, __pyx_k_iimin, sizeof(__pyx_k_iimin), 0, 0, 1, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
   {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},
   {&__pyx_n_s_jj, __pyx_k_jj, sizeof(__pyx_k_jj), 0, 0, 1, 1},
   {&__pyx_n_s_jjmax, __pyx_k_jjmax, sizeof(__pyx_k_jjmax), 0, 0, 1, 1},
@@ -6008,7 +6008,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -6019,7 +6019,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__4);
   __Pyx_GIVEREF(__pyx_tuple__4);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -6030,7 +6030,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6041,7 +6041,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__6);
   __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -6052,7 +6052,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__7);
   __Pyx_GIVEREF(__pyx_tuple__7);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6063,7 +6063,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -6084,7 +6084,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__10 = PyTuple_Pack(15, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_nkx, __pyx_n_s_wkx, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_ii, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
-  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve1d_boundary_none, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve1d_boundary_none, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_none.pyx":80
  * 
@@ -6096,7 +6096,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__12 = PyTuple_Pack(22, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_tuple__12);
   __Pyx_GIVEREF(__pyx_tuple__12);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve2d_boundary_none, 80, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 22, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve2d_boundary_none, 80, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_none.pyx":154
  * 
@@ -6108,7 +6108,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__14 = PyTuple_Pack(29, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_nkz, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_wkz, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_kk, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_kkmin, __pyx_n_s_kkmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_ [...]
   __Pyx_GOTREF(__pyx_tuple__14);
   __Pyx_GIVEREF(__pyx_tuple__14);
-  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 29, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve3d_boundary_none, 154, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 29, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve3d_boundary_none, 154, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -6294,7 +6294,7 @@ PyMODINIT_FUNC PyInit_boundary_none(void)
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
diff --git a/astropy/convolution/boundary_wrap.c b/astropy/convolution/boundary_wrap.c
index c198d6a..ac0574a 100644
--- a/astropy/convolution/boundary_wrap.c
+++ b/astropy/convolution/boundary_wrap.c
@@ -482,7 +482,7 @@ typedef struct {
 } __Pyx_BufFmt_Context;
 
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -491,7 +491,7 @@ typedef struct {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -500,7 +500,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -509,7 +509,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -518,7 +518,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -527,7 +527,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -536,7 +536,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -545,7 +545,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -554,7 +554,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -563,7 +563,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -572,7 +572,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -581,7 +581,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -590,7 +590,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -599,7 +599,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -608,7 +608,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -617,7 +617,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -626,7 +626,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -635,7 +635,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -644,7 +644,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -653,7 +653,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -662,7 +662,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -702,7 +702,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_wrap_DT
 
 /*--- Type declarations ---*/
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -711,7 +711,7 @@ typedef __pyx_t_5numpy_float_t __pyx_t_7astropy_11convolution_13boundary_wrap_DT
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -720,7 +720,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -729,7 +729,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -1140,7 +1140,7 @@ static char __pyx_k_convolve1d_boundary_wrap[] = "convolve1d_boundary_wrap";
 static char __pyx_k_convolve2d_boundary_wrap[] = "convolve2d_boundary_wrap";
 static char __pyx_k_convolve3d_boundary_wrap[] = "convolve3d_boundary_wrap";
 static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/convolution/boundary_wrap.pyx";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/convolution/boundary_wrap.pyx";
 static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_Convolution_kernel_must_have_odd[] = "Convolution kernel must have odd dimensions";
 static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
@@ -1154,6 +1154,7 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
 static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
 static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
 static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s_astropy_convolution_boundary_wra;
 static PyObject *__pyx_n_s_bot;
@@ -1173,7 +1174,6 @@ static PyObject *__pyx_n_s_iii;
 static PyObject *__pyx_n_s_iimax;
 static PyObject *__pyx_n_s_iimin;
 static PyObject *__pyx_n_s_import;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
 static PyObject *__pyx_n_s_j;
 static PyObject *__pyx_n_s_jj;
 static PyObject *__pyx_n_s_jjj;
@@ -4266,7 +4266,7 @@ static PyObject *__pyx_pf_7astropy_11convolution_13boundary_wrap_4convolve3d_bou
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -4316,7 +4316,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __Pyx_GIVEREF(__pyx_v_info->obj);
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
  *             # of flags
  * 
  *             if info == NULL: return             # <<<<<<<<<<<<<<
@@ -4329,7 +4329,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
  * 
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -4338,7 +4338,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -4347,7 +4347,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
  *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
@@ -4356,7 +4356,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
  *             ndim = PyArray_NDIM(self)
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -4366,7 +4366,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 copy_shape = 1             # <<<<<<<<<<<<<<
@@ -4378,7 +4378,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
  *                 copy_shape = 1
  *             else:
  *                 copy_shape = 0             # <<<<<<<<<<<<<<
@@ -4389,7 +4389,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
  *                 copy_shape = 0
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4403,7 +4403,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L6_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4415,7 +4415,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L6_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -4429,7 +4429,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -4443,7 +4443,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L9_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -4455,7 +4455,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L9_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -4469,7 +4469,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
@@ -4478,7 +4478,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
  * 
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim             # <<<<<<<<<<<<<<
@@ -4487,7 +4487,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->ndim = __pyx_v_ndim;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim
  *             if copy_shape:             # <<<<<<<<<<<<<<
@@ -4497,7 +4497,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (__pyx_v_copy_shape != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
@@ -4506,7 +4506,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
@@ -4515,7 +4515,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):             # <<<<<<<<<<<<<<
@@ -4526,7 +4526,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
       __pyx_v_i = __pyx_t_5;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
@@ -4535,7 +4535,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
       (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]
  *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
@@ -4548,7 +4548,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
  *                     info.shape[i] = PyArray_DIMS(self)[i]
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
@@ -4557,7 +4557,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
@@ -4568,7 +4568,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L11:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
@@ -4577,7 +4577,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->suboffsets = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
@@ -4586,7 +4586,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)
  *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
@@ -4595,7 +4595,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
  * 
  *             cdef int t
  *             cdef char* f = NULL             # <<<<<<<<<<<<<<
@@ -4604,7 +4604,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_f = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
  *             cdef int t
  *             cdef char* f = NULL
  *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
@@ -4616,7 +4616,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
  *             cdef int offset
  * 
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
@@ -4625,7 +4625,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
  * 
  *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
@@ -4643,7 +4643,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L15_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
  *             if not hasfields and not copy_shape:
  *                 # do not call releasebuffer
  *                 info.obj = None             # <<<<<<<<<<<<<<
@@ -4659,7 +4659,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
  *             else:
  *                 # need to call releasebuffer
  *                 info.obj = self             # <<<<<<<<<<<<<<
@@ -4674,7 +4674,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L14:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
  *                 info.obj = self
  * 
  *             if not hasfields:             # <<<<<<<<<<<<<<
@@ -4684,7 +4684,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
  * 
  *             if not hasfields:
  *                 t = descr.type_num             # <<<<<<<<<<<<<<
@@ -4694,7 +4694,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_4 = __pyx_v_descr->type_num;
     __pyx_v_t = __pyx_t_4;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
  *             if not hasfields:
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -4714,7 +4714,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L20_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -4732,7 +4732,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_L19_bool_binop_done:;
     if (__pyx_t_1) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4746,7 +4746,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4755,7 +4755,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     switch (__pyx_v_t) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
@@ -4766,7 +4766,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_b;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
@@ -4777,7 +4777,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_B;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
@@ -4788,7 +4788,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_h;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
@@ -4799,7 +4799,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_H;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
@@ -4810,7 +4810,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_i;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
@@ -4821,7 +4821,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_I;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
@@ -4832,7 +4832,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_l;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
@@ -4843,7 +4843,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_L;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
@@ -4854,7 +4854,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
@@ -4865,7 +4865,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
@@ -4876,7 +4876,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_f;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
@@ -4887,7 +4887,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_d;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
@@ -4898,7 +4898,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_g;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
@@ -4909,7 +4909,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zf;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
@@ -4920,7 +4920,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zd;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
@@ -4931,7 +4931,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zg;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -4943,7 +4943,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
       default:
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -4969,7 +4969,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f             # <<<<<<<<<<<<<<
@@ -4978,7 +4978,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = __pyx_v_f;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f
  *                 return             # <<<<<<<<<<<<<<
@@ -4990,7 +4990,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
  *                 return
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
@@ -4999,7 +4999,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = ((char *)malloc(255));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
@@ -5008,7 +5008,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     (__pyx_v_info->format[0]) = '^';
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0             # <<<<<<<<<<<<<<
@@ -5017,7 +5017,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_offset = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0
  *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
@@ -5027,7 +5027,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_f = __pyx_t_7;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
  *                                       info.format + _buffer_format_string_len,
  *                                       &offset)
  *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
@@ -5037,7 +5037,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     (__pyx_v_f[0]) = '\x00';
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -5069,7 +5069,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5093,7 +5093,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
@@ -5103,7 +5103,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
@@ -5115,7 +5115,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -5125,7 +5125,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
@@ -5137,7 +5137,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -5149,7 +5149,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5166,7 +5166,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
  * 
  * cdef inline object PyArray_MultiIterNew1(a):
  *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
@@ -5180,7 +5180,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -5199,7 +5199,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5216,7 +5216,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
@@ -5230,7 +5230,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -5249,7 +5249,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5266,7 +5266,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
@@ -5280,7 +5280,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -5299,7 +5299,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5316,7 +5316,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
@@ -5330,7 +5330,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -5349,7 +5349,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5366,7 +5366,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
@@ -5380,7 +5380,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -5399,7 +5399,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -5431,7 +5431,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_util_dtypestring", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
  *     cdef int delta_offset
  *     cdef tuple i
  *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -5440,7 +5440,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
  *     cdef tuple i
  *     cdef int endian_detector = 1
  *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -5449,7 +5449,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -5471,7 +5471,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
  * 
  *     for childname in descr.names:
  *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
@@ -5484,7 +5484,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
  *     for childname in descr.names:
  *         fields = descr.fields[childname]
  *         child, new_offset = fields             # <<<<<<<<<<<<<<
@@ -5523,7 +5523,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
  *         child, new_offset = fields
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
@@ -5540,7 +5540,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -5554,7 +5554,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
  * 
  *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -5574,7 +5574,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L8_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -5592,7 +5592,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_L7_bool_binop_done:;
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -5606,7 +5606,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
  * 
  *         # Output padding bytes
  *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
@@ -5622,7 +5622,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (!__pyx_t_6) break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
  *         # Output padding bytes
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
@@ -5631,7 +5631,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       (__pyx_v_f[0]) = 120;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte
  *             f += 1             # <<<<<<<<<<<<<<
@@ -5640,7 +5640,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       __pyx_v_f = (__pyx_v_f + 1);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
  *             f[0] = 120 # "x"; pad byte
  *             f += 1
  *             offset[0] += 1             # <<<<<<<<<<<<<<
@@ -5651,7 +5651,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
  *             offset[0] += 1
  * 
  *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
@@ -5661,7 +5661,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_8 = 0;
     (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
  *         offset[0] += child.itemsize
  * 
  *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
@@ -5671,7 +5671,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
  * 
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num             # <<<<<<<<<<<<<<
@@ -5683,7 +5683,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num
  *             if end - f < 5:             # <<<<<<<<<<<<<<
@@ -5693,7 +5693,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_6) {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -5707,7 +5707,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
@@ -5725,7 +5725,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
@@ -5743,7 +5743,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
@@ -5761,7 +5761,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
@@ -5779,7 +5779,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
@@ -5797,7 +5797,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
@@ -5815,7 +5815,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
@@ -5833,7 +5833,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
@@ -5851,7 +5851,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
@@ -5869,7 +5869,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
@@ -5887,7 +5887,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
@@ -5905,7 +5905,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
@@ -5923,7 +5923,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
@@ -5941,7 +5941,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
@@ -5961,7 +5961,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
@@ -5981,7 +5981,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
@@ -6001,7 +6001,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
@@ -6020,7 +6020,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       /*else*/ {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -6043,7 +6043,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       __pyx_L15:;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *             f += 1             # <<<<<<<<<<<<<<
@@ -6055,7 +6055,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     /*else*/ {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
  *             # Cython ignores struct boundary information ("T{...}"),
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
@@ -6067,7 +6067,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L13:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -6077,7 +6077,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)
  *     return f             # <<<<<<<<<<<<<<
@@ -6087,7 +6087,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   __pyx_r = __pyx_v_f;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -6112,7 +6112,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6127,7 +6127,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
  * cdef inline void set_array_base(ndarray arr, object base):
  *      cdef PyObject* baseptr
  *      if base is None:             # <<<<<<<<<<<<<<
@@ -6138,7 +6138,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
  *      cdef PyObject* baseptr
  *      if base is None:
  *          baseptr = NULL             # <<<<<<<<<<<<<<
@@ -6150,7 +6150,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
  *          baseptr = NULL
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
@@ -6159,7 +6159,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
     Py_INCREF(__pyx_v_base);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
@@ -6170,7 +6170,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
@@ -6179,7 +6179,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   Py_XDECREF(__pyx_v_arr->base);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)
  *      arr.base = baseptr             # <<<<<<<<<<<<<<
@@ -6188,7 +6188,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   __pyx_v_arr->base = __pyx_v_baseptr;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -6200,7 +6200,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6214,7 +6214,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("get_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
  * 
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:             # <<<<<<<<<<<<<<
@@ -6224,7 +6224,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:
  *         return None             # <<<<<<<<<<<<<<
@@ -6238,7 +6238,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
  *         return None
  *     else:
  *         return <object>arr.base             # <<<<<<<<<<<<<<
@@ -6249,7 +6249,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -6293,6 +6293,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
   {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s_astropy_convolution_boundary_wra, __pyx_k_astropy_convolution_boundary_wra, sizeof(__pyx_k_astropy_convolution_boundary_wra), 0, 0, 1, 1},
   {&__pyx_n_s_bot, __pyx_k_bot, sizeof(__pyx_k_bot), 0, 0, 1, 1},
@@ -6312,7 +6313,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_iimax, __pyx_k_iimax, sizeof(__pyx_k_iimax), 0, 0, 1, 1},
   {&__pyx_n_s_iimin, __pyx_k_iimin, sizeof(__pyx_k_iimin), 0, 0, 1, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
   {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},
   {&__pyx_n_s_jj, __pyx_k_jj, sizeof(__pyx_k_jj), 0, 0, 1, 1},
   {&__pyx_n_s_jjj, __pyx_k_jjj, sizeof(__pyx_k_jjj), 0, 0, 1, 1},
@@ -6391,7 +6391,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -6402,7 +6402,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__4);
   __Pyx_GIVEREF(__pyx_tuple__4);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -6413,7 +6413,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6424,7 +6424,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__6);
   __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -6435,7 +6435,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__7);
   __Pyx_GIVEREF(__pyx_tuple__7);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -6446,7 +6446,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -6467,7 +6467,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__10 = PyTuple_Pack(16, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_nkx, __pyx_n_s_wkx, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_iii, __pyx_n_s_ii, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
-  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve1d_boundary_wrap, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 16, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve1d_boundary_wrap, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_wrap.pyx":84
  * 
@@ -6479,7 +6479,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__12 = PyTuple_Pack(24, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_n_s_ker, __pyx_n_s_val); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno  [...]
   __Pyx_GOTREF(__pyx_tuple__12);
   __Pyx_GIVEREF(__pyx_tuple__12);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve2d_boundary_wrap, 84, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(2, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve2d_boundary_wrap, 84, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "astropy/convolution/boundary_wrap.pyx":167
  * 
@@ -6491,7 +6491,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__14 = PyTuple_Pack(32, __pyx_n_s_f, __pyx_n_s_g, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_nkx, __pyx_n_s_nky, __pyx_n_s_nkz, __pyx_n_s_wkx, __pyx_n_s_wky, __pyx_n_s_wkz, __pyx_n_s_fixed, __pyx_n_s_conv, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_iii, __pyx_n_s_jjj, __pyx_n_s_kkk, __pyx_n_s_ii, __pyx_n_s_jj, __pyx_n_s_kk, __pyx_n_s_iimin, __pyx_n_s_iimax, __pyx_n_s_jjmin, __pyx_n_s_jjmax, __pyx_n_s_kkmin, __pyx_n_s_kkmax, __pyx_n_s_top, __pyx_n_s_bot, __pyx_ [...]
   __Pyx_GOTREF(__pyx_tuple__14);
   __Pyx_GIVEREF(__pyx_tuple__14);
-  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 32, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_convolve3d_boundary_wrap, 167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 32, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_convolve3d_boundary_wrap, 167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -6677,7 +6677,7 @@ PyMODINIT_FUNC PyInit_boundary_wrap(void)
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
diff --git a/astropy/convolution/convolve.py b/astropy/convolution/convolve.py
index 426200b..4d346e5 100644
--- a/astropy/convolution/convolve.py
+++ b/astropy/convolution/convolve.py
@@ -388,7 +388,7 @@ def convolve_fft(array, kernel, boundary='fill', fill_value=0, crop=True,
     arrayshape = array.shape
     kernshape = kernel.shape
 
-    array_size_B = (np.product(arrayshape, dtype=np.int64) * 
+    array_size_B = (np.product(arrayshape, dtype=np.int64) *
                     np.dtype(complex_dtype).itemsize)
     if array_size_B > 1024**3 and not allow_huge:
         raise ValueError("Size Error: Arrays will be %s.  Use "
@@ -474,11 +474,11 @@ def convolve_fft(array, kernel, boundary='fill', fill_value=0, crop=True,
             newshape = np.array([np.max([imsh, kernsh])
                                  for imsh, kernsh in zip(arrayshape, kernshape)])
 
-    # For future reference, this can be used to predict "almost exactly" 
+    # For future reference, this can be used to predict "almost exactly"
     # how much *additional* memory will be used.
-    # size * (array + kernel + kernelfft + arrayfft + 
-    #         (kernel*array)fft + 
-    #         optional(weight image + weight_fft + weight_ifft) + 
+    # size * (array + kernel + kernelfft + arrayfft +
+    #         (kernel*array)fft +
+    #         optional(weight image + weight_fft + weight_ifft) +
     #         optional(returned_fft))
     #total_memory_used_GB = (np.product(newshape)*np.dtype(complex_dtype).itemsize
     #                        * (5 + 3*((interpolate_nan or ignore_edge_zeros) and kernel_is_normalized))
diff --git a/astropy/convolution/kernels.py b/astropy/convolution/kernels.py
index 1279fcb..08e091c 100644
--- a/astropy/convolution/kernels.py
+++ b/astropy/convolution/kernels.py
@@ -363,7 +363,7 @@ class Ring2DKernel(Kernel2D):
         Inner radius of the ring kernel.
     width : number
         Width of the ring kernel.
-    mode: str, optional
+    mode : str, optional
         One of the following discretization modes:
             * 'center' (default)
                 Discretize model by taking the value
@@ -416,7 +416,7 @@ class Trapezoid1DKernel(Kernel1D):
     Parameters
     ----------
     width : number
-        Width of the filter kernel, defined as the width of the constant part, 
+        Width of the filter kernel, defined as the width of the constant part,
         before it begins to slope down.
     slope : number
         Slope of the filter kernel's tails
@@ -474,7 +474,7 @@ class TrapezoidDisk2DKernel(Kernel2D):
     Parameters
     ----------
     radius : number
-        Width of the filter kernel, defined as the width of the constant part, 
+        Width of the filter kernel, defined as the width of the constant part,
         before it begins to slope down.
     slope : number
         Slope of the filter kernel's tails
diff --git a/astropy/convolution/tests/test_discretize.py b/astropy/convolution/tests/test_discretize.py
index c798a28..9bd6658 100644
--- a/astropy/convolution/tests/test_discretize.py
+++ b/astropy/convolution/tests/test_discretize.py
@@ -104,3 +104,52 @@ def test_subpixel_gauss_2D():
     gauss_2D = Gaussian2D(1, 0, 0, 0.1, 0.1)
     values = discretize_model(gauss_2D, (-1, 2), (-1, 2), mode='integrate', factor=100)
     assert_allclose(values.sum(), 2 * np.pi * 0.01, atol=0.00001)
+
+def test_discretize_callable_1d():
+    """
+    Test discretize when a 1d function is passed.
+    """
+    def f(x):
+        return x ** 2
+    y = discretize_model(f, (-5, 6))
+    assert_allclose(y, np.arange(-5, 6) ** 2)
+
+def test_discretize_callable_2d():
+    """
+    Test discretize when a 2d function is passed.
+    """
+    def f(x, y):
+        return x ** 2 + y ** 2
+    actual = discretize_model(f, (-5, 6), (-5, 6))
+    y, x = (np.indices((11, 11)) - 5)
+    desired = x ** 2 + y ** 2
+    assert_allclose(actual, desired)
+
+def test_type_exception():
+    """
+    Test type exception.
+    """
+    with pytest.raises(TypeError) as exc:
+        discretize_model(float(0), (-10, 11))
+    assert exc.value.args[0] == 'Model must be callable.'
+
+def test_dim_exception_1d():
+    """
+    Test dimension exception 1d.
+    """
+    def f(x):
+        return x ** 2
+    with pytest.raises(ValueError) as exc:
+        discretize_model(f, (-10, 11), (-10, 11))
+    assert exc.value.args[0] == "y range specified, but model is only 1-d."
+
+def test_dim_exception_2d():
+    """
+    Test dimension exception 2d.
+    """
+    def f(x, y):
+        return x ** 2 + y ** 2
+    with pytest.raises(ValueError) as exc:
+        discretize_model(f, (-10, 11))
+    assert exc.value.args[0] == "y range not specified, but model is 2-d"
+
diff --git a/astropy/convolution/tests/test_pickle.py b/astropy/convolution/tests/test_pickle.py
new file mode 100644
index 0000000..e88534b
--- /dev/null
+++ b/astropy/convolution/tests/test_pickle.py
@@ -0,0 +1,24 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import absolute_import, division, print_function, unicode_literals
+import numpy as np
+from ...extern.six.moves import cPickle
+from ... import convolution as conv
+from ...tests.helper import pytest, pickle_protocol, check_pickling_recovery
+
+ at pytest.mark.parametrize("name,args,kwargs,xfail",
+                         [(conv.CustomKernel, [],
+                           {'array':np.random.rand(15)},
+                           False),
+                          (conv.Gaussian1DKernel, [1.0],
+                           {'x_size':5},
+                           True),
+                          (conv.Gaussian2DKernel, [1.0],
+                           {'x_size':5, 'y_size':5},
+                           True),
+                         ])
+def test_simple_object(pickle_protocol, name, args, kwargs, xfail):
+    # Tests easily instantiated objects
+    if xfail:
+        pytest.xfail()
+    original = name(*args, **kwargs)
+    check_pickling_recovery(original, pickle_protocol)
diff --git a/astropy/convolution/utils.py b/astropy/convolution/utils.py
index 8de4b9c..387eb37 100644
--- a/astropy/convolution/utils.py
+++ b/astropy/convolution/utils.py
@@ -4,8 +4,7 @@ from __future__ import (absolute_import, division, print_function,
 
 import numpy as np
 
-from ..modeling.core import Fittable1DModel, Fittable2DModel
-
+from ..modeling.core import FittableModel, custom_model
 
 __all__ = ['discretize_model']
 
@@ -74,12 +73,16 @@ def add_kernel_arrays_2D(array_1, array_2):
 
 def discretize_model(model, x_range, y_range=None, mode='center', factor=10):
     """
-    Function to evaluate analytical models on a grid.
+    Function to evaluate analytical model functions on a grid.
+
+    So far the function can only deal with pixel coordinates.
 
     Parameters
     ----------
-    model : `~astropy.modeling.FittableModel`
-        Model to be evaluated.
+    model : `~astropy.modeling.FittableModel` or callable.
+        Analytic model function to be discretized. Callables, which are not an
+        instances of `~astropy.modeling.FittableModel` are passed to
+        `~astropy.modeling.custom_model` and then evaluated.
     x_range : tuple
         x range in which the model is evaluated.
     y_range : tuple, optional
@@ -135,27 +138,37 @@ def discretize_model(model, x_range, y_range=None, mode='center', factor=10):
 
 
     """
-    if isinstance(model, Fittable2DModel) and y_range is None:
-        raise Exception("Please specify y range.")
+    if not callable(model):
+        raise TypeError('Model must be callable.')
+    if not isinstance(model, FittableModel):
+        model = custom_model(model)()
+    ndim = model.n_inputs
+    if ndim > 2:
+        raise ValueError('discretize_model only supports 1-d and 2-d models.')
+
+    if ndim == 2 and y_range is None:
+        raise ValueError("y range not specified, but model is 2-d")
+    if ndim == 1 and y_range is not None:
+        raise ValueError("y range specified, but model is only 1-d.")
     if mode == "center":
-        if isinstance(model, Fittable1DModel):
+        if ndim == 1:
             return discretize_center_1D(model, x_range)
-        if isinstance(model, Fittable2DModel):
+        elif ndim == 2:
             return discretize_center_2D(model, x_range, y_range)
     elif mode == "linear_interp":
-        if isinstance(model, Fittable1DModel):
+        if ndim == 1:
             return discretize_linear_1D(model, x_range)
-        if isinstance(model, Fittable2DModel):
+        if ndim == 2:
             return discretize_bilinear_2D(model, x_range, y_range)
     elif mode == "oversample":
-        if isinstance(model, Fittable1DModel):
+        if ndim == 1:
             return discretize_oversample_1D(model, x_range, factor)
-        if isinstance(model, Fittable2DModel):
+        if ndim == 2:
             return discretize_oversample_2D(model, x_range, y_range, factor)
     elif mode == "integrate":
-        if isinstance(model, Fittable1DModel):
+        if ndim == 1:
             return discretize_integrate_1D(model, x_range)
-        if isinstance(model, Fittable2DModel):
+        if ndim == 2:
             return discretize_integrate_2D(model, x_range, y_range)
     else:
         raise DiscretizationError('Invalid mode.')
diff --git a/astropy/coordinates/__init__.py b/astropy/coordinates/__init__.py
index cfb1722..c0ebf5a 100644
--- a/astropy/coordinates/__init__.py
+++ b/astropy/coordinates/__init__.py
@@ -19,5 +19,6 @@ from .name_resolve import *
 from .matching import *
 from .representation import *
 from .sky_coordinate import *
+from .funcs import *
 
 __doc__ += builtin_frames._transform_graph_docs
diff --git a/astropy/coordinates/angle_utilities.py b/astropy/coordinates/angle_utilities.py
index ce3e478..533b0df 100644
--- a/astropy/coordinates/angle_utilities.py
+++ b/astropy/coordinates/angle_utilities.py
@@ -149,21 +149,21 @@ class _AngleParser(object):
 
         def p_colon(p):
             '''
-            colon : sign UINT COLON UINT
+            colon : sign UINT COLON ufloat
                   | sign UINT COLON UINT COLON ufloat
             '''
             if len(p) == 5:
-                p[0] = (p[1] * p[2], p[4], 0.0)
+                p[0] = (p[1] * p[2], p[4])
             elif len(p) == 7:
                 p[0] = (p[1] * p[2], p[4], p[6])
 
         def p_spaced(p):
             '''
-            spaced : sign UINT UINT
+            spaced : sign UINT ufloat
                    | sign UINT UINT ufloat
             '''
             if len(p) == 4:
-                p[0] = (p[1] * p[2], p[3], 0.0)
+                p[0] = (p[1] * p[2], p[3])
             elif len(p) == 5:
                 p[0] = (p[1] * p[2], p[3], p[4])
 
@@ -182,8 +182,9 @@ class _AngleParser(object):
         def p_hms(p):
             '''
             hms : sign UINT HOUR
-                | sign UINT HOUR UINT
+                | sign UINT HOUR ufloat
                 | sign UINT HOUR UINT MINUTE
+                | sign UINT HOUR UFLOAT MINUTE
                 | sign UINT HOUR UINT MINUTE ufloat
                 | sign UINT HOUR UINT MINUTE ufloat SECOND
                 | generic HOUR
@@ -193,15 +194,16 @@ class _AngleParser(object):
             elif len(p) == 4:
                 p[0] = (p[1] * p[2], u.hourangle)
             elif len(p) in (5, 6):
-                p[0] = ((p[1] * p[2], p[4], 0.0), u.hourangle)
+                p[0] = ((p[1] * p[2], p[4]), u.hourangle)
             elif len(p) in (7, 8):
                 p[0] = ((p[1] * p[2], p[4], p[6]), u.hourangle)
 
         def p_dms(p):
             '''
             dms : sign UINT DEGREE
-                | sign UINT DEGREE UINT
+                | sign UINT DEGREE ufloat
                 | sign UINT DEGREE UINT MINUTE
+                | sign UINT DEGREE UFLOAT MINUTE
                 | sign UINT DEGREE UINT MINUTE ufloat
                 | sign UINT DEGREE UINT MINUTE ufloat SECOND
                 | generic DEGREE
@@ -211,7 +213,7 @@ class _AngleParser(object):
             elif len(p) == 4:
                 p[0] = (p[1] * p[2], u.degree)
             elif len(p) in (5, 6):
-                p[0] = ((p[1] * p[2], p[4], 0.0), u.degree)
+                p[0] = ((p[1] * p[2], p[4]), u.degree)
             elif len(p) in (7, 8):
                 p[0] = ((p[1] * p[2], p[4], p[6]), u.degree)
 
@@ -297,6 +299,8 @@ def _check_second_range(sec):
     """
     if np.any(sec == 60.):
         warn(IllegalSecondWarning(sec, 'Treating as 0 sec, +1 min'))
+    elif sec is None:
+        pass
     elif np.any(sec < -60.) or np.any(sec > 60.):
         # "Error: seconds not in range [-60,60) ({0}).".format(sec))
         raise IllegalSecondError(sec)
@@ -361,7 +365,7 @@ def degrees_to_dms(d):
     return np.floor(sign * d), sign * np.floor(m), sign * s
 
 
-def dms_to_degrees(d, m, s):
+def dms_to_degrees(d, m, s=None):
     """
     Convert degrees, arcminute, arcsecond to a float degrees value.
     """
@@ -372,13 +376,14 @@ def dms_to_degrees(d, m, s):
     # determine sign
     sign = np.copysign(1.0, d)
 
-    # TODO: This will fail if d or m have values after the decimal
-    # place
-
     try:
-        d = np.floor(np.abs(np.asarray(d)))
-        m = np.floor(np.abs(np.asarray(m)))
-        s = np.abs(s)
+        d = np.floor(np.abs(d))
+        if s is None:
+            m = np.abs(m)
+            s = 0
+        else:
+            m = np.floor(np.abs(m))
+            s = np.abs(s)
     except ValueError:
         raise ValueError(format_exception(
             "{func}: dms values ({1[0]},{2[1]},{3[2]}) could not be "
@@ -387,7 +392,7 @@ def dms_to_degrees(d, m, s):
     return sign * (d + m / 60. + s / 3600.)
 
 
-def hms_to_hours(h, m, s):
+def hms_to_hours(h, m, s=None):
     """
     Convert hour, minute, second to a float hour value.
     """
@@ -397,13 +402,14 @@ def hms_to_hours(h, m, s):
     # determine sign
     sign = np.copysign(1.0, h)
 
-    # TODO: This will fail if d or m have values after the decimal
-    # place
-
     try:
         h = np.floor(np.abs(h))
-        m = np.floor(np.abs(m))
-        s = np.abs(s)
+        if s is None:
+            m = np.abs(m)
+            s = 0
+        else:
+            m = np.floor(np.abs(m))
+            s = np.abs(s)
     except ValueError:
         raise ValueError(format_exception(
             "{func}: HMS values ({1[0]},{2[1]},{3[2]}) could not be "
@@ -634,7 +640,7 @@ def angular_separation(lon1, lat1, lon2, lat2):
     Notes
     -----
     The angular separation is calculated using the Vincenty formula [1]_,
-    which is slighly more complex and computationally expensive than
+    which is slightly more complex and computationally expensive than
     some alternatives, but is stable at at all distances, including the
     poles and antipodes.
 
diff --git a/astropy/coordinates/angles.py b/astropy/coordinates/angles.py
index 72353c3..29c0496 100644
--- a/astropy/coordinates/angles.py
+++ b/astropy/coordinates/angles.py
@@ -16,7 +16,7 @@ import numpy as np
 from ..extern import six
 from . import angle_utilities as util
 from .. import units as u
-from ..utils import deprecated, isiterable
+from ..utils import isiterable
 
 
 __all__ = ['Angle', 'Latitude', 'Longitude']
@@ -48,6 +48,8 @@ class Angle(u.Quantity):
       Angle(u'1°2′3″')
       Angle('1d2m3.4s')
       Angle('-1h2m3s')
+      Angle('-1h2.5m')
+      Angle('-1:2.5', unit=u.deg)
       Angle((-1, 2, 3), unit=u.deg)  # (d, m, s)
       Angle(10.2345 * u.deg)
       Angle(Angle(10.2345 * u.deg))
@@ -137,13 +139,12 @@ class Angle(u.Quantity):
     @staticmethod
     def _tuple_to_float(angle, unit):
         """
-        Converts an angle represented as a 3-tuple into a floating
+        Converts an angle represented as a 3-tuple or 2-tuple into a floating
         point number in the given unit.
         """
         if isinstance(angle, tuple):
             # TODO: Numpy array of tuples?
             if unit is u.hourangle:
-                util.check_hms_ranges(*angle)
                 angle = util.hms_to_hours(*angle)
             elif unit is u.degree:
                 angle = util.dms_to_degrees(*angle)
@@ -199,7 +200,7 @@ class Angle(u.Quantity):
         members.  The ``d``, ``m``, ``s`` are thus always positive, and the sign of
         the angle is given by ``sign``. (This is a read-only property.)
 
-        This is primarily intented for use with `dms` to generate string
+        This is primarily intended for use with `dms` to generate string
         representations of coordinates that are correct for negative angles.
         """
         return signed_dms_tuple(np.sign(self.degree),
@@ -218,7 +219,7 @@ class Angle(u.Quantity):
             used.
 
         decimal : bool, optional
-            If `True`, a decimal respresentation will be used, otherwise
+            If `True`, a decimal representation will be used, otherwise
             the returned string will be in sexagesimal form.
 
         sep : str, optional
@@ -267,8 +268,10 @@ class Angle(u.Quantity):
 
         Returns
         -------
-        strrepr : str
-            A string representation of the angle.
+        strrepr : str or array
+            A string representation of the angle. If the angle is an array, this
+            will be an array with a unicode dtype.
+
 
         """
         if unit is None:
@@ -366,8 +369,11 @@ class Angle(u.Quantity):
                 s = '${0}$'.format(s)
             return s
 
-        format_ufunc = np.vectorize(do_format, otypes=[np.object])
+        # we want unicode outputs for degree signs and such
+        # for newer numpy's, this just works as you would expect
+        format_ufunc = np.vectorize(do_format, otypes=['U'])
         result = format_ufunc(values)
+
         if result.ndim == 0:
             result = result[()]
         return result
@@ -461,13 +467,6 @@ class Angle(u.Quantity):
             ok &= np.all(self < Angle(upper))
         return bool(ok)
 
-    @deprecated("0.3", name="format", alternative="to_string")
-    def format(self, unit=u.degree, decimal=False, sep='fromunit', precision=5,
-               alwayssign=False, pad=False):
-        return self.to_string(
-            unit=unit, decimal=decimal, sep=sep, precision=precision,
-            alwayssign=alwayssign, pad=pad)
-
     def __str__(self):
         return str(self.to_string())
 
@@ -531,7 +530,7 @@ class Latitude(Angle):
 
     def _validate_angles(self, angles=None):
         """Check that angles are between -90 and 90 degrees.
-        If not given, the check is done on the object iself"""
+        If not given, the check is done on the object itself"""
         # Convert the lower and upper bounds to the "native" unit of
         # this angle.  This limits multiplication to two values,
         # rather than the N values in `self.value`.  Also, the
@@ -666,7 +665,7 @@ class Longitude(Angle):
 
     def __array_finalize__(self, obj):
         super(Longitude, self).__array_finalize__(obj)
-        self._wrap_angle = getattr(obj, '_wrap_angle', None)
+        self._wrap_angle = getattr(obj, '_wrap_angle', 360 * u.deg)
 
     # Any calculation should drop to Angle
     def __array_wrap__(self, obj, context=None):
diff --git a/astropy/coordinates/baseframe.py b/astropy/coordinates/baseframe.py
index 1052de3..6d98d81 100644
--- a/astropy/coordinates/baseframe.py
+++ b/astropy/coordinates/baseframe.py
@@ -1,8 +1,10 @@
 # -*- coding: utf-8 -*-
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 """
-Framework and base classes for coordinate frames/"low-level" coordinate classes.
+Framework and base classes for coordinate frames/"low-level" coordinate
+classes.
 """
+
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
@@ -13,50 +15,60 @@ from copy import deepcopy
 from collections import namedtuple
 
 # Dependencies
+import numpy as np
 
 # Project
 from ..utils.compat.misc import override__dir__
 from ..extern import six
-from ..utils.compat.odict import OrderedDict
-from ..utils.exceptions import AstropyDeprecationWarning
+from ..utils.exceptions import AstropyDeprecationWarning, AstropyWarning
 from .. import units as u
 from ..utils import OrderedDict
 from .transformations import TransformGraph
 from .representation import (BaseRepresentation, CartesianRepresentation,
-                             SphericalRepresentation, UnitSphericalRepresentation,
+                             SphericalRepresentation,
+                             UnitSphericalRepresentation,
                              REPRESENTATION_CLASSES)
+from .earth import EarthLocation
+
+
+__all__ = ['BaseCoordinateFrame', 'frame_transform_graph', 'GenericFrame',
+           'FrameAttribute', 'TimeFrameAttribute', 'QuantityFrameAttribute',
+           'EarthLocationAttribute', 'RepresentationMapping']
 
-__all__ = ['BaseCoordinateFrame', 'frame_transform_graph', 'GenericFrame', 'FrameAttribute',
-           'TimeFrameAttribute', 'RepresentationMapping']
 
 # the graph used for all transformations between frames
 frame_transform_graph = TransformGraph()
 
 
 def _get_repr_cls(value):
-    """Return a valid representation class from ``value`` or raise exception."""
+    """
+    Return a valid representation class from ``value`` or raise exception.
+    """
+
     if value in REPRESENTATION_CLASSES:
         value = REPRESENTATION_CLASSES[value]
     try:
-        assert issubclass(value, BaseRepresentation)  # value might not be a class, so use try
-    except:
-        raise ValueError('representation is {0!r} but must be a BaseRepresentation class '
-                         ' or one of the string aliases {1}'
-                         .format(value, list(REPRESENTATION_CLASSES)))
+        # value might not be a class, so use try
+        assert issubclass(value, BaseRepresentation)
+    except (TypeError, AssertionError):
+        raise ValueError(
+            'Representation is {0!r} but must be a BaseRepresentation class '
+            'or one of the string aliases {1}'.format(
+                value, list(REPRESENTATION_CLASSES)))
     return value
 
 
 class FrameMeta(type):
-    def __new__(cls, name, parents, clsdct):
-        if 'default_representation' in clsdct:
-            def_repr = clsdct.pop('default_representation')
-            found_def_repr = True
+    def __new__(mcls, name, bases, members):
+        if 'default_representation' in members:
+            default_repr = members.pop('default_representation')
+            found_default_repr = True
         else:
-            def_repr = None
-            found_def_repr = False
+            default_repr = None
+            found_default_repr = False
 
-        if 'frame_specific_representation_info' in clsdct:
-            repr_info = clsdct.pop('frame_specific_representation_info')
+        if 'frame_specific_representation_info' in members:
+            repr_info = members.pop('frame_specific_representation_info')
             found_repr_info = True
         else:
             repr_info = None
@@ -64,46 +76,51 @@ class FrameMeta(type):
 
         # somewhat hacky, but this is the best way to get the MRO according to
         # https://mail.python.org/pipermail/python-list/2002-December/167861.html
-        mro = super(FrameMeta, cls).__new__(cls, name, parents, clsdct).__mro__
-        parent_clsdcts = [c.__dict__ for c in mro]
-
-        #now look through the whole MRO for the class attributes, raw
-        # for frame_attr_names, and leading underscore for others
-        for clsdcti in parent_clsdcts:
-            if not found_def_repr and '_default_representation' in clsdcti:
-                def_repr = clsdcti['_default_representation']
-                found_def_repr = True
-            if not found_repr_info and '_frame_specific_representation_info' in clsdcti:
-                repr_info = clsdcti['_frame_specific_representation_info']
+        tmp_cls = super(FrameMeta, mcls).__new__(mcls, name, bases, members)
+
+        # now look through the whole MRO for the class attributes, raw for
+        # frame_attr_names, and leading underscore for others
+        for m in (c.__dict__ for c in tmp_cls.__mro__):
+            if not found_default_repr and '_default_representation' in m:
+                default_repr = m['_default_representation']
+                found_default_repr = True
+            if (not found_repr_info and
+                    '_frame_specific_representation_info' in m):
+                repr_info = m['_frame_specific_representation_info']
                 found_repr_info = True
 
-            if found_def_repr and found_repr_info:
+            if found_default_repr and found_repr_info:
                 break
         else:
-            raise ValueError('Could not find all expected BaseCoordinateFrame '
-                             'class attributes.  Are you mis-using FrameMeta?')
+            raise ValueError(
+                'Could not find all expected BaseCoordinateFrame class '
+                'attributes.  Are you mis-using FrameMeta?')
 
         # Make read-only properties for the frame class attributes that should
         # be read-only to make them immutable after creation.
         # We copy attributes instead of linking to make sure there's no
         # accidental cross-talk between classes
-        clsdct['_default_representation'] = def_repr
-        clsdct['default_representation'] = FrameMeta.readonly_prop_factory('default_representation')
-
-        clsdct['_frame_specific_representation_info'] = deepcopy(repr_info)
-        clsdct['frame_specific_representation_info'] = FrameMeta.readonly_prop_factory('frame_specific_representation_info')
+        mcls.readonly_prop_factory(members, 'default_representation',
+                                   default_repr)
+        mcls.readonly_prop_factory(members,
+                                   'frame_specific_representation_info',
+                                   deepcopy(repr_info))
 
         # now set the frame name as lower-case class name, if it isn't explicit
-        if 'name' not in clsdct:
-            clsdct['name'] = name.lower()
+        if 'name' not in members:
+            members['name'] = name.lower()
 
-        return super(FrameMeta, cls).__new__(cls, name, parents, clsdct)
+        return super(FrameMeta, mcls).__new__(mcls, name, bases, members)
 
     @staticmethod
-    def readonly_prop_factory(attrnm):
+    def readonly_prop_factory(members, attr, value):
+        private_attr = '_' + attr
+
         def getter(self):
-            return getattr(self, '_' + attrnm)
-        return property(getter)
+            return getattr(self, private_attr)
+
+        members[private_attr] = value
+        members[attr] = property(getter)
 
 
 class FrameAttribute(object):
@@ -118,7 +135,8 @@ class FrameAttribute(object):
 
       class FK4(BaseCoordinateFrame):
           equinox = TimeFrameAttribute(default=_EQUINOX_B1950)
-          obstime = TimeFrameAttribute(default=None, secondary_attribute='equinox')
+          obstime = TimeFrameAttribute(default=None,
+                                       secondary_attribute='equinox')
 
     This means that ``equinox`` and ``obstime`` are available to be set as
     keyword arguments when creating an ``FK4`` class instance and are then
@@ -136,13 +154,8 @@ class FrameAttribute(object):
     default : object
         Default value for the attribute if not provided
     secondary_attribute : str
-        Name of a secondary instance attribute which supplies the value
-        if ``default is None`` and no value was supplied during initialization.
-
-    Returns
-    -------
-    frame_attr : descriptor
-        A new data descriptor to hold a frame attribute
+        Name of a secondary instance attribute which supplies the value if
+        ``default is None`` and no value was supplied during initialization.
     """
 
     _nextid = 1
@@ -168,10 +181,10 @@ class FrameAttribute(object):
         as needed.  The method should catch any internal exceptions and raise
         ValueError with an informative message.
 
-        The method returns the validated input along with a boolean that indicates
-        whether the input value was actually converted.  If the input value was
-        already the correct type then the ``converted`` return value should be
-        ``False``.
+        The method returns the validated input along with a boolean that
+        indicates whether the input value was actually converted.  If the input
+        value was already the correct type then the ``converted`` return value
+        should be ``False``.
 
         Parameters
         ----------
@@ -195,8 +208,9 @@ class FrameAttribute(object):
 
     def __get__(self, instance, frame_cls=None):
         if not hasattr(self, 'name'):
-            # Find attribute name of self by finding this object in the frame class
-            # which is requesting this attribute or any of its superclasses.
+            # Find attribute name of self by finding this object in the frame
+            # class which is requesting this attribute or any of its
+            # superclasses.
             for mro_cls in frame_cls.__mro__:
                 for name, val in mro_cls.__dict__.items():
                     if val is self:
@@ -205,10 +219,12 @@ class FrameAttribute(object):
                 if hasattr(self, 'name'):  # Can't nicely break out of two loops
                     break
             else:
-                # Cannot think of a way to actually raise this exception.  This instance
-                # containing this code must be in the class dict in order to get excecuted
-                # by attribute access.  But leave this here just in case...
-                raise AttributeError('Unexpected inability to locate descriptor')
+                # Cannot think of a way to actually raise this exception.  This
+                # instance containing this code must be in the class dict in
+                # order to get excecuted by attribute access.  But leave this
+                # here just in case...
+                raise AttributeError(
+                        'Unexpected inability to locate descriptor')
 
         out = None
 
@@ -241,18 +257,14 @@ class TimeFrameAttribute(FrameAttribute):
     default : object
         Default value for the attribute if not provided
     secondary_attribute : str
-        Name of a secondary instance attribute which supplies the value
-        if ``default is None`` and no value was supplied during initialization.
-
-    Returns
-    -------
-    frame_attr : descriptor
-        A new data descriptor to hold a frame attribute
+        Name of a secondary instance attribute which supplies the value if
+        ``default is None`` and no value was supplied during initialization.
     """
+
     def convert_input(self, value):
         """
-        Convert input value to a Time object and validate by running through the
-        Time constructor.  Also check that the input was a scalar.
+        Convert input value to a Time object and validate by running through
+        the Time constructor.  Also check that the input was a scalar.
 
         Parameters
         ----------
@@ -270,6 +282,7 @@ class TimeFrameAttribute(FrameAttribute):
         ValueError
             If the input is not valid for this attribute.
         """
+
         from ..time import Time
 
         if value is None:
@@ -282,32 +295,157 @@ class TimeFrameAttribute(FrameAttribute):
             try:
                 out = Time(value)
             except Exception as err:
-                raise ValueError('Invalid time input {0}={1!r}\n{2}'
-                                 .format(self.name, value, err))
+                raise ValueError(
+                    'Invalid time input {0}={1!r}\n{2}'.format(self.name,
+                                                               value, err))
             converted = True
 
         if not out.isscalar:
-            raise ValueError('Time input {0}={1!r} must be a single (scalar) value'
-                             .format(self.name, value))
+            msg0 = ('Time input {0}={1!r} is not a single (scalar) value. Some '
+                    'transformations do not yet support vector frame '
+                    'attributes, so some transformations may not work.')
+            msg = msg0.format(self.name, value)
+            warnings.warn(msg, AstropyWarning)
 
         return out, converted
 
 
-class RepresentationMapping(namedtuple('RepresentationMapping',
-                            ['reprname', 'framename', 'defaultunit'])):
+class QuantityFrameAttribute(FrameAttribute):
+    """
+    A frame attribute that is a quantity with specified units and shape
+    (optionally).
+
+    Parameters
+    ----------
+    default : object
+        Default value for the attribute if not provided
+    secondary_attribute : str
+        Name of a secondary instance attribute which supplies the value if
+        ``default is None`` and no value was supplied during initialization.
+    unit : unit object or None
+        Name of a unit that the input will be converted into. If None, no
+        unit-checking or conversion is performed
+    shape : tuple or None
+        If given, specifies the shape the attribute must be
+    """
+    def __init__(self, default=None, secondary_attribute='', unit=None, shape=None):
+        super(QuantityFrameAttribute, self).__init__(default, secondary_attribute)
+        self.unit = unit
+        self.shape = shape
+
+    def convert_input(self, value):
+        """
+        Checks that the input is a Quantity with the necessary units (or the
+        special value ``0``).
+
+        Parameters
+        ----------
+        value : object
+            Input value to be converted.
+
+        Returns
+        -------
+        out, converted : correctly-typed object, boolean
+            Tuple consisting of the correctly-typed object and a boolean which
+            indicates if conversion was actually performed.
+
+        Raises
+        ------
+        ValueError
+            If the input is not valid for this attribute.
+        """
+        if np.all(value == 0) and self.unit is not None and self.unit is not None:
+            return u.Quantity(np.zeros(self.shape), self.unit), True
+        else:
+            converted = True
+            if not (hasattr(value, 'unit') ):
+                raise TypeError('Tried to set a QuantityFrameAttribute with '
+                                'something that does not have a unit.')
+            oldvalue = value
+            value = u.Quantity(oldvalue, copy=False).to(self.unit)
+            if self.shape is not None and value.shape != self.shape:
+                raise ValueError('The provided value has shape "{0}", but '
+                                 'should have shape "{1}"'.format(value.shape,
+                                                                  self.shape))
+            if (oldvalue.unit == value.unit and hasattr(oldvalue, 'value') and
+                np.all(oldvalue.value == value.value)):
+                converted = False
+            return value, converted
+
+
+class EarthLocationAttribute(FrameAttribute):
+    """
+    A frame attribute that can act as a `~astropy.coordinates.EarthLocation`.
+    It can be created as anything that can be transformed to the
+    `~astropy.coordinates.ITRS` frame, but always presents as an `EarthLocation`
+    when accessed after creation.
+
+    Parameters
+    ----------
+    default : object
+        Default value for the attribute if not provided
+    secondary_attribute : str
+        Name of a secondary instance attribute which supplies the value if
+        ``default is None`` and no value was supplied during initialization.
+    """
+
+    def convert_input(self, value):
+        """
+        Checks that the input is a Quantity with the necessary units (or the
+        special value ``0``).
+
+        Parameters
+        ----------
+        value : object
+            Input value to be converted.
+
+        Returns
+        -------
+        out, converted : correctly-typed object, boolean
+            Tuple consisting of the correctly-typed object and a boolean which
+            indicates if conversion was actually performed.
+
+        Raises
+        ------
+        ValueError
+            If the input is not valid for this attribute.
+        """
+        if value is None:
+            return None, False
+        elif isinstance(value, EarthLocation):
+            return value, False
+        else:
+            #we have to do the import here because of some tricky circular deps
+            from .builtin_frames import ITRS
+
+            if not hasattr(value, 'transform_to'):
+                raise ValueError('"{0}" was passed into an '
+                                 'EarthLocationAttribute, but it does not have '
+                                 '"transform_to" method'.format(value))
+            itrsobj = value.transform_to(ITRS)
+            return itrsobj.earth_location, True
+
+_RepresentationMappingBase = \
+    namedtuple('RepresentationMapping',
+               ('reprname', 'framename', 'defaultunit'))
+
+
+class RepresentationMapping(_RepresentationMappingBase):
     """
     This `~collections.namedtuple` is used with the
     ``frame_specific_representation_info`` attribute to tell frames what
     attribute names (and default units) to use for a particular representation.
     ``reprname`` and ``framename`` should be strings, while ``defaultunit`` can
-    be either an astropy unit, the string ``'recommended'`` (to use whatever the
-    representation's ``recommended_units`` is), or None (to indicate that no
-    unit mapping should be done).
+    be either an astropy unit, the string ``'recommended'`` (to use whatever
+    the representation's ``recommended_units`` is), or None (to indicate that
+    no unit mapping should be done).
     """
+
     def __new__(cls, reprname, framename, defaultunit='recommended'):
         # this trick just provides some defaults
         return super(RepresentationMapping, cls).__new__(cls, reprname,
-                                                         framename, defaultunit)
+                                                         framename,
+                                                         defaultunit)
 
 
 @six.add_metaclass(FrameMeta)
@@ -329,15 +467,15 @@ class BaseCoordinateFrame(object):
        built-in classes code for details.
 
     * `frame_specific_representation_info`
-        A dictionary mapping the name or class of a representation to a list
-        of `~astropy.coordinates.RepresentationMapping` objects that tell what
+        A dictionary mapping the name or class of a representation to a list of
+        `~astropy.coordinates.RepresentationMapping` objects that tell what
         names and default units should be used on this frame for the components
         of that representation.
-
     """
 
     default_representation = None
-    frame_specific_representation_info = {}  # specifies special names/units for representation attributes
+    # specifies special names/units for representation attributes
+    frame_specific_representation_info = {}
 
     # This __new__ provides for backward-compatibility with pre-0.4 API.
     # TODO: remove in 1.0
@@ -345,12 +483,14 @@ class BaseCoordinateFrame(object):
 
         # Only do backward-compatibility if frame is previously defined one
         frame_name = cls.__name__.lower()
-        if frame_name not in ['altaz', 'fk4', 'fk4noeterms', 'fk5', 'galactic', 'icrs']:
+        if frame_name not in ['altaz', 'fk4', 'fk4noeterms', 'fk5',
+                              'galactic', 'icrs']:
             return super(BaseCoordinateFrame, cls).__new__(cls)
 
         use_skycoord = False
 
-        if len(args) > 1 or (len(args) == 1 and not isinstance(args[0], BaseRepresentation)):
+        if (len(args) > 1 or (len(args) == 1 and
+                not isinstance(args[0], BaseRepresentation))):
             for arg in args:
                 if (not isinstance(arg, u.Quantity)
                     and not isinstance(arg, BaseRepresentation)):
@@ -369,21 +509,26 @@ class BaseCoordinateFrame(object):
                     break
 
         if 'unit' in kwargs and not use_skycoord:
-            warnings.warn("Initializing frames using the ``unit`` argument is "
-                          "now deprecated. Use SkyCoord or pass Quantity "
-                          " instances to frames instead.", AstropyDeprecationWarning)
+            warnings.warn(
+                "Initializing frames using the ``unit`` argument is "
+                "now deprecated. Use SkyCoord or pass Quantity "
+                "instances to frames instead.", AstropyDeprecationWarning)
             use_skycoord = True
 
         if not use_skycoord:
-            representation = _get_repr_cls(kwargs.get('representation',
-                                                      cls._default_representation))
-            for key in cls._get_representation_info()[representation]['names']:
+            representation = kwargs.get('representation',
+                                        cls._default_representation)
+            representation = _get_repr_cls(representation)
+
+            repr_info = cls._get_representation_info()
+
+            for key in repr_info[representation]['names']:
                 if key in kwargs:
                     if not isinstance(kwargs[key], u.Quantity):
-                        warnings.warn("Initializing frames using non-Quantity "
-                                      "arguments is now deprecated. Use "
-                                      "SkyCoord or pass Quantity instances "
-                                      "instead.", AstropyDeprecationWarning)
+                        warnings.warn(
+                            "Initializing frames using non-Quantity arguments "
+                            "is now deprecated. Use SkyCoord or pass Quantity "
+                            "instances instead.", AstropyDeprecationWarning)
                         use_skycoord = True
                         break
 
@@ -400,7 +545,8 @@ class BaseCoordinateFrame(object):
         if 'representation' in kwargs:
             self.representation = kwargs.pop('representation')
 
-        representation_data = None  # if not set below, this is a frame with no data
+        # if not set below, this is a frame with no data
+        representation_data = None
 
         for fnm, fdefault in self.get_frame_attr_names().items():
             # Read-only frame attributes are defined as FrameAttribue
@@ -424,8 +570,9 @@ class BaseCoordinateFrame(object):
                                 args[0] is None):
             representation_data = args.pop(0)
             if len(args) > 0:
-                raise TypeError('Cannot create a frame with both a '
-                                'representation and other positional arguments')
+                raise TypeError(
+                    'Cannot create a frame with both a representation and '
+                    'other positional arguments')
 
         elif self.representation:
             repr_kwargs = {}
@@ -442,18 +589,20 @@ class BaseCoordinateFrame(object):
             if repr_kwargs:
                 if repr_kwargs.get('distance', True) is None:
                     del repr_kwargs['distance']
-                if (self.representation == SphericalRepresentation and
+                if (issubclass(self.representation, SphericalRepresentation) and
                         'distance' not in repr_kwargs):
                     representation_data = UnitSphericalRepresentation(**repr_kwargs)
                 else:
                     representation_data = self.representation(**repr_kwargs)
 
         if len(args) > 0:
-            raise TypeError(self.__class__.__name__ + '.__init__ had {0} '
-                            'remaining unprocessed arguments'.format(len(args)))
+            raise TypeError(
+                '{0}.__init__ had {1} remaining unhandled arguments'.format(
+                    self.__class__.__name__, len(args)))
         if kwargs:
-            raise TypeError('Coordinate frame got unexpected keywords: ' +
-                            str(kwargs.keys()))
+            raise TypeError(
+                'Coordinate frame got unexpected keywords: {0}'.format(
+                    list(kwargs)))
 
         self._data = representation_data
 
@@ -620,8 +769,9 @@ class BaseCoordinateFrame(object):
             A new object with the same frame attributes as this one, but
             with the ``representation`` as the data.
         """
-        frattrs = dict([(nm, getattr(self, nm)) for nm in self.get_frame_attr_names()
-                        if nm not in self._attr_names_with_defaults])
+        frattrs = dict([(attr, getattr(self, attr))
+                        for attr in self.get_frame_attr_names()
+                        if attr not in self._attr_names_with_defaults])
         return self.__class__(representation, **frattrs)
 
     def represent_as(self, new_representation, in_frame_units=False):
@@ -668,7 +818,8 @@ class BaseCoordinateFrame(object):
         """
         new_representation = _get_repr_cls(new_representation)
 
-        cached_repr = self._rep_cache.get((new_representation.__name__, in_frame_units))
+        cached_repr = self._rep_cache.get((new_representation.__name__,
+                                           in_frame_units))
         if not cached_repr:
             data = self.data.represent_as(new_representation)
 
@@ -676,7 +827,8 @@ class BaseCoordinateFrame(object):
             # set of names and units, then use that.
             new_attrs = self.representation_info.get(new_representation)
             if new_attrs and in_frame_units:
-                datakwargs = dict((comp, getattr(data, comp)) for comp in data.components)
+                datakwargs = dict((comp, getattr(data, comp))
+                                  for comp in data.components)
                 for comp, new_attr_unit in zip(data.components, new_attrs['units']):
                     if new_attr_unit:
                         datakwargs[comp] = datakwargs[comp].to(new_attr_unit)
@@ -756,12 +908,11 @@ class BaseCoordinateFrame(object):
                 coord2 = coord.transform_to(some_unknown_frame)
 
         This will work even if ``some_unknown_frame``  turns out to be the same
-        frame class as ``coord``.  This is intended for cases where the frame is
-        the same regardless of the frame attributes (e.g. ICRS), but be aware
-        that it *might* also indicate that someone forgot to define the
+        frame class as ``coord``.  This is intended for cases where the frame
+        is the same regardless of the frame attributes (e.g. ICRS), but be
+        aware that it *might* also indicate that someone forgot to define the
         transformation between two objects of the same frame class but with
         different attributes.
-
         """
 
         new_frame_cls = new_frame if inspect.isclass(new_frame) else new_frame.__class__
@@ -789,22 +940,58 @@ class BaseCoordinateFrame(object):
         Returns
         -------
         isdefault : bool
-            True if the attribute ``attrnm`` has its value by default, False if it
-            was specified at creation of this frame.
+            True if the attribute ``attrnm`` has its value by default, False if
+            it was specified at creation of this frame.
         """
         return attrnm in self._attr_names_with_defaults
 
+    def is_equivalent_frame(self, other):
+        """
+        Checks if this object is the same frame as the ``other`` object.
+
+        To be the same frame, two objects must be the same frame class and have
+        the same frame attributes.  Note that it does *not* matter what, if any,
+        data either object has.
+
+        Parameters
+        ----------
+        other : BaseCoordinateFrame
+            the other frame to check
+
+        Returns
+        -------
+        isequiv : bool
+            True if the frames are the same, False if not.
+
+        Raises
+        ------
+        TypeError
+            If ``other`` isn't a `BaseCoordinateFrame` or subclass.
+        """
+        if self.__class__ == other.__class__:
+            for frame_attr_name in self.get_frame_attr_names():
+                if getattr(self, frame_attr_name) != getattr(other, frame_attr_name):
+                    return False
+            return True
+        elif not isinstance(other, BaseCoordinateFrame):
+            raise TypeError("Tried to do is_equivalent_frame on something that "
+                            "isn't a frame")
+        else:
+            return False
+
     def __repr__(self):
         frameattrs = ', '.join([attrnm + '=' + str(getattr(self, attrnm))
                                 for attrnm in self.get_frame_attr_names()])
 
         if self.has_data:
             if self.representation:
-                if (self.representation == SphericalRepresentation and
+                if (issubclass(self.representation, SphericalRepresentation) and
                         isinstance(self.data, UnitSphericalRepresentation)):
-                    data = self.represent_as(UnitSphericalRepresentation, in_frame_units=True)
+                    data = self.represent_as(self.data.__class__,
+                                             in_frame_units=True)
                 else:
-                    data = self.represent_as(self.representation, in_frame_units=True)
+                    data = self.represent_as(self.representation,
+                                             in_frame_units=True)
 
                 data_repr = repr(data)
                 for nmpref, nmrepr in self.representation_component_names.items():
@@ -817,23 +1004,23 @@ class BaseCoordinateFrame(object):
             if data_repr.startswith('<' + data.__class__.__name__):
                 # standard form from BaseRepresentation
                 if frameattrs:
-                    frameattrs = frameattrs + ', '
+                    frameattrs = ' (' + frameattrs + ')'
 
                 #remove both the leading "<" and the space after the name
                 data_repr = data_repr[(len(data.__class__.__name__) + 2):]
 
-                return '<{0} Coordinate: {1}{2}'.format(self.__class__.__name__,
+                return '<{0} Coordinate{1}: {2}'.format(self.__class__.__name__,
                                                         frameattrs, data_repr)
             else:
                 # should only happen if a representation has a non-standard
                 # __repr__ method, and we just punt to that
                 if frameattrs:
-                    frameattrs = ': ' + frameattrs + ', '
+                    frameattrs = ' (' + frameattrs + '), '
                 s = '<{0} Coordinate{1}Data:\n{2}>'
                 return s.format(self.__class__.__name__, frameattrs, data_repr)
         else:
             if frameattrs:
-                frameattrs = ': ' + frameattrs
+                frameattrs = ' (' + frameattrs + ')'
             return '<{0} Frame{1}>'.format(self.__class__.__name__, frameattrs)
 
     def __getitem__(self, view):
@@ -856,14 +1043,20 @@ class BaseCoordinateFrame(object):
 
     def __getattr__(self, attr):
         """
-        Allow access to attributes defined in self.representation_component_names.
+        Allow access to attributes defined in
+        ``self.representation_component_names``.
 
-        TODO: dynamic representation transforms (i.e. include cylindrical et al.).
+        TODO: dynamic representation transforms (i.e. include cylindrical et
+        al.).
         """
+
         # attr == '_representation' is likely from the hasattr() test in the
-        # representation property which is used for self.representation_component_names.
+        # representation property which is used for
+        # self.representation_component_names.
+        #
         # Prevent infinite recursion here.
-        if attr == '_representation' or attr not in self.representation_component_names:
+        if (attr == '_representation' or
+                attr not in self.representation_component_names):
             raise AttributeError("'{0}' object has no attribute '{1}'"
                                  .format(self.__class__.__name__, attr))
 
@@ -877,7 +1070,8 @@ class BaseCoordinateFrame(object):
             for representation_attr in self.representation_info.values():
                 repr_attr_names.extend(representation_attr['names'])
         if attr in repr_attr_names:
-            raise AttributeError('Cannot set any frame attribute {0}'.format(attr))
+            raise AttributeError(
+                'Cannot set any frame attribute {0}'.format(attr))
         else:
             super(BaseCoordinateFrame, self).__setattr__(attr, value)
 
@@ -907,7 +1101,8 @@ class BaseCoordinateFrame(object):
         from .angles import Angle
 
         self_unit_sph = self.represent_as(UnitSphericalRepresentation)
-        other_unit_sph = other.transform_to(self.__class__).represent_as(UnitSphericalRepresentation)
+        other_transformed = other.transform_to(self.__class__)
+        other_unit_sph = other_transformed.represent_as(UnitSphericalRepresentation)
 
         # Get the separation as a Quantity, convert to Angle in degrees
         sep = angular_separation(self_unit_sph.lon, self_unit_sph.lat,
@@ -934,6 +1129,7 @@ class BaseCoordinateFrame(object):
         ValueError
             If this or the other coordinate do not have distances.
         """
+
         from .distances import Distance
 
         if self.data.__class__ == UnitSphericalRepresentation:
@@ -957,8 +1153,10 @@ class BaseCoordinateFrame(object):
     @property
     def cartesian(self):
         """
-        Shorthand for a cartesian representation of the coordinates in this object.
+        Shorthand for a cartesian representation of the coordinates in this
+        object.
         """
+
         # TODO: if representations are updated to use a full transform graph,
         #       the representation aliases should not be hard-coded like this
         return self.represent_as(CartesianRepresentation, in_frame_units=True)
@@ -968,6 +1166,7 @@ class BaseCoordinateFrame(object):
         """
         Shorthand for a spherical representation of the coordinates in this object.
         """
+
         # TODO: if representations are updated to use a full transform graph,
         #       the representation aliases should not be hard-coded like this
         return self.represent_as(SphericalRepresentation, in_frame_units=True)
@@ -1008,5 +1207,3 @@ class GenericFrame(BaseCoordinateFrame):
             raise AttributeError("can't set frame attribute '{0}'".format(name))
         else:
             super(GenericFrame, self).__setattr__(name, value)
-
-
diff --git a/astropy/coordinates/builtin_frames.py b/astropy/coordinates/builtin_frames.py
deleted file mode 100644
index 52c9995..0000000
--- a/astropy/coordinates/builtin_frames.py
+++ /dev/null
@@ -1,629 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This module contains the coordinate frames actually implemented by astropy.
-"""
-from __future__ import (absolute_import, unicode_literals, division,
-                        print_function)
-
-# Standard library
-import inspect
-
-# Dependencies
-import numpy as np
-
-# Project
-from ..extern import six
-from ..utils.compat.odict import OrderedDict
-from .. import units as u
-from ..time import Time
-from .angles import Angle
-from .representation import (SphericalRepresentation, CartesianRepresentation,
-                             UnitSphericalRepresentation)
-from .baseframe import (BaseCoordinateFrame, frame_transform_graph, GenericFrame,
-                        FrameAttribute, TimeFrameAttribute,
-                        RepresentationMapping)
-from .transformations import FunctionTransform, DynamicMatrixTransform
-
-
-__all__ = ['ICRS', 'FK5', 'FK4', 'FK4NoETerms', 'Galactic', 'AltAz']
-
-# The UTC time scale is not properly defined prior to 1960, so Time('B1950',
-# scale='utc') will emit a warning. Instead, we use Time('B1950', scale='tai')
-# which is equivalent, but does not emit a warning.
-_EQUINOX_J2000 = Time('J2000', scale='utc')
-_EQUINOX_B1950 = Time('B1950', scale='tai')
-
-
-class ICRS(BaseCoordinateFrame):
-    """
-    A coordinate or frame in the ICRS system.
-
-    If you're looking for "J2000" coordinates, and aren't sure if you want to
-    use this or `FK5`, you probably want to use ICRS. It's more well-defined as
-    a catalog coordinate and is an inertial system, and is very close (within
-    tens of arcseconds) to J2000 equatorial.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    ra : `Angle`, optional, must be keyword
-        The RA for this object (``dec`` must also be given and ``representation``
-        must be None).
-    dec : `Angle`, optional, must be keyword
-        The Declination for this object (``ra`` must also be given and
-        ``representation`` must be None).
-    distance : `~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-        (``representation`` must be None).
-    """
-
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'ra'),
-                      RepresentationMapping('lat', 'dec')]
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-
-    @staticmethod
-    def _icrs_to_fk5_matrix():
-        """
-        B-matrix from USNO circular 179.  Used by the ICRS->FK5 transformation
-        functions.
-        """
-        from .angles import rotation_matrix
-
-        eta0 = -19.9 / 3600000.
-        xi0 = 9.1 / 3600000.
-        da0 = -22.9 / 3600000.
-
-        m1 = rotation_matrix(-eta0, 'x')
-        m2 = rotation_matrix(xi0, 'y')
-        m3 = rotation_matrix(da0, 'z')
-
-        return m1 * m2 * m3
-
-# define this because it only needs to be computed once
-ICRS._ICRS_TO_FK5_J2000_MAT = ICRS._icrs_to_fk5_matrix()
-
-
-class FK5(BaseCoordinateFrame):
-    """
-    A coordinate or frame in the FK5 system.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    ra : `Angle`, optional, must be keyword
-        The RA for this object (``dec`` must also be given and ``representation``
-        must be None).
-    dec : `Angle`, optional, must be keyword
-        The Declination for this object (``ra`` must also be given and
-        ``representation`` must be None).
-    distance : `~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-        (``representation`` must be None).
-    equinox : `~astropy.time.Time`, optional, must be keyword
-        The equinox of this frame.
-    """
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'ra'),
-                      RepresentationMapping('lat', 'dec')]
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-    equinox = TimeFrameAttribute(default=_EQUINOX_J2000)
-
-    @staticmethod
-    def _precession_matrix(oldequinox, newequinox):
-        """
-        Compute and return the precession matrix for FK5 based on Capitaine et
-        al. 2003/IAU2006.  Used inside some of the transformation functions.
-
-        Parameters
-        ----------
-        oldequinox : `~astropy.time.Time`
-            The equinox to precess from.
-        newequinox : `~astropy.time.Time`
-            The equinox to precess to.
-
-        Returns
-        -------
-        newcoord : array
-            The precession matrix to transform to the new equinox
-        """
-        from .earth_orientation import precession_matrix_Capitaine
-
-        return precession_matrix_Capitaine(oldequinox, newequinox)
-
-
-# Has to be defined at module level, because `transform` needs an FK5 reference
- at frame_transform_graph.transform(DynamicMatrixTransform, FK5, FK5)
-def fk5_to_fk5(fk5coord1, fk5frame2):
-    return fk5coord1._precession_matrix(fk5coord1.equinox, fk5frame2.equinox)
-
-
-class FK4(BaseCoordinateFrame):
-    """
-    A coordinate or frame in the FK4 system.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    ra : `Angle`, optional, must be keyword
-        The RA for this object (``dec`` must also be given and ``representation``
-        must be None).
-    dec : `Angle`, optional, must be keyword
-        The Declination for this object (``ra`` must also be given and
-        ``representation`` must be None).
-    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-        (``representation`` must be None).
-    equinox : astropy.time.Time, optional, must be keyword
-        The equinox of this frame.
-    obstime : astropy.time.Time, optional, must be keyword
-        The time this frame was observed.  If None, will be the same as
-        ``equinox``.
-    """
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'ra'),
-                      RepresentationMapping('lat', 'dec')]
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-    equinox = TimeFrameAttribute(default=_EQUINOX_B1950)
-    obstime = TimeFrameAttribute(default=None, secondary_attribute='equinox')
-
-
- at frame_transform_graph.transform(FunctionTransform, FK4, FK4)
-def fk4_to_fk4(fk4coord1, fk4frame2):
-    # deceptively complicated: need to transform to No E-terms FK4, precess, and
-    # then come back, because precession is non-trivial with E-terms
-    fnoe_w_eqx1 = fk4coord1.transform_to(FK4NoETerms(equinox=fk4coord1.equinox))
-    fnoe_w_eqx2 = fnoe_w_eqx1.transform_to(FK4NoETerms(equinox=fk4frame2.equinox))
-    return fnoe_w_eqx2.transform_to(fk4frame2)
-
-
-class FK4NoETerms(BaseCoordinateFrame):
-    """
-    A coordinate or frame in the FK4 system, but with the E-terms of aberration
-    removed.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    ra : `Angle`, optional, must be keyword
-        The RA for this object (``dec`` must also be given and ``representation``
-        must be None).
-    dec : `Angle`, optional, must be keyword
-        The Declination for this object (``ra`` must also be given and
-        ``representation`` must be None).
-    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-        (``representation`` must be None).
-    obstime : astropy.time.Time, optional, must be keyword
-        The time this frame was observed.  If None, will be the same as
-        ``equinox``.
-    """
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'ra'),
-                      RepresentationMapping('lat', 'dec')]
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-    equinox = TimeFrameAttribute(default=_EQUINOX_B1950)
-    obstime = TimeFrameAttribute(default=None, secondary_attribute='equinox')
-
-    @staticmethod
-    def _precession_matrix(oldequinox, newequinox):
-        """
-        Compute and return the precession matrix for FK4 using Newcomb's method.
-        Used inside some of the transformation functions.
-
-        Parameters
-        ----------
-        oldequinox : `~astropy.time.Time`
-            The equinox to precess from.
-        newequinox : `~astropy.time.Time`
-            The equinox to precess to.
-
-        Returns
-        -------
-        newcoord : array
-            The precession matrix to transform to the new equinox
-        """
-        from .earth_orientation import _precession_matrix_besselian
-
-        return _precession_matrix_besselian(oldequinox.byear, newequinox.byear)
-
-    @staticmethod
-    def _fk4_B_matrix(obstime):
-        """
-        This is a correction term in the FK4 transformations because FK4 is a
-        rotating system - see Murray 89 eqn 29
-        """
-        # Note this is *julian century*, not besselian
-        T = (obstime.jyear - 1950.) / 100.
-        return _B1950_TO_J2000_M + _FK4_CORR * T
-
-
- at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, FK4NoETerms)
-def fk4noe_to_fk4noe(fk4necoord1, fk4neframe2):
-    return fk4necoord1._precession_matrix(fk4necoord1.equinox, fk4neframe2.equinox)
-
-
-class Galactic(BaseCoordinateFrame):
-    """
-    Galactic Coordinates.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    l : `Angle`, optional, must be keyword
-        The Galactic longitude for this object (``b`` must also be given and
-        ``representation`` must be None).
-    b : `Angle`, optional, must be keyword
-        The Galactic latitude for this object (``l`` must also be given and
-        ``representation`` must be None).
-    distance : `~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-    """
-
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'l'),
-                      RepresentationMapping('lat', 'b')],
-        'cartesian': [RepresentationMapping('x', 'w'),
-                      RepresentationMapping('y', 'u'),
-                      RepresentationMapping('z', 'v')]
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-
-    # North galactic pole and zeropoint of l in FK4/FK5 coordinates. Needed for
-    # transformations to/from FK4/5
-
-    # These are from the IAU's definition of galactic coordinates
-    _ngp_B1950 = FK4NoETerms(ra=192.25*u.degree, dec=27.4*u.degree)
-    _lon0_B1950 = Angle(123, u.degree)
-
-    # These are *not* from Reid & Brunthaler 2004 - instead, they were
-    # derived by doing:
-    #
-    # >>> FK4NoETerms(ra=192.25*u.degree, dec=27.4*u.degree).transform_to(FK5)
-    #
-    # This gives better consistency with other codes than using the values
-    # from Reid & Brunthaler 2004 and the best self-consistency between FK5
-    # -> Galactic and FK5 -> FK4 -> Galactic. The lon0 angle was found by
-    # optimizing the self-consistency.
-    _ngp_J2000 = FK5(ra=192.8594812065348*u.degree, dec=27.12825118085622*u.degree)
-    _lon0_J2000 = Angle(122.9319185680026, u.degree)
-
-
-class AltAz(BaseCoordinateFrame):
-    """
-    A coordinate or frame in the Altitude-Azimuth system (i.e., Horizontal
-    coordinates).
-
-    .. warning::
-        The AltAz class currently does not support any transformations. In a
-        future version, it will support the standard IAU2000 AltAz<->ICRS
-        transformations.  It is provided right now as a placeholder for storing
-        as-observed horizontal coordinates.
-
-    Parameters
-    ----------
-    representation : `BaseRepresentation` or None
-        A representation object or None to have no data (or use the other keywords)
-    az : `Angle`, optional, must be keyword
-        The Azimuth for this object (``alt`` must also be given and
-        ``representation`` must be None).
-    alt : `Angle`, optional, must be keyword
-        The Altitude for this object (``az`` must also be given and
-        ``representation`` must be None).
-    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
-        The Distance for this object along the line-of-sight.
-    """
-
-    frame_specific_representation_info = {
-        'spherical': [RepresentationMapping('lon', 'az'),
-                      RepresentationMapping('lat', 'alt')],
-    }
-    frame_specific_representation_info['unitspherical'] = \
-        frame_specific_representation_info['spherical']
-
-    default_representation = SphericalRepresentation
-    equinox = TimeFrameAttribute(default=_EQUINOX_B1950)
-    location = FrameAttribute(default=None)
-    obstime = TimeFrameAttribute(default=None)
-
-    def __init__(self, *args, **kwargs):
-        from warnings import warn
-        from astropy.utils.exceptions import AstropyWarning
-
-        warn(AstropyWarning('The AltAz class currently does not support any '
-                            'transformations.  In a future version, it will '
-                            'support the standard IAU2000 AltAz<->ICRS '
-                            'transformations.'))
-        super(AltAz, self).__init__(*args, **kwargs)
-
-
-# <--------------------------------transformations------------------------------>
-# Transformations are defined here instead of in the classes themselves, because
-# we need references to the various objects to give to the decorators.
-
-# ICRS to/from FK5 -------------------------------->
- at frame_transform_graph.transform(DynamicMatrixTransform, ICRS, FK5)
-def icrs_to_fk5(icrscoord, fk5frame):
-    # ICRS is by design very close to J2000 equinox
-    pmat = fk5frame._precession_matrix(_EQUINOX_J2000, fk5frame.equinox)
-    return pmat * icrscoord._ICRS_TO_FK5_J2000_MAT
-
-
-# can't be static because the equinox is needed
- at frame_transform_graph.transform(DynamicMatrixTransform, FK5, ICRS)
-def fk5_to_icrs(fk5coord, icrsframe):
-    # ICRS is by design very close to J2000 equinox
-    pmat = fk5coord._precession_matrix(fk5coord.equinox, _EQUINOX_J2000)
-    return icrsframe._ICRS_TO_FK5_J2000_MAT.T * pmat
-
-
-# FK4-NO-E to/from FK4 ----------------------------->
-
-# In the present framework, we include two coordinate classes for FK4
-# coordinates - one including the E-terms of aberration (FK4), and
-# one not including them (FK4NoETerms). The following functions
-# implement the transformation between these two.
-def fk4_e_terms(equinox):
-    """
-    Return the e-terms of aberation vector
-
-    Parameters
-    ----------
-    equinox : Time object
-        The equinox for which to compute the e-terms
-    """
-
-    from . import earth_orientation as earth
-
-    # Constant of aberration at J2000
-    k = 0.0056932
-
-    # Eccentricity of the Earth's orbit
-    e = earth.eccentricity(equinox.jd)
-    e = np.radians(e)
-
-    # Mean longitude of perigee of the solar orbit
-    g = earth.mean_lon_of_perigee(equinox.jd)
-    g = np.radians(g)
-
-    # Obliquity of the ecliptic
-    o = earth.obliquity(equinox.jd, algorithm=1980)
-    o = np.radians(o)
-
-    return e * k * np.sin(g), \
-           -e * k * np.cos(g) * np.cos(o), \
-           -e * k * np.cos(g) * np.sin(o)
-
-
- at frame_transform_graph.transform(FunctionTransform, FK4, FK4NoETerms)
-def fk4_to_fk4_no_e(fk4coord, fk4noeframe):
-    from .representation import CartesianRepresentation, UnitSphericalRepresentation
-
-    # Extract cartesian vector
-    c = fk4coord.cartesian.xyz
-    r = np.asarray(c.reshape((3, c.size // 3)))
-
-    # Find distance (for re-normalization)
-    d_orig = np.sqrt(np.sum(r ** 2))
-
-    # Apply E-terms of aberration. Note that this depends on the equinox (not
-    # the observing time/epoch) of the coordinates. See issue #1496 for a
-    # discussion of this.
-    eterms_a = np.asarray(fk4_e_terms(fk4coord.equinox))
-    r = r - eterms_a.reshape(3, 1) + np.dot(eterms_a, r) * r
-
-    # Find new distance (for re-normalization)
-    d_new = np.sqrt(np.sum(r ** 2))
-
-    # Renormalize
-    r = r * d_orig / d_new
-
-    subshape = c.shape[1:]
-    x = r[0].reshape(subshape)
-    y = r[1].reshape(subshape)
-    z = r[2].reshape(subshape)
-
-    #now re-cast into an appropriate Representation, and precess if need be
-    if isinstance(fk4coord.data, UnitSphericalRepresentation):
-        representation = CartesianRepresentation(x=x*u.one, y=y*u.one, z=z*u.one)
-        representation = representation.represent_as(UnitSphericalRepresentation)
-    else:
-        representation = CartesianRepresentation(x=x*c.unit, y=y*c.unit, z=z*c.unit)
-
-    # if no obstime was given in the new frame, use the old one for consistency
-    newobstime = fk4coord._obstime if fk4noeframe._obstime is None else fk4noeframe._obstime
-
-    fk4noe = FK4NoETerms(representation, equinox=fk4coord.equinox,
-                         obstime=newobstime)
-    if fk4coord.equinox != fk4noeframe.equinox:
-        #precession
-        fk4noe = fk4noe.transform_to(fk4noeframe)
-    return fk4noe
-
-
- at frame_transform_graph.transform(FunctionTransform, FK4NoETerms, FK4)
-def fk4_no_e_to_fk4(fk4noecoord, fk4frame):
-    from .representation import CartesianRepresentation, UnitSphericalRepresentation
-
-    #first precess, if necessary
-    if fk4noecoord.equinox != fk4frame.equinox:
-        fk4noe_w_fk4equinox = FK4NoETerms(equinox=fk4frame.equinox,
-                                          obstime=fk4noecoord.obstime)
-        fk4noecoord = fk4noecoord.transform_to(fk4noe_w_fk4equinox)
-
-    # Extract cartesian vector
-    c = fk4noecoord.cartesian.xyz
-    r = np.asarray(c.reshape((3, c.size // 3)))
-
-    # Find distance (for re-normalization)
-    d_orig = np.sqrt(np.sum(r ** 2))
-
-    # Apply E-terms of aberration. Note that this depends on the equinox (not
-    # the observing time/epoch) of the coordinates. See issue #1496 for a
-    # discussion of this.
-    eterms_a = np.asarray(fk4_e_terms(fk4noecoord.equinox))
-    r0 = r.copy()
-    for _ in range(10):
-        r = (eterms_a.reshape(3, 1) + r0) / (1. + np.dot(eterms_a, r))
-
-    # Find new distance (for re-normalization)
-    d_new = np.sqrt(np.sum(r ** 2))
-
-    # Renormalize
-    r = r * d_orig / d_new
-
-    subshape = c.shape[1:]
-    x = r[0].reshape(subshape)
-    y = r[1].reshape(subshape)
-    z = r[2].reshape(subshape)
-
-    #now re-cast into an appropriate Representation, and precess if need be
-    if isinstance(fk4noecoord.data, UnitSphericalRepresentation):
-        representation = CartesianRepresentation(x=x*u.one, y=y*u.one, z=z*u.one)
-        representation = representation.represent_as(UnitSphericalRepresentation)
-    else:
-        representation = CartesianRepresentation(x=x*c.unit, y=y*c.unit, z=z*c.unit)
-
-    return fk4frame.realize_frame(representation)
-
-# FK5 to/from FK4 ------------------->
-
-# B1950->J2000 matrix from Murray 1989 A&A 218,325 eqn 28
-_B1950_TO_J2000_M = \
-    np.mat([[0.9999256794956877, -0.0111814832204662, -0.0048590038153592],
-            [0.0111814832391717,  0.9999374848933135, -0.0000271625947142],
-            [0.0048590037723143, -0.0000271702937440,  0.9999881946023742]])
-
-_FK4_CORR = \
-    np.mat([[-0.0026455262, -1.1539918689, +2.1111346190],
-            [+1.1540628161, -0.0129042997, +0.0236021478],
-            [-2.1112979048, -0.0056024448, +0.0102587734]]) * 1.e-6
-
-
-# This transformation can't be static because the observation date is needed.
- at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, FK5)
-def fk4_no_e_to_fk5(fk4noecoord, fk5frame):
-    # Correction terms for FK4 being a rotating system
-    B = FK4NoETerms._fk4_B_matrix(fk4noecoord.obstime)
-
-    # construct both precession matricies - if the equinoxes are B1950 and
-    # J2000, these are just identity matricies
-    pmat1 = fk4noecoord._precession_matrix(fk4noecoord.equinox, _EQUINOX_B1950)
-    pmat2 = fk5frame._precession_matrix(_EQUINOX_J2000, fk5frame.equinox)
-
-    return pmat2 * B * pmat1
-
-
-# This transformation can't be static because the observation date is needed.
- at frame_transform_graph.transform(DynamicMatrixTransform, FK5, FK4NoETerms)
-def fk5_to_fk4_no_e(fk5coord, fk4noeframe):
-    # Get transposed version of the rotating correction terms... so with the
-    # transpose this takes us from FK5/J200 to FK4/B1950
-    B = FK4NoETerms._fk4_B_matrix(fk4noeframe.obstime).T
-
-    # construct both precession matricies - if the equinoxes are B1950 and
-    # J2000, these are just identity matricies
-    pmat1 = fk5coord._precession_matrix(fk5coord.equinox, _EQUINOX_J2000)
-    pmat2 = fk4noeframe._precession_matrix(_EQUINOX_B1950, fk4noeframe.equinox)
-
-    return pmat2 * B * pmat1
-
-
-# Galactic to/from FK4/FK5 ----------------------->
-# can't be static because the equinox is needed
- at frame_transform_graph.transform(DynamicMatrixTransform, FK5, Galactic)
-def fk5_to_gal(fk5coord, galframe):
-    from .angles import rotation_matrix
-
-    #need precess to J2000 first
-    pmat = fk5coord._precession_matrix(fk5coord.equinox, _EQUINOX_J2000)
-    mat1 = rotation_matrix(180 - Galactic._lon0_J2000.degree, 'z')
-    mat2 = rotation_matrix(90 - Galactic._ngp_J2000.dec.degree, 'y')
-    mat3 = rotation_matrix(Galactic._ngp_J2000.ra.degree, 'z')
-
-    return mat1 * mat2 * mat3 * pmat
-
-
- at frame_transform_graph.transform(DynamicMatrixTransform, Galactic, FK5)
-def _gal_to_fk5(galcoord, fk5frame):
-    return fk5_to_gal(fk5frame, galcoord).T
-
-
- at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, Galactic)
-def fk4_to_gal(fk4coords, galframe):
-    from .angles import rotation_matrix
-
-    mat1 = rotation_matrix(180 - Galactic._lon0_B1950.degree, 'z')
-    mat2 = rotation_matrix(90 - Galactic._ngp_B1950.dec.degree, 'y')
-    mat3 = rotation_matrix(Galactic._ngp_B1950.ra.degree, 'z')
-    matprec = fk4coords._precession_matrix(fk4coords.equinox, _EQUINOX_B1950)
-
-    return mat1 * mat2 * mat3 * matprec
-
-
- at frame_transform_graph.transform(DynamicMatrixTransform, Galactic, FK4NoETerms)
-def gal_to_fk4(galcoords, fk4frame):
-    return fk4_to_gal(fk4frame, galcoords).T
-
-
-def _make_transform_graph_docs():
-    """
-    Generates a string for use with the coordinate package's docstring
-    to show the available transforms and coordinate systems
-    """
-    from textwrap import dedent
-
-    isclass = inspect.isclass
-    coosys = [item for item in list(six.itervalues(globals()))
-              if isclass(item) and issubclass(item, BaseCoordinateFrame)]
-    coosys.remove(BaseCoordinateFrame)
-    coosys.remove(GenericFrame)
-    graphstr = frame_transform_graph.to_dot_graph(addnodes=coosys)
-
-    docstr = """
-    The diagram below shows all of the coordinate systems built into the
-    `~astropy.coordinates` package, their aliases (useful for converting
-    other coordinates to them using attribute-style access) and the
-    pre-defined transformations between them.  The user is free to
-    override any of these transformations by defining new transformations
-    between these systems, but the pre-defined transformations should be
-    sufficient for typical usage.
-
-    The graph also indicates the priority for each transformation as a
-    number next to the arrow.  These priorities are used to decide the
-    preferred order when two transformation paths have the same number
-    of steps.  These priorities are defined such that the path with a
-    *smaller* total priority is favored.
-
-
-    .. graphviz::
-
-    """
-
-    return dedent(docstr) + '    ' + graphstr.replace('\n', '\n    ')
-_transform_graph_docs = _make_transform_graph_docs()
diff --git a/astropy/coordinates/builtin_frames/__init__.py b/astropy/coordinates/builtin_frames/__init__.py
new file mode 100644
index 0000000..b4db3cb
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/__init__.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This package contains the coordinate frames actually implemented by astropy.
+
+Users shouldn't use this module directly, but rather import from the
+`astropy.coordinates` module.  While it is likely to exist for the long-term,
+the existence of this package and details of its organization should be
+considered an implementation detail, and is not guaranteed to hold for future
+versions of astropy.
+
+Notes
+-----
+The builtin frame classes are all imported automatically into this package's
+namespace, so there's no need to access the sub-modules directly.
+
+To implement a new frame in Astropy, a developer should add the frame as a new
+module in this package.  Any "self" transformations (i.e., those that transform
+from one frame to another frame of the same class) should be included in that
+module.  Transformation functions connecting the new frame to other frames
+should be in a separate module, which should be imported in this package's
+``__init__.py`` to ensure the transformations are hooked up when this package is
+imported.  Placing the trasnformation functions in separate modules avoids
+circular dependencies, because they need references to the frame classes.
+"""
+
+from .icrs import ICRS
+from .fk5 import FK5
+from .fk4 import FK4, FK4NoETerms
+from .galactic import Galactic
+from .galactocentric import Galactocentric
+from .altaz import AltAz
+from .gcrs import GCRS
+from .cirs import CIRS
+from .itrs import ITRS
+
+#need to import transformations so that they get registered in the graph
+from . import icrs_fk5_transforms
+from . import fk4_fk5_transforms
+from . import galactic_transforms
+from . import icrs_cirs_transforms
+from . import cirs_observed_transforms
+from . import intermediate_rotation_transforms
+
+# we define an __all__ because otherwise the transformation modules get included
+__all__ = ['ICRS', 'FK5', 'FK4', 'FK4NoETerms', 'Galactic', 'Galactocentric',
+           'AltAz', 'GCRS', 'CIRS', 'ITRS']
+
+def _make_transform_graph_docs():
+    """
+    Generates a string for use with the coordinate package's docstring
+    to show the available transforms and coordinate systems
+    """
+    import inspect
+    from textwrap import dedent
+    from ...extern import six
+    from ..baseframe import BaseCoordinateFrame, frame_transform_graph
+
+    isclass = inspect.isclass
+    coosys = [item for item in list(six.itervalues(globals()))
+              if isclass(item) and issubclass(item, BaseCoordinateFrame)]
+    graphstr = frame_transform_graph.to_dot_graph(addnodes=coosys)
+
+    docstr = """
+    The diagram below shows all of the coordinate systems built into the
+    `~astropy.coordinates` package, their aliases (useful for converting
+    other coordinates to them using attribute-style access) and the
+    pre-defined transformations between them.  The user is free to
+    override any of these transformations by defining new transformations
+    between these systems, but the pre-defined transformations should be
+    sufficient for typical usage.
+
+    The graph also indicates the priority for each transformation as a
+    number next to the arrow.  These priorities are used to decide the
+    preferred order when two transformation paths have the same number
+    of steps.  These priorities are defined such that the path with a
+    *smaller* total priority is favored.
+
+
+    .. graphviz::
+
+    """
+
+    return dedent(docstr) + '    ' + graphstr.replace('\n', '\n    ')
+_transform_graph_docs = _make_transform_graph_docs()
diff --git a/astropy/coordinates/builtin_frames/altaz.py b/astropy/coordinates/builtin_frames/altaz.py
new file mode 100644
index 0000000..4104922
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/altaz.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ... import units as u
+from ..representation import SphericalRepresentation
+from ..baseframe import (BaseCoordinateFrame, FrameAttribute,
+                         TimeFrameAttribute, QuantityFrameAttribute,
+                         RepresentationMapping, EarthLocationAttribute)
+
+_90DEG = 90*u.deg
+
+
+class AltAz(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the Altitude-Azimuth system (Horizontal
+    coordinates).  Azimuth is oriented East of North (i.e., N=0, E=90 degrees).
+
+    This frame is assumed to *include* refraction effects if the ``pressure``
+    frame attribute is non-zero.
+
+    This frame has the following frame attributes, which are necessary for
+    transforming from AltAz to some other system:
+
+    * ``obstime``
+        The time at which the observation is taken.  Used for determining the
+        position and orientation of the Earth.
+    * ``location``
+        The location on the Earth.  This can be specified either as an
+        `~astropy.coordinates.EarthLocation` object or as anything that can be
+        transformed to an `~astropy.coordinates.ITRS` frame.
+    * ``pressure``
+        The atmospheric pressure as an `~astropy.units.Quantity` with pressure
+        units.  This is necessary for performing refraction corrections.
+        Setting this to 0 (the default) will disable refraction calculations
+        when transforming to/from this frame.
+    * ``temperature``
+        The ground-level temperature as an `~astropy.units.Quantity` in
+        deg C.  This is necessary for performing refraction corrections.
+    * ``relative_humidity``
+        The relative humidity as a number from 0 to 1.  This is necessary for
+        performing refraction corrections.
+    * ``obswl``
+        The average wavelength of observations as an `~astropy.units.Quantity`
+         with length units.  This is necessary for performing refraction
+         corrections.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    az : `Angle`, optional, must be keyword
+        The Azimuth for this object (``alt`` must also be given and
+        ``representation`` must be None).
+    alt : `Angle`, optional, must be keyword
+        The Altitude for this object (``az`` must also be given and
+        ``representation`` must be None).
+    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+
+    Notes
+    -----
+    The refraction model is based on that implemented in ERFA, which is fast
+    but becomes inaccurate for altitudes below about 5 degrees.  Near and below
+    altitudes of 0, it can even give meaningless answers, and in this case
+    transforming to AltAz and back to another frame can give highly discrepent
+    results.  For much better numerical stability, leaving the ``pressure`` at
+    ``0`` (the default), disabling the refraction correction (yielding
+    "topocentric" horizontal coordinates).
+
+    """
+
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'az'),
+                      RepresentationMapping('lat', 'alt')],
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+
+    obstime = TimeFrameAttribute(default=None)
+    location = EarthLocationAttribute(default=None)
+    pressure = QuantityFrameAttribute(default=0, unit=u.hPa)
+    temperature = QuantityFrameAttribute(default=0, unit=u.deg_C)
+    relative_humidity = FrameAttribute(default=0)
+    obswl = QuantityFrameAttribute(default=1*u.micron, unit=u.micron)
+
+    def __init__(self, *args, **kwargs):
+        super(AltAz, self).__init__(*args, **kwargs)
+
+    @property
+    def secz(self):
+        """
+        Secant if the zenith angle for this coordinate, a common estimate of the
+        airmass.
+        """
+        return 1/np.sin(self.alt)
+
+    @property
+    def zen(self):
+        """
+        The zenith angle for this coordinate
+        """
+        return _90DEG.to(self.alt.unit) - self.alt
+
+
+#self-transform defined in cirs_observed_transforms.py
diff --git a/astropy/coordinates/builtin_frames/cirs.py b/astropy/coordinates/builtin_frames/cirs.py
new file mode 100644
index 0000000..25296a5
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/cirs.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..representation import SphericalRepresentation
+from ..baseframe import BaseCoordinateFrame, RepresentationMapping, TimeFrameAttribute
+from .utils import DEFAULT_OBSTIME
+
+class CIRS(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the Celestial Intermediate Reference System (CIRS).
+
+    This frame has one frame attribute:
+
+    * ``obstime``
+        The time at which the observation is taken.  Used for determining the
+        position of the Earth and its precession.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : `~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    """
+
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+
+    obstime = TimeFrameAttribute(default=DEFAULT_OBSTIME)
+
+#The "self-transform" is defined in icrs_cirs_transformations.py, because in
+#the current implementation it goes through ICRS (like GCRS)
diff --git a/astropy/coordinates/builtin_frames/cirs_observed_transforms.py b/astropy/coordinates/builtin_frames/cirs_observed_transforms.py
new file mode 100644
index 0000000..5ab96b9
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/cirs_observed_transforms.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+Contains the transformation functions for getting to "observed" systems from CIRS.
+Currently that just means AltAz.
+"""
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ... import units as u
+from ..baseframe import frame_transform_graph
+from ..transformations import FunctionTransform
+from ..representation import SphericalRepresentation, UnitSphericalRepresentation
+from ... import _erfa as erfa
+
+from .cirs import CIRS
+from .altaz import AltAz
+from .utils import get_polar_motion, get_dut1utc, PIOVER2
+
+
+ at frame_transform_graph.transform(FunctionTransform, CIRS, AltAz)
+def cirs_to_altaz(cirs_coo, altaz_frame):
+    if np.all(cirs_coo.obstime != altaz_frame.obstime):
+        # the only frame attribute for the current CIRS is the obstime, but this
+        # would need to be updated if a future change allowed specifying an
+        # Earth location algorithm or something
+        cirs_coo = cirs_coo.transform_to(CIRS(obstime=altaz_frame.obstime))
+    srepr = cirs_coo.represent_as(UnitSphericalRepresentation)
+    cirs_ra = srepr.lon.to(u.radian).value
+    cirs_dec = srepr.lat.to(u.radian).value
+
+    lon, lat, height = altaz_frame.location.to_geodetic('WGS84')
+    xp, yp = get_polar_motion(cirs_coo.obstime)
+
+    #first set up the astrometry context for ICRS<->CIRS
+    astrom = erfa.apio13(cirs_coo.obstime.jd1, cirs_coo.obstime.jd2,
+                         get_dut1utc(cirs_coo.obstime),
+                         lon.to(u.radian).value, lat.to(u.radian).value,
+                         height.to(u.m).value,
+                         xp, yp,  # polar motion
+                         # all below are already in correct units because they are QuantityFrameAttribues
+                         altaz_frame.pressure.value,
+                         altaz_frame.temperature.value,
+                         altaz_frame.relative_humidity,
+                         altaz_frame.obswl.value)
+
+    az, zen, ha, obs_dec, obs_ra = erfa.atioq(cirs_ra, cirs_dec, astrom)
+
+    dat = cirs_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        rep = UnitSphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False),
+                                          lon=u.Quantity(az, u.radian, copy=False),
+                                          copy=False)
+    else:
+        #now we get the distance as just the cartesian
+        #distance from the earth location to the coordinate location
+        distance = altaz_frame.location.itrs.separation_3d(cirs_coo)
+        rep = SphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False),
+                                      lon=u.Quantity(az, u.radian, copy=False),
+                                      distance=distance,
+                                      copy=False)
+    return altaz_frame.realize_frame(rep)
+
+
+ at frame_transform_graph.transform(FunctionTransform, AltAz, CIRS)
+def altaz_to_cirs(altaz_coo, cirs_frame):
+    srepr = altaz_coo.represent_as(UnitSphericalRepresentation)
+    az = srepr.lon.to(u.radian).value
+    zen = PIOVER2 - srepr.lat.to(u.radian).value
+
+    lon, lat, height = altaz_coo.location.to_geodetic('WGS84')
+    xp, yp = get_polar_motion(altaz_coo.obstime)
+
+    #first set up the astrometry context for ICRS<->CIRS at the altaz_coo time
+    astrom = erfa.apio13(altaz_coo.obstime.jd1, altaz_coo.obstime.jd2,
+                         get_dut1utc(altaz_coo.obstime),
+                         lon.to(u.radian).value, lat.to(u.radian).value,
+                         height.to(u.m).value,
+                         xp, yp,  # polar motion
+                         # all below are already in correct units because they are QuantityFrameAttribues
+                         altaz_coo.pressure.value,
+                         altaz_coo.temperature.value,
+                         altaz_coo.relative_humidity,
+                         altaz_coo.obswl.value)
+
+    # the 'A' indicates zen/az inputs
+    cirs_ra, cirs_dec = erfa.atoiq('A', az, zen, astrom)
+
+    dat = altaz_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        distance = None
+    else:
+        #now we get the distance as just the cartesian
+        #distance from the earth location to the coordinate location
+        distance = altaz_coo.location.itrs.separation_3d(altaz_coo)
+
+    #the final transform may be a no-op if the obstimes are the same
+    return CIRS(ra=cirs_ra*u.radian, dec=cirs_dec*u.radian, distance=distance,
+                obstime=altaz_coo.obstime).transform_to(cirs_frame)
+
+
+ at frame_transform_graph.transform(FunctionTransform, AltAz, AltAz)
+def altaz_to_altaz(from_coo, to_frame):
+    # for now we just implement this through CIRS to make sure we get everything
+    # covered
+    return from_coo.transform_to(CIRS(obstime=from_coo.obstime)).transform_to(to_frame)
diff --git a/astropy/coordinates/builtin_frames/fk4.py b/astropy/coordinates/builtin_frames/fk4.py
new file mode 100644
index 0000000..2636183
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/fk4.py
@@ -0,0 +1,243 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ... import units as u
+from ..representation import (SphericalRepresentation, CartesianRepresentation,
+                              UnitSphericalRepresentation)
+from ..baseframe import (BaseCoordinateFrame, frame_transform_graph,
+                         TimeFrameAttribute, RepresentationMapping)
+from ..transformations import FunctionTransform, DynamicMatrixTransform
+from .. import earth_orientation as earth
+
+from .utils import EQUINOX_B1950
+
+
+class FK4(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the FK4 system.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    equinox : astropy.time.Time, optional, must be keyword
+        The equinox of this frame.
+    obstime : astropy.time.Time, optional, must be keyword
+        The time this frame was observed.  If None, will be the same as
+        ``equinox``.
+    """
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+    equinox = TimeFrameAttribute(default=EQUINOX_B1950)
+    obstime = TimeFrameAttribute(default=None, secondary_attribute='equinox')
+
+# the "self" transform
+ at frame_transform_graph.transform(FunctionTransform, FK4, FK4)
+def fk4_to_fk4(fk4coord1, fk4frame2):
+    # deceptively complicated: need to transform to No E-terms FK4, precess, and
+    # then come back, because precession is non-trivial with E-terms
+    fnoe_w_eqx1 = fk4coord1.transform_to(FK4NoETerms(equinox=fk4coord1.equinox))
+    fnoe_w_eqx2 = fnoe_w_eqx1.transform_to(FK4NoETerms(equinox=fk4frame2.equinox))
+    return fnoe_w_eqx2.transform_to(fk4frame2)
+
+
+class FK4NoETerms(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the FK4 system, but with the E-terms of aberration
+    removed.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : :class:`~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    obstime : astropy.time.Time, optional, must be keyword
+        The time this frame was observed.  If None, will be the same as
+        ``equinox``.
+    """
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+    equinox = TimeFrameAttribute(default=EQUINOX_B1950)
+    obstime = TimeFrameAttribute(default=None, secondary_attribute='equinox')
+
+    @staticmethod
+    def _precession_matrix(oldequinox, newequinox):
+        """
+        Compute and return the precession matrix for FK4 using Newcomb's method.
+        Used inside some of the transformation functions.
+
+        Parameters
+        ----------
+        oldequinox : `~astropy.time.Time`
+            The equinox to precess from.
+        newequinox : `~astropy.time.Time`
+            The equinox to precess to.
+
+        Returns
+        -------
+        newcoord : array
+            The precession matrix to transform to the new equinox
+        """
+        return earth._precession_matrix_besselian(oldequinox.byear, newequinox.byear)
+
+
+# the "self" transform
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, FK4NoETerms)
+def fk4noe_to_fk4noe(fk4necoord1, fk4neframe2):
+    return fk4necoord1._precession_matrix(fk4necoord1.equinox, fk4neframe2.equinox)
+
+
+# FK4-NO-E to/from FK4 ----------------------------->
+# Unlike other frames, this module include *two* frame classes for FK4
+# coordinates - one including the E-terms of aberration (FK4), and
+# one not including them (FK4NoETerms). The following functions
+# implement the transformation between these two.
+def fk4_e_terms(equinox):
+    """
+    Return the e-terms of aberation vector
+
+    Parameters
+    ----------
+    equinox : Time object
+        The equinox for which to compute the e-terms
+    """
+    # Constant of aberration at J2000
+    k = 0.0056932
+
+    # Eccentricity of the Earth's orbit
+    e = earth.eccentricity(equinox.jd)
+    e = np.radians(e)
+
+    # Mean longitude of perigee of the solar orbit
+    g = earth.mean_lon_of_perigee(equinox.jd)
+    g = np.radians(g)
+
+    # Obliquity of the ecliptic
+    o = earth.obliquity(equinox.jd, algorithm=1980)
+    o = np.radians(o)
+
+    return e * k * np.sin(g), \
+           -e * k * np.cos(g) * np.cos(o), \
+           -e * k * np.cos(g) * np.sin(o)
+
+
+ at frame_transform_graph.transform(FunctionTransform, FK4, FK4NoETerms)
+def fk4_to_fk4_no_e(fk4coord, fk4noeframe):
+    # Extract cartesian vector
+    c = fk4coord.cartesian.xyz
+    r = np.asarray(c.reshape((3, c.size // 3)))
+
+    # Find distance (for re-normalization)
+    d_orig = np.sqrt(np.sum(r ** 2))
+
+    # Apply E-terms of aberration. Note that this depends on the equinox (not
+    # the observing time/epoch) of the coordinates. See issue #1496 for a
+    # discussion of this.
+    eterms_a = np.asarray(fk4_e_terms(fk4coord.equinox))
+    r = r - eterms_a.reshape(3, 1) + np.dot(eterms_a, r) * r
+
+    # Find new distance (for re-normalization)
+    d_new = np.sqrt(np.sum(r ** 2))
+
+    # Renormalize
+    r = r * d_orig / d_new
+
+    subshape = c.shape[1:]
+    x = r[0].reshape(subshape)
+    y = r[1].reshape(subshape)
+    z = r[2].reshape(subshape)
+
+    #now re-cast into an appropriate Representation, and precess if need be
+    if isinstance(fk4coord.data, UnitSphericalRepresentation):
+        representation = CartesianRepresentation(x=x*u.one, y=y*u.one, z=z*u.one)
+        representation = representation.represent_as(UnitSphericalRepresentation)
+    else:
+        representation = CartesianRepresentation(x=x*c.unit, y=y*c.unit, z=z*c.unit)
+
+    # if no obstime was given in the new frame, use the old one for consistency
+    newobstime = fk4coord._obstime if fk4noeframe._obstime is None else fk4noeframe._obstime
+
+    fk4noe = FK4NoETerms(representation, equinox=fk4coord.equinox,
+                         obstime=newobstime)
+    if fk4coord.equinox != fk4noeframe.equinox:
+        #precession
+        fk4noe = fk4noe.transform_to(fk4noeframe)
+    return fk4noe
+
+
+ at frame_transform_graph.transform(FunctionTransform, FK4NoETerms, FK4)
+def fk4_no_e_to_fk4(fk4noecoord, fk4frame):
+    #first precess, if necessary
+    if fk4noecoord.equinox != fk4frame.equinox:
+        fk4noe_w_fk4equinox = FK4NoETerms(equinox=fk4frame.equinox,
+                                          obstime=fk4noecoord.obstime)
+        fk4noecoord = fk4noecoord.transform_to(fk4noe_w_fk4equinox)
+
+    # Extract cartesian vector
+    c = fk4noecoord.cartesian.xyz
+    r = np.asarray(c.reshape((3, c.size // 3)))
+
+    # Find distance (for re-normalization)
+    d_orig = np.sqrt(np.sum(r ** 2))
+
+    # Apply E-terms of aberration. Note that this depends on the equinox (not
+    # the observing time/epoch) of the coordinates. See issue #1496 for a
+    # discussion of this.
+    eterms_a = np.asarray(fk4_e_terms(fk4noecoord.equinox))
+    r0 = r.copy()
+    for _ in range(10):
+        r = (eterms_a.reshape(3, 1) + r0) / (1. + np.dot(eterms_a, r))
+
+    # Find new distance (for re-normalization)
+    d_new = np.sqrt(np.sum(r ** 2))
+
+    # Renormalize
+    r = r * d_orig / d_new
+
+    subshape = c.shape[1:]
+    x = r[0].reshape(subshape)
+    y = r[1].reshape(subshape)
+    z = r[2].reshape(subshape)
+
+    #now re-cast into an appropriate Representation, and precess if need be
+    if isinstance(fk4noecoord.data, UnitSphericalRepresentation):
+        representation = CartesianRepresentation(x=x*u.one, y=y*u.one, z=z*u.one)
+        representation = representation.represent_as(UnitSphericalRepresentation)
+    else:
+        representation = CartesianRepresentation(x=x*c.unit, y=y*c.unit, z=z*c.unit)
+
+    return fk4frame.realize_frame(representation)
+
diff --git a/astropy/coordinates/builtin_frames/fk4_fk5_transforms.py b/astropy/coordinates/builtin_frames/fk4_fk5_transforms.py
new file mode 100644
index 0000000..d3997fc
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/fk4_fk5_transforms.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+
+
+import numpy as np
+
+from ..baseframe import frame_transform_graph
+from ..transformations import DynamicMatrixTransform
+
+from .fk4 import FK4NoETerms
+from .fk5 import FK5
+from .utils import EQUINOX_B1950, EQUINOX_J2000
+
+
+
+# FK5 to/from FK4 ------------------->
+# B1950->J2000 matrix from Murray 1989 A&A 218,325 eqn 28
+_B1950_TO_J2000_M = \
+    np.mat([[0.9999256794956877, -0.0111814832204662, -0.0048590038153592],
+            [0.0111814832391717,  0.9999374848933135, -0.0000271625947142],
+            [0.0048590037723143, -0.0000271702937440,  0.9999881946023742]])
+
+_FK4_CORR = \
+    np.mat([[-0.0026455262, -1.1539918689, +2.1111346190],
+            [+1.1540628161, -0.0129042997, +0.0236021478],
+            [-2.1112979048, -0.0056024448, +0.0102587734]]) * 1.e-6
+
+def _fk4_B_matrix(obstime):
+    """
+    This is a correction term in the FK4 transformations because FK4 is a
+    rotating system - see Murray 89 eqn 29
+    """
+    # Note this is *julian century*, not besselian
+    T = (obstime.jyear - 1950.) / 100.
+    return _B1950_TO_J2000_M + _FK4_CORR * T
+
+
+# This transformation can't be static because the observation date is needed.
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, FK5)
+def fk4_no_e_to_fk5(fk4noecoord, fk5frame):
+    # Correction terms for FK4 being a rotating system
+    B = _fk4_B_matrix(fk4noecoord.obstime)
+
+    # construct both precession matricies - if the equinoxes are B1950 and
+    # J2000, these are just identity matricies
+    pmat1 = fk4noecoord._precession_matrix(fk4noecoord.equinox, EQUINOX_B1950)
+    pmat2 = fk5frame._precession_matrix(EQUINOX_J2000, fk5frame.equinox)
+
+    return pmat2 * B * pmat1
+
+
+# This transformation can't be static because the observation date is needed.
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK5, FK4NoETerms)
+def fk5_to_fk4_no_e(fk5coord, fk4noeframe):
+    # Get transposed version of the rotating correction terms... so with the
+    # transpose this takes us from FK5/J200 to FK4/B1950
+    B = _fk4_B_matrix(fk4noeframe.obstime).T
+
+    # construct both precession matricies - if the equinoxes are B1950 and
+    # J2000, these are just identity matricies
+    pmat1 = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
+    pmat2 = fk4noeframe._precession_matrix(EQUINOX_B1950, fk4noeframe.equinox)
+
+    return pmat2 * B * pmat1
diff --git a/astropy/coordinates/builtin_frames/fk5.py b/astropy/coordinates/builtin_frames/fk5.py
new file mode 100644
index 0000000..d7b3f25
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/fk5.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..representation import SphericalRepresentation
+from ..baseframe import (BaseCoordinateFrame, frame_transform_graph,
+                         TimeFrameAttribute, RepresentationMapping)
+from ..transformations import DynamicMatrixTransform
+from .. import earth_orientation as earth
+
+from .utils import EQUINOX_J2000
+
+
+class FK5(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the FK5 system.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : `~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    equinox : `~astropy.time.Time`, optional, must be keyword
+        The equinox of this frame.
+    """
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+    equinox = TimeFrameAttribute(default=EQUINOX_J2000)
+
+    @staticmethod
+    def _precession_matrix(oldequinox, newequinox):
+        """
+        Compute and return the precession matrix for FK5 based on Capitaine et
+        al. 2003/IAU2006.  Used inside some of the transformation functions.
+
+        Parameters
+        ----------
+        oldequinox : `~astropy.time.Time`
+            The equinox to precess from.
+        newequinox : `~astropy.time.Time`
+            The equinox to precess to.
+
+        Returns
+        -------
+        newcoord : array
+            The precession matrix to transform to the new equinox
+        """
+        return earth.precession_matrix_Capitaine(oldequinox, newequinox)
+
+
+# This is the "self-transform".  Defined at module level because the decorator
+#  needs a reference to the FK5 class
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK5, FK5)
+def fk5_to_fk5(fk5coord1, fk5frame2):
+    return fk5coord1._precession_matrix(fk5coord1.equinox, fk5frame2.equinox)
diff --git a/astropy/coordinates/builtin_frames/galactic.py b/astropy/coordinates/builtin_frames/galactic.py
new file mode 100644
index 0000000..f02927b
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/galactic.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ... import units as u
+from ..angles import Angle
+from ..representation import SphericalRepresentation
+from ..baseframe import BaseCoordinateFrame, RepresentationMapping
+
+# these are needed for defining the NGP
+from .fk5 import FK5
+from .fk4 import FK4NoETerms
+
+
+class Galactic(BaseCoordinateFrame):
+    """
+    Galactic Coordinates.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    l : `Angle`, optional, must be keyword
+        The Galactic longitude for this object (``b`` must also be given and
+        ``representation`` must be None).
+    b : `Angle`, optional, must be keyword
+        The Galactic latitude for this object (``l`` must also be given and
+        ``representation`` must be None).
+    distance : `~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+    """
+
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'l'),
+                      RepresentationMapping('lat', 'b')],
+        'cartesian': [RepresentationMapping('x', 'w'),
+                      RepresentationMapping('y', 'u'),
+                      RepresentationMapping('z', 'v')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+
+    # North galactic pole and zeropoint of l in FK4/FK5 coordinates. Needed for
+    # transformations to/from FK4/5
+
+    # These are from the IAU's definition of galactic coordinates
+    _ngp_B1950 = FK4NoETerms(ra=192.25*u.degree, dec=27.4*u.degree)
+    _lon0_B1950 = Angle(123, u.degree)
+
+    # These are *not* from Reid & Brunthaler 2004 - instead, they were
+    # derived by doing:
+    #
+    # >>> FK4NoETerms(ra=192.25*u.degree, dec=27.4*u.degree).transform_to(FK5)
+    #
+    # This gives better consistency with other codes than using the values
+    # from Reid & Brunthaler 2004 and the best self-consistency between FK5
+    # -> Galactic and FK5 -> FK4 -> Galactic. The lon0 angle was found by
+    # optimizing the self-consistency.
+    _ngp_J2000 = FK5(ra=192.8594812065348*u.degree, dec=27.12825118085622*u.degree)
+    _lon0_J2000 = Angle(122.9319185680026, u.degree)
diff --git a/astropy/coordinates/builtin_frames/galactic_transforms.py b/astropy/coordinates/builtin_frames/galactic_transforms.py
new file mode 100644
index 0000000..010542a
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/galactic_transforms.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..angles import rotation_matrix
+from ..baseframe import frame_transform_graph
+from ..transformations import DynamicMatrixTransform
+
+from .fk5 import FK5
+from .fk4 import FK4NoETerms
+from .utils import EQUINOX_B1950, EQUINOX_J2000
+from .galactic import Galactic
+
+
+# Galactic to/from FK4/FK5 ----------------------->
+# can't be static because the equinox is needed
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK5, Galactic)
+def fk5_to_gal(fk5coord, galframe):
+    #need precess to J2000 first
+    pmat = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
+    mat1 = rotation_matrix(180 - Galactic._lon0_J2000.degree, 'z')
+    mat2 = rotation_matrix(90 - Galactic._ngp_J2000.dec.degree, 'y')
+    mat3 = rotation_matrix(Galactic._ngp_J2000.ra.degree, 'z')
+
+    return mat1 * mat2 * mat3 * pmat
+
+
+ at frame_transform_graph.transform(DynamicMatrixTransform, Galactic, FK5)
+def _gal_to_fk5(galcoord, fk5frame):
+    return fk5_to_gal(fk5frame, galcoord).T
+
+
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK4NoETerms, Galactic)
+def fk4_to_gal(fk4coords, galframe):
+    mat1 = rotation_matrix(180 - Galactic._lon0_B1950.degree, 'z')
+    mat2 = rotation_matrix(90 - Galactic._ngp_B1950.dec.degree, 'y')
+    mat3 = rotation_matrix(Galactic._ngp_B1950.ra.degree, 'z')
+    matprec = fk4coords._precession_matrix(fk4coords.equinox, EQUINOX_B1950)
+
+    return mat1 * mat2 * mat3 * matprec
+
+
+ at frame_transform_graph.transform(DynamicMatrixTransform, Galactic, FK4NoETerms)
+def gal_to_fk4(galcoords, fk4frame):
+    return fk4_to_gal(fk4frame, galcoords).T
diff --git a/astropy/coordinates/builtin_frames/galactocentric.py b/astropy/coordinates/builtin_frames/galactocentric.py
new file mode 100644
index 0000000..5313ff6
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/galactocentric.py
@@ -0,0 +1,209 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ... import units as u
+from ..angles import Angle
+from ..representation import CartesianRepresentation, UnitSphericalRepresentation
+from ..baseframe import (BaseCoordinateFrame, FrameAttribute,
+                         frame_transform_graph)
+from ..transformations import FunctionTransform
+from ..errors import ConvertError
+
+from .icrs import ICRS
+
+# Measured by minimizing the difference between a plane of coordinates along
+#   l=0, b=[-90,90] and the Galactocentric x-z plane
+ROLL0 = Angle(58.5986320306*u.degree)
+
+class Galactocentric(BaseCoordinateFrame):
+    r"""
+    A coordinate or frame in the Galactocentric system. This frame
+    requires specifying the Sun-Galactic center distance, and optionally
+    the height of the Sun above the Galactic midplane.
+
+    The position of the Sun is assumed to be on the x axis of the final,
+    right-handed system. That is, the x axis points from the position of
+    the Sun projected to the Galactic midplane to the Galactic center --
+    roughly towards :math:`(l,b) = (0^\circ,0^\circ)`. For the default
+    transformation (:math:`{\rm roll}=0^\circ`), the y axis points roughly
+    towards Galactic longitude :math:`l=90^\circ`, and the z axis points
+    roughly towards the North Galactic Pole (:math:`b=90^\circ`).
+
+    The default position of the Galactic Center in ICRS coordinates is
+    taken from Reid et al. 2004,
+    http://adsabs.harvard.edu/abs/2004ApJ...616..872R.
+
+    .. math::
+
+        {\rm RA} = 17:45:37.224~{\rm hr}\\
+        {\rm Dec} = -28:56:10.23~{\rm deg}
+
+    The default distance to the Galactic Center is 8.3 kpc, e.g.,
+    Gillessen et al. 2009,
+    http://adsabs.harvard.edu/abs/2009ApJ...692.1075G.
+
+    The default height of the Sun above the Galactic midplane is taken to
+    be 27 pc, as measured by
+    http://adsabs.harvard.edu/abs/2001ApJ...553..184C.
+
+    For a more detailed look at the math behind this transformation, see
+    the document :ref:`coordinates-galactocentric`.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other
+        keywords)
+    galcen_distance : `~astropy.units.Quantity`, optional, must be keyword
+        The distance from the Sun to the Galactic center.
+    galcen_ra : `Angle`, optional, must be keyword
+        The Right Ascension (RA) of the Galactic center in the ICRS frame.
+    galcen_dec : `Angle`, optional, must be keyword
+        The Declination (Dec) of the Galactic center in the ICRS frame.
+    z_sun : `~astropy.units.Quantity`, optional, must be keyword
+        The distance from the Sun to the Galactic midplane.
+    roll : `Angle`, optional, must be keyword
+        The angle to rotate about the final x-axis, relative to the
+        orientation for Galactic. For example, if this roll angle is 0,
+        the final x-z plane will align with the Galactic coordinates x-z
+        plane. Unless you really know what this means, you probably should
+        not change this!
+
+    Examples
+    --------
+    To transform to the Galactocentric frame with the default
+    frame attributes, pass the uninstantiated class name to the
+    ``transform_to()`` method of a coordinate frame or
+    `~astropy.coordinates.SkyCoord` object::
+
+        >>> import astropy.units as u
+        >>> import astropy.coordinates as coord
+        >>> c = coord.ICRS(ra=[158.3122, 24.5] * u.degree,
+        ...                dec=[-17.3, 81.52] * u.degree,
+        ...                distance=[11.5, 24.12] * u.kpc)
+        >>> c.transform_to(coord.Galactocentric) # doctest: +FLOAT_CMP
+        <Galactocentric Coordinate (galcen_distance=8.3 kpc, galcen_ra=266d24m18.36s, galcen_dec=-28d56m10.23s, z_sun=27.0 pc, roll=0.0 deg): (x, y, z) in kpc
+            [(-9.6083818980977, -9.400621883358546, 6.520560663896347),
+             (-21.283023068029138, 18.763340128812384, 7.846938548636718)]>
+
+    To specify a custom set of parameters, you have to include extra keyword
+    arguments when initializing the Galactocentric frame object::
+
+        >>> c.transform_to(coord.Galactocentric(galcen_distance=8.1*u.kpc)) # doctest: +FLOAT_CMP
+        <Galactocentric Coordinate (galcen_distance=8.1 kpc, galcen_ra=266d24m18.36s, galcen_dec=-28d56m10.23s, z_sun=27.0 pc, roll=0.0 deg): (x, y, z) in kpc
+            [(-9.407859235565343, -9.400621883358546, 6.520665737962164),
+             (-21.08239383088295, 18.763340128812384, 7.84798134569032)]>
+
+    Similarly, transforming from the Galactocentric frame to another coordinate frame::
+
+        >>> c = coord.Galactocentric(x=[-8.3, 4.5] * u.kpc,
+        ...                          y=[0., 81.52] * u.kpc,
+        ...                          z=[0.027, 24.12] * u.kpc)
+        >>> c.transform_to(coord.ICRS) # doctest: +FLOAT_CMP
+        <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
+            [(86.22349058727241, 28.8389413808627, 4.391577882957292e-05),
+             (289.6680265194508, 49.88763881149547, 85.96407345372828)]>
+
+    Or, with custom specification of the Galactic center::
+
+        >>> c = coord.Galactocentric(x=[-8.0, 4.5] * u.kpc,
+        ...                          y=[0., 81.52] * u.kpc,
+        ...                          z=[21.0, 24120.0] * u.pc,
+        ...                          z_sun=21 * u.pc, galcen_distance=8. * u.kpc)
+        >>> c.transform_to(coord.ICRS) # doctest: +FLOAT_CMP
+        <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
+            [(86.25852490164378, 28.85773187391088, 2.7562547481200286e-05),
+             (289.77285254989323, 50.062904565432014, 85.92160096237191)]>
+
+    """
+    default_representation = CartesianRepresentation
+
+    # TODO: these can all become QuantityFrameAttribute's once #3217 is merged
+    galcen_distance = FrameAttribute(default=8.3*u.kpc)
+    galcen_ra = FrameAttribute(default=Angle(266.4051*u.degree))
+    galcen_dec = FrameAttribute(default=Angle(-28.936175*u.degree))
+    z_sun = FrameAttribute(default=27.*u.pc)
+    roll = FrameAttribute(default=0.*u.deg)
+
+# ICRS to/from Galactocentric ----------------------->
+ at frame_transform_graph.transform(FunctionTransform, ICRS, Galactocentric)
+def icrs_to_galactocentric(icrs_coord, galactocentric_frame):
+    from ..representation import CartesianRepresentation
+    from ..angles import rotation_matrix
+
+    if isinstance(icrs_coord.data, UnitSphericalRepresentation):
+        raise ConvertError("Transforming to a Galactocentric frame requires "
+                           "a 3D coordinate, e.g. (angle, angle, distance) or"
+                           " (x, y, z).")
+
+    xyz = icrs_coord.cartesian.xyz
+
+    # define rotation matrix to align x(ICRS) with the vector to the Galactic center
+    mat1 = rotation_matrix(-galactocentric_frame.galcen_dec, 'y')
+    mat2 = rotation_matrix(galactocentric_frame.galcen_ra, 'z')
+    R1 = mat1 * mat2
+
+    # extra roll away from the Galactic x-z plane
+    R2 = rotation_matrix(ROLL0 - galactocentric_frame.roll, 'x')
+
+    # construct transformation matrix
+    R = R2*R1
+
+    # some reshape hacks to handle ND arrays
+    orig_shape = xyz.shape
+    xyz = R.dot(xyz.reshape(xyz.shape[0], np.prod(xyz.shape[1:]))).reshape(orig_shape)
+
+    # translate by Sun-Galactic center distance along new x axis
+    xyz[0] = xyz[0] - galactocentric_frame.galcen_distance
+
+    # rotate about y' to account for tilt due to Sun's height above the plane
+    z_d = (galactocentric_frame.z_sun / galactocentric_frame.galcen_distance).decompose()
+    R = rotation_matrix(-np.arcsin(z_d), 'y')
+    xyz = R.dot(xyz.reshape(xyz.shape[0], np.prod(xyz.shape[1:]))).reshape(orig_shape)
+
+    representation = CartesianRepresentation(xyz)
+    return galactocentric_frame.realize_frame(representation)
+
+ at frame_transform_graph.transform(FunctionTransform, Galactocentric, ICRS)
+def galactocentric_to_icrs(galactocentric_coord, icrs_frame):
+    from ..representation import CartesianRepresentation
+    from ..angles import rotation_matrix
+
+    if isinstance(galactocentric_coord.data, UnitSphericalRepresentation):
+        raise ConvertError("Transforming from a Galactocentric frame requires "
+                           "a 3D coordinate, e.g. (angle, angle, distance) or"
+                           " (x, y, z).")
+
+    xyz = galactocentric_coord.cartesian.xyz
+
+    # rotate about y' to account for tilt due to Sun's height above the plane
+    z_d = (galactocentric_coord.z_sun / galactocentric_coord.galcen_distance).decompose()
+    R = rotation_matrix(np.arcsin(z_d), 'y')
+
+    # some reshape hacks to handle ND arrays
+    orig_shape = xyz.shape
+    xyz = R.dot(xyz.reshape(xyz.shape[0], np.prod(xyz.shape[1:]))).reshape(orig_shape)
+
+    # translate by Sun-Galactic center distance along x axis
+    xyz[0] = xyz[0] + galactocentric_coord.galcen_distance
+
+    # define inverse rotation matrix that aligns x(ICRS) with the vector to the Galactic center
+    mat1 = rotation_matrix(-galactocentric_coord.galcen_dec, 'y')
+    mat2 = rotation_matrix(galactocentric_coord.galcen_ra, 'z')
+    R1 = mat1 * mat2
+
+    # extra roll away from the Galactic x-z plane
+    R2 = rotation_matrix(ROLL0 - galactocentric_coord.roll, 'x')
+
+    # construct transformation matrix
+    R = R2*R1
+
+    # rotate into ICRS frame
+    xyz = np.linalg.inv(R).dot(xyz.reshape(xyz.shape[0], np.prod(xyz.shape[1:]))).reshape(orig_shape)
+
+    representation = CartesianRepresentation(xyz)
+    return icrs_frame.realize_frame(representation)
diff --git a/astropy/coordinates/builtin_frames/gcrs.py b/astropy/coordinates/builtin_frames/gcrs.py
new file mode 100644
index 0000000..35cd486
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/gcrs.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ... import units as u
+from ..representation import SphericalRepresentation
+from ..baseframe import (BaseCoordinateFrame, RepresentationMapping,
+                         TimeFrameAttribute, QuantityFrameAttribute)
+from .utils import DEFAULT_OBSTIME
+
+
+class GCRS(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the Geocentric Celestial Reference System (GCRS).
+
+    GCRS is distinct form ICRS mainly in that it is relative to the Earth's
+    center-of-mass rather than the solar system Barycenter.  That means this
+    frame includes the effects of abberation (unlike ICRS). For more background
+    on the GCRS, see the references provided in the
+    :ref:`astropy-coordinates-seealso` section of the documentation. (Of
+    particular note is Section 1.2 of
+    `USNO Circular 179 <http://aa.usno.navy.mil/publications/docs/Circular_179.php>`_)
+
+    This frame also includes frames that are defined *relative* to the Earth,
+    but that are offset (in both position and velocity) from the Earth.
+
+
+
+    This frame has three frame attributes:
+
+    * ``obstime``
+        The time at which the observation is taken.  Used for determining the
+        position of the Earth.
+    * ``obsgeoloc``
+        3-vector giving the position of the observer relative to the
+        center-of-mass of the Earth, oriented the same as BCRS/ICRS.
+        Defaults to 0,  meaning "true" GCRS.
+    * ``obsgeovel``
+        3-vector giving the celocity of the observer relative to the
+        center-of-mass of the Earth, oriented the same as BCRS/ICRS.
+        Defaults to 0, meaning "true" GCRS.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : `~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    """
+
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
+
+    obstime = TimeFrameAttribute(default=DEFAULT_OBSTIME)
+    obsgeoloc = QuantityFrameAttribute(default=0, unit=u.m, shape=(3,))
+    obsgeovel = QuantityFrameAttribute(default=0, unit=u.m/u.s, shape=(3,))
+
+#The "self-transform" is defined in icrs_cirs_transformations.py, because in
+#the current implementation it goes through ICRS (like CIRS)
diff --git a/astropy/coordinates/builtin_frames/icrs.py b/astropy/coordinates/builtin_frames/icrs.py
new file mode 100644
index 0000000..38abfa1
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/icrs.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..representation import SphericalRepresentation
+from ..baseframe import BaseCoordinateFrame, RepresentationMapping
+
+
+class ICRS(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the ICRS system.
+
+    If you're looking for "J2000" coordinates, and aren't sure if you want to
+    use this or `~astropy.coordinates.FK5`, you probably want to use ICRS. It's
+    more well-defined as a catalog coordinate and is an inertial system, and is
+    very close (within tens of milliarcseconds) to J2000 equatorial.
+
+    For more background on the ICRS and related coordinate transformations, see the
+    references provided in the  :ref:`astropy-coordinates-seealso` section of the
+    documentation.
+
+    Parameters
+    ----------
+    representation : `BaseRepresentation` or None
+        A representation object or None to have no data (or use the other keywords)
+    ra : `Angle`, optional, must be keyword
+        The RA for this object (``dec`` must also be given and ``representation``
+        must be None).
+    dec : `Angle`, optional, must be keyword
+        The Declination for this object (``ra`` must also be given and
+        ``representation`` must be None).
+    distance : `~astropy.units.Quantity`, optional, must be keyword
+        The Distance for this object along the line-of-sight.
+        (``representation`` must be None).
+    """
+
+    frame_specific_representation_info = {
+        'spherical': [RepresentationMapping('lon', 'ra'),
+                      RepresentationMapping('lat', 'dec')]
+    }
+    frame_specific_representation_info['unitspherical'] = \
+        frame_specific_representation_info['spherical']
+
+    default_representation = SphericalRepresentation
diff --git a/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py b/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py
new file mode 100644
index 0000000..a51b51e
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py
@@ -0,0 +1,168 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+Contains the transofrmation functions for getting from ICRS to CIRS and anything
+in between (currently that means GCRS)
+"""
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ... import units as u
+from ..baseframe import frame_transform_graph
+from ..transformations import FunctionTransform
+from ..representation import UnitSphericalRepresentation, SphericalRepresentation
+from ... import _erfa as erfa
+
+from .icrs import ICRS
+from .gcrs import GCRS
+from .cirs import CIRS
+
+
+#first the ICRS/CIRS related transforms
+
+ at frame_transform_graph.transform(FunctionTransform, ICRS, CIRS)
+def icrs_to_cirs(icrs_coo, cirs_frame):
+    #parallax in arcsec
+    if isinstance(icrs_coo.data, UnitSphericalRepresentation):  # no distance
+        px = 0
+    else:
+        px = 1 / icrs_coo.distance.to(u.parsec).value
+    srepr = icrs_coo.represent_as(UnitSphericalRepresentation)
+    i_ra = srepr.lon.to(u.radian).value
+    i_dec = srepr.lat.to(u.radian).value
+
+    #first set up the astrometry context for ICRS<->CIRS
+    astrom, eo = erfa.apci13(cirs_frame.obstime.jd1, cirs_frame.obstime.jd2)
+
+    # TODO: possibly switch to something that is like atciq, but skips the first
+    # step, b/c that involves some  wasteful computations b/c pm=0  here
+    cirs_ra, cirs_dec = erfa.atciq(i_ra, i_dec, 0, 0, px, 0, astrom)
+
+    dat = icrs_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        rep = UnitSphericalRepresentation(lat=u.Quantity(cirs_dec, u.radian, copy=False),
+                                          lon=u.Quantity(cirs_ra, u.radian, copy=False),
+                                          copy=False)
+    else:
+        #compute the distance as just the cartesian sum from moving to the Earth
+        #we have to do this because the ERFA functions throw away distance info
+        distance = np.sum((astrom['eb']*u.au + icrs_coo.cartesian.xyz.T)**2, -1)**0.5
+        rep = SphericalRepresentation(lat=u.Quantity(cirs_dec, u.radian, copy=False),
+                                      lon=u.Quantity(cirs_ra, u.radian, copy=False),
+                                      distance=distance, copy=False)
+
+    return cirs_frame.realize_frame(rep)
+
+ at frame_transform_graph.transform(FunctionTransform, CIRS, ICRS)
+def cirs_to_icrs(cirs_coo, icrs_frame):
+    srepr = cirs_coo.represent_as(UnitSphericalRepresentation)
+    cirs_ra = srepr.lon.to(u.radian).value
+    cirs_dec = srepr.lat.to(u.radian).value
+
+    #first set up the astrometry context for ICRS<->CIRS
+    astrom, eo = erfa.apci13(cirs_coo.obstime.jd1, cirs_coo.obstime.jd2)
+
+    icrs_ra, icrs_dec = erfa.aticq(cirs_ra, cirs_dec, astrom)
+
+    dat = cirs_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        rep = UnitSphericalRepresentation(lat=u.Quantity(icrs_dec, u.radian, copy=False),
+                                          lon=u.Quantity(icrs_ra, u.radian, copy=False),
+                                          copy=False)
+    else:
+        #compute the distance as just the cartesian sum from moving to the SSB
+        #we have to do this because the ERFA functions throw away distance info
+        distance = np.sum((-astrom['eb']*u.au + cirs_coo.cartesian.xyz.T)**2, -1)**0.5
+        rep = SphericalRepresentation(lat=u.Quantity(icrs_dec, u.radian, copy=False),
+                                      lon=u.Quantity(icrs_ra, u.radian, copy=False),
+                                      distance=distance, copy=False)
+    return icrs_frame.realize_frame(rep)
+
+ at frame_transform_graph.transform(FunctionTransform, CIRS, CIRS)
+def cirs_to_cirs(from_coo, to_frame):
+    if np.all(from_coo.obstime == to_frame.obstime):
+        return to_frame.realize_frame(from_coo.data)
+    else:
+        # the CIRS<-> CIRS transform actually goes through ICRS.  This has a
+        # subtle implication that a point in CIRS is uniquely determined
+        # by the corresponding astrometric ICRS coordinate *at its
+        # current time*.  This has some subtle implications in terms of GR, but
+        # is sort of glossed over in the current scheme because we are dropping
+        # distances anyway.
+        return from_coo.transform_to(ICRS).transform_to(to_frame)
+
+
+# Now the GCRS-related transforms to/from ICRS
+
+ at frame_transform_graph.transform(FunctionTransform, ICRS, GCRS)
+def icrs_to_gcrs(icrs_coo, gcrs_frame):
+    #parallax in arcsec
+    if isinstance(icrs_coo.data, UnitSphericalRepresentation):  # no distance
+        px = 0
+    else:
+        px = 1 / icrs_coo.distance.to(u.parsec).value
+    srepr = icrs_coo.represent_as(UnitSphericalRepresentation)
+    i_ra = srepr.lon.to(u.radian).value
+    i_dec = srepr.lat.to(u.radian).value
+
+    #first set up the astrometry context for ICRS<->GCRS
+    pv = np.array([gcrs_frame.obsgeoloc.value,
+                   gcrs_frame.obsgeovel.value])
+    astrom = erfa.apcs13(gcrs_frame.obstime.jd1, gcrs_frame.obstime.jd2, pv)
+
+    # TODO: possibly switch to something that is like atciq, but skips the first
+    # step, b/c that involves some  wasteful computations b/c pm=0  here
+    gcrs_ra, gcrs_dec = erfa.atciq(i_ra, i_dec, 0, 0, px, 0, astrom)
+
+    dat = icrs_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        rep = UnitSphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
+                                          lon=u.Quantity(gcrs_ra, u.radian, copy=False),
+                                          copy=False)
+    else:
+        #compute the distance as just the cartesian sum from moving to the Earth
+        #we have to do this because the ERFA functions throw away distance info
+        distance = np.sum((astrom['eb']*u.au + icrs_coo.cartesian.xyz.T)**2, -1)**0.5
+        rep = SphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
+                                      lon=u.Quantity(gcrs_ra, u.radian, copy=False),
+                                      distance=distance, copy=False)
+    return gcrs_frame.realize_frame(rep)
+
+
+ at frame_transform_graph.transform(FunctionTransform, GCRS, ICRS)
+def gcrs_to_icrs(gcrs_coo, icrs_frame):
+    srepr = gcrs_coo.represent_as(UnitSphericalRepresentation)
+    cirs_ra = srepr.lon.to(u.radian).value
+    cirs_dec = srepr.lat.to(u.radian).value
+
+    #first set up the astrometry context for ICRS<->GCRS
+    pv = np.array([gcrs_coo.obsgeoloc.value,
+                   gcrs_coo.obsgeovel.value])
+    astrom = erfa.apcs13(gcrs_coo.obstime.jd1, gcrs_coo.obstime.jd2, pv)
+
+    icrs_ra, icrs_dec = erfa.aticq(cirs_ra, cirs_dec, astrom)
+
+    dat = gcrs_coo.data
+    if dat.get_name() == 'unitspherical'  or dat.to_cartesian().x.unit == u.one:
+        rep = UnitSphericalRepresentation(lat=u.Quantity(icrs_dec, u.radian, copy=False),
+                                          lon=u.Quantity(icrs_ra, u.radian, copy=False),
+                                          copy=False)
+    else:
+        #compute the distance as just the cartesian sum from moving to the SSB
+        #we have to do this because the ERFA functions throw away distance info
+        distance = np.sum((-astrom['eb']*u.au + gcrs_coo.cartesian.xyz.T)**2, -1)**0.5
+        rep = SphericalRepresentation(lat=u.Quantity(icrs_dec, u.radian, copy=False),
+                                      lon=u.Quantity(icrs_ra, u.radian, copy=False),
+                                      distance=distance, copy=False)
+    return icrs_frame.realize_frame(rep)
+
+
+ at frame_transform_graph.transform(FunctionTransform, GCRS, GCRS)
+def gcrs_to_gcrs(from_coo, to_frame):
+    if np.all(from_coo.obstime == to_frame.obstime):
+        return to_frame.realize_frame(from_coo.data)
+    else:
+        # like CIRS, we do this self-transform via ICRS
+        return from_coo.transform_to(ICRS).transform_to(to_frame)
diff --git a/astropy/coordinates/builtin_frames/icrs_fk5_transforms.py b/astropy/coordinates/builtin_frames/icrs_fk5_transforms.py
new file mode 100644
index 0000000..0b20ffe
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/icrs_fk5_transforms.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..angles import rotation_matrix
+from ..baseframe import frame_transform_graph
+from ..transformations import DynamicMatrixTransform
+
+from .fk5 import FK5
+from .icrs import ICRS
+from .utils import EQUINOX_J2000
+
+
+def _icrs_to_fk5_matrix():
+    """
+    B-matrix from USNO circular 179.  Used by the ICRS->FK5 transformation
+    functions.
+    """
+
+    eta0 = -19.9 / 3600000.
+    xi0 = 9.1 / 3600000.
+    da0 = -22.9 / 3600000.
+
+    m1 = rotation_matrix(-eta0, 'x')
+    m2 = rotation_matrix(xi0, 'y')
+    m3 = rotation_matrix(da0, 'z')
+
+    return m1 * m2 * m3
+# define this here because it only needs to be computed once
+_ICRS_TO_FK5_J2000_MAT = _icrs_to_fk5_matrix()
+
+
+ at frame_transform_graph.transform(DynamicMatrixTransform, ICRS, FK5)
+def icrs_to_fk5(icrscoord, fk5frame):
+    # ICRS is by design very close to J2000 equinox
+    pmat = fk5frame._precession_matrix(EQUINOX_J2000, fk5frame.equinox)
+    return pmat * _ICRS_TO_FK5_J2000_MAT
+
+
+# can't be static because the equinox is needed
+ at frame_transform_graph.transform(DynamicMatrixTransform, FK5, ICRS)
+def fk5_to_icrs(fk5coord, icrsframe):
+    # ICRS is by design very close to J2000 equinox
+    pmat = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
+    return _ICRS_TO_FK5_J2000_MAT.T * pmat
diff --git a/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py b/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py
new file mode 100644
index 0000000..2a57caf
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+Contains the transformation functions for getting to/from ITRS, GCRS, and CIRS.
+These are distinct from the ICRS and AltAz functions because they are just
+rotations without aberration corrections or offsets.
+"""
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from ..baseframe import frame_transform_graph
+from ..transformations import FunctionTransform
+from ..representation import CartesianRepresentation
+from ... import _erfa as erfa
+
+from .gcrs import GCRS
+from .cirs import CIRS
+from .itrs import ITRS
+from .utils import get_polar_motion
+
+# first define helper functions
+def gcrs_to_itrs_mat(time):
+    #first compute the celestial-to-intermediate matrix
+    c2imat = erfa.c2i06a(time.jd1, time.jd2)
+
+    #now compute the polar motion p-matrix
+    xp, yp = get_polar_motion(time)
+    sp = erfa.sp00(time.jd1, time.jd2)
+    pmmat = erfa.pom00(xp, yp, sp)
+
+    #now determine the Earth Rotation Angle for the input obstime
+    era = erfa.era00(time.jd1, time.jd2)
+
+    return erfa.c2tcio(c2imat, era, pmmat)
+
+
+def cirs_to_itrs_mat(time):
+    #compute the polar motion p-matrix
+    xp, yp = get_polar_motion(time)
+    sp = erfa.sp00(time.jd1, time.jd2)
+    pmmat = erfa.pom00(xp, yp, sp)
+
+    #now determine the Earth Rotation Angle for the input obstime
+    era = erfa.era00(time.jd1, time.jd2)
+
+    #c2tcio expects a GCRS->CIRS matrix, but we just set that to an I-matrix
+    #because we're already in CIRS
+    return erfa.c2tcio(np.eye(3), era, pmmat)
+
+
+def cartrepr_from_matmul(pmat, coo, transpose=False):
+    if pmat.shape[-2:] != (3, 3):
+        raise ValueError("tried to do matrix multiplication with an array that "
+                         "doesn't end in 3x3")
+    xyz = coo.cartesian.xyz.T
+    # these expression are the same as iterating over the first dimension of
+    # pmat and xyz and doing matrix multiplication on each in turn.  resulting
+    # dimension is <coo shape> x 3
+    pmat = pmat.reshape(pmat.size//9, 3, 3)
+    if transpose:
+        pmat = pmat.transpose(0, 2, 1)
+    newxyz = np.sum(pmat * xyz.reshape(xyz.size//3, 1, 3), axis=-1)
+
+    return CartesianRepresentation(newxyz.T)
+
+
+# now the actual transforms
+
+# the priority for the GCRS<->ITRS trasnsforms are higher (=less traveled) to
+#make GCRS<->ICRS<->CIRS the preferred route over GCRS<->ITRS<->CIRS
+ at frame_transform_graph.transform(FunctionTransform, GCRS, ITRS, priority=1.01)
+def gcrs_to_itrs(gcrs_coo, itrs_frame):
+    # first get us to a 0 pos/vel GCRS at the target obstime
+    gcrs_coo2 = gcrs_coo.transform_to(GCRS(obstime=itrs_frame.obstime))
+
+    #now get the pmatrix
+    pmat = gcrs_to_itrs_mat(itrs_frame.obstime)
+    crepr = cartrepr_from_matmul(pmat, gcrs_coo2)
+    return itrs_frame.realize_frame(crepr)
+
+
+ at frame_transform_graph.transform(FunctionTransform, ITRS, GCRS, priority=1.01)
+def itrs_to_gcrs(itrs_coo, gcrs_frame):
+    #compute the pmatrix, and then multiply by its transpose
+    pmat = gcrs_to_itrs_mat(itrs_coo.obstime)
+    newrepr = cartrepr_from_matmul(pmat, itrs_coo, transpose=True)
+    gcrs = GCRS(newrepr, obstime=itrs_coo.obstime)
+
+    #now do any needed offsets (no-op if same obstime and 0 pos/vel)
+    return gcrs.transform_to(gcrs_frame)
+
+
+ at frame_transform_graph.transform(FunctionTransform, CIRS, ITRS)
+def cirs_to_itrs(cirs_coo, itrs_frame):
+    # first get us to CIRS at the target obstime
+    cirs_coo2 = cirs_coo.transform_to(CIRS(obstime=itrs_frame.obstime))
+
+    #now get the pmatrix
+    pmat = cirs_to_itrs_mat(itrs_frame.obstime)
+    crepr = cartrepr_from_matmul(pmat, cirs_coo2)
+    return itrs_frame.realize_frame(crepr)
+
+
+ at frame_transform_graph.transform(FunctionTransform, ITRS, CIRS)
+def itrs_to_cirs(itrs_coo, cirs_frame):
+    #compute the pmatrix, and then multiply by its transpose
+    pmat = cirs_to_itrs_mat(itrs_coo.obstime)
+    newrepr = cartrepr_from_matmul(pmat, itrs_coo, transpose=True)
+    cirs = CIRS(newrepr, obstime=itrs_coo.obstime)
+
+    #now do any needed offsets (no-op if same obstime)
+    return cirs.transform_to(cirs_frame)
+
+
+ at frame_transform_graph.transform(FunctionTransform, ITRS, ITRS)
+def itrs_to_itrs(from_coo, to_frame):
+    # this self-transform goes through CIRS right now, which implicitly also
+    # goes back to ICRS
+    return from_coo.transform_to(CIRS).transform_to(to_frame)
+
+
+
+#TODO: implement GCRS<->CIRS if there's call for it.  The thing that's awkward
+#is that they both have obstimes, so an extra set of transformations are necessary.
+#so unless there's a specific need for that, better to just have it go through te above
+#two steps anyway
diff --git a/astropy/coordinates/builtin_frames/itrs.py b/astropy/coordinates/builtin_frames/itrs.py
new file mode 100644
index 0000000..ac4c94f
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/itrs.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+from ..representation import CartesianRepresentation
+from ..baseframe import BaseCoordinateFrame, TimeFrameAttribute, frame_transform_graph
+from ..transformations import FunctionTransform
+from .utils import DEFAULT_OBSTIME
+
+
+class ITRS(BaseCoordinateFrame):
+    """
+    A coordinate or frame in the International Terrestrial Reference System
+    (ITRS).  This is approximately a geocentric system, although strictly it is
+    defined by a series of reference locations near the surface of the Earth.
+    For more background on the ITRS, see the references provided in the
+    :ref:`astropy-coordinates-seealso` section of the documentation.
+
+    Note that this frame does *not* have an ``obstime``, because it is
+    rotating with the Earth.
+    """
+
+    default_representation = CartesianRepresentation
+
+    obstime = TimeFrameAttribute(default=DEFAULT_OBSTIME)
+
+    @property
+    def earth_location(self):
+        """
+        The data in this frame as an `~astropy.coordinates.EarthLocation` class.
+        """
+        from ..earth import EarthLocation
+
+        cart = self.represent_as(CartesianRepresentation)
+        return EarthLocation(x=cart.x, y=cart.y, z=cart.z)
+
+# Self-transform is in intermediate_rotation_transforms.py with all the other
+# ITRS transforms
diff --git a/astropy/coordinates/builtin_frames/utils.py b/astropy/coordinates/builtin_frames/utils.py
new file mode 100644
index 0000000..35c779b
--- /dev/null
+++ b/astropy/coordinates/builtin_frames/utils.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This module contains functions/values used repeatedly in different modules of
+the ``builtin_frames`` package.
+"""
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import warnings
+
+import numpy as np
+
+from ... import units as u
+from ...time import Time
+from ...utils import iers
+from ...utils.exceptions import AstropyWarning
+
+# The UTC time scale is not properly defined prior to 1960, so Time('B1950',
+# scale='utc') will emit a warning. Instead, we use Time('B1950', scale='tai')
+# which is equivalent, but does not emit a warning.
+EQUINOX_J2000 = Time('J2000', scale='utc')
+EQUINOX_B1950 = Time('B1950', scale='tai')
+
+# This is a time object that is the default "obstime" when such an attribute is
+# necessary.  Currently, we use J2000.
+DEFAULT_OBSTIME = Time('J2000', scale='utc')
+
+PIOVER2 = np.pi / 2.
+
+#comes from the mean of the 1962-2014 IERS B data
+_DEFAULT_PM = (0.035, 0.29)*u.arcsec
+
+_IERS_HINT = """
+If you need enough precision such that this matters (~<10 arcsec), you can download the latest IERS predictions by doing:
+from astropy.utils.data import download_file
+from astropy.utils import iers
+iers.IERS.iers_table = iers.IERS_A.open(download_file(iers.IERS_A_URL, cache=True))"""
+
+
+def get_polar_motion(time):
+    """
+    gets the two polar motion components in radians for use with apio13
+    """
+    #get the polar motion from the IERS table
+    xp, yp, status = iers.IERS.open().pm_xy(time.jd1, time.jd2, return_status=True)
+
+    wmsg = None
+    if np.any(status == iers.TIME_BEFORE_IERS_RANGE):
+        wmsg = ('Tried to get polar motions for times before IERS data is '
+                'valid. Defaulting to polar motion from the 50-yr mean for those.')
+        xp.ravel()[status.ravel()==iers.TIME_BEFORE_IERS_RANGE] = _DEFAULT_PM[0]
+        yp.ravel()[status.ravel()==iers.TIME_BEFORE_IERS_RANGE] = _DEFAULT_PM[1]
+
+        warnings.warn(wmsg, AstropyWarning)
+
+    if np.any(status == iers.TIME_BEYOND_IERS_RANGE):
+        wmsg = ('Tried to get polar motions for times after IERS data is '
+                'valid. Defaulting to polar motion from the 50-yr mean for those.' + _IERS_HINT)
+
+        xp.ravel()[status.ravel()==iers.TIME_BEYOND_IERS_RANGE] = _DEFAULT_PM[0]
+        yp.ravel()[status.ravel()==iers.TIME_BEYOND_IERS_RANGE] = _DEFAULT_PM[1]
+
+        warnings.warn(wmsg, AstropyWarning)
+
+    return xp.to(u.radian).value, yp.to(u.radian).value
+
+
+def get_dut1utc(time):
+    """
+    This function is used to get UT1-UTC in coordinates because normally it
+    gives an error outside the IERS range, but in coordinates we want to allow
+    it to go through but with a warning.
+    """
+    try:
+        return time.delta_ut1_utc
+    except IndexError as e:
+        msg = e.args[0] + ' Assuming UT1-UTC=0 for coordinate transformations.' + _IERS_HINT
+        warnings.warn(msg, AstropyWarning)
+        return np.zeros(time.shape)
diff --git a/astropy/coordinates/distances.py b/astropy/coordinates/distances.py
index 9d8270a..e19902f 100644
--- a/astropy/coordinates/distances.py
+++ b/astropy/coordinates/distances.py
@@ -4,19 +4,14 @@
 This module contains the classes and utility functions for distance and
 cartesian coordinates.
 """
-
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-import math
-
 import numpy as np
 
 from .. import units as u
-from ..utils import deprecated
 
-__all__ = ['Distance', 'CartesianPoints', 'cartesian_to_spherical',
-           'spherical_to_cartesian']
+__all__ = ['Distance']
 
 
 __doctest_requires__ = {'*': ['scipy.integrate']}
@@ -206,159 +201,6 @@ class Distance(u.Quantity):
         return cls(10 ** ((dm.value + 5) / 5.), u.pc, copy=False)
 
 
- at deprecated('v0.4', alternative='astropy.coordinates.CartesianRepresentation')
-class CartesianPoints(u.Quantity):
-    """
-    A cartesian representation of a point in three-dimensional space.
-
-    Parameters
-    ----------
-    x : `~astropy.units.Quantity` or array-like
-        The first cartesian coordinate or a single array or
-        `~astropy.units.Quantity` where the first dimension is length-3.
-    y : `~astropy.units.Quantity` or array-like, optional
-        The second cartesian coordinate.
-    z : `~astropy.units.Quantity` or array-like, optional
-        The third cartesian coordinate.
-    unit : `~astropy.units.UnitBase` object or `None`
-        The physical unit of the coordinate values. If ``x``, ``y``, or ``z``
-        are quantities, they will be converted to this unit.
-    dtype : `~numpy.dtype`, optional
-        See `~astropy.units.Quantity`. Must be given as a keyword argument.
-    copy : bool, optional
-        See `~astropy.units.Quantity`. Must be given as a keyword argument.
-
-    Raises
-    ------
-    UnitsError
-        If the units on ``x``, ``y``, and ``z`` do not match or an invalid
-        unit is given.
-    ValueError
-        If ``y`` and ``z`` don't match ``x``'s shape or ``x`` is not length-3
-    TypeError
-        If incompatible array types are passed into ``x``, ``y``, or ``z``
-
-    """
-
-    #this ensures that __array_wrap__ gets called for ufuncs even when
-    #where a quantity is first, like ``3*u.m + c``
-    __array_priority__ = 10001
-
-    def __new__(cls, x, y=None, z=None, unit=None, dtype=None, copy=True):
-        if y is None and z is None:
-            if len(x) != 3:
-                raise ValueError('Input to CartesianPoints is not length 3')
-
-            qarr = x
-            if unit is None and hasattr(qarr, 'unit'):
-                unit = qarr.unit  # for when a Quantity is given
-        elif y is not None and z is not None:
-            if unit is None:
-                #they must all match units or this fails
-                for coo in (x, y, z):
-                    if hasattr(coo, 'unit'):
-                        if unit is not None and coo.unit != unit:
-                            raise u.UnitsError('Units for `x`, `y`, and `z` do '
-                                               'not match in CartesianPoints   ')
-                        unit = coo.unit
-                #if `unit`  is still None at this point, it means none were
-                #Quantties, which is fine, because it means the user wanted
-                #the unit to be None
-            else:
-                #convert any that are like a Quantity to the given unit
-                if hasattr(x, 'to'):
-                    x = x.to(unit)
-                if hasattr(y, 'to'):
-                    y = y.to(unit)
-                if hasattr(z, 'to'):
-                    z = z.to(unit)
-
-            qarr = [np.asarray(coo) for coo in (x, y, z)]
-            if not (qarr[0].shape == qarr[1].shape == qarr[2].shape):
-                raise ValueError("Shapes for `x`, `y`, and `z` don't match in "
-                                 "CartesianPoints")
-                #let the unit be whatever it is
-        else:
-            raise TypeError('Must give all of `x`, `y`, and `z` or just array in '
-                            'CartesianPoints')
-        try:
-            unit = _convert_to_and_validate_length_unit(unit, True)
-        except TypeError as e:
-            raise u.UnitsError(str(e))
-
-        try:
-            qarr = np.asarray(qarr)
-        except ValueError as e:
-            raise TypeError(str(e))
-
-        if qarr.dtype.kind not in 'iuf':
-            raise TypeError("Unsupported dtype '{0}'".format(qarr.dtype))
-
-        return u.Quantity.__new__(cls, qarr, unit, dtype=dtype, copy=copy)
-
-    def __quantity_subclass__(self, unit):
-        if unit.is_equivalent(u.m):
-            return CartesianPoints, True
-        else:
-            return u.Quantity.__quantity_subclass__(unit)[0], False
-
-    def __array_wrap__(self, obj, context=None):
-        #always convert to CartesianPoints because all operations that would
-        #screw up the units are killed by _convert_to_and_validate_length_unit
-        obj = u.Quantity.__array_wrap__(obj, context=context)
-
-        #always prefer self's unit, if possible
-        if obj.unit.is_equivalent(self.unit):
-            return obj.to(self.unit)
-        else:
-            return obj
-
-    @property
-    def x(self):
-        """
-        The second cartesian coordinate as a `~astropy.units.Quantity`.
-        """
-        return self.view(u.Quantity)[0]
-
-    @property
-    def y(self):
-        """
-        The second cartesian coordinate as a `~astropy.units.Quantity`.
-        """
-        return self.view(u.Quantity)[1]
-
-    @property
-    def z(self):
-        """
-        The third cartesian coordinate as a `~astropy.units.Quantity`.
-        """
-        return self.view(u.Quantity)[2]
-
-    def to_spherical(self):
-        """
-        Converts to the spherical representation of this point.
-
-        Returns
-        -------
-        r : `~astropy.units.Quantity`
-            The radial coordinate (in the same units as this `CartesianPoints`).
-        lat : `~astropy.units.Quantity`
-            The spherical coordinates latitude.
-        lon : `~astropy.units.Quantity`
-            The spherical coordinates longitude.
-
-        """
-        from .angles import Latitude, Longitude
-
-        rarr, latarr, lonarr = cartesian_to_spherical(self.x, self.y, self.z)
-
-        r = Distance(rarr, unit=self.unit)
-        lat = Latitude(latarr, unit=u.radian)
-        lon = Longitude(lonarr, unit=u.radian)
-
-        return r, lat, lon
-
-
 def _convert_to_and_validate_length_unit(unit, allow_dimensionless=False):
     """
     raises UnitsError if not a length unit
@@ -372,103 +214,3 @@ def _convert_to_and_validate_length_unit(unit, allow_dimensionless=False):
 
     return unit
 
-#<------------transformation-related utility functions----------------->
-
-
-def cartesian_to_spherical(x, y, z):
-    """
-    Converts 3D rectangular cartesian coordinates to spherical polar
-    coordinates.
-
-    Note that the resulting angles are latitude/longitude or
-    elevation/azimuthal form.  I.e., the origin is along the equator
-    rather than at the north pole.
-
-    .. note::
-        This is a low-level function used internally in
-        `astropy.coordinates`.  It is provided for users if they really
-        want to use it, but it is recommended that you use the
-        `astropy.coordinates` coordinate systems.
-
-    Parameters
-    ----------
-    x : scalar or array-like
-        The first cartesian coordinate.
-    y : scalar or array-like
-        The second cartesian coordinate.
-    z : scalar or array-like
-        The third cartesian coordinate.
-
-    Returns
-    -------
-    r : float or array
-        The radial coordinate (in the same units as the inputs).
-    lat : float or array
-        The latitude in radians
-    lon : float or array
-        The longitude in radians
-    """
-
-    xsq = x ** 2
-    ysq = y ** 2
-    zsq = z ** 2
-
-    r = (xsq + ysq + zsq) ** 0.5
-    s = (xsq + ysq) ** 0.5
-
-    if np.isscalar(x) and np.isscalar(y) and np.isscalar(z):
-        lon = math.atan2(y, x)
-        lat = math.atan2(z, s)
-    else:
-        lon = np.arctan2(y, x)
-        lat = np.arctan2(z, s)
-
-    return r, lat, lon
-
-
-def spherical_to_cartesian(r, lat, lon):
-    """
-    Converts spherical polar coordinates to rectangular cartesian
-    coordinates.
-
-    Note that the input angles should be in latitude/longitude or
-    elevation/azimuthal form.  I.e., the origin is along the equator
-    rather than at the north pole.
-
-    .. note::
-        This is a low-level function used internally in
-        `astropy.coordinates`.  It is provided for users if they really
-        want to use it, but it is recommended that you use the
-        `astropy.coordinates` coordinate systems.
-
-    Parameters
-    ----------
-    r : scalar or array-like
-        The radial coordinate (in the same units as the inputs).
-    lat : scalar or array-like
-        The latitude in radians
-    lon : scalar or array-like
-        The longitude in radians
-
-    Returns
-    -------
-    x : float or array
-        The first cartesian coordinate.
-    y : float or array
-        The second cartesian coordinate.
-    z : float or array
-        The third cartesian coordinate.
-
-
-    """
-
-    if np.isscalar(r) and np.isscalar(lat) and np.isscalar(lon):
-        x = r * math.cos(lat) * math.cos(lon)
-        y = r * math.cos(lat) * math.sin(lon)
-        z = r * math.sin(lat)
-    else:
-        x = r * np.cos(lat) * np.cos(lon)
-        y = r * np.cos(lat) * np.sin(lon)
-        z = r * np.sin(lat)
-
-    return x, y, z
diff --git a/astropy/coordinates/earth.py b/astropy/coordinates/earth.py
index 2667ed8..c4c727d 100644
--- a/astropy/coordinates/earth.py
+++ b/astropy/coordinates/earth.py
@@ -4,20 +4,21 @@ from __future__ import (absolute_import, division, print_function,
 
 import numpy as np
 from .. import units as u
+from .. import _erfa as erfa
 from ..utils import OrderedDict
 from . import Longitude, Latitude
 
 try:
     # Not guaranteed available at setup time.
-    from ..time import erfa_time
+    from .. import _erfa as erfa
 except ImportError:
     if not _ASTROPY_SETUP_:
         raise
 
 __all__ = ['EarthLocation']
 
-# translation between ellipsoid names and corresponding number used in ERFA
-ELLIPSOIDS = OrderedDict([('WGS84', 1), ('GRS80', 2), ('WGS72', 3)])
+# Available ellipsoids (defined in erfam.h, with numbers exposed in erfa).
+ELLIPSOIDS = ('WGS84', 'GRS80', 'WGS72')
 
 
 def _check_ellipsoid(ellipsoid=None, default='WGS84'):
@@ -25,28 +26,33 @@ def _check_ellipsoid(ellipsoid=None, default='WGS84'):
         ellipsoid = default
     if ellipsoid not in ELLIPSOIDS:
         raise ValueError('Ellipsoid {0} not among known ones ({1})'
-                         .format(ellipsoid, ELLIPSOIDS.keys()))
+                         .format(ellipsoid, ELLIPSOIDS))
     return ellipsoid
 
 
 class EarthLocation(u.Quantity):
     """
-    Location on Earth.
+    Location on the Earth.
 
     Initialization is first attempted assuming geocentric (x, y, z) coordinates
     are given; if that fails, another attempt is made assuming geodetic
     coordinates (longitude, latitude, height above a reference ellipsoid).
-    Internally, the coordinates are stored as geocentric.
+    When using the geodetic forms, Longitudes are measured increasing to the
+    east, so west longitudes are negative. Internally, the coordinates are
+    stored as geocentric.
 
     To ensure a specific type of coordinates is used, use the corresponding
     class methods (`from_geocentric` and `from_geodetic`) or initialize the
     arguments with names (``x``, ``y``, ``z`` for geocentric; ``lon``, ``lat``,
     ``height`` for geodetic).  See the class methods for details.
 
+
     Notes
     -----
-    For conversion to and from geodetic coordinates, the ERFA routines
-    ``gc2gd`` and ``gd2gc`` are used.  See https://github.com/liberfa/erfa
+    This class fits into the coordinates transformation framework in that it
+    encodes a position on the `~astropy.coordinates.ITRS` frame.  To get a
+    proper `~astropy.coordinates.ITRS` object from this object, use the ``itrs``
+    property.
     """
 
     _ellipsoid = 'WGS84'
@@ -133,7 +139,7 @@ class EarthLocation(u.Quantity):
             Height above reference ellipsoid (if float, in meters; default: 0).
         ellipsoid : str, optional
             Name of the reference ellipsoid to use (default: 'WGS84').
-            Available ellipoids are:  'WGS84', 'GRS80', 'WGS72'.
+            Available ellipsoids are:  'WGS84', 'GRS80', 'WGS72'.
 
         Raises
         ------
@@ -161,7 +167,7 @@ class EarthLocation(u.Quantity):
                                                   lat.to(u.radian).value,
                                                   height.to(u.m).value)
         # get geocentric coordinates. Have to give one-dimensional array.
-        xyz = erfa_time.era_gd2gc(ELLIPSOIDS[ellipsoid], _lon.ravel(),
+        xyz = erfa.gd2gc(getattr(erfa, ellipsoid), _lon.ravel(),
                                   _lat.ravel(), _height.ravel())
         self = xyz.view(cls._location_dtype, cls).reshape(lon.shape)
         self._unit = u.meter
@@ -209,12 +215,11 @@ class EarthLocation(u.Quantity):
         """
         ellipsoid = _check_ellipsoid(ellipsoid, default=self.ellipsoid)
         self_array = self.to(u.meter).view(self._array_dtype, np.ndarray)
-        lon, lat, height = erfa_time.era_gc2gd(ELLIPSOIDS[ellipsoid],
-                                               np.atleast_2d(self_array))
-        return (Longitude(lon.squeeze() * u.radian, u.degree,
+        lon, lat, height = erfa.gc2gd(getattr(erfa, ellipsoid), self_array)
+        return (Longitude(lon * u.radian, u.degree,
                           wrap_angle=180.*u.degree),
-                Latitude(lat.squeeze() * u.radian, u.degree),
-                u.Quantity(height.squeeze() * u.meter, self.unit))
+                Latitude(lat * u.radian, u.degree),
+                u.Quantity(height * u.meter, self.unit))
 
     @property
     def longitude(self):
@@ -231,7 +236,7 @@ class EarthLocation(u.Quantity):
         """Height of the location, for the default ellipsoid."""
         return self.geodetic[2]
 
-    # mostly for symmetry with geodedic and to_geodetic.
+    # mostly for symmetry with geodetic and to_geodetic.
     @property
     def geocentric(self):
         """Convert to a tuple with X, Y, and Z as quantities"""
@@ -242,6 +247,17 @@ class EarthLocation(u.Quantity):
         return (self.x, self.y, self.z)
 
     @property
+    def itrs(self):
+        """
+        Generates an `~astropy.coordinates.ITRS` object with the coordinates of
+        this object.
+        """
+        #potential circular imports prevent this from being up top
+        from .builtin_frames import ITRS
+
+        return ITRS(x=self.x, y=self.y, z=self.z)
+
+    @property
     def x(self):
         """The X component of the geocentric coordinates."""
         return self['x']
diff --git a/astropy/coordinates/earth_orientation.py b/astropy/coordinates/earth_orientation.py
index 4f9c3cf..268cdf9 100644
--- a/astropy/coordinates/earth_orientation.py
+++ b/astropy/coordinates/earth_orientation.py
@@ -29,7 +29,7 @@ def eccentricity(jd):
     Parameters
     ----------
     jd : scalar or array-like
-        julian date at which to compute the eccentricity
+        Julian date at which to compute the eccentricity
 
     returns
     -------
@@ -56,7 +56,7 @@ def mean_lon_of_perigee(jd):
     Parameters
     ----------
     jd : scalar or array-like
-        julian date at which to compute the mean longitude of perigee
+        Julian date at which to compute the mean longitude of perigee
 
     returns
     -------
@@ -82,7 +82,7 @@ def obliquity(jd, algorithm=2006):
     Parameters
     ----------
     jd : scalar or array-like
-        julian date at which to compute the obliquity
+        Julian date at which to compute the obliquity
     algorithm : int
         Year of algorithm based on IAU adoption. Can be 2006, 2000 or 1980. The
         2006 algorithm is mentioned in Circular 179, but the canonical reference
@@ -123,7 +123,7 @@ def obliquity(jd, algorithm=2006):
 # TODO: replace this with SOFA equivalent
 def precession_matrix_Capitaine(fromepoch, toepoch):
     """
-    Computes the precession matrix from one julian epoch to another.
+    Computes the precession matrix from one Julian epoch to another.
     The exact method is based on Capitaine et al. 2003, which should
     match the IAU 2006 standard.
 
@@ -158,7 +158,7 @@ def _precess_from_J2000_Capitaine(epoch):
     Parameters
     ----------
     epoch : scalar
-        The epoch as a julian year number (e.g. J2000 is 2000.0)
+        The epoch as a Julian year number (e.g. J2000 is 2000.0)
 
     """
     from .angles import rotation_matrix
@@ -179,10 +179,10 @@ def _precess_from_J2000_Capitaine(epoch):
 
 def _precession_matrix_besselian(epoch1, epoch2):
     """
-    computes the precession matrix from one Besselian epoch to another using
+    Computes the precession matrix from one Besselian epoch to another using
     Newcomb's method.
 
-    ``epoch1`` and ``epoch2`` are in besselian year numbers
+    ``epoch1`` and ``epoch2`` are in Besselian year numbers.
     """
     from .angles import rotation_matrix
 
diff --git a/astropy/coordinates/errors.py b/astropy/coordinates/errors.py
index afac457..b578cbc 100644
--- a/astropy/coordinates/errors.py
+++ b/astropy/coordinates/errors.py
@@ -77,7 +77,7 @@ class IllegalMinuteError(RangeError):
 
     Examples
     --------
-    
+
     .. code-block:: python
 
         if not 0 <= min < 60:
diff --git a/astropy/coordinates/funcs.py b/astropy/coordinates/funcs.py
new file mode 100644
index 0000000..799fafb
--- /dev/null
+++ b/astropy/coordinates/funcs.py
@@ -0,0 +1,183 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+This module contains convenience functions for coordinate-related functionality.
+
+This is generally just wrapping around the object-oriented coordinates
+framework, but it is useful for some users who are used to more functional
+interfaces.
+"""
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from .. import units as u
+from ..utils import isiterable
+
+__all__ = ['cartesian_to_spherical', 'spherical_to_cartesian', 'get_sun', 'concatenate']
+
+
+def cartesian_to_spherical(x, y, z):
+    """
+    Converts 3D rectangular cartesian coordinates to spherical polar
+    coordinates.
+
+    Note that the resulting angles are latitude/longitude or
+    elevation/azimuthal form.  I.e., the origin is along the equator
+    rather than at the north pole.
+
+    .. note::
+        This function simply wraps functionality provided by the
+        `~astropy.coordinates.CartesianRepresentation` and
+        `~astropy.coordinates.SphericalRepresentation` classes.  In general,
+        for both performance and readability, we suggest using these classes
+        directly.  But for situations where a quick one-off conversion makes
+        sense, this function is provided.
+
+    Parameters
+    ----------
+    x : scalar, array-like, or `~astropy.units.Quantity`
+        The first cartesian coordinate.
+    y : scalar, array-like, or `~astropy.units.Quantity`
+        The second cartesian coordinate.
+    z : scalar, array-like, or `~astropy.units.Quantity`
+        The third cartesian coordinate.
+
+    Returns
+    -------
+    r : `~astropy.units.Quantity`
+        The radial coordinate (in the same units as the inputs).
+    lat : `~astropy.units.Quantity`
+        The latitude in radians
+    lon : `~astropy.units.Quantity`
+        The longitude in radians
+    """
+    from .representation import SphericalRepresentation, CartesianRepresentation
+
+    if not hasattr(x, 'unit'):
+        x = x * u.dimensionless_unscaled
+    if not hasattr(y, 'unit'):
+        y = y * u.dimensionless_unscaled
+    if not hasattr(z, 'unit'):
+        z = z * u.dimensionless_unscaled
+
+    cart = CartesianRepresentation(x, y, z)
+    sph = cart.represent_as(SphericalRepresentation)
+
+    return sph.distance, sph.lat, sph.lon
+
+
+def spherical_to_cartesian(r, lat, lon):
+    """
+    Converts spherical polar coordinates to rectangular cartesian
+    coordinates.
+
+    Note that the input angles should be in latitude/longitude or
+    elevation/azimuthal form.  I.e., the origin is along the equator
+    rather than at the north pole.
+
+    .. note::
+        This is a low-level function used internally in
+        `astropy.coordinates`.  It is provided for users if they really
+        want to use it, but it is recommended that you use the
+        `astropy.coordinates` coordinate systems.
+
+    Parameters
+    ----------
+    r : scalar, array-like, or `~astropy.units.Quantity`
+        The radial coordinate (in the same units as the inputs).
+    lat : scalar, array-like, or `~astropy.units.Quantity`
+        The latitude (in radians if array or scalar)
+    lon : scalar, array-like, or `~astropy.units.Quantity`
+        The longitude (in radians if array or scalar)
+
+    Returns
+    -------
+    x : float or array
+        The first cartesian coordinate.
+    y : float or array
+        The second cartesian coordinate.
+    z : float or array
+        The third cartesian coordinate.
+
+
+    """
+    from .representation import SphericalRepresentation, CartesianRepresentation
+
+    if not hasattr(r, 'unit'):
+        r = r * u.dimensionless_unscaled
+    if not hasattr(lat, 'unit'):
+        lat = lat * u.radian
+    if not hasattr(lon, 'unit'):
+        lon = lon * u.radian
+
+    sph = SphericalRepresentation(distance=r, lat=lat, lon=lon)
+    cart = sph.represent_as(CartesianRepresentation)
+
+    return cart.x, cart.y, cart.z
+
+
+def get_sun(time):
+    """
+    Determines the location of the sun at a given time, in
+    geocentric coordinates.
+
+    Parameters
+    ----------
+    table : `~astropy.time.Time`
+        The time at which to compute the location of the sun.
+
+    Returns
+    -------
+    newsc : `~astropy.coordinates.SkyCoord`
+        The location of the sun as a `~astropy.coordinates.SkyCoord` in the
+        `~astropy.coordinates.GCRS` frame.
+
+
+    Notes
+    -----
+    The algorithm for determining the sun/earth relative position is based
+    on the simplified version of VSOP2000 that is part of ERFA. Compared to
+    JPL's ephemeris, it should be good to about 4 km (in the Sun-Earth
+    vector) from 1900-2100 C.E., 8 km for the 1800-2200 span, and perhaps
+    250 km over the 1000-3000.
+
+    """
+    from .. import _erfa as erfa
+    from .representation import CartesianRepresentation
+    from .sky_coordinate import SkyCoord
+    from .builtin_frames import GCRS
+
+    earth_pv_helio, earth_pv_bary = erfa.epv00(time.jd1, time.jd2)
+    x = -earth_pv_helio[..., 0, 0] * u.AU
+    y = -earth_pv_helio[..., 0, 1] * u.AU
+    z = -earth_pv_helio[..., 0, 2] * u.AU
+    cartrep = CartesianRepresentation(x=x, y=y, z=z)
+    return SkyCoord(cartrep, frame=GCRS)
+
+def concatenate(coords):
+    """
+    Combine multiple coordinate objects into a single
+    `~astropy.coordinates.SkyCoord`.
+
+    "Coordinate objects" here mean frame objects with data,
+    `~astropy.coordinates.SkyCoord`, or representation objects.  Currently,
+    they must all be in the same frame, but in a future version this may be
+    relaxed to allow inhomogenous sequences of objects.
+
+    Parameters
+    ----------
+    coords : sequence of coordinate objects
+        The objects to concatenate
+
+    Returns
+    -------
+    cskycoord : SkyCoord
+        A single sky coordinate with its data set to the concatenation of all
+        the elements in ``coords``
+    """
+    from .sky_coordinate import SkyCoord
+
+    if getattr(coords, 'isscalar', False) or not isiterable(coords):
+        raise TypeError('The argument to concatenate must be iterable')
+    return SkyCoord(coords)
diff --git a/astropy/coordinates/matching.py b/astropy/coordinates/matching.py
index 9f3993d..e9e4930 100644
--- a/astropy/coordinates/matching.py
+++ b/astropy/coordinates/matching.py
@@ -10,8 +10,10 @@ import numpy as np
 
 from ..extern import six
 from .representation import UnitSphericalRepresentation
+from .. import units as u
 
-__all__ = ['match_coordinates_3d', 'match_coordinates_sky']
+__all__ = ['match_coordinates_3d', 'match_coordinates_sky', 'search_around_3d',
+           'search_around_sky']
 
 
 def match_coordinates_3d(matchcoord, catalogcoord, nthneighbor=1, storekdtree='_kdtree_3d'):
@@ -46,7 +48,7 @@ def match_coordinates_3d(matchcoord, catalogcoord, nthneighbor=1, storekdtree='_
     Returns
     -------
     idx : integer array
-        Indecies into ``catalogcoord`` to get the matched points for each
+        Indices into ``catalogcoord`` to get the matched points for each
         ``matchcoord``. Shape matches ``matchcoord``.
     sep2d : `~astropy.coordinates.Angle`
         The on-sky separation between the closest match for each ``matchcoord``
@@ -60,39 +62,7 @@ def match_coordinates_3d(matchcoord, catalogcoord, nthneighbor=1, storekdtree='_
     This function requires `SciPy <http://www.scipy.org>`_ to be installed
     or it will fail.
     """
-    from warnings import warn
-
-    #without scipy this will immediately fail
-    from scipy import spatial
-    try:
-        KDTree = spatial.cKDTree
-    except:
-        warn('C-base KD tree not found, falling back on (much slower) '
-             'python implementation')
-        KDTree = spatial.KDTree
-
-    if storekdtree is True:  # backwards compatibility for pre v0.4
-        storekdtree = '_kdtree'
-
-    # figure out where any cached KDTree might be
-    if isinstance(storekdtree, six.string_types):
-        kdt = getattr(catalogcoord, storekdtree, None)
-        if kdt is not None and not isinstance(kdt, KDTree):
-            raise ValueError('Invalid `storekdtree` string:' + storekdtree)
-    elif isinstance(storekdtree, KDTree):
-        kdt = storekdtree
-        storekdtree = None
-    elif not storekdtree:
-        kdt = None
-    else:
-        raise ValueError('Invalid `storekdtree` argument:' +
-                          str(storekdtree))
-
-    if kdt is None:
-        #need to build the cartesian KD-tree for the catalog
-        cartxyz = catalogcoord.cartesian.xyz
-        flatxyz = cartxyz.reshape((3, np.prod(cartxyz.shape) // 3))
-        kdt = KDTree(flatxyz.value.T)
+    kdt = _get_cartesian_kdtree(catalogcoord, storekdtree)
 
     #make sure coordinate systems match
     matchcoord = matchcoord.transform_to(catalogcoord)
@@ -108,10 +78,6 @@ def match_coordinates_3d(matchcoord, catalogcoord, nthneighbor=1, storekdtree='_
         dist = dist[:, -1]
         idx = idx[:, -1]
 
-    if storekdtree:
-        #cache the kdtree in `catalogcoord`
-        setattr(catalogcoord, storekdtree, kdt)
-
     sep2d = catalogcoord[idx].separation(matchcoord)
     return idx.reshape(matchxyz.shape[1:]), sep2d, dist.reshape(matchxyz.shape[1:]) * catunit
 
@@ -141,14 +107,14 @@ def match_coordinates_sky(matchcoord, catalogcoord, nthneighbor=1, storekdtree='
         itself as the closest match).
     storekdtree : bool or str, optional
         If a string, will store the KD-Tree used for the computation
-        in the ``catalogcoord``, as an attrbute in ``catalogcoord`` with the
+        in the ``catalogcoord`` as an attribute in ``catalogcoord`` with the
         provided name.  This dramatically speeds up subsequent calls with the
         same catalog. If False, the KD-Tree is discarded after use.
 
     Returns
     -------
     idx : integer array
-        Indecies into ``catalogcoord`` to get the matched points for each
+        Indices into ``catalogcoord`` to get the matched points for each
         ``matchcoord``. Shape matches ``matchcoord``.
     sep2d : `~astropy.coordinates.Angle`
         The on-sky separation between the closest match for each
@@ -175,6 +141,12 @@ def match_coordinates_sky(matchcoord, catalogcoord, nthneighbor=1, storekdtree='
     cat_urepr = catalogcoord.data.represent_as(UnitSphericalRepresentation)
     newcat_u = catalogcoord.realize_frame(cat_urepr)
 
+    if isinstance(storekdtree, six.string_types) and hasattr(catalogcoord, storekdtree):
+        # Check for a stored KD-tree on the passed-in coordinate.  Normally it
+        # will have a distinct name from the "3D" one, so it's safe to use even
+        # though it's based on UnitSphericalRepresentation.
+        storekdtree = getattr(catalogcoord, storekdtree)
+
     idx, sep2d, sep3d = match_coordinates_3d(newmatch_u, newcat_u, nthneighbor, storekdtree)
     # sep3d is *wrong* above, because the distance information was removed,
     # unless one of the catalogs doesn't have a real distance
@@ -183,7 +155,264 @@ def match_coordinates_sky(matchcoord, catalogcoord, nthneighbor=1, storekdtree='
         sep3d = catalogcoord[idx].separation_3d(newmatch)
 
     #update the kdtree on the actual passed-in coordinate
-    if storekdtree:
+    if isinstance(storekdtree, six.string_types):
         setattr(catalogcoord, storekdtree, getattr(newcat_u, storekdtree))
 
     return idx, sep2d, sep3d
+
+
+def search_around_3d(coords1, coords2, distlimit, storekdtree='_kdtree_3d'):
+    """
+    Searches for pairs of points that are at least as close as a specified
+    distance in 3D space.
+
+    Parameters
+    ----------
+    coords1 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
+        The first set of coordinates, which will be searched for matches from
+        ``coords2`` within ``seplimit``.
+    coords2 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
+        The second set of coordinates, which will be searched for matches from
+        ``coords1`` within ``seplimit``.
+    distlimit : `~astropy.units.Quantity` with distance units
+        The physical radius to search within.
+    storekdtree : bool or str, optional
+        If a string, will store the KD-Tree used in the search as attributes
+        with the name ``storekdtree`` in ``coords2``.  This speeds up subsequent
+        calls to this function.  If False, the KD-Trees are not saved.
+
+    Returns
+    -------
+    idx1 : integer array
+        Indices into ``coords1`` that matches to the corresponding element of
+        ``idx2``. Shape matches ``idx2``.
+    idx2 : integer array
+        Indices into ``coords2`` that matches to the corresponding element of
+        ``idx1``. Shape matches ``idx1``.
+    sep2d : `~astropy.coordinates.Angle`
+        The on-sky separation between the coordinates. Shape matches ``idx1``
+        and ``idx2``.
+    dist3d : `~astropy.units.Quantity`
+        The 3D distance between the coordinates. Shape matches ``idx1`` and
+        ``idx2``.
+
+    Notes
+    -----
+    This function requires `SciPy <http://www.scipy.org>`_ to be installed
+    or it will fail.
+
+    If you are using this function to search in a catalog for matches around
+    specific points, the convention is for ``coords2`` to be the catalog, and
+    ``coords1`` are the points to search around.  While these operations are
+    mathematically the same if ``coords1`` and ``coords2`` are flipped, some of
+    the optimizations may work better if this convention is obeyed.
+
+    In the current implementation, the return values are always sorted in the
+    same order as the ``coords1`` (so ``idx1`` is in ascending order).  This is
+    considered an implementation detail, though, so it could change in a future
+    release.
+    """
+    if not distlimit.isscalar:
+        raise ValueError('distlimit must be a scalar in search_around_3d')
+
+    kdt2 = _get_cartesian_kdtree(coords2, storekdtree)
+    cunit = coords2.cartesian.x.unit
+
+    # we convert coord1 to match coord2's frame.  We do it this way
+    # so that if the conversion does happen, the KD tree of coord2 at least gets
+    # saved. (by convention, coord2 is the "catalog" if that makes sense)
+    coords1 = coords1.transform_to(coords2)
+
+    kdt1 = _get_cartesian_kdtree(coords1, storekdtree, forceunit=cunit)
+
+    # this is the *cartesian* 3D distance that corresponds to the given angle
+    d = distlimit.to(cunit).value
+
+    idxs1 = []
+    idxs2 = []
+    for i, matches in enumerate(kdt1.query_ball_tree(kdt2, d)):
+        for match in matches:
+            idxs1.append(i)
+            idxs2.append(match)
+    idxs1 = np.array(idxs1)
+    idxs2 = np.array(idxs2)
+
+    if idxs1.size == 0:
+        d2ds = u.Quantity([], u.deg)
+        d3ds = u.Quantity([], u.dimensionless_unscaled)
+    else:
+        d2ds = coords1[idxs1].separation(coords2[idxs2])
+        d3ds = coords1[idxs1].separation_3d(coords2[idxs2])
+
+    return idxs1, idxs2, d2ds, d3ds
+
+
+def search_around_sky(coords1, coords2, seplimit, storekdtree='_kdtree_sky'):
+    """
+    Searches for pairs of points that have an angular separation at least as
+    close as a specified angle.
+
+    Parameters
+    ----------
+    coords1 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
+        The first set of coordinates, which will be searched for matches from
+        ``coords2`` within ``seplimit``.
+    coords2 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
+        The second set of coordinates, which will be searched for matches from
+        ``coords1`` within ``seplimit``.
+    seplimit : `~astropy.units.Quantity` with angle units
+        The on-sky separation to search within.
+    storekdtree : bool or str, optional
+        If a string, will store the KD-Tree used in the search as attributes
+        with the name ``storekdtree`` in ``coords2``.  This speeds up subsequent
+        calls to this function.  If False, the KD-Trees are not saved.
+
+    Returns
+    -------
+    idx1 : integer array
+        Indices into ``coords1`` that matches to the corresponding element of
+        ``idx2``. Shape matches ``idx2``.
+    idx2 : integer array
+        Indices into ``coords2`` that matches to the corresponding element of
+        ``idx1``. Shape matches ``idx1``.
+    sep2d : `~astropy.coordinates.Angle`
+        The on-sky separation between the coordinates. Shape matches ``idx1``
+        and ``idx2``.
+    dist3d : `~astropy.units.Quantity`
+        The 3D distance between the coordinates. Shape matches ``idx1`` and
+        ``idx2``. If either ``coords1`` or ``coords2`` don't have a distance,
+        this is the 3D distance on the unit sphere, rather than a physical
+        distance.
+
+    Notes
+    -----
+    This function requires `SciPy <http://www.scipy.org>`_ to be installed
+    or it will fail.
+
+    In the current implementation, the return values are always sorted in the
+    same order as the ``coords1`` (so ``idx1`` is in ascending order).  This is
+    considered an implementation detail, though, so it could change in a future
+    release.
+    """
+    from . import Angle
+
+    if not seplimit.isscalar:
+        raise ValueError('seplimit must be a scalar in search_around_sky')
+
+    # we convert coord1 to match coord2's frame.  We do it this way
+    # so that if the conversion does happen, the KD tree of coord2 at least gets
+    # saved. (by convention, coord2 is the "catalog" if that makes sense)
+    coords1 = coords1.transform_to(coords2)
+
+    #strip out distance info
+    urepr1 = coords1.data.represent_as(UnitSphericalRepresentation)
+    ucoords1 = coords1.realize_frame(urepr1)
+
+    kdt1 = _get_cartesian_kdtree(ucoords1, storekdtree)
+
+    if hasattr(coords2, storekdtree):
+        #just use the stored KD-Tree
+        kdt2 = getattr(coords2, storekdtree)
+    else:
+        #strip out distance info
+        urepr2 = coords2.data.represent_as(UnitSphericalRepresentation)
+        ucoords2 = coords2.realize_frame(urepr2)
+
+        kdt2 = _get_cartesian_kdtree(ucoords2, storekdtree)
+        #save the KD-Tree in coords2, *not* ucoords2
+        setattr(coords2, storekdtree, kdt2)
+
+    # this is the *cartesian* 3D distance that corresponds to the given angle
+    r = (2 * np.sin(Angle(seplimit) / 2.0)).value
+
+    idxs1 = []
+    idxs2 = []
+    for i, matches in enumerate(kdt1.query_ball_tree(kdt2, r)):
+        for match in matches:
+            idxs1.append(i)
+            idxs2.append(match)
+    idxs1 = np.array(idxs1)
+    idxs2 = np.array(idxs2)
+
+    if idxs1.size == 0:
+        d2ds = u.Quantity([], u.deg)
+        d3ds = u.Quantity([], u.dimensionless_unscaled)
+    else:
+
+        d2ds = coords1[idxs1].separation(coords2[idxs2])
+        try:
+            d3ds = coords1[idxs1].separation_3d(coords2[idxs2])
+        except ValueError:
+            # they don't have distances, so we just fall back on the cartesian
+            # distance, computed from d2ds
+            d3ds = 2 * np.sin(d2ds / 2.0)
+
+    return idxs1, idxs2, d2ds, d3ds
+
+
+def _get_cartesian_kdtree(coord, attrname_or_kdt='_kdtree', forceunit=None):
+    """
+    This is a utility function to retrieve (and build/cache, if necessary)
+    a 3D cartesian KD-Tree from various sorts of astropy coordinate objects.
+
+    Parameters
+    ----------
+    coord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
+        The coordinates to build the KD-Tree for.
+    attrname_or_kdt : bool or str or KDTree
+        If a string, will store the KD-Tree used for the computation
+        in the ``coord``, as an attribute in ``coord`` with the
+        provided name. If given as a KD-Tree, it will just be used directly.
+    forceunit: unit or None
+        If a unit, the cartesian coordinates will convert to that unit before
+        being put in the KD-Tree.  If None, whatever unit it's already in
+        will be used
+
+    Returns
+    -------
+    kdt : `~scipy.spatial.cKDTree` or `~scipy.spatial.KDTree`
+        The KD-Tree representing the 3D cartesian representation of the input
+        coordinates.
+    """
+    from warnings import warn
+
+    #without scipy this will immediately fail
+    from scipy import spatial
+    try:
+        KDTree = spatial.cKDTree
+    except:
+        warn('C-based KD tree not found, falling back on (much slower) '
+             'python implementation')
+        KDTree = spatial.KDTree
+
+    if attrname_or_kdt is True:  # backwards compatibility for pre v0.4
+        attrname_or_kdt = '_kdtree'
+
+    # figure out where any cached KDTree might be
+    if isinstance(attrname_or_kdt, six.string_types):
+        kdt = getattr(coord, attrname_or_kdt, None)
+        if kdt is not None and not isinstance(kdt, KDTree):
+            raise ValueError('The `attrname_or_kdt` "{0}" is not a scipy KD tree!'.format(attrname_or_kdt))
+    elif isinstance(attrname_or_kdt, KDTree):
+        kdt = attrname_or_kdt
+        attrname_or_kdt = None
+    elif not attrname_or_kdt:
+        kdt = None
+    else:
+        raise ValueError('Invalid `attrname_or_kdt` argument for KD-Tree:' +
+                          str(attrname_or_kdt))
+
+    if kdt is None:
+        #need to build the cartesian KD-tree for the catalog
+        if forceunit is None:
+            cartxyz = coord.cartesian.xyz
+        else:
+            cartxyz = coord.cartesian.xyz.to(forceunit)
+        flatxyz = cartxyz.reshape((3, np.prod(cartxyz.shape) // 3))
+        kdt = KDTree(flatxyz.value.T)
+
+    if attrname_or_kdt:
+        #cache the kdtree in `coord`
+        setattr(coord, attrname_or_kdt, kdt)
+
+    return kdt
diff --git a/astropy/coordinates/representation.py b/astropy/coordinates/representation.py
index 9b6c293..692d1bb 100644
--- a/astropy/coordinates/representation.py
+++ b/astropy/coordinates/representation.py
@@ -16,6 +16,7 @@ from .angles import Angle, Longitude, Latitude
 from .distances import Distance
 from ..extern import six
 from ..utils import OrderedDict
+from ..utils.compat.numpy import broadcast_arrays
 
 __all__ = ["BaseRepresentation", "CartesianRepresentation",
            "SphericalRepresentation", "UnitSphericalRepresentation",
@@ -27,17 +28,6 @@ __all__ = ["BaseRepresentation", "CartesianRepresentation",
 REPRESENTATION_CLASSES = {}
 
 
-def broadcast_quantity(*args):
-    """
-    A Quantity-aware version of np.broadcast_arrays
-    """
-    new_arrays = np.broadcast_arrays(*args)
-    new_quantities = []
-    for i in range(len(new_arrays)):
-        new_quantities.append(args[i]._new_view(new_arrays[i]))
-    return tuple(new_quantities)
-
-
 class MetaBaseRepresentation(type):
     def __init__(cls, name, bases, dct):
         super(MetaBaseRepresentation, cls).__init__(name, bases, dct)
@@ -230,7 +220,7 @@ class CartesianRepresentation(BaseRepresentation):
             raise u.UnitsError("x, y, and z should have matching physical types")
 
         try:
-            x, y, z = broadcast_quantity(x, y, z)
+            x, y, z = broadcast_arrays(x, y, z, subok=True)
         except ValueError:
             raise ValueError("Input parameters x, y, and z cannot be broadcast")
 
@@ -315,7 +305,8 @@ class SphericalRepresentation(BaseRepresentation):
             distance = distance.view(Distance)
 
         try:
-            lon, lat, distance = broadcast_quantity(lon, lat, distance)
+            lon, lat, distance = broadcast_arrays(lon, lat, distance,
+                                                  subok=True)
         except ValueError:
             raise ValueError("Input parameters lon, lat, and distance cannot be broadcast")
 
@@ -345,7 +336,7 @@ class SphericalRepresentation(BaseRepresentation):
         return self._distance
 
     def represent_as(self, other_class):
-        # Take a short cut if the other clsss is a spherical representation
+        # Take a short cut if the other class is a spherical representation
         if other_class is PhysicsSphericalRepresentation:
             return PhysicsSphericalRepresentation(phi=self.lon,
                                                   theta=90 * u.deg - self.lat,
@@ -422,7 +413,7 @@ class UnitSphericalRepresentation(BaseRepresentation):
         lat = self.attr_classes['lat'](lat, copy=copy)
 
         try:
-            lon, lat = broadcast_quantity(lon, lat)
+            lon, lat = broadcast_arrays(lon, lat, subok=True)
         except ValueError:
             raise ValueError("Input parameters lon and lat cannot be broadcast")
 
@@ -539,7 +530,7 @@ class PhysicsSphericalRepresentation(BaseRepresentation):
             r = r.view(Distance)
 
         try:
-            phi, theta, r = broadcast_quantity(phi, theta, r)
+            phi, theta, r = broadcast_arrays(phi, theta, r, subok=True)
         except ValueError:
             raise ValueError("Input parameters phi, theta, and r cannot be broadcast")
 
@@ -653,7 +644,7 @@ class CylindricalRepresentation(BaseRepresentation):
             raise u.UnitsError("rho and z should have matching physical types")
 
         try:
-            rho, phi, z = broadcast_quantity(rho, phi, z)
+            rho, phi, z = broadcast_arrays(rho, phi, z, subok=True)
         except ValueError:
             raise ValueError("Input parameters rho, phi, and z cannot be broadcast")
 
diff --git a/astropy/coordinates/sky_coordinate.py b/astropy/coordinates/sky_coordinate.py
index 54a2782..2061dfd 100644
--- a/astropy/coordinates/sky_coordinate.py
+++ b/astropy/coordinates/sky_coordinate.py
@@ -1,6 +1,8 @@
 from __future__ import (absolute_import, division, print_function, unicode_literals)
 
+import re
 import collections
+import warnings
 
 import numpy as np
 
@@ -9,6 +11,8 @@ from ..extern import six
 from ..extern.six.moves import zip
 from ..units import Unit, IrreducibleUnit
 from .. import units as u
+from ..wcs.utils import skycoord_to_pixel, pixel_to_skycoord
+from ..utils.exceptions import AstropyDeprecationWarning
 
 from .distances import Distance
 from .baseframe import BaseCoordinateFrame, frame_transform_graph, GenericFrame, _get_repr_cls
@@ -18,6 +22,13 @@ from .representation import (BaseRepresentation, SphericalRepresentation,
 
 __all__ = ['SkyCoord']
 
+PLUS_MINUS_RE = re.compile(r'(\+|\-)')
+J_PREFIXED_RA_DEC_RE = re.compile(
+    r"""J                              # J prefix
+    ([0-9]{6,7}\.?[0-9]{0,2})          # RA as HHMMSS.ss or DDDMMSS.ss, optional decimal digits
+    ([\+\-][0-9]{6}\.?[0-9]{0,2})\s*$  # Dec as DDMMSS.ss, optional decimal digits
+    """, re.VERBOSE)
+
 
 # Define a convenience mapping.  This is used like a module constants
 # but is actually dynamically evaluated.
@@ -34,11 +45,12 @@ class SkyCoord(object):
     """High-level object providing a flexible interface for celestial coordinate
     representation, manipulation, and transformation between systems.
 
-    The `SkyCoord` class accepts a wide variety of inputs for initialization.
-    At a minimum these must provide one or more celestial coordinate values
-    with unambiguous units.  Typically one also specifies the coordinate
-    frame, though this is not required.  The general pattern is for spherical
-    representations is::
+    The `SkyCoord` class accepts a wide variety of inputs for initialization. At
+    a minimum these must provide one or more celestial coordinate values with
+    unambiguous units.  Inputs may be scalars or lists/tuples/arrays, yielding
+    scalar or array coordinates (can be checked via ``SkyCoord.isscalar``).
+    Typically one also specifies the coordinate frame, though this is not
+    required. The general pattern for spherical representations is::
 
       SkyCoord(COORD, [FRAME], keyword_args ...)
       SkyCoord(LON, LAT, [FRAME], keyword_args ...)
@@ -83,6 +95,8 @@ class SkyCoord(object):
 
       >>> c = SkyCoord(w=0, u=1, v=2, unit='kpc', frame='galactic', representation='cartesian')
 
+      >>> c = SkyCoord([ICRS(ra=1*u.deg, dec=2*u.deg), ICRS(ra=3*u.deg, dec=4*u.deg)])
+
     As shown, the frame can be a `~astropy.coordinates.BaseCoordinateFrame`
     class or the corresponding string alias.  The frame classes that are built in
     to astropy are `ICRS`, `FK5`, `FK4`, `FK4NoETerms`, and `Galactic`.
@@ -125,6 +139,11 @@ class SkyCoord(object):
             Cartesian coordinates values for the Galactic frame.
     """
 
+
+    # Declare that SkyCoord can be used as a Table column by defining the
+    # attribute where column attributes will be stored.
+    _astropy_column_attrs = None
+
     def __init__(self, *args, **kwargs):
 
         # Parse the args and kwargs to assemble a sanitized and validated
@@ -223,7 +242,7 @@ class SkyCoord(object):
                 # coord_kwargs will contain keys like 'ra', 'dec', 'distance'
                 # along with any frame attributes like equinox or obstime which
                 # were explicitly specified in the coordinate object (i.e. non-default).
-                coord_kwargs = _parse_coordinate_arg(args[0], frame, units)
+                coord_kwargs = _parse_coordinate_arg(args[0], frame, units, kwargs)
 
             elif len(args) <= 3:
                 frame_attr_names = frame.representation_component_names.keys()
@@ -244,7 +263,7 @@ class SkyCoord(object):
             for attr, coord_value in coord_kwargs.items():
                 if (attr in valid_kwargs
                         and valid_kwargs[attr] is not None
-                        and valid_kwargs[attr] != coord_value):
+                        and np.any(valid_kwargs[attr] != coord_value)):
                     raise ValueError("Coordinate attribute '{0}'={1!r} conflicts with "
                                      "keyword argument '{0}'={2!r}"
                                      .format(attr, coord_value, valid_kwargs[attr]))
@@ -411,8 +430,12 @@ class SkyCoord(object):
         clsnm = self.__class__.__name__
         coonm = self.frame.__class__.__name__
 
-        s = '<{clsnm} ({coonm})'.format(**locals())
         crepr = repr(self.frame)
+        frameattrs = ''
+        if crepr.find('):') != -1:
+            frameattrs = ': '+crepr[crepr.index('(')+1:crepr.index('):')]
+
+        s = '<{clsnm} ({coonm}{frameattrs})'.format(**locals())
         return s + crepr[crepr.index(':'):]
 
     def to_string(self, style='decimal', **kwargs):
@@ -471,14 +494,56 @@ class SkyCoord(object):
                             sph_coord.lat.to_string(**latargs))
         else:
             coord_string = []
-            for lonangle, latangle in zip(sph_coord.lon, sph_coord.lat):
+            for lonangle, latangle in zip(sph_coord.lon.ravel(), sph_coord.lat.ravel()):
                 coord_string += [(lonangle.to_string(**lonargs)
                                  + " " +
                                  latangle.to_string(**latargs))]
+            if len(sph_coord.shape) > 1:
+                coord_string = np.array(coord_string).reshape(sph_coord.shape)
 
         return coord_string
 
-    # High-level convinience methods
+    def is_equivalent_frame(self, other):
+        """
+        Checks if this object's frame as the same as that of the ``other``
+        object.
+
+        To be the same frame, two objects must be the same frame class and have
+        the same frame attributes. For two `SkyCoord` objects, *all* of the
+        frame attributes have to match, not just those relevant for the object's
+        frame.
+
+        Parameters
+        ----------
+        other : SkyCoord or BaseCoordinateFrame
+            The other object to check.
+
+        Returns
+        -------
+        isequiv : bool
+            True if the frames are the same, False if not.
+
+        Raises
+        ------
+        TypeError
+            If ``other`` isn't a `SkyCoord` or a `BaseCoordinateFrame` or subclass.
+        """
+        if isinstance(other, BaseCoordinateFrame):
+            return self.frame.is_equivalent_frame(other)
+        elif isinstance(other, SkyCoord):
+            if other.frame.name != self.frame.name:
+                return False
+
+            for fattrnm in FRAME_ATTR_NAMES_SET():
+                if getattr(self, fattrnm) != getattr(other, fattrnm):
+                    return False
+            return True
+        else:
+            #not a BaseCoordinateFrame nor a SkyCoord object
+            raise TypeError("Tried to do is_equivalent_frame on something that "
+                            "isn't frame-like")
+
+    # High-level convenience methods
     def separation(self, other):
         """
         Computes on-sky separation between this coordinate and another.
@@ -685,6 +750,100 @@ class SkyCoord(object):
 
         return res
 
+    def search_around_sky(self, searcharoundcoords, seplimit):
+        """
+        Searches for all coordinates in this object around a supplied set of
+        points within a given on-sky separation.
+
+        Parameters
+        ----------
+        searcharoundcoords : `~astropy.coordinates.SkyCoord` or `~astropy.coordinates.BaseCoordinateFrame`
+            The coordinate(s) to search around to try to find matching points in
+            this `SkyCoord`.
+        seplimit : `~astropy.units.Quantity` with angle units
+            The on-sky separation to search within.
+
+        Returns
+        -------
+        idxsearcharound : integer array
+            Indices into ``coords1`` that matches to the corresponding element of
+            ``idxself``. Shape matches ``idxself``.
+        idxself : integer array
+            Indices into ``coords2`` that matches to the corresponding element of
+            ``idxsearcharound``. Shape matches ``idxsearcharound``.
+        sep2d : `~astropy.coordinates.Angle`
+            The on-sky separation between the coordinates. Shape matches
+            ``idxsearcharound`` and ``idxself``.
+        dist3d : `~astropy.units.Quantity`
+            The 3D distance between the coordinates. Shape matches
+            ``idxsearcharound`` and ``idxself``.
+
+        Notes
+        -----
+        This method requires `SciPy <http://www.scipy.org>`_ to be
+        installed or it will fail.
+
+        In the current implementation, the return values are always sorted in
+        the same order as the ``searcharoundcoords`` (so ``idxsearcharound`` is
+        in ascending order).  This is considered an implementation detail,
+        though, so it could change in a future release.
+
+        See Also
+        --------
+        astropy.coordinates.search_around_sky
+        """
+        from .matching import search_around_sky
+
+        return search_around_sky(searcharoundcoords, self, seplimit,
+                                 storekdtree='_kdtree_sky')
+
+    def search_around_3d(self, searcharoundcoords, distlimit):
+        """
+        Searches for all coordinates in this object around a supplied set of
+        points within a given 3D radius.
+
+        Parameters
+        ----------
+        searcharoundcoords : `~astropy.coordinates.SkyCoord` or `~astropy.coordinates.BaseCoordinateFrame`
+            The coordinate(s) to search around to try to find matching points in
+            this `SkyCoord`.
+        distlimit : `~astropy.units.Quantity` with distance units
+            The physical radius to search within.
+
+        Returns
+        -------
+        idxsearcharound : integer array
+            Indices into ``coords1`` that matches to the corresponding element of
+            ``idxself``. Shape matches ``idxself``.
+        idxself : integer array
+            Indices into ``coords2`` that matches to the corresponding element of
+            ``idxsearcharound``. Shape matches ``idxsearcharound``.
+        sep2d : `~astropy.coordinates.Angle`
+            The on-sky separation between the coordinates. Shape matches
+            ``idxsearcharound`` and ``idxself``.
+        dist3d : `~astropy.units.Quantity`
+            The 3D distance between the coordinates. Shape matches
+            ``idxsearcharound`` and ``idxself``.
+
+        Notes
+        -----
+        This method requires `SciPy <http://www.scipy.org>`_ to be
+        installed or it will fail.
+
+        In the current implementation, the return values are always sorted in
+        the same order as the ``searcharoundcoords`` (so ``idxsearcharound`` is
+        in ascending order).  This is considered an implementation detail,
+        though, so it could change in a future release.
+
+        See Also
+        --------
+        astropy.coordinates.search_around_3d
+        """
+        from .matching import search_around_3d
+
+        return search_around_3d(searcharoundcoords, self, distlimit,
+                                storekdtree='_kdtree_3d')
+
     def position_angle(self, other):
         """
         Computes the on-sky position angle (East of North) between this
@@ -729,6 +888,141 @@ class SkyCoord(object):
 
         return angle_utilities.position_angle(slon, slat, olon, olat)
 
+    # WCS pixel to/from sky conversions
+    def to_pixel(self, wcs, origin=0, mode='all'):
+        """
+        Convert this coordinate to pixel coordinates using a `~astropy.wcs.WCS`
+        object.
+
+        Parameters
+        ----------
+        wcs : `~astropy.wcs.WCS`
+            The WCS to use for convert
+        origin : int
+            Whether to return 0 or 1-based pixel coordinates.
+        mode : 'all' or 'wcs'
+            Whether to do the transformation including distortions (``'all'``) or
+            only including only the core WCS transformation (``'wcs'``).
+
+        Returns
+        -------
+        xp, yp : `numpy.ndarray`
+            The pixel coordinates
+
+        See Also
+        --------
+        from_pixel : to do the inverse operation
+        astropy.wcs.utils.skycoord_to_pixel : the implementation of this method
+        """
+        return skycoord_to_pixel(self, wcs=wcs, origin=origin, mode=mode)
+
+    @classmethod
+    def from_pixel(cls, xp, yp, wcs, origin=0, mode='all'):
+        """
+        Create a new `SkyCoord` from pixel coordinates using an
+        `~astropy.wcs.WCS` object.
+
+        Parameters
+        ----------
+        xp, yp : float or `numpy.ndarray`
+            The coordinates to convert.
+        wcs : `~astropy.wcs.WCS`
+            The WCS to use for convert
+        origin : int
+            Whether to return 0 or 1-based pixel coordinates.
+        mode : 'all' or 'wcs'
+            Whether to do the transformation including distortions (``'all'``) or
+            only including only the core WCS transformation (``'wcs'``).
+
+        Returns
+        -------
+        coord : an instance of this class
+            A new object with sky coordinates corresponding to the input ``xp``
+            and ``yp``.
+
+        See Also
+        --------
+        to_pixel : to do the inverse operation
+        astropy.wcs.utils.pixel_to_skycoord : the implementation of this method
+        """
+        return pixel_to_skycoord(xp, yp, wcs=wcs, origin=origin, mode=mode, cls=cls)
+
+    # Table interactions
+    @classmethod
+    def guess_from_table(cls, table, **coord_kwargs):
+        """
+        A convenience method to create and return a new `SkyCoord` from the data
+        in an astropy Table.
+
+        This method matches table columns that start with the case-insensitive
+        names of the the components of the requested frames, if they are also
+        followed by a non-alphanumeric character. It will also match columns
+        that *end* with the component name if a non-alphanumeric character is
+        *before* it.
+
+        For example, the first rule means columns with names like
+        ``'RA[J2000]'`` or ``'ra'`` will be interpreted as ``ra`` attributes for
+        `~astropy.coordinates.ICRS` frames, but ``'RAJ2000'`` or ``'radius'``
+        are *not*. Similarly, the second rule applied to the
+        `~astropy.coordinates.Galactic` frame means that a column named
+        ``'gal_l'`` will be used as the the ``l`` component, but ``gall`` or
+        ``'fill'`` will not.
+
+        The definition of alphanumeric here is based on Unicode's definition
+        of alphanumeric, except without ``_`` (which is normally considered
+        alphanumeric).  So for ASCII, this means the non-alphanumeric characters
+        are ``<space>_!"#$%&'()*+,-./:;<=>?@[\]^`{|}~``).
+
+        Parameters
+        ----------
+        table : astropy.Table
+            The table to load data from.
+        coord_kwargs
+            Any additional keyword arguments are passed directly to this class's
+            constructor.
+
+        Returns
+        -------
+        newsc : same as this class
+            The new `SkyCoord` (or subclass) object.
+        """
+        inital_frame = coord_kwargs.get('frame')
+        frame = _get_frame([], coord_kwargs)
+        coord_kwargs['frame'] = inital_frame
+
+        comp_kwargs = {}
+        for comp_name in frame.representation_component_names:
+            # this matches things like 'ra[...]'' but *not* 'rad'.
+            # note that the "_" must be in there explicitly, because
+            # "alphanumeric" usually includes underscores.
+            starts_with_comp = comp_name + r'(\W|\b|_)'
+            # this part matches stuff like 'center_ra', but *not*
+            # 'aura'
+            ends_with_comp = r'.*(\W|\b|_)' + comp_name + r'\b'
+            #the final regex ORs together the two patterns
+            rex = re.compile('(' +starts_with_comp + ')|(' + ends_with_comp + ')',
+                             re.IGNORECASE | re.UNICODE)
+
+            for col_name in table.colnames:
+                if rex.match(col_name):
+                    if comp_name in comp_kwargs:
+                        oldname = comp_kwargs[comp_name].name
+                        msg = ('Found at least two matches for  component "{0}"'
+                               ': "{1}" and "{2}". Cannot continue with this '
+                               'ambiguity.')
+                        raise ValueError(msg.format(comp_name, oldname, col_name))
+                    comp_kwargs[comp_name] = table[col_name]
+
+        for k, v in comp_kwargs.items():
+            if k in coord_kwargs:
+                raise ValueError('Found column "{0}" in table, but it was '
+                                 'already provided as "{1}" keyword to '
+                                 'guess_from_table function.'.format(v.name, k))
+            else:
+                coord_kwargs[k] = v
+
+        return cls(**coord_kwargs)
+
     # Name resolve
     @classmethod
     def from_name(cls, name, frame='icrs'):
@@ -802,6 +1096,34 @@ def _get_frame(args, kwargs):
     """
     frame = kwargs.pop('frame', None)
 
+    if frame is None and len(args) > 1:
+
+        # We do not allow frames to be passed as positional arguments if data
+        # is passed separately from frame.
+
+        for arg in args:
+
+            if isinstance(arg, (SkyCoord, BaseCoordinateFrame)):
+                raise ValueError("{0} instance cannot be passed as a positional "
+                                 "argument for the frame, pass it using the "
+                                 "frame= keyword instead.".format(arg.__class__.__name__))
+
+    # If the frame is an instance or SkyCoord, we split up the attributes and
+    # make it into a class.
+
+    if isinstance(frame, SkyCoord):
+        frame = frame.frame
+
+    if isinstance(frame, BaseCoordinateFrame):
+
+        for attr in frame.get_frame_attr_names():
+            if attr in kwargs:
+                raise ValueError("cannot specify frame attribute '{0}' directly in SkyCoord since a frame instance was passed in".format(attr))
+            else:
+                kwargs[attr] = getattr(frame, attr)
+
+        frame = frame.__class__
+
     if frame is not None:
         # Frame was provided as kwarg so validate and coerce into corresponding frame.
         frame_cls = _get_frame_class(frame)
@@ -816,6 +1138,9 @@ def _get_frame(args, kwargs):
                 pass
             else:
                 args.remove(arg)
+                warnings.warn("Passing a frame as a positional argument is now "
+                              "deprecated, use the frame= keyword argument "
+                              "instead.", AstropyDeprecationWarning)
                 break
         else:
             # Not in args nor kwargs - default to icrs
@@ -879,14 +1204,19 @@ def _get_units(args, kwargs):
     return units
 
 
-def _parse_coordinate_arg(coords, frame, units):
+def _parse_coordinate_arg(coords, frame, units, init_kwargs):
     """
     Single unnamed arg supplied.  This must be:
     - Coordinate frame with data
     - Representation
+    - SkyCoord
     - List or tuple of:
       - String which splits into two values
       - Iterable with two values
+      - SkyCoord, frame, or representation objects.
+
+    Returns a dict mapping coordinate attribute names to values (or lists of
+    values)
     """
     is_scalar = False  # Differentiate between scalar and list input
     valid_kwargs = {}  # Returned dict of lon, lat, and distance (optional)
@@ -937,46 +1267,81 @@ def _parse_coordinate_arg(coords, frame, units):
         values = coords.transpose()  # Iterates over repr attrs
 
     elif isinstance(coords, (collections.Sequence, np.ndarray)):
-        # Handles generic list-like input.
+        # Handles list-like input.
 
-        # First turn into a list of lists like [[v1_0, v2_0, v3_0], ... [v1_N, v2_N, v3_N]]
         vals = []
-        for ii, coord in enumerate(coords):
-            if isinstance(coord, six.string_types):
-                coord1 = coord.split()
-                if len(coord1) == 6:
-                    coord1 = (' '.join(coord1[:3]), ' '.join(coord1[3:]))
-                coord = coord1
-
-            vals.append(coord)  # This assumes coord is a sequence at this point
-
-        # Do some basic validation of the list elements: all have a length and all
-        # lengths the same
-        try:
-            n_coords = sorted(set(len(x) for x in vals))
-        except:
-            raise ValueError('One or more elements of input sequence does not have a length')
-
-        if len(n_coords) > 1:
-            raise ValueError('Input coordinate values must have same number of elements, found {0}'
-                             .format(n_coords))
-        n_coords = n_coords[0]
-
-        # Must have no more coord inputs than representation attributes
-        if n_coords > n_attr_names:
-            raise ValueError('Input coordinates have {0} values but {1} representation '
-                             'only accepts {2}'
-                             .format(n_coords, frame.representation.get_name(), n_attr_names))
-
-        # Now transpose vals to get [(v1_0 .. v1_N), (v2_0 .. v2_N), (v3_0 .. v3_N)]
-        # (ok since we know it is exactly rectangular).  (Note: can't just use zip(*values)
-        # because Longitude et al distinguishes list from tuple so [a1, a2, ..] is needed
-        # while (a1, a2, ..) doesn't work.
-        values = [list(x) for x in zip(*vals)]
-
-        if is_scalar:
-            values = [x[0] for x in values]
-
+        is_ra_dec_representation = ('ra' in frame.representation_component_names and
+                                    'dec' in frame.representation_component_names)
+        coord_types = (SkyCoord, BaseCoordinateFrame, BaseRepresentation)
+        if any(isinstance(coord, coord_types) for coord in coords):
+            # this parsing path is used when there are coordinate-like objects
+            # in the list - instead of creating lists of values, we create
+            # SkyCoords from the list elements and then combine them.
+            scs = [SkyCoord(coord, **init_kwargs) for coord in coords]
+
+            # now check that they're all self-consistent in their frames
+            for sc in scs[1:]:
+                if not sc.is_equivalent_frame(scs[0]):
+                        raise ValueError("List of inputs don't have equivalent "
+                                         "frames: {0} != {1}".format(sc, scs[0]))
+
+            # get the frame attributes from the first one, because from above we
+            # know it matches all the others
+            for fattrnm in FRAME_ATTR_NAMES_SET():
+                valid_kwargs[fattrnm] = getattr(scs[0], fattrnm)
+
+            # Now combine the values, to be used below
+            values = []
+            for data_attr_name in frame_attr_names:
+                data_vals = []
+                for sc in scs:
+                    data_val = getattr(sc, data_attr_name)
+                    data_vals.append(data_val.reshape(1,) if sc.isscalar else data_val)
+                concat_vals = np.concatenate(data_vals)
+                # Hack because np.concatenate doesn't fully work with Quantity
+                if isinstance(concat_vals, u.Quantity):
+                    concat_vals._unit = data_val.unit
+                values.append(concat_vals)
+        else:
+            #none of the elements are "frame-like"
+            #turn into a list of lists like [[v1_0, v2_0, v3_0], ... [v1_N, v2_N, v3_N]]
+            for coord in coords:
+                if isinstance(coord, six.string_types):
+                    coord1 = coord.split()
+                    if len(coord1) == 6:
+                        coord = (' '.join(coord1[:3]), ' '.join(coord1[3:]))
+                    elif is_ra_dec_representation:
+                        coord = _parse_ra_dec(coord)
+                    else:
+                        coord = coord1
+                vals.append(coord)  # Assumes coord is a sequence at this point
+
+            # Do some basic validation of the list elements: all have a length and all
+            # lengths the same
+            try:
+                n_coords = sorted(set(len(x) for x in vals))
+            except:
+                raise ValueError('One or more elements of input sequence does not have a length')
+
+            if len(n_coords) > 1:
+                raise ValueError('Input coordinate values must have same number of elements, found {0}'
+                                 .format(n_coords))
+            n_coords = n_coords[0]
+
+            # Must have no more coord inputs than representation attributes
+            if n_coords > n_attr_names:
+                raise ValueError('Input coordinates have {0} values but '
+                                 'representation {1} only accepts {2}'
+                                 .format(n_coords, frame.representation.get_name(), n_attr_names))
+
+            # Now transpose vals to get [(v1_0 .. v1_N), (v2_0 .. v2_N), (v3_0 .. v3_N)]
+            # (ok since we know it is exactly rectangular).  (Note: can't just use zip(*values)
+            # because Longitude et al distinguishes list from tuple so [a1, a2, ..] is needed
+            # while (a1, a2, ..) doesn't work.
+            values = [list(x) for x in zip(*vals)]
+
+            if is_scalar:
+                values = [x[0] for x in values]
     else:
         raise ValueError('Cannot parse coordinates from first argument')
 
@@ -988,9 +1353,8 @@ def _parse_coordinate_arg(coords, frame, units):
                 frame_attr_names, repr_attr_classes, values, units):
             valid_kwargs[frame_attr_name] = repr_attr_class(value, unit=unit)
     except Exception as err:
-        raise ValueError('Cannot parse longitude and latitude from first argument: {0}'
-                         .format(err))
-
+        raise ValueError('Cannot parse first argument data "{0}" for attribute '
+                         '{1}'.format(value, frame_attr_name), err)
     return valid_kwargs
 
 
@@ -1014,3 +1378,60 @@ def _get_representation_attrs(frame, units, kwargs):
             valid_kwargs[frame_attr_name] = repr_attr_class(value, unit=unit)
 
     return valid_kwargs
+
+
+def _parse_ra_dec(coord_str):
+    """
+    Parse RA and Dec values from a coordinate string. Currently the
+    following formats are supported:
+
+     * space separated 6-value format
+     * space separated <6-value format, this requires a plus or minus sign
+       separation between RA and Dec
+     * sign separated format
+     * JHHMMSS.ss+DDMMSS.ss format, with up to two optional decimal digits
+     * JDDDMMSS.ss+DDMMSS.ss format, with up to two optional decimal digits
+
+    Parameters
+    ----------
+    coord_str : str
+        Coordinate string to parse.
+
+    Returns
+    -------
+    coord : str or list of str
+        Parsed coordinate values.
+    """
+
+    if isinstance(coord_str, six.string_types):
+        coord1 = coord_str.split()
+    else:
+        # This exception should never be raised from SkyCoord
+        raise TypeError('coord_str must be a single str')
+
+    if len(coord1) == 6:
+        coord = (' '.join(coord1[:3]), ' '.join(coord1[3:]))
+    elif len(coord1) > 2:
+        coord = PLUS_MINUS_RE.split(coord_str)
+        coord = (coord[0], ' '.join(coord[1:]))
+    elif len(coord1) == 1:
+        match_j = J_PREFIXED_RA_DEC_RE.match(coord_str)
+        if match_j:
+            coord = match_j.groups()
+            if len(coord[0].split('.')[0]) == 7:
+                coord = ('{0} {1} {2}'.
+                         format(coord[0][0:3], coord[0][3:5], coord[0][5:]),
+                         '{0} {1} {2}'.
+                         format(coord[1][0:3], coord[1][3:5], coord[1][5:]))
+            else:
+                coord = ('{0} {1} {2}'.
+                         format(coord[0][0:2], coord[0][2:4], coord[0][4:]),
+                         '{0} {1} {2}'.
+                         format(coord[1][0:3], coord[1][3:5], coord[1][5:]))
+        else:
+            coord = PLUS_MINUS_RE.split(coord_str)
+            coord = (coord[0], ' '.join(coord[1:]))
+    else:
+        coord = coord1
+
+    return coord
diff --git a/astropy/coordinates/tests/accuracy/test_altaz_icrs.py b/astropy/coordinates/tests/accuracy/test_altaz_icrs.py
new file mode 100644
index 0000000..41b79ed
--- /dev/null
+++ b/astropy/coordinates/tests/accuracy/test_altaz_icrs.py
@@ -0,0 +1,159 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Accuracy tests for AltAz to ICRS coordinate transformations.
+
+We use "known good" examples computed with other coordinate libraries.
+
+Note that we use very low precision asserts because some people run tests on 32-bit
+machines and we want the tests to pass there.
+TODO: check if these tests pass on 32-bit machines and implement
+higher-precision checks on 64-bit machines.
+"""
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+from ....tests.helper import pytest, catch_warnings
+from .... import units as u
+from ....time import Time, TimeDelta
+from ...builtin_frames import AltAz
+from ... import EarthLocation
+from ... import Angle, SkyCoord
+
+
+def test_against_hor2eq():
+    """Check that Astropy gives consistent results with an IDL hor2eq example.
+
+    See EXAMPLE input and output here:
+    http://idlastro.gsfc.nasa.gov/ftp/pro/astro/hor2eq.pro
+    """
+    # Observatory position for `kpno` from here:
+    # http://idlastro.gsfc.nasa.gov/ftp/pro/astro/observatory.pro
+    location = EarthLocation(lon=Angle('-111d36.0m'),
+                             lat=Angle('31d57.8m'),
+                             height=2120. * u.m)
+
+    # obstime = Time('2041-12-26 05:00:00')
+    obstime = Time(2466879.7083333, format='jd')
+    # obstime += TimeDelta(-2, format='sec')
+
+    altaz_frame = AltAz(obstime=obstime, location=location,
+                        temperature=0 * u.deg_C, pressure=0.781 * u.bar)
+    altaz = SkyCoord('264d55m06s 37d54m41s', frame=altaz_frame)
+
+    radec_frame = 'icrs'
+
+    # The following transformation throws a warning about precision problems
+    # because the observation date is in the future
+    with catch_warnings() as _:
+        radec_actual = altaz.transform_to(radec_frame)
+
+    radec_expected = SkyCoord('00h13m14.1s  +15d11m0.3s', frame=radec_frame)
+    distance = radec_actual.separation(radec_expected).to('arcsec')
+    # print(radec_expected)
+    # print(radec_actual)
+    # print(distance)
+
+    # TODO: why is there a difference of 2.6 arcsec currently?
+    # radec_expected = ra=3.30875 deg, dec=15.183416666666666 deg
+    # radec_actual = ra=3.3094193224314625 deg, dec=15.183757021354532 deg
+    # distance = 2.6285 arcsec
+    assert distance < 5 * u.arcsec
+
+
+def test_against_pyephem():
+    """Check that Astropy gives consistent results with one PyEphem example.
+
+    PyEphem: http://rhodesmill.org/pyephem/
+
+    See example input and output here:
+    https://gist.github.com/zonca/1672906
+    https://github.com/phn/pytpm/issues/2#issuecomment-3698679
+    """
+    obstime = Time('2011-09-18 08:50:00')
+    location = EarthLocation(lon=Angle('-109d24m53.1s'),
+                             lat=Angle('33d41m46.0s'),
+                             height=30000. * u.m)
+    # We are using the default pressure and temperature in PyEphem
+    # relative_humidity = ?
+    # obswl = ?
+    altaz_frame = AltAz(obstime=obstime, location=location,
+                        temperature=15 * u.deg_C, pressure=1.010 * u.bar)
+
+    altaz = SkyCoord('6.8927d -60.7665d', frame=altaz_frame)
+    radec_actual = altaz.transform_to('icrs')
+
+    radec_expected = SkyCoord('196.497518d -4.569323d', frame='icrs')  # EPHEM
+    # radec_expected = SkyCoord('196.496220d -4.569390d', frame='icrs')  # HORIZON
+    distance = radec_actual.separation(radec_expected).to('arcsec')
+    # TODO: why is this difference so large?
+    # It currently is: 31.45187984720655 arcsec
+    assert distance < 1e3 * u.arcsec
+
+    # Add assert on current Astropy result so that we notice if something changes
+    radec_expected = SkyCoord('196.495372d -4.560694d', frame='icrs')
+    distance = radec_actual.separation(radec_expected).to('arcsec')
+    # Current value: 0.0031402822944751997 arcsec
+    assert distance < 1 * u.arcsec
+
+
+def test_against_jpl_horizons():
+    """Check that Astropy gives consistent results with the JPL Horizons example.
+
+    The input parameters and reference results are taken from this page:
+    (from the first row of the Results table at the bottom of that page)
+    http://ssd.jpl.nasa.gov/?horizons_tutorial
+    """
+    obstime = Time('1998-07-28 03:00')
+    location = EarthLocation(lon=Angle('248.405300d'),
+                             lat=Angle('31.9585d'),
+                             height=2.06 * u.km)
+    temperature = 15 * u.deg_C  # TODO: correct???
+    pressure = 1.010 * u.bar  # TODO: correct???
+    # relative_humidity = ?
+    # obswl = ?
+    altaz_frame = AltAz(obstime=obstime, location=location,
+                        temperature=temperature, pressure=pressure)
+
+    altaz = SkyCoord('143.2970d 2.6223d', frame=altaz_frame)
+    radec_actual = altaz.transform_to('icrs')
+    radec_expected = SkyCoord('19h24m55.01s -40d56m28.9s', frame='icrs')
+    distance = radec_actual.separation(radec_expected).to('arcsec')
+    # TODO: why is this difference so large?
+    # It currently is: 557.2748864283525 arcsec
+    assert distance < 1e4 * u.arcsec
+
+
+ at pytest.mark.xfail
+def test_fk5_equinox_and_epoch_j2000_0_to_topocentric_observed():
+    """
+    http://phn.github.io/pytpm/conversions.html#fk5-equinox-and-epoch-j2000-0-to-topocentric-observed
+    """
+    # Observatory position for `kpno` from here:
+    # http://idlastro.gsfc.nasa.gov/ftp/pro/astro/observatory.pro
+    location = EarthLocation(lon=Angle('-111.598333d'),
+                             lat=Angle('31.956389d'),
+                             height=2093.093 * u.m)  # TODO: height correct?
+
+    obstime = Time('2010-01-01 12:00:00', scale='utc')
+    # relative_humidity = ?
+    # obswl = ?
+    altaz_frame = AltAz(obstime=obstime, location=location,
+                        temperature=0 * u.deg_C, pressure=0.781 * u.bar)
+
+    radec = SkyCoord('12h22m54.899s 15d49m20.57s', frame='fk5')
+
+    altaz_actual = radec.transform_to(altaz_frame)
+
+    altaz_expected = SkyCoord('264d55m06s 37d54m41s', frame='altaz')
+    # altaz_expected = SkyCoord('343.586827647d 15.7683070508d', frame='altaz')
+    # altaz_expected = SkyCoord('133.498195532d 22.0162383595d', frame='altaz')
+    distance = altaz_actual.separation(altaz_expected)
+    # print(altaz_actual)
+    # print(altaz_expected)
+    # print(distance)
+    """TODO: Current output is completely incorrect ... xfailing this test for now.
+
+    <SkyCoord (AltAz: obstime=2010-01-01 12:00:00.000, location=(-1994497.7199061865, -5037954.447348028, 3357437.2294832403) m, pressure=781.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron):00:00.000, location=(-1994497.7199061865, -5037954.447348028, 3357437.2294832403) m, pressure=781.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron): az=133.4869896371561 deg, alt=67.97857990957701 deg>
+    <SkyCoord (AltAz: obstime=None, location=None, pressure=0.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron): az=264.91833333333335 deg, alt=37.91138888888889 deg>
+    68d02m45.732s
+    """
+
+    assert distance < 1 * u.arcsec
diff --git a/astropy/coordinates/tests/test_angles.py b/astropy/coordinates/tests/test_angles.py
index e03bd72..23eede3 100644
--- a/astropy/coordinates/tests/test_angles.py
+++ b/astropy/coordinates/tests/test_angles.py
@@ -57,24 +57,37 @@ def test_create_angles():
     with pytest.raises(ValueError):
         a13 = Angle(12.34, unit="not a unit")
 
-    a14 = Angle("12h43m32") # no trailing 's', but unambiguous
+    a14 = Angle("03h36m29.7888000120") # no trailing 's', but unambiguous
 
     a15 = Angle("5h4m3s") # single digits, no decimal
 
     a16 = Angle("1 d")
     a17 = Angle("1 degree")
+
     assert a16.degree == 1
     assert a17.degree == 1
 
+    a18 = Angle("54 07.4472", unit=u.degree)
+    a19 = Angle("54:07.4472", unit=u.degree)
+    a20 = Angle("54d07.4472m", unit=u.degree)
+    a21 = Angle("3h36m", unit=u.hour)
+    a22 = Angle("3.6h", unit=u.hour)
+    a23 = Angle("- 3h", unit=u.hour)
+    a24 = Angle("+ 3h", unit=u.hour)
+
     #ensure the above angles that should match do
-    assert a1 == a2 == a3 == a4 == a5 == a6 == a7
+    assert a1 == a2 == a3 == a4 == a5 == a6 == a7 == a8 == a18 == a19 == a20
     assert_allclose(a1.radian, a2.radian)
     assert_allclose(a2.degree, a3.degree)
     assert_allclose(a3.radian, a4.radian)
     assert_allclose(a4.radian, a5.radian)
     assert_allclose(a5.radian, a6.radian)
     assert_allclose(a6.radian, a7.radian)
-    #assert a10 == a11 == a12
+
+    assert_allclose(a10.degree, a11.degree)
+    assert a11 == a12 == a14
+    assert a21 == a22
+    assert a23 == -a24
 
     # check for illegal ranges / values
     with pytest.raises(IllegalSecondError):
@@ -815,3 +828,22 @@ def test_angle_axis():
 
     assert an2 - 89*u.deg < 1e-10*u.deg
     assert_allclose(ax2, [-2**-0.5, -2**-0.5, 0])
+
+def test_array_angle_tostring():
+    aobj = Angle([1, 2], u.deg)
+    assert aobj.to_string().dtype.kind == 'U'
+    assert np.all(aobj.to_string() == ['1d00m00s', '2d00m00s'])
+
+def test_wrap_at_without_new():
+    """
+    Regression test for subtle bugs from situations where an Angle is
+    created via numpy channels that don't do the standard __new__ but instead
+    depend on array_finalize to set state.  Longitude is used because the
+    bug was in its _wrap_angle not getting initialized correctly
+    """
+    l1 = Longitude([1]*u.deg)
+    l2 = Longitude([2]*u.deg)
+
+    l = np.concatenate([l1, l2])
+    assert l._wrap_angle is not None
+
diff --git a/astropy/coordinates/tests/test_api_ape5.py b/astropy/coordinates/tests/test_api_ape5.py
index 65e9577..78c501c 100644
--- a/astropy/coordinates/tests/test_api_ape5.py
+++ b/astropy/coordinates/tests/test_api_ape5.py
@@ -251,7 +251,7 @@ def test_transform_api():
     fk5_J2001_frame = FK5(equinox=J2001)
 
     # if they do not have data, the string instead is the frame specification
-    assert repr(fk5_J2001_frame) == "<FK5 Frame: equinox=J2001.000>"
+    assert repr(fk5_J2001_frame) == "<FK5 Frame (equinox=J2001.000)>"
 
     #  Note that, although a frame object is immutable and can't have data added, it
     #  can be used to create a new object that does have data by giving the
diff --git a/astropy/coordinates/tests/test_arrays.py b/astropy/coordinates/tests/test_arrays.py
index cbcf9fb..8c4caa9 100644
--- a/astropy/coordinates/tests/test_arrays.py
+++ b/astropy/coordinates/tests/test_arrays.py
@@ -6,7 +6,6 @@
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-from ...extern import six
 from ...tests.helper import pytest
 
 import numpy as np
@@ -43,7 +42,7 @@ def test_angle_arrays():
     npt.assert_almost_equal(a6.value, 945.0)
     assert a6.unit is u.degree
 
-    with pytest.raises((TypeError, ValueError)):  # ValueError for numpy 1.5.x
+    with pytest.raises(TypeError):
         # Arrays where the elements are Angle objects are not supported -- it's
         # really tricky to do correctly, if at all, due to the possibility of
         # nesting.
diff --git a/astropy/coordinates/tests/test_earth.py b/astropy/coordinates/tests/test_earth.py
index f617fa4..19523e0 100644
--- a/astropy/coordinates/tests/test_earth.py
+++ b/astropy/coordinates/tests/test_earth.py
@@ -231,7 +231,7 @@ class TestInput():
         with pytest.raises(ValueError):
             self.location.to_geodetic('foo')
 
-    @pytest.mark.parametrize('ellipsoid', ELLIPSOIDS.keys())
+    @pytest.mark.parametrize('ellipsoid', ELLIPSOIDS)
     def test_ellipsoid(self, ellipsoid):
         """Test that different ellipsoids are understood, and differ"""
         # check that heights differ for different ellipsoids
diff --git a/astropy/coordinates/tests/test_frames.py b/astropy/coordinates/tests/test_frames.py
index 3d26c8a..d0bb79f 100644
--- a/astropy/coordinates/tests/test_frames.py
+++ b/astropy/coordinates/tests/test_frames.py
@@ -150,7 +150,7 @@ def test_frame_repr():
     assert repr(i) == '<ICRS Frame>'
 
     f5 = FK5()
-    assert repr(f5).startswith('<FK5 Frame: equinox=')
+    assert repr(f5).startswith('<FK5 Frame (equinox=')
 
     i2 = ICRS(ra=1*u.deg, dec=2*u.deg)
     i3 = ICRS(ra=1*u.deg, dec=2*u.deg, distance=3*u.kpc)
@@ -323,12 +323,13 @@ def test_sep():
     assert_allclose(sep3d.to(u.kpc).value, np.array([1, 1]))
 
 
-def test_time_inputs():
+def test_time_inputs(recwarn):
     """
     Test validation and conversion of inputs for equinox and obstime attributes.
     """
     from ...time import Time
     from ..builtin_frames import FK4
+    from ...utils.exceptions import AstropyWarning
 
     c = FK4(1 * u.deg, 2 * u.deg, equinox='J2001.5', obstime='2000-01-01 12:00:00')
     assert c.equinox == Time('J2001.5')
@@ -342,9 +343,10 @@ def test_time_inputs():
         c = FK4(1 * u.deg, 2 * u.deg, obstime='hello')
     assert 'Invalid time input' in str(err)
 
-    with pytest.raises(ValueError) as err:
-        c = FK4(1 * u.deg, 2 * u.deg, obstime=['J2000', 'J2001'])
-    assert "must be a single (scalar) value" in str(err)
+    #should yield a warning about vector times not always working
+    c = FK4(1 * u.deg, 2 * u.deg, obstime=['J2000', 'J2001'])
+    w = recwarn.pop(AstropyWarning)
+    assert "is not a single (scalar) value" in str(w.message)
 
 
 def test_is_frame_attr_default():
@@ -495,3 +497,115 @@ def test_len0_data():
     i = ICRS([]*u.deg, []*u.deg)
     assert i.has_data
     repr(i)
+
+def test_quantity_attributes():
+    from ..builtin_frames import GCRS
+
+    #make sure we can create a GCRS frame with valid inputs
+    GCRS(obstime='J2002', obsgeoloc=[1, 2, 3]*u.km, obsgeovel=[4, 5, 6]*u.km/u.s)
+
+    #make sure it fails for invalid lovs or vels
+    with pytest.raises(TypeError):
+        GCRS(obsgeoloc=[1, 2, 3])  #no unit
+    with pytest.raises(u.UnitsError):
+        GCRS(obsgeoloc=[1, 2, 3]*u.km/u.s)  #incorrect unit
+    with pytest.raises(ValueError):
+        GCRS(obsgeoloc=[1, 3]*u.km)  #incorrect shape
+
+def test_eloc_attributes():
+    from .. import AltAz, ITRS, GCRS, EarthLocation
+
+    el = EarthLocation(lon=12.3*u.deg, lat=45.6*u.deg, height=1*u.km)
+    it = ITRS(representation.SphericalRepresentation(lon=12.3*u.deg, lat=45.6*u.deg, distance=1*u.km))
+    gc = GCRS(ra=12.3*u.deg, dec=45.6*u.deg, distance=6375*u.km)
+
+    el1 = AltAz(location=el).location
+    assert isinstance(el1, EarthLocation)
+    assert el1.latitude == el.latitude
+    assert el1.longitude == el.longitude
+    assert el1.height == el.height
+
+    el2 = AltAz(location=it).location
+    assert isinstance(el2, EarthLocation)
+    assert el2.latitude != it.spherical.lat
+    assert el2.longitude != it.spherical.lon
+    assert el2.height < -6000*u.km
+
+    el3 = AltAz(location=gc).location  #this one implicitly does transform_to
+    assert isinstance(el3, EarthLocation)
+    assert el3.latitude != gc.dec
+    assert el3.longitude != gc.ra
+    assert np.abs(el3.height) < 500*u.km
+
+
+def test_equivalent_frames():
+    from .. import SkyCoord
+    from ..builtin_frames import ICRS, FK4, FK5, AltAz
+
+    i = ICRS()
+    i2 = ICRS(1*u.deg, 2*u.deg)
+    assert i.is_equivalent_frame(i)
+    assert i.is_equivalent_frame(i2)
+    with pytest.raises(TypeError):
+        assert i.is_equivalent_frame(10)
+    with pytest.raises(TypeError):
+        assert i2.is_equivalent_frame(SkyCoord(i2))
+
+    f1 = FK5()
+    f2 = FK5(1*u.deg, 2*u.deg, equinox='J2000')
+    f3 = FK5(equinox='J2010')
+    f4 = FK4(equinox='J2010')
+
+    assert f1.is_equivalent_frame(f1)
+    assert not i.is_equivalent_frame(f1)
+    assert f1.is_equivalent_frame(f2)
+    assert not f1.is_equivalent_frame(f3)
+    assert not f3.is_equivalent_frame(f4)
+
+    aa1 = AltAz()
+    aa2 = AltAz(obstime='J2010')
+
+    assert aa2.is_equivalent_frame(aa2)
+    assert not aa1.is_equivalent_frame(i)
+    assert not aa1.is_equivalent_frame(aa2)
+
+
+def test_representation_subclass():
+
+    # Regression test for #3354
+
+    from ..builtin_frames import FK5
+
+    # Normally when instantiating a frame without a distance the frame will try
+    # and use UnitSphericalRepresentation internally instead of
+    # SphericalRepresentation.
+    frame = FK5(representation=representation.SphericalRepresentation, ra=32 * u.deg, dec=20 * u.deg)
+    assert type(frame._data) == representation.UnitSphericalRepresentation
+    assert frame.representation == representation.SphericalRepresentation
+
+    # If using a SphericalRepresentation class this used to not work, so we
+    # test here that this is now fixed.
+    class NewSphericalRepresentation(representation.SphericalRepresentation):
+        attr_classes = representation.SphericalRepresentation.attr_classes
+
+    frame = FK5(representation=NewSphericalRepresentation, lon=32 * u.deg, lat=20 * u.deg)
+    assert type(frame._data) == representation.UnitSphericalRepresentation
+    assert frame.representation == NewSphericalRepresentation
+
+    # A similar issue then happened in __repr__ with subclasses of
+    # SphericalRepresentation.
+    assert repr(frame) == "<FK5 Coordinate (equinox=J2000.000): lon=32.0 deg, lat=20.0 deg>"
+
+    # A more subtle issue is when specifying a custom
+    # UnitSphericalRepresentation subclass for the data and
+    # SphericalRepresentation or a subclass for the representation.
+
+    class NewUnitSphericalRepresentation(representation.UnitSphericalRepresentation):
+        attr_classes = representation.UnitSphericalRepresentation.attr_classes
+        def __repr__(self):
+            return "<NewUnitSphericalRepresentation: spam spam spam>"
+
+    frame = FK5(NewUnitSphericalRepresentation(lon=32 * u.deg, lat=20 * u.deg),
+                representation=NewSphericalRepresentation)
+
+    assert repr(frame) == "<FK5 Coordinate (equinox=J2000.000):  spam spam spam>"
diff --git a/astropy/coordinates/tests/test_funcs.py b/astropy/coordinates/tests/test_funcs.py
new file mode 100644
index 0000000..c2f5cb5
--- /dev/null
+++ b/astropy/coordinates/tests/test_funcs.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Tests for miscellaneous functionality in the `funcs` module
+"""
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+from ...tests.helper import pytest
+
+from ... import units as u
+from ...time import Time
+
+
+def test_sun():
+    """
+    Test that `get_sun` works and it behaves roughly as it should (in GCRS)
+    """
+    from ..funcs import get_sun
+
+    northern_summer_solstice = Time('2010-6-21')
+    northern_winter_solstice = Time('2010-12-21')
+    equinox_1 = Time('2010-3-21')
+    equinox_2 = Time('2010-9-21')
+
+    gcrs1 = get_sun(equinox_1)
+    assert np.abs(gcrs1.dec.deg) < 1
+
+    gcrs2 = get_sun(Time([northern_summer_solstice, equinox_2, northern_winter_solstice]))
+    assert np.all(np.abs(gcrs2.dec - [23.5, 0, -23.5]*u.deg) < 1*u.deg)
+
+def test_concatenate():
+    from .. import FK5, SkyCoord
+    from ..funcs import concatenate
+
+    fk5 = FK5(1*u.deg, 2*u.deg)
+    sc = SkyCoord(3*u.deg, 4*u.deg, frame='fk5')
+
+    res = concatenate([fk5, sc])
+    np.testing.assert_allclose(res.ra, [1, 3]*u.deg)
+    np.testing.assert_allclose(res.dec, [2, 4]*u.deg)
+
+    with pytest.raises(TypeError):
+        concatenate(fk5)
+
+    with pytest.raises(TypeError):
+        concatenate(1*u.deg)
diff --git a/astropy/coordinates/tests/test_iau_fullstack.py b/astropy/coordinates/tests/test_iau_fullstack.py
new file mode 100644
index 0000000..3d7a80d
--- /dev/null
+++ b/astropy/coordinates/tests/test_iau_fullstack.py
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+from numpy import testing as npt
+
+from ... import units as u
+from ...time import Time
+from ..builtin_frames import ICRS, AltAz
+from .. import EarthLocation
+from .. import SkyCoord
+from ...tests.helper import pytest
+from ... import _erfa as erfa
+from ...utils import iers
+from .utils import randomly_sample_sphere
+
+
+# These fixtures are used in test_iau_fullstack
+ at pytest.fixture(scope="module")
+def fullstack_icrs():
+    ra, dec, _ = randomly_sample_sphere(1000)
+    return ICRS(ra=ra, dec=dec)
+
+ at pytest.fixture(scope="module")
+def fullstack_fiducial_altaz(fullstack_icrs):
+    altazframe = AltAz(location=EarthLocation(lat=0*u.deg, lon=0*u.deg, height=0*u.m),
+                       obstime=Time('J2000'))
+    return fullstack_icrs.transform_to(altazframe)
+
+ at pytest.fixture(scope="module", params=['J2000.1', 'J2010'])
+def fullstack_times(request):
+    return Time(request.param)
+
+ at pytest.fixture(scope="module", params=[(0, 0, 0), (23, 0, 0), (-70, 0, 0), (0, 100, 0), (23, 0, 3000)])
+def fullstack_locations(request):
+    return EarthLocation(lat=request.param[0]*u.deg, lon=request.param[0]*u.deg,
+                         height=request.param[0]*u.m)
+
+ at pytest.fixture(scope="module", params=[(0*u.bar, 0*u.deg_C, 0, 1*u.micron),
+                                        (1*u.bar, 0*u.deg_C, 0, 1*u.micron),
+                                        (1*u.bar, 10*u.deg_C, 0, 1*u.micron),
+                                        (1*u.bar, 0*u.deg_C, .5, 1*u.micron),
+                                        (1*u.bar, 0*u.deg_C, 0, 21*u.cm)])
+def fullstack_obsconditions(request):
+    return request.param
+
+
+def _erfa_check(ira, idec, astrom):
+    """
+    This function does the same thing the astropy layer is supposed to do, but
+    all in erfa
+    """
+    cra, cdec = erfa.atciq(ira, idec, 0, 0, 0, 0, astrom)
+    az, zen, ha, odec, ora = erfa.atioq(cra, cdec, astrom)
+    alt = np.pi/2-zen
+    cra2, cdec2 = erfa.atoiq('A', az, zen, astrom)
+    ira2, idec2 = erfa.aticq(cra2, cdec2, astrom)
+
+    dct = locals()
+    del dct['astrom']
+    return dct
+
+
+def test_iau_fullstack(fullstack_icrs,  fullstack_fiducial_altaz,
+                       fullstack_times, fullstack_locations,
+                       fullstack_obsconditions):
+    """
+    Test the full transform from ICRS <-> AltAz
+    """
+
+    # create the altaz frame
+    altazframe = AltAz(obstime=fullstack_times, location=fullstack_locations,
+                       pressure=fullstack_obsconditions[0],
+                       temperature=fullstack_obsconditions[1],
+                       relative_humidity=fullstack_obsconditions[2],
+                       obswl=fullstack_obsconditions[3])
+
+    aacoo = fullstack_icrs.transform_to(altazframe)
+
+    # compare aacoo to the fiducial AltAz - should always be different
+    assert np.all(np.abs(aacoo.alt - fullstack_fiducial_altaz.alt) > 50*u.milliarcsecond)
+    assert np.all(np.abs(aacoo.az - fullstack_fiducial_altaz.az) > 50*u.milliarcsecond)
+
+    # if the refraction correction is included, we *only* do the comparisons
+    # where altitude >5 degrees.  The SOFA guides imply that below 5 is where
+    # where accuracy gets more problematic, and testing reveals that alt<~0
+    # gives garbage round-tripping, and <10 can give ~1 arcsec uncertainty
+    if fullstack_obsconditions[0].value == 0:
+        # but if there is no refraction correction, check everything
+        msk = slice(None)
+        tol = 5*u.microarcsecond
+    else:
+        msk = aacoo.alt > 5*u.deg
+        # most of them aren't this bad, but some of those at low alt are offset
+        # this much.  For alt > 10, this is always better than 100 masec
+        tol = 750*u.milliarcsecond
+
+    # now make sure the full stack round-tripping works
+    icrs2 = aacoo.transform_to(ICRS)
+
+    adras = np.abs(fullstack_icrs.ra - icrs2.ra)[msk]
+    addecs = np.abs(fullstack_icrs.dec - icrs2.dec)[msk]
+    assert np.all(adras < tol), 'largest RA change is {0} mas, > {1}'.format(np.max(adras.arcsec*1000), tol)
+    assert np.all(addecs < tol), 'largest Dec change is {0} mas, > {1}'.format(np.max(addecs.arcsec*1000), tol)
+
+    # check that we're consistent with the ERFA alt/az result
+    xp, yp = u.Quantity(iers.IERS.open().pm_xy(fullstack_times.jd1, fullstack_times.jd2)).to(u.radian).value
+    lon = fullstack_locations.geodetic[0].to(u.radian).value
+    lat = fullstack_locations.geodetic[1].to(u.radian).value
+    height = fullstack_locations.geodetic[2].to(u.m).value
+    astrom, eo = erfa.apco13(fullstack_times.jd1, fullstack_times.jd2,
+                             fullstack_times.delta_ut1_utc,
+                             lon, lat, height,
+                             xp, yp,
+                             fullstack_obsconditions[0].to(u.hPa).value,
+                             fullstack_obsconditions[1].to(u.deg_C).value,
+                             fullstack_obsconditions[2],
+                             fullstack_obsconditions[3].to(u.micron).value)
+    erfadct = _erfa_check(fullstack_icrs.ra.rad, fullstack_icrs.dec.rad, astrom)
+    npt.assert_allclose(erfadct['alt'], aacoo.alt.radian, atol=1e-7)
+    npt.assert_allclose(erfadct['az'], aacoo.az.radian, atol=1e-7)
+
+
+def test_fiducial_roudtrip(fullstack_icrs, fullstack_fiducial_altaz):
+    """
+    Test the full transform from ICRS <-> AltAz
+    """
+    aacoo = fullstack_icrs.transform_to(fullstack_fiducial_altaz)
+
+    # make sure the round-tripping works
+    icrs2 = aacoo.transform_to(ICRS)
+    npt.assert_allclose(fullstack_icrs.ra.deg, icrs2.ra.deg)
+    npt.assert_allclose(fullstack_icrs.dec.deg, icrs2.dec.deg)
+
+
+def test_future_altaz(recwarn):
+    """
+    While this does test the full stack, it is mostly meant to check that a
+    warning is raised when attempting to get to AltAz in the future (beyond
+    IERS tables)
+    """
+    from ...utils.exceptions import AstropyWarning
+
+    location = EarthLocation(lat=0*u.deg, lon=0*u.deg)
+    t = Time('J2030')
+
+    SkyCoord(1*u.deg, 2*u.deg).transform_to(AltAz(location=location, obstime=t))
+    w1 = recwarn.pop(AstropyWarning)
+    w2 = recwarn.pop(AstropyWarning)
+    assert "Tried to get polar motions for times after IERS data is valid." in str(w1.message)
+    assert "(some) times are outside of range covered by IERS table." in str(w2.message)
diff --git a/astropy/coordinates/tests/test_matching.py b/astropy/coordinates/tests/test_matching.py
index eef51d0..8ab786c 100644
--- a/astropy/coordinates/tests/test_matching.py
+++ b/astropy/coordinates/tests/test_matching.py
@@ -112,5 +112,29 @@ def test_matching_method():
     npt.assert_allclose(d2d1, d2d2)
     npt.assert_allclose(d3d1, d3d2)
 
-
     assert len(idx1) == len(d2d1) == len(d3d1) == 20
+
+
+ at pytest.mark.skipif(str('not HAS_SCIPY'))
+def test_search_around():
+    from .. import ICRS
+    from ..matching import search_around_sky, search_around_3d
+
+    coo1 = ICRS([4, 2.1]*u.degree, [0, 0]*u.degree, distance=[1, 5] * u.kpc)
+    coo2 = ICRS([1, 2, 3, 4]*u.degree, [0, 0, 0, 0]*u.degree, distance=[1, 1, 1, 5] * u.kpc)
+
+    idx1_1deg, idx2_1deg, d2d_1deg, d3d_1deg = search_around_sky(coo1, coo2, 1.01*u.deg)
+    idx1_0p05deg, idx2_0p05deg, d2d_0p05deg, d3d_0p05deg = search_around_sky(coo1, coo2, 0.05*u.deg)
+
+    assert list(zip(idx1_1deg, idx2_1deg)) == [(0, 2), (0, 3), (1, 1), (1, 2)]
+    assert d2d_1deg[0] == 1.0*u.deg
+    npt.assert_allclose(d2d_1deg, [1, 0, .1, .9]*u.deg)
+
+    assert list(zip(idx1_0p05deg, idx2_0p05deg)) == [(0, 3)]
+
+    idx1_1kpc, idx2_1kpc, d2d_1kpc, d3d_1kpc = search_around_3d(coo1, coo2, 1*u.kpc)
+    idx1_sm, idx2_sm, d2d_sm, d3d_sm = search_around_3d(coo1, coo2, 0.05*u.kpc)
+
+    assert list(zip(idx1_1kpc, idx2_1kpc)) == [(0, 0), (0, 1), (0, 2), (1, 3)]
+    assert list(zip(idx1_sm, idx2_sm)) == [(0, 1), (0, 2)]
+    npt.assert_allclose(d2d_sm, [2, 1]*u.deg)
diff --git a/astropy/coordinates/tests/test_pickle.py b/astropy/coordinates/tests/test_pickle.py
index 77b526d..d90131e 100644
--- a/astropy/coordinates/tests/test_pickle.py
+++ b/astropy/coordinates/tests/test_pickle.py
@@ -1,5 +1,15 @@
 from ...extern.six.moves import cPickle as pickle
 from ...coordinates import Longitude
+from ... import coordinates as coord
+from ...tests.helper import pytest, pickle_protocol, check_pickling_recovery
+import numpy as np
+
+#Can't test distances without scipy due to cosmology deps
+try:
+    import scipy
+    HAS_SCIPY = True
+except:
+    HAS_SCIPY = False
 
 def test_basic():
     lon1 = Longitude(1.23, "radian", wrap_angle='180d')
@@ -13,3 +23,49 @@ def test_pickle_longitude_wrap_angle():
 
     assert a.rad == b.rad
     assert a.wrap_angle == b.wrap_angle
+
+
+_names = [coord.Angle,
+          coord.Distance,
+          coord.DynamicMatrixTransform,
+          coord.ICRS,
+          coord.Latitude,
+          coord.Longitude,
+          coord.StaticMatrixTransform,
+          ]
+
+_xfail = [False,
+          not HAS_SCIPY,
+          True,
+          True,
+          False,
+          True,
+          False]
+
+_args = [[0.0],
+         [],
+         [lambda *args: np.identity(3), coord.ICRS, coord.ICRS],
+         [0, 0],
+         [0],
+         [0],
+         [np.identity(3), coord.ICRS, coord.ICRS],
+         ]
+
+_kwargs = [{'unit':'radian'},
+           {'z':0.23},
+           {},
+           {'unit':['radian', 'radian']},
+           {'unit':'radian'},
+           {'unit':'radian'},
+           {},
+           ]
+
+
+ at pytest.mark.parametrize("name,args,kwargs,xfail",
+                         zip(_names, _args, _kwargs, _xfail))
+def test_simple_object(pickle_protocol, name, args, kwargs, xfail):
+    # Tests easily instantiated objects
+    if xfail:
+        pytest.xfail()
+    original = name(*args, **kwargs)
+    check_pickling_recovery(original, pickle_protocol)
diff --git a/astropy/coordinates/tests/test_sky_coord.py b/astropy/coordinates/tests/test_sky_coord.py
index e87122f..1e7d865 100644
--- a/astropy/coordinates/tests/test_sky_coord.py
+++ b/astropy/coordinates/tests/test_sky_coord.py
@@ -16,12 +16,14 @@ import numpy as np
 from numpy import testing as npt
 
 from ... import units as u
-from ...tests.helper import pytest
+from ...tests.helper import pytest, catch_warnings
 from ..representation import REPRESENTATION_CLASSES
 from ...coordinates import (ICRS, FK4, FK5, Galactic, SkyCoord, Angle,
-                            SphericalRepresentation, CartesianRepresentation)
+                            SphericalRepresentation, CartesianRepresentation,
+                            UnitSphericalRepresentation)
 from ...coordinates import Latitude, Longitude
 from ...time import Time
+from ...utils.exceptions import AstropyDeprecationWarning
 
 RA = 1.0 * u.deg
 DEC = 2.0 * u.deg
@@ -31,6 +33,12 @@ J2001 = Time('J2001', scale='utc')
 
 allclose = functools.partial(np.allclose, rtol=0.0, atol=1e-8)
 
+try:
+    import scipy
+    HAS_SCIPY = True
+except ImportError:
+    HAS_SCIPY = False
+
 
 def test_transform_to():
     for frame in (FK5, FK5(equinox=Time('J1975.0')),
@@ -126,16 +134,65 @@ def test_coord_init_string():
 
     with pytest.raises(ValueError) as err:
         SkyCoord('1d 2d 3d')
-    assert "Cannot parse longitude and latitude" in str(err)
+    assert "Cannot parse first argument data" in str(err)
 
     sc1 = SkyCoord('8 00 00 +5 00 00.0', unit=(u.hour, u.deg), frame='icrs')
     assert isinstance(sc1, SkyCoord)
     assert allclose(sc1.ra, Angle(120 * u.deg))
     assert allclose(sc1.dec, Angle(5 * u.deg))
 
-    with pytest.raises(ValueError) as err:
-        SkyCoord('8 00 -5 00 00.0', unit=(u.hour, u.deg), frame='icrs')
-    assert 'coordinates have 5 values but spherical representation only accepts 3' in str(err)
+    sc11 = SkyCoord('8h00m00s+5d00m00.0s', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc11, SkyCoord)
+    assert allclose(sc1.ra, Angle(120 * u.deg))
+    assert allclose(sc1.dec, Angle(5 * u.deg))
+
+    sc2 = SkyCoord('8 00 -5 00 00.0', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc2, SkyCoord)
+    assert allclose(sc2.ra, Angle(120 * u.deg))
+    assert allclose(sc2.dec, Angle(-5 * u.deg))
+
+    sc3 = SkyCoord('8 00 -5 00.6', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc3, SkyCoord)
+    assert allclose(sc3.ra, Angle(120 * u.deg))
+    assert allclose(sc3.dec, Angle(-5.01 * u.deg))
+
+    sc4 = SkyCoord('J080000.00-050036.00', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc4, SkyCoord)
+    assert allclose(sc4.ra, Angle(120 * u.deg))
+    assert allclose(sc4.dec, Angle(-5.01 * u.deg))
+
+    sc41 = SkyCoord('J080000+050036', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc41, SkyCoord)
+    assert allclose(sc41.ra, Angle(120 * u.deg))
+    assert allclose(sc41.dec, Angle(+5.01 * u.deg))
+
+    sc5 = SkyCoord('8h00.6m -5d00.6m', unit=(u.hour, u.deg), frame='icrs')
+    assert isinstance(sc5, SkyCoord)
+    assert allclose(sc5.ra, Angle(120.15 * u.deg))
+    assert allclose(sc5.dec, Angle(-5.01 * u.deg))
+
+    sc6 = SkyCoord('8h00.6m -5d00.6m', unit=(u.hour, u.deg), frame='fk4')
+    assert isinstance(sc6, SkyCoord)
+    assert allclose(sc6.ra, Angle(120.15 * u.deg))
+    assert allclose(sc6.dec, Angle(-5.01 * u.deg))
+
+    sc61 = SkyCoord('8h00.6m-5d00.6m', unit=(u.hour, u.deg), frame='fk4')
+    assert isinstance(sc61, SkyCoord)
+    assert allclose(sc6.ra, Angle(120.15 * u.deg))
+    assert allclose(sc6.dec, Angle(-5.01 * u.deg))
+
+    sc61 = SkyCoord('8h00.6-5d00.6', unit=(u.hour, u.deg), frame='fk4')
+    assert isinstance(sc61, SkyCoord)
+    assert allclose(sc6.ra, Angle(120.15 * u.deg))
+    assert allclose(sc6.dec, Angle(-5.01 * u.deg))
+
+    sc7 = SkyCoord("J1874221.60+122421.6", unit=u.deg)
+    assert isinstance(sc7, SkyCoord)
+    assert allclose(sc7.ra, Angle(187.706 * u.deg))
+    assert allclose(sc7.dec, Angle(12.406 * u.deg))
+
+    with pytest.raises(ValueError):
+        SkyCoord('8 00 -5 00.6', unit=(u.deg, u.deg), frame='galactic')
 
 
 def test_coord_init_unit():
@@ -183,11 +240,11 @@ def test_coord_init_list():
 
     with pytest.raises(ValueError) as err:
         SkyCoord(['1d 2d 3d'])
-    assert "Cannot parse longitude and latitude" in str(err)
+    assert "Cannot parse first argument data" in str(err)
 
     with pytest.raises(ValueError) as err:
         SkyCoord([('1d', '2d', '3d')])
-    assert "Cannot parse longitude and latitude" in str(err)
+    assert "Cannot parse first argument data" in str(err)
 
     sc = SkyCoord([1 * u.deg, 1 * u.deg], [2 * u.deg, 2 * u.deg])
     assert allclose(sc.ra, Angle('1d'))
@@ -236,27 +293,44 @@ def test_coord_init_representation():
     assert allclose(sc_cart.z, 3.0)
 
 
+FRAME_DEPRECATION_WARNING = ("Passing a frame as a positional argument is now "
+                             "deprecated, use the frame= keyword argument "
+                             "instead.")
+
 def test_frame_init():
     """
     Different ways of providing the frame.
     """
+
     sc = SkyCoord(RA, DEC, frame='icrs')
     assert sc.frame.name == 'icrs'
 
     sc = SkyCoord(RA, DEC, frame=ICRS)
     assert sc.frame.name == 'icrs'
 
-    sc = SkyCoord(RA, DEC, 'icrs')
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        sc = SkyCoord(RA, DEC, 'icrs')
     assert sc.frame.name == 'icrs'
+    assert len(w) == 1
+    assert str(w[0].message) == FRAME_DEPRECATION_WARNING
 
-    sc = SkyCoord(RA, DEC, ICRS)
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        sc = SkyCoord(RA, DEC, ICRS)
     assert sc.frame.name == 'icrs'
+    assert len(w) == 1
+    assert str(w[0].message) == FRAME_DEPRECATION_WARNING
 
-    sc = SkyCoord('icrs', RA, DEC)
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        sc = SkyCoord('icrs', RA, DEC)
     assert sc.frame.name == 'icrs'
+    assert len(w) == 1
+    assert str(w[0].message) == FRAME_DEPRECATION_WARNING
 
-    sc = SkyCoord(ICRS, RA, DEC)
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        sc = SkyCoord(ICRS, RA, DEC)
     assert sc.frame.name == 'icrs'
+    assert len(w) == 1
+    assert str(w[0].message) == FRAME_DEPRECATION_WARNING
 
     sc = SkyCoord(sc)
     assert sc.frame.name == 'icrs'
@@ -278,7 +352,7 @@ def test_attr_inheritance():
     equinox should be inherited to the SkyCoord.  If there is a conflict
     then raise an exception.
     """
-    sc = SkyCoord('icrs', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='icrs', unit='deg', equinox='J1999', obstime='J2001')
     sc2 = SkyCoord(sc)
     assert sc2.equinox == sc.equinox
     assert sc2.obstime == sc.obstime
@@ -293,7 +367,7 @@ def test_attr_inheritance():
     assert allclose(sc2.dec, sc.dec)
     assert allclose(sc2.distance, sc.distance)
 
-    sc = SkyCoord('fk4', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='fk4', unit='deg', equinox='J1999', obstime='J2001')
     sc2 = SkyCoord(sc)
     assert sc2.equinox == sc.equinox
     assert sc2.obstime == sc.obstime
@@ -313,7 +387,7 @@ def test_attr_conflicts():
     """
     Check conflicts resolution between coordinate attributes and init kwargs.
     """
-    sc = SkyCoord('icrs', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='icrs', unit='deg', equinox='J1999', obstime='J2001')
 
     # OK if attrs both specified but with identical values
     SkyCoord(sc, equinox='J1999', obstime='J2001')
@@ -327,7 +401,7 @@ def test_attr_conflicts():
     assert "Coordinate attribute 'obstime'=" in str(err)
 
     # Same game but with fk4 which has equinox and obstime frame attrs
-    sc = SkyCoord('fk4', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='fk4', unit='deg', equinox='J1999', obstime='J2001')
 
     # OK if attrs both specified but with identical values
     SkyCoord(sc, equinox='J1999', obstime='J2001')
@@ -349,15 +423,15 @@ def test_frame_attr_getattr():
     from self.frame when that object has the relevant attribute, otherwise
     from self.
     """
-    sc = SkyCoord('icrs', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='icrs', unit='deg', equinox='J1999', obstime='J2001')
     assert sc.equinox == 'J1999'  # Just the raw value (not validated)
     assert sc.obstime == 'J2001'
 
-    sc = SkyCoord('fk4', 1, 2, unit='deg', equinox='J1999', obstime='J2001')
+    sc = SkyCoord(1, 2, frame='fk4', unit='deg', equinox='J1999', obstime='J2001')
     assert sc.equinox == Time('J1999')  # Coming from the self.frame object
     assert sc.obstime == Time('J2001')
 
-    sc = SkyCoord('fk4', 1, 2, unit='deg', equinox='J1999')
+    sc = SkyCoord(1, 2, frame='fk4', unit='deg', equinox='J1999')
     assert sc.equinox == Time('J1999')
     assert sc.obstime == Time('J1999')
 
@@ -379,8 +453,8 @@ def test_to_string():
 
 
 def test_seps():
-    sc1 = SkyCoord('icrs', 0 * u.deg, 1 * u.deg)
-    sc2 = SkyCoord('icrs', 0 * u.deg, 2 * u.deg)
+    sc1 = SkyCoord(0 * u.deg, 1 * u.deg, frame='icrs')
+    sc2 = SkyCoord(0 * u.deg, 2 * u.deg, frame='icrs')
 
     sep = sc1.separation(sc2)
 
@@ -389,8 +463,8 @@ def test_seps():
     with pytest.raises(ValueError):
         sc1.separation_3d(sc2)
 
-    sc3 = SkyCoord('icrs', 1 * u.deg, 1 * u.deg, distance=1 * u.kpc)
-    sc4 = SkyCoord('icrs', 1 * u.deg, 1 * u.deg, distance=2 * u.kpc)
+    sc3 = SkyCoord(1 * u.deg, 1 * u.deg, distance=1 * u.kpc, frame='icrs')
+    sc4 = SkyCoord(1 * u.deg, 1 * u.deg, distance=2 * u.kpc, frame='icrs')
     sep3d = sc3.separation_3d(sc4)
 
     assert sep3d == 1 * u.kpc
@@ -399,13 +473,13 @@ def test_seps():
 def test_repr():
     # Repr tests must use exact floating point vals because Python 2.6
     # outputs values like 0.1 as 0.1000000000001.  No workaround found.
-    sc1 = SkyCoord('icrs', 0 * u.deg, 1 * u.deg)
-    sc2 = SkyCoord('icrs', 1 * u.deg, 1 * u.deg, distance=1 * u.kpc)
+    sc1 = SkyCoord(0 * u.deg, 1 * u.deg, frame='icrs')
+    sc2 = SkyCoord(1 * u.deg, 1 * u.deg, frame='icrs', distance=1 * u.kpc)
 
     assert repr(sc1) == '<SkyCoord (ICRS): ra=0.0 deg, dec=1.0 deg>'
     assert repr(sc2) == '<SkyCoord (ICRS): ra=1.0 deg, dec=1.0 deg, distance=1.0 kpc>'
 
-    sc3 = SkyCoord('icrs', 0.25 * u.deg, [1, 2.5] * u.deg)
+    sc3 = SkyCoord(0.25 * u.deg, [1, 2.5] * u.deg, frame='icrs')
     assert repr(sc3) == ('<SkyCoord (ICRS): (ra, dec) in deg\n'
                          '    [(0.25, 1.0), (0.25, 2.5)]>')
 
@@ -417,9 +491,9 @@ def test_ops():
     """
     Tests miscellaneous operations like `len`
     """
-    sc = SkyCoord('icrs', 0 * u.deg, 1 * u.deg)
-    sc_arr = SkyCoord('icrs', 0 * u.deg, [1, 2] * u.deg)
-    sc_empty = SkyCoord('icrs', [] * u.deg, [] * u.deg)
+    sc = SkyCoord(0 * u.deg, 1 * u.deg, frame='icrs')
+    sc_arr = SkyCoord(0 * u.deg, [1, 2] * u.deg, frame='icrs')
+    sc_empty = SkyCoord([] * u.deg, [] * u.deg, frame='icrs')
 
     assert sc.isscalar
     assert not sc_arr.isscalar
@@ -706,11 +780,46 @@ def test_units_known_fail():
     with pytest.raises(u.UnitsError):
         SkyCoord(1, 2, 3, unit=u.deg, representation='spherical')
 
+
 def test_nodata_failure():
     with pytest.raises(ValueError):
         SkyCoord()
 
 
+ at pytest.mark.parametrize('mode, origin', [('wcs', 0),
+                                          ('all', 0),
+                                          ('all', 1)])
+def test_wcs_methods(mode, origin):
+    from ...wcs import WCS
+    from ...utils.data import get_pkg_data_contents
+    from ...wcs.utils import pixel_to_skycoord
+
+    header = get_pkg_data_contents('../../wcs/tests/maps/1904-66_TAN.hdr', encoding='binary')
+    wcs = WCS(header)
+
+    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')
+
+    xp, yp = ref.to_pixel(wcs, mode=mode, origin=origin)
+
+    # WCS is in FK5 so we need to transform back to ICRS
+    new = pixel_to_skycoord(xp, yp, wcs, mode=mode, origin=origin).transform_to('icrs')
+
+    npt.assert_allclose(new.ra.degree, ref.ra.degree)
+    npt.assert_allclose(new.dec.degree, ref.dec.degree)
+
+    #also try to round-trip with `from_pixel`
+    scnew = SkyCoord.from_pixel(xp, yp, wcs, mode=mode, origin=origin).transform_to('icrs')
+    npt.assert_allclose(scnew.ra.degree, ref.ra.degree)
+    npt.assert_allclose(scnew.dec.degree, ref.dec.degree)
+
+    #Also make sure the right type comes out
+    class SkyCoord2(SkyCoord):
+        pass
+    scnew2 = SkyCoord2.from_pixel(xp, yp, wcs, mode=mode, origin=origin)
+    assert scnew.__class__ is SkyCoord
+    assert scnew2.__class__ is SkyCoord2
+
+
 def test_frame_attr_transform_inherit():
     """
     Test that frame attributes get inherited as expected during transform.
@@ -767,3 +876,227 @@ def test_immutable():
 
     c1.foo = 42
     assert c1.foo == 42
+
+
+ at pytest.mark.skipif(str('not HAS_SCIPY'))
+def test_search_around():
+    """
+    Test the search_around_* methods
+
+    Here we don't actually test the values are right, just that the methods of
+    SkyCoord work.  The accuracy tests are in ``test_matching.py``
+    """
+    from ...utils import NumpyRNGContext
+
+    with NumpyRNGContext(987654321):
+        sc1 = SkyCoord(np.random.rand(20) * 360.*u.degree,
+                      (np.random.rand(20) * 180. - 90.)*u.degree)
+        sc2 = SkyCoord(np.random.rand(100) * 360. * u.degree,
+                      (np.random.rand(100) * 180. - 90.)*u.degree)
+
+        sc1ds = SkyCoord(ra=sc1.ra, dec=sc1.dec, distance=np.random.rand(20)*u.kpc)
+        sc2ds = SkyCoord(ra=sc2.ra, dec=sc2.dec, distance=np.random.rand(100)*u.kpc)
+
+    idx1_sky, idx2_sky, d2d_sky, d3d_sky = sc1.search_around_sky(sc2, 10*u.deg)
+    idx1_3d, idx2_3d, d2d_3d, d3d_3d = sc1ds.search_around_3d(sc2ds, 250*u.pc)
+
+
+def test_init_with_frame_instance_keyword():
+
+    # Frame instance
+    c1 = SkyCoord(3 * u.deg, 4 * u.deg,
+                  frame=FK5(equinox='J2010'))
+    assert c1.equinox == Time('J2010')
+
+    # Frame instance with data (data gets ignored)
+    c2 = SkyCoord(3 * u.deg, 4 * u.deg,
+                 frame=FK5(1. * u.deg, 2 * u.deg,
+                 equinox='J2010'))
+    assert c2.equinox == Time('J2010')
+    assert allclose(c2.ra.degree, 3)
+    assert allclose(c2.dec.degree, 4)
+
+    # SkyCoord instance
+    c3 = SkyCoord(3 * u.deg, 4 * u.deg, frame=c1)
+    assert c3.equinox == Time('J2010')
+
+    # Check duplicate arguments
+    with pytest.raises(ValueError) as exc:
+        c = SkyCoord(3 * u.deg, 4 * u.deg, frame=FK5(equinox='J2010'), equinox='J2001')
+    assert exc.value.args[0] == ("cannot specify frame attribute "
+                                 "'equinox' directly in SkyCoord "
+                                 "since a frame instance was passed in")
+
+
+def test_init_with_frame_instance_positional():
+
+    # Frame instance
+    with pytest.raises(ValueError) as exc:
+        c1 = SkyCoord(3 * u.deg, 4 * u.deg, FK5(equinox='J2010'))
+    assert exc.value.args[0] == ("FK5 instance cannot be passed as a "
+                                 "positional argument for the frame, "
+                                 "pass it using the frame= keyword "
+                                 "instead.")
+
+    # Positional frame instance with data raises exception
+    with pytest.raises(ValueError) as exc:
+        SkyCoord(3 * u.deg, 4 * u.deg, FK5(1. * u.deg, 2 * u.deg, equinox='J2010'))
+    assert exc.value.args[0] == ("FK5 instance cannot be passed as a "
+                                 "positional argument for the frame, "
+                                 "pass it using the frame= keyword "
+                                 "instead.")
+
+    # Positional SkyCoord instance (for frame) raises exception
+    with pytest.raises(ValueError) as exc:
+        SkyCoord(3 * u.deg, 4 * u.deg, SkyCoord(1. * u.deg, 2 * u.deg, equinox='J2010'))
+    assert exc.value.args[0] == ("SkyCoord instance cannot be passed as a "
+                                 "positional argument for the frame, "
+                                 "pass it using the frame= keyword "
+                                 "instead.")
+
+
+def test_guess_from_table():
+    from ...table import Table, Column
+    from ...utils import NumpyRNGContext
+
+    tab = Table()
+    with NumpyRNGContext(987654321):
+        tab.add_column(Column(data=np.random.rand(1000),unit='deg',name='RA[J2000]'))
+        tab.add_column(Column(data=np.random.rand(1000),unit='deg',name='DEC[J2000]'))
+
+    sc = SkyCoord.guess_from_table(tab)
+    npt.assert_array_equal(sc.ra.deg, tab['RA[J2000]'])
+    npt.assert_array_equal(sc.dec.deg, tab['DEC[J2000]'])
+
+    # try without units in the table
+    tab['RA[J2000]'].unit = None
+    tab['DEC[J2000]'].unit = None
+    # should fail if not given explicitly
+    with pytest.raises(u.UnitsError):
+        sc2 = SkyCoord.guess_from_table(tab)
+
+    # but should work if provided
+    sc2 = SkyCoord.guess_from_table(tab, unit=u.deg)
+    npt.assert_array_equal(sc.ra.deg, tab['RA[J2000]'])
+    npt.assert_array_equal(sc.dec.deg, tab['DEC[J2000]'])
+
+    # should fail if two options are available - ambiguity bad!
+    tab.add_column(Column(data=np.random.rand(1000), name='RA_J1900'))
+    with pytest.raises(ValueError) as excinfo:
+        sc3 = SkyCoord.guess_from_table(tab, unit=u.deg)
+    assert 'J1900' in excinfo.value.args[0] and 'J2000' in excinfo.value.args[0]
+
+    # should also fail if user specifies something already in the table, but
+    # should succeed even if the user has to give one of the components
+    tab.remove_column('RA_J1900')
+    with pytest.raises(ValueError):
+        sc3 = SkyCoord.guess_from_table(tab, ra=tab['RA[J2000]'], unit=u.deg)
+
+    oldra = tab['RA[J2000]']
+    tab.remove_column('RA[J2000]')
+    sc3 = SkyCoord.guess_from_table(tab, ra=oldra, unit=u.deg)
+    npt.assert_array_equal(sc3.ra.deg, oldra)
+    npt.assert_array_equal(sc3.dec.deg, tab['DEC[J2000]'])
+
+    # check a few non-ICRS/spherical systems
+    x, y, z = np.arange(3).reshape(3, 1) * u.pc
+    l, b = np.arange(2).reshape(2, 1) * u.deg
+
+    tabcart = Table([x, y, z], names=('x', 'y', 'z'))
+    tabgal = Table([b, l], names=('b', 'l'))
+
+    sc_cart = SkyCoord.guess_from_table(tabcart, representation='cartesian')
+    npt.assert_array_equal(sc_cart.x, x)
+    npt.assert_array_equal(sc_cart.y, y)
+    npt.assert_array_equal(sc_cart.z, z)
+
+    sc_gal = SkyCoord.guess_from_table(tabgal, frame='galactic')
+    npt.assert_array_equal(sc_gal.l, l)
+    npt.assert_array_equal(sc_gal.b, b)
+
+    #also try some column names that *end* with the attribute name
+    tabgal['b'].name = 'gal_b'
+    tabgal['l'].name = 'gal_l'
+    SkyCoord.guess_from_table(tabgal, frame='galactic')
+
+    tabgal['gal_b'].name = 'blob'
+    tabgal['gal_l'].name = 'central'
+    with pytest.raises(ValueError):
+        SkyCoord.guess_from_table(tabgal, frame='galactic')
+
+
+def test_skycoord_list_creation():
+    """
+    Test that SkyCoord can be created in a reasonable way with lists of SkyCoords
+    (regression for #2702)
+    """
+    sc = SkyCoord(ra=[1, 2, 3]*u.deg, dec=[4, 5, 6]*u.deg)
+    sc0 = sc[0]
+    sc2 = sc[2]
+    scnew = SkyCoord([sc0, sc2])
+    assert np.all(scnew.ra == [1, 3]*u.deg)
+    assert np.all(scnew.dec == [4, 6]*u.deg)
+
+    #also check ranges
+    sc01 = sc[:2]
+    scnew2 = SkyCoord([sc01, sc2])
+    assert np.all(scnew2.ra == sc.ra)
+    assert np.all(scnew2.dec == sc.dec)
+
+    #now try with a mix of skycoord, frame, and repr objects
+    frobj = ICRS(2*u.deg, 5*u.deg)
+    reprobj = UnitSphericalRepresentation(3*u.deg, 6*u.deg)
+    scnew3 = SkyCoord([sc0, frobj, reprobj])
+    assert np.all(scnew3.ra == sc.ra)
+    assert np.all(scnew3.dec == sc.dec)
+
+    #should *fail* if different frame attributes or types are passed in
+    scfk5_j2000 = SkyCoord(1*u.deg, 4*u.deg, frame='fk5')
+    with pytest.raises(ValueError):
+        SkyCoord([sc0, scfk5_j2000])
+    scfk5_j2010 = SkyCoord(1*u.deg, 4*u.deg, frame='fk5', equinox='J2010')
+    with pytest.raises(ValueError):
+        SkyCoord([scfk5_j2000, scfk5_j2010])
+
+    # but they should inherit if they're all consistent
+    scfk5_2_j2010 = SkyCoord(2*u.deg, 5*u.deg, frame='fk5', equinox='J2010')
+    scfk5_3_j2010 = SkyCoord(3*u.deg, 6*u.deg, frame='fk5', equinox='J2010')
+
+    scnew4 = SkyCoord([scfk5_j2010, scfk5_2_j2010, scfk5_3_j2010])
+    assert np.all(scnew4.ra == sc.ra)
+    assert np.all(scnew4.dec == sc.dec)
+    assert scnew4.equinox == Time('J2010')
+
+
+def test_nd_skycoord_to_string():
+    c = SkyCoord(np.ones((2, 2)), 1, unit=('deg', 'deg'))
+    ts = c.to_string()
+    assert np.all(ts.shape == c.shape)
+    assert np.all(ts == u'1 1')
+
+
+def test_equiv_skycoord():
+    sci1 = SkyCoord(1*u.deg, 2*u.deg, frame='icrs')
+    sci2 = SkyCoord(1*u.deg, 3*u.deg, frame='icrs')
+    assert sci1.is_equivalent_frame(sci1)
+    assert sci1.is_equivalent_frame(sci2)
+
+    assert sci1.is_equivalent_frame(ICRS())
+    assert not sci1.is_equivalent_frame(FK5())
+    with pytest.raises(TypeError):
+        sci1.is_equivalent_frame(10)
+
+    scf1 = SkyCoord(1*u.deg, 2*u.deg, frame='fk5')
+    scf2 = SkyCoord(1*u.deg, 2*u.deg, frame='fk5', equinox='J2005')
+    #obstime is *not* an FK5 attribute, but we still want scf1 and scf3 to come
+    #to come out different because they're part of SkyCoord
+    scf3 = SkyCoord(1*u.deg, 2*u.deg, frame='fk5', obstime='J2005')
+
+    assert scf1.is_equivalent_frame(scf1)
+    assert not scf1.is_equivalent_frame(sci1)
+    assert scf1.is_equivalent_frame(FK5())
+
+    assert not scf1.is_equivalent_frame(scf2)
+    assert scf2.is_equivalent_frame(FK5(equinox='J2005'))
+    assert not scf3.is_equivalent_frame(scf1)
+    assert not scf3.is_equivalent_frame(FK5(equinox='J2005'))
diff --git a/astropy/coordinates/tests/test_transformations.py b/astropy/coordinates/tests/test_transformations.py
index 045b293..ed84a80 100644
--- a/astropy/coordinates/tests/test_transformations.py
+++ b/astropy/coordinates/tests/test_transformations.py
@@ -4,19 +4,19 @@
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-from math import fabs
-
 import numpy as np
 from numpy import testing as npt
 
 from ... import units as u
 from ..distances import Distance
 from .. import transformations as t
-from ..builtin_frames import ICRS, FK5, FK4, FK4NoETerms, Galactic
+from ..builtin_frames import ICRS, FK5, FK4, FK4NoETerms, Galactic, \
+                             Galactocentric, CIRS, GCRS, AltAz, ITRS
 from .. import representation as r
 from ..baseframe import frame_transform_graph
 from ...tests.helper import pytest
-
+from .utils import randomly_sample_sphere
+from ...time import Time
 
 
 #Coordinates just for these tests.
@@ -140,8 +140,7 @@ def test_sphere_cart():
     """
     from numpy.testing.utils import assert_allclose
     from ...utils import NumpyRNGContext
-    from ..distances import spherical_to_cartesian, cartesian_to_spherical
-
+    from .. import spherical_to_cartesian, cartesian_to_spherical
 
     x, y, z = spherical_to_cartesian(1, 0, 0)
     npt.assert_allclose(x, 1)
@@ -194,9 +193,6 @@ def test_m31_coord_transforms(fromsys, tosys, fromcoo, tocoo):
     This tests a variety of coordinate conversions for the Chandra point-source
     catalog location of M31 from NED.
     """
-
-    from ...time import Time
-
     coo1 = fromsys(ra=fromcoo[0]*u.deg, dec=fromcoo[1]*u.deg, distance=m31_dist)
     coo2 = coo1.transform_to(tosys)
     if tosys is FK4:
@@ -222,8 +218,6 @@ def test_precession():
     """
     Ensures that FK4 and FK5 coordinates precess their equinoxes
     """
-    from ...time import Time
-
     j2000 = Time('J2000', scale='utc')
     b1950 = Time('B1950', scale='utc')
     j1975 = Time('J1975', scale='utc')
@@ -262,8 +256,6 @@ def test_obstime():
     Checks to make sure observation time is
     accounted for at least in FK4 <-> ICRS transformations
     """
-    from ...time import Time
-
     b1950 = Time('B1950', scale='utc')
     j1975 = Time('J1975', scale='utc')
 
@@ -295,3 +287,269 @@ def test_fk5_galactic():
     indirect = fk5.transform_to(FK4NoETerms).transform_to(Galactic)
 
     assert direct.separation(indirect).degree < 1.e-10
+
+
+def test_galactocentric():
+    # when z_sun=0, transformation should be very similar to Galactic
+    icrs_coord = ICRS(ra=np.linspace(0,360,10)*u.deg,
+                      dec=np.linspace(-90,90,10)*u.deg,
+                      distance=1.*u.kpc)
+
+    g_xyz = icrs_coord.transform_to(Galactic).cartesian.xyz
+    gc_xyz = icrs_coord.transform_to(Galactocentric(z_sun=0*u.kpc)).cartesian.xyz
+    diff = np.array(np.abs(g_xyz - gc_xyz))
+
+    assert np.allclose(diff[0], 8.3, atol=1E-5)
+    assert np.allclose(diff[1:], 0, atol=1E-5)
+
+    # generate some test coordinates
+    g = Galactic(l=[0,0,45,315]*u.deg, b=[-45,45,0,0]*u.deg,
+                 distance=[np.sqrt(2)]*4*u.kpc)
+    xyz = g.transform_to(Galactocentric(galcen_distance=1.*u.kpc, z_sun=0.*u.pc)).cartesian.xyz
+    true_xyz = np.array([[0,0,-1.],[0,0,1],[0,1,0],[0,-1,0]]).T*u.kpc
+    assert np.allclose(xyz.to(u.kpc).value, true_xyz.to(u.kpc).value, atol=1E-5)
+
+    # check that ND arrays work
+
+    # from Galactocentric to Galactic
+    x = np.linspace(-10., 10., 100) * u.kpc
+    y = np.linspace(-10., 10., 100) * u.kpc
+    z = np.zeros_like(x)
+
+    g1 = Galactocentric(x=x, y=y, z=z)
+    g2 = Galactocentric(x=x.reshape(100,1,1), y=y.reshape(100,1,1), z=z.reshape(100,1,1))
+
+    g1t = g1.transform_to(Galactic)
+    g2t = g2.transform_to(Galactic)
+
+    np.testing.assert_almost_equal(g1t.cartesian.xyz.value, g2t.cartesian.xyz.value[:,:,0,0])
+
+    # from Galactic to Galactocentric
+    l = np.linspace(15, 30., 100) * u.deg
+    b = np.linspace(-10., 10., 100) * u.deg
+    d = np.ones_like(l.value) * u.kpc
+
+    g1 = Galactic(l=l, b=b, distance=d)
+    g2 = Galactic(l=l.reshape(100,1,1), b=b.reshape(100,1,1), distance=d.reshape(100,1,1))
+
+    g1t = g1.transform_to(Galactocentric)
+    g2t = g2.transform_to(Galactocentric)
+
+    np.testing.assert_almost_equal(g1t.cartesian.xyz.value, g2t.cartesian.xyz.value[:,:,0,0])
+
+def test_icrs_cirs():
+    """
+    Check a few cases of ICRS<->CIRS for consistency.
+
+    Also includes the CIRS<->CIRS transforms at different times, as those go
+    through ICRS
+    """
+    ra, dec, dist = randomly_sample_sphere(200)
+    inod = ICRS(ra=ra, dec=dec)
+    iwd = ICRS(ra=ra, dec=dec, distance=dist*u.pc)
+
+    cframe1 = CIRS()
+    cirsnod = inod.transform_to(cframe1)  #uses the default time
+    #first do a round-tripping test
+    inod2 = cirsnod.transform_to(ICRS)
+    npt.assert_allclose(inod.ra, inod2.ra)
+    npt.assert_allclose(inod.dec, inod2.dec)
+
+    #now check that a different time yields different answers
+    cframe2 = CIRS(obstime=Time('J2005', scale='utc'))
+    cirsnod2 = inod.transform_to(cframe2)
+    assert not np.allclose(cirsnod.ra, cirsnod2.ra, rtol=1e-8)
+    assert not np.allclose(cirsnod.dec, cirsnod2.dec, rtol=1e-8)
+
+    # parallax effects should be included, so with and w/o distance should be different
+    cirswd = iwd.transform_to(cframe1)
+    assert not np.allclose(cirswd.ra, cirsnod.ra, rtol=1e-8)
+    assert not np.allclose(cirswd.dec, cirsnod.dec, rtol=1e-8)
+    # and the distance should transform at least somehow
+    assert not np.allclose(cirswd.distance, iwd.distance, rtol=1e-8)
+
+    #now check that the cirs self-transform works as expected
+    cirsnod3 = cirsnod.transform_to(cframe1)  # should be a no-op
+    npt.assert_allclose(cirsnod.ra, cirsnod3.ra)
+    npt.assert_allclose(cirsnod.dec, cirsnod3.dec)
+
+    cirsnod4 = cirsnod.transform_to(cframe2)  # should be different
+    assert not np.allclose(cirsnod4.ra, cirsnod.ra, rtol=1e-8)
+    assert not np.allclose(cirsnod4.dec, cirsnod.dec, rtol=1e-8)
+
+    cirsnod5 = cirsnod4.transform_to(cframe1)  # should be back to the same
+    npt.assert_allclose(cirsnod.ra, cirsnod5.ra)
+    npt.assert_allclose(cirsnod.dec, cirsnod5.dec)
+
+
+def test_icrs_gcrs():
+    """
+    Check ICRS<->GCRS for consistency
+    """
+    ra, dec, dist = randomly_sample_sphere(200)
+    inod = ICRS(ra=ra, dec=dec)
+    iwd = ICRS(ra=ra, dec=dec, distance=dist*u.pc)
+
+    gframe1 = GCRS()
+    gcrsnod = inod.transform_to(gframe1)  #uses the default time
+    #first do a round-tripping test
+    inod2 = gcrsnod.transform_to(ICRS)
+    npt.assert_allclose(inod.ra, inod2.ra)
+    npt.assert_allclose(inod.dec, inod2.dec)
+
+    #now check that a different time yields different answers
+    gframe2 = GCRS(obstime=Time('J2005', scale='utc'))
+    gcrsnod2 = inod.transform_to(gframe2)
+    assert not np.allclose(gcrsnod.ra, gcrsnod2.ra, rtol=1e-8, atol=1e-10)
+    assert not np.allclose(gcrsnod.dec, gcrsnod2.dec, rtol=1e-8, atol=1e-10)
+
+    # parallax effects should be included, so with and w/o distance should be different
+    gcrswd = iwd.transform_to(gframe1)
+    assert not np.allclose(gcrswd.ra, gcrsnod.ra, rtol=1e-8, atol=1e-10)
+    assert not np.allclose(gcrswd.dec, gcrsnod.dec, rtol=1e-8, atol=1e-10)
+    # and the distance should transform at least somehow
+    assert not np.allclose(gcrswd.distance, iwd.distance, rtol=1e-8, atol=1e-10)
+
+    #now check that the cirs self-transform works as expected
+    gcrsnod3 = gcrsnod.transform_to(gframe1)  # should be a no-op
+    npt.assert_allclose(gcrsnod.ra, gcrsnod3.ra)
+    npt.assert_allclose(gcrsnod.dec, gcrsnod3.dec)
+
+    gcrsnod4 = gcrsnod.transform_to(gframe2)  # should be different
+    assert not np.allclose(gcrsnod4.ra, gcrsnod.ra, rtol=1e-8, atol=1e-10)
+    assert not np.allclose(gcrsnod4.dec, gcrsnod.dec, rtol=1e-8, atol=1e-10)
+
+    gcrsnod5 = gcrsnod4.transform_to(gframe1)  # should be back to the same
+    npt.assert_allclose(gcrsnod.ra, gcrsnod5.ra, rtol=1e-8, atol=1e-10)
+    npt.assert_allclose(gcrsnod.dec, gcrsnod5.dec, rtol=1e-8, atol=1e-10)
+
+    #also make sure that a GCRS with a different geoloc/geovel gets a different answer
+    # roughly a moon-like frame
+    gframe3 = GCRS(obsgeoloc=[385000., 0, 0]*u.km, obsgeovel=[1, 0, 0]*u.km/u.s)
+    gcrsnod6 = inod.transform_to(gframe3)  # should be different
+    assert not np.allclose(gcrsnod.ra, gcrsnod6.ra, rtol=1e-8, atol=1e-10)
+    assert not np.allclose(gcrsnod.dec, gcrsnod6.dec, rtol=1e-8, atol=1e-10)
+    inodviag3 = gcrsnod6.transform_to(ICRS)  # and now back to the original
+    npt.assert_allclose(inod.ra, inodviag3.ra)
+    npt.assert_allclose(inod.dec, inodviag3.dec)
+
+
+def test_cirs_to_altaz():
+    """
+    Check the basic CIRS<->AltAz transforms.  More thorough checks implicitly
+    happen in `test_iau_fullstack`
+    """
+    from .. import EarthLocation
+
+    ra, dec, dist = randomly_sample_sphere(200)
+    cirs = CIRS(ra=ra, dec=dec, obstime='J2000')
+    crepr = r.SphericalRepresentation(lon=ra, lat=dec, distance=dist)
+    cirscart = CIRS(crepr, obstime=cirs.obstime, representation=r.CartesianRepresentation)
+
+    loc = EarthLocation(lat=0*u.deg, lon=0*u.deg, height=0*u.m)
+    altazframe = AltAz(location=loc, obstime=Time('J2005'))
+
+    cirs2 = cirs.transform_to(altazframe).transform_to(cirs)
+    cirs3 = cirscart.transform_to(altazframe).transform_to(cirs)
+
+    #check round-tripping
+    npt.assert_allclose(cirs.ra.deg, cirs2.ra.deg)
+    npt.assert_allclose(cirs.dec.deg, cirs2.dec.deg)
+    npt.assert_allclose(cirs.ra.deg, cirs3.ra.deg)
+    npt.assert_allclose(cirs.dec.deg, cirs3.dec.deg)
+
+
+def test_gcrs_itrs():
+    """
+    Check basic GCRS<->ITRS transforms for round-tripping.
+    """
+    ra, dec, _ = randomly_sample_sphere(200)
+    gcrs = GCRS(ra=ra, dec=dec, obstime='J2000')
+    gcrs6 = GCRS(ra=ra, dec=dec, obstime='J2006')
+
+    gcrs2 = gcrs.transform_to(ITRS).transform_to(gcrs)
+    gcrs6_2 = gcrs6.transform_to(ITRS).transform_to(gcrs)
+
+    npt.assert_allclose(gcrs.ra.deg, gcrs2.ra.deg)
+    npt.assert_allclose(gcrs.dec.deg, gcrs2.dec.deg)
+    assert not np.allclose(gcrs.ra.deg, gcrs6_2.ra.deg)
+    assert not np.allclose(gcrs.dec.deg, gcrs6_2.dec.deg)
+
+    #also try with the cartesian representation
+    gcrsc = gcrs.realize_frame(gcrs.data)
+    gcrsc.representation = r.CartesianRepresentation
+    gcrsc2 = gcrsc.transform_to(ITRS).transform_to(gcrsc)
+    npt.assert_allclose(gcrsc.spherical.lon.deg, gcrsc2.ra.deg)
+    npt.assert_allclose(gcrsc.spherical.lat.deg, gcrsc2.dec.deg)
+
+
+def test_cirs_itrs():
+    """
+    Check basic CIRS<->ITRS transforms for round-tripping.
+    """
+    ra, dec, _ = randomly_sample_sphere(200)
+    cirs = CIRS(ra=ra, dec=dec, obstime='J2000')
+    cirs6 = CIRS(ra=ra, dec=dec, obstime='J2006')
+
+    cirs2 = cirs.transform_to(ITRS).transform_to(cirs)
+    cirs6_2 = cirs6.transform_to(ITRS).transform_to(cirs) # different obstime
+
+    #just check round-tripping
+    npt.assert_allclose(cirs.ra.deg, cirs2.ra.deg)
+    npt.assert_allclose(cirs.dec.deg, cirs2.dec.deg)
+    assert not np.allclose(cirs.ra.deg, cirs6_2.ra.deg)
+    assert not np.allclose(cirs.dec.deg, cirs6_2.dec.deg)
+
+
+def test_gcrs_cirs():
+    """
+    Check GCRS<->CIRS transforms for round-tripping.  More complicated than the
+    above two because it's multi-hop
+    """
+    ra, dec, _ = randomly_sample_sphere(200)
+    gcrs = GCRS(ra=ra, dec=dec, obstime='J2000')
+    gcrs6 = GCRS(ra=ra, dec=dec, obstime='J2006')
+
+    gcrs2 = gcrs.transform_to(CIRS).transform_to(gcrs)
+    gcrs6_2 = gcrs6.transform_to(CIRS).transform_to(gcrs)
+
+    npt.assert_allclose(gcrs.ra.deg, gcrs2.ra.deg)
+    npt.assert_allclose(gcrs.dec.deg, gcrs2.dec.deg)
+    assert not np.allclose(gcrs.ra.deg, gcrs6_2.ra.deg)
+    assert not np.allclose(gcrs.dec.deg, gcrs6_2.dec.deg)
+
+    #now try explicit intermediate pathways and ensure they're all consistent
+    gcrs3 = gcrs.transform_to(ITRS).transform_to(CIRS).transform_to(ITRS).transform_to(gcrs)
+    npt.assert_allclose(gcrs.ra.deg, gcrs3.ra.deg)
+    npt.assert_allclose(gcrs.dec.deg, gcrs3.dec.deg)
+
+    gcrs4 = gcrs.transform_to(ICRS).transform_to(CIRS).transform_to(ICRS).transform_to(gcrs)
+    npt.assert_allclose(gcrs.ra.deg, gcrs4.ra.deg)
+    npt.assert_allclose(gcrs.dec.deg, gcrs4.dec.deg)
+
+
+def test_gcrs_altaz():
+    """
+    Check GCRS<->AltAz transforms for round-tripping.  Has multiple paths
+    """
+    from .. import EarthLocation
+
+    ra, dec, _ = randomly_sample_sphere(1)
+    gcrs = GCRS(ra=ra[0], dec=dec[0], obstime='J2000')
+
+    # check array times sure N-d arrays work
+    times = Time(np.linspace(2456293.25, 2456657.25, 51) * u.day,
+                 format='jd', scale='utc')
+
+    loc = EarthLocation(lon=10 * u.deg, lat=80. * u.deg)
+    aaframe = AltAz(obstime=times, location=loc)
+
+    aa1 = gcrs.transform_to(aaframe)
+    aa2 = gcrs.transform_to(ICRS).transform_to(CIRS).transform_to(aaframe)
+    aa3 = gcrs.transform_to(ITRS).transform_to(CIRS).transform_to(aaframe)
+
+    # make sure they're all consistent
+    npt.assert_allclose(aa1.alt.deg, aa2.alt.deg)
+    npt.assert_allclose(aa1.az.deg, aa2.az.deg)
+    npt.assert_allclose(aa1.alt.deg, aa3.alt.deg)
+    npt.assert_allclose(aa1.az.deg, aa3.az.deg)
diff --git a/astropy/coordinates/tests/utils.py b/astropy/coordinates/tests/utils.py
new file mode 100644
index 0000000..34890f1
--- /dev/null
+++ b/astropy/coordinates/tests/utils.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+from ... import units as u
+from ...utils import NumpyRNGContext
+
+
+def randomly_sample_sphere(ntosample, randomseed=12345):
+    """
+    Generates a set of spherical coordinates uniformly distributed over the
+    sphere in a way that gives the same answer for the same seed.  Also
+    generates a random distance vector on [0, 1] (no units)
+
+    This simply returns (lon, lat, r) instead of a representation to avoid
+    failures due to the representation module.
+    """
+    with NumpyRNGContext(randomseed):
+        lat = np.arcsin(np.random.rand(ntosample)*2-1)
+        lon = np.random.rand(ntosample)*np.pi*2
+        r = np.random.rand(ntosample)
+
+    return lon*u.rad, lat*u.rad, r
diff --git a/astropy/coordinates/transformations.py b/astropy/coordinates/transformations.py
index 9c8eca6..c6be0c2 100644
--- a/astropy/coordinates/transformations.py
+++ b/astropy/coordinates/transformations.py
@@ -302,7 +302,7 @@ class TransformGraph(object):
         This function always returns a `CompositeTransform`, because
         `CompositeTransform` is slightly more adaptable in the way it can be
         called than other transform classes. Specifically, it takes care of
-        inetermediate steps of transformations in a way that is consistent with
+        intermediate steps of transformations in a way that is consistent with
         1-hop transformations.
 
         """
@@ -504,7 +504,7 @@ class TransformGraph(object):
             The coordinate frame class to transform into.
         priority : number
             The priority if this transform when finding the shortest
-            coordinate tranform path - large numbers are lower priorities.
+            coordinate transform path - large numbers are lower priorities.
 
         Returns
         -------
@@ -541,7 +541,7 @@ class TransformGraph(object):
 
         """
         def deco(func):
-            # this doesn't do anything directly with the trasnform because
+            # this doesn't do anything directly with the transform because
             # ``register_graph=self`` stores it in the transform graph
             # automatically
             transcls(func, fromsys, tosys, priority=priority,
@@ -568,7 +568,7 @@ class CoordinateTransform(object):
         The coordinate frame class to transform into.
     priority : number
         The priority if this transform when finding the shortest
-        coordinate tranform path - large numbers are lower priorities.
+        coordinate transform path - large numbers are lower priorities.
     register_graph : `TransformGraph` or `None`
         A graph to register this transformation with on creation, or
         `None` to leave it unregistered.
@@ -671,7 +671,7 @@ class FunctionTransform(CoordinateTransform):
         The coordinate frame class to transform into.
     priority : number
         The priority if this transform when finding the shortest
-        coordinate tranform path - large numbers are lower priorities.
+        coordinate transform path - large numbers are lower priorities.
     register_graph : `TransformGraph` or `None`
         A graph to register this transformation with on creation, or
         `None` to leave it unregistered.
@@ -733,7 +733,7 @@ class StaticMatrixTransform(CoordinateTransform):
         The coordinate frame class to transform into.
     priority : number
         The priority if this transform when finding the shortest
-        coordinate tranform path - large numbers are lower priorities.
+        coordinate transform path - large numbers are lower priorities.
     register_graph : `TransformGraph` or `None`
         A graph to register this transformation with on creation, or
         `None` to leave it unregistered.
@@ -799,7 +799,7 @@ class DynamicMatrixTransform(CoordinateTransform):
         The coordinate frame class to transform into.
     priority : number
         The priority if this transform when finding the shortest
-        coordinate tranform path - large numbers are lower priorities.
+        coordinate transform path - large numbers are lower priorities.
     register_graph : `TransformGraph` or `None`
         A graph to register this transformation with on creation, or
         `None` to leave it unregistered.
@@ -860,7 +860,7 @@ class CompositeTransform(CoordinateTransform):
         The coordinate frame class to transform into.
     priority : number
         The priority if this transform when finding the shortest
-        coordinate tranform path - large numbers are lower priorities.
+        coordinate transform path - large numbers are lower priorities.
     register_graph : `TransformGraph` or `None`
         A graph to register this transformation with on creation, or
         `None` to leave it unregistered.
@@ -919,6 +919,6 @@ class CompositeTransform(CoordinateTransform):
             curr_toframe = t.tosys(**frattrs)
             curr_coord = t(curr_coord, curr_toframe)
 
-        # this is safe even in the case enere self.transforms is empty, because
+        # this is safe even in the case where self.transforms is empty, because
         # coordinate objects are immutible, so copying is not needed
         return curr_coord
diff --git a/astropy/cosmology/core.py b/astropy/cosmology/core.py
index 016723d..bd3f36a 100644
--- a/astropy/cosmology/core.py
+++ b/astropy/cosmology/core.py
@@ -11,8 +11,8 @@ from abc import ABCMeta, abstractmethod
 import numpy as np
 
 from .. import constants as const
-from ..utils.misc import isiterable, deprecated
 from .. import units as u
+from ..utils import isiterable
 from ..utils.state import ScienceState, ScienceStateAlias
 
 from . import parameters
@@ -25,9 +25,8 @@ from . import parameters
 # and Linder 2003, PRL 90, 91301
 
 __all__ = ["FLRW", "LambdaCDM", "FlatLambdaCDM", "wCDM", "FlatwCDM",
-           "Flatw0waCDM", "w0waCDM", "wpwaCDM", "w0wzCDM", "get_current",
-           "set_current", "WMAP5", "WMAP7", "WMAP9", "Planck13",
-           "default_cosmology"]
+           "Flatw0waCDM", "w0waCDM", "wpwaCDM", "w0wzCDM", "WMAP5", "WMAP7",
+           "WMAP9", "Planck13", "default_cosmology"]
 
 __doctest_requires__ = {'*': ['scipy.integrate']}
 
@@ -102,6 +101,10 @@ class FLRW(Cosmology):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Notes
     -----
     Class instances are static -- you can't change the values
@@ -109,13 +112,25 @@ class FLRW(Cosmology):
     read only.
     """
     def __init__(self, H0, Om0, Ode0, Tcmb0=2.725, Neff=3.04,
-                 m_nu=u.Quantity(0.0, u.eV), name=None):
+                 m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
         # all densities are in units of the critical density
         self._Om0 = float(Om0)
         if self._Om0 < 0.0:
             raise ValueError("Matter density can not be negative")
         self._Ode0 = float(Ode0)
+        if Ob0 is not None:
+            self._Ob0 = float(Ob0)
+            if self._Ob0 < 0.0:
+                raise ValueError("Baryonic density can not be negative")
+            if self._Ob0 > self._Om0:
+                raise ValueError("Baryonic density can not be larger than "
+                                 "total matter density")
+            self._Odm0 = self._Om0 - self._Ob0
+        else:
+            self._Ob0 = None
+            self._Odm0 = None
+
         self._Neff = float(Neff)
         if self._Neff < 0.0:
             raise ValueError("Effective number of neutrinos can "
@@ -193,13 +208,10 @@ class FLRW(Cosmology):
                 else:
                     self._massivenu = True
                     if len(m_nu) != self._nneutrinos:
-                        raise ValueError("Unexpected number of neutrino masses")
+                        errstr = "Unexpected number of neutrino masses"
+                        raise ValueError(errstr)
                     # Segregate out the massless ones
-                    try:
-                        # Numpy < 1.6 doesn't have count_nonzero
-                        self._nmasslessnu = np.count_nonzero(m_nu.value == 0)
-                    except AttributeError:
-                        self._nmasslessnu = len(np.nonzero(m_nu.value == 0)[0])
+                    self._nmasslessnu = len(np.nonzero(m_nu.value == 0)[0])
                     self._nmassivenu = self._nneutrinos - self._nmasslessnu
                     w = np.nonzero(m_nu.value > 0)[0]
                     self._massivenu_mass = m_nu[w]
@@ -249,9 +261,11 @@ class FLRW(Cosmology):
 
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, Ode0={3:.3g}, "\
-                 "Tcmb0={4:.4g}, Neff={5:.3g}, m_nu={6})"
+                 "Tcmb0={4:.4g}, Neff={5:.3g}, m_nu={6}, "\
+                 "Ob0={7:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0, self._Ode0,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
     # Set up a set of properties for H0, Om0, Ode0, Ok0, etc. for user access.
     # Note that we don't let these be set (so, obj.Om0 = value fails)
@@ -272,6 +286,16 @@ class FLRW(Cosmology):
         return self._Ode0
 
     @property
+    def Ob0(self):
+        """ Omega baryon; baryonic matter density/critical density at z=0"""
+        return self._Ob0
+
+    @property
+    def Odm0(self):
+        """ Omega dark matter; dark matter density/critical density at z=0"""
+        return self._Odm0
+
+    @property
     def Ok0(self):
         """ Omega curvature; the effective curvature density/critical density
         at z=0"""
@@ -347,13 +371,75 @@ class FLRW(Cosmology):
         """ Omega nu; the density/critical density of neutrinos at z=0"""
         return self._Onu0
 
+    def clone(self, **kwargs):
+        """ Returns a copy of this object, potentially with some changes.
+
+        Returns
+        -------
+        newcos : Subclass of FLRW
+        A new instance of this class with the specified changes.
+
+        Notes
+        -----
+        This assumes that the values of all constructor arguments
+        are available as properties, which is true of all the provided
+        subclasses but may not be true of user-provided ones.  You can't
+        change the type of class, so this can't be used to change between
+        flat and non-flat.  If no modifications are requested, then
+        a reference to this object is returned.
+
+        Examples
+        --------
+        To make a copy of the Planck13 cosmology with a different Omega_m
+        and a new name:
+
+        >>> from astropy.cosmology import Planck13
+        >>> newcos = Planck13.clone(name="Modified Planck 2013", Om0=0.35)
+        """
+
+        # Quick return check, taking advantage of the
+        # immutability of cosmological objects
+        if len(kwargs) == 0:
+            return self
+
+        # Get constructor arguments
+        import inspect
+        arglist = inspect.getargspec(self.__init__).args
+
+        # Build the dictionary of values used to construct this
+        #  object.  This -assumes- every argument to __init__ has a
+        #  property.  This is true of all the classes we provide, but
+        #  maybe a user won't do that.  So at least try to have a useful
+        #  error message.
+        argdict = {}
+        for arg in arglist[1:]:  # Skip self, which should always be first
+            try:
+                val = getattr(self, arg)
+                argdict[arg] = val
+            except AttributeError:
+                # We didn't find a property -- complain usefully
+                errstr = "Object did not have property corresponding "\
+                         "to constructor argument '%s'; perhaps it is a "\
+                         "user provided subclass that does not do so"
+                raise AttributeError(errstr % arg)
+
+        # Now substitute in new arguments
+        for newarg in kwargs:
+            if newarg not in argdict:
+                errstr = "User provided argument '%s' not found in "\
+                         "constructor for this object"
+                raise AttributeError(errstr % newarg)
+            argdict[newarg] = kwargs[newarg]
+
+        return self.__class__(**argdict)
+
     @abstractmethod
     def w(self, z):
         """ The dark energy equation of state.
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -378,7 +464,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -392,13 +478,66 @@ class FLRW(Cosmology):
             z = np.asarray(z)
         return self._Om0 * (1. + z) ** 3 * self.inv_efunc(z) ** 2
 
+    def Ob(self, z):
+        """ Return the density parameter for baryonic matter at redshift ``z``.
+
+        Parameters
+        ----------
+        z : array-like
+          Input redshifts.
+
+        Returns
+        -------
+        Ob : ndarray, or float if input scalar
+          The density of baryonic matter relative to the critical density at
+          each redshift.
+
+        Raises
+        ------
+        ValueError
+          If Ob0 is None.
+        """
+
+        if self._Ob0 is None:
+            raise ValueError("Baryon density not set for this cosmology")
+        if isiterable(z):
+            z = np.asarray(z)
+        return self._Ob0 * (1. + z) ** 3 * self.inv_efunc(z) ** 2
+
+    def Odm(self, z):
+        """ Return the density parameter for dark matter at redshift ``z``.
+
+        Parameters
+        ----------
+        z : array-like
+          Input redshifts.
+
+        Returns
+        -------
+        Odm : ndarray, or float if input scalar
+          The density of non-relativistic dark matter relative to the critical
+          density at each redshift.
+
+        Raises
+        ------
+        ValueError
+          If Ob0 is None.
+        """
+
+        if self._Odm0 is None:
+            raise ValueError("Baryonic density not set for this cosmology, "
+                             "unclear meaning of dark matter density")
+        if isiterable(z):
+            z = np.asarray(z)
+        return self._Odm0 * (1. + z) ** 3 * self.inv_efunc(z) ** 2
+
     def Ok(self, z):
         """ Return the equivalent density parameter for curvature
         at redshift ``z``.
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -423,7 +562,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -449,7 +588,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -468,7 +607,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -496,7 +635,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -514,7 +653,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -610,7 +749,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -660,7 +799,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -694,7 +833,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -721,7 +860,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -746,7 +885,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -770,7 +909,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -788,7 +927,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -810,7 +949,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar
 
         Returns
@@ -827,15 +966,34 @@ class FLRW(Cosmology):
         if not isiterable(z):
             return self._hubble_time * quad(self._tfunc, 0, z)[0]
 
-        out = np.array([quad(self._tfunc, 0, redshift)[0] for redshift in z])
-        return self._hubble_time * np.array(out)
+        f = np.vectorize(lambda red: quad(self._tfunc, 0, red)[0])
+        return self._hubble_time * f(z)
+
+    def lookback_distance(self, z):
+        """
+        The lookback distance is the light travel time distance to a given
+        redshift. It is simply c * lookback_time.  It may be used to calculate
+        the proper distance between two redshifts, e.g. for the mean free path
+        to ionizing radiation.
+
+        Parameters
+        ----------
+        z : array-like
+          Input redshifts.  Must be 1D or scalar
+
+        Returns
+        -------
+        d : `~astropy.units.Quantity`
+          Lookback distance in Mpc
+        """
+        return (self.lookback_time(z) * const.c).to(u.Mpc)
 
     def age(self, z):
         """ Age of the universe in Gyr at redshift ``z``.
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -852,15 +1010,15 @@ class FLRW(Cosmology):
         if not isiterable(z):
             return self._hubble_time * quad(self._tfunc, z, np.inf)[0]
 
-        out = [quad(self._tfunc, redshift, np.inf)[0] for redshift in z]
-        return self._hubble_time * np.array(out)
+        f = np.vectorize(lambda red: quad(self._tfunc, red, np.inf)[0])
+        return self._hubble_time * f(z)
 
     def critical_density(self, z):
         """ Critical density in grams per cubic cm at redshift ``z``.
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -881,7 +1039,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -894,8 +1052,8 @@ class FLRW(Cosmology):
         if not isiterable(z):
             return self._hubble_distance * quad(self.inv_efunc, 0, z)[0]
 
-        out = [quad(self.inv_efunc, 0, redshift)[0] for redshift in z]
-        return self._hubble_distance * np.array(out)
+        f = np.vectorize(lambda red: quad(self.inv_efunc, 0, red)[0])
+        return self._hubble_distance * f(z)
 
     def comoving_transverse_distance(self, z):
         """ Comoving transverse distance in Mpc at a given redshift.
@@ -907,7 +1065,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -944,7 +1102,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -967,7 +1125,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -995,7 +1153,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z1, z2 : array_like, shape (N,)
+        z1, z2 : array-like, shape (N,)
           Input redshifts. z2 must be large than z1.
 
         Returns
@@ -1063,7 +1221,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1081,8 +1239,8 @@ class FLRW(Cosmology):
         if not isiterable(z):
             return quad(self._xfunc, 0, z)[0]
 
-        out = np.array([quad(self._xfunc, 0, redshift)[0] for redshift in z])
-        return out
+        f = np.vectorize(lambda red: quad(self._xfunc, 0, red)[0])
+        return f(z)
 
     def distmod(self, z):
         """ Distance modulus at redshift ``z``.
@@ -1092,7 +1250,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1122,7 +1280,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1158,7 +1316,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1178,7 +1336,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1196,7 +1354,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1214,7 +1372,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1232,7 +1390,7 @@ class FLRW(Cosmology):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.  Must be 1D or scalar.
 
         Returns
@@ -1293,16 +1451,17 @@ class LambdaCDM(FLRW):
     """
 
     def __init__(self, H0, Om0, Ode0, Tcmb0=2.725, Neff=3.04,
-                 m_nu=u.Quantity(0.0, u.eV), name=None):
+                 m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
 
     def w(self, z):
         """Returns dark energy equation of state at redshift ``z``.
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1329,7 +1488,7 @@ class LambdaCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1353,7 +1512,7 @@ class LambdaCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1385,7 +1544,7 @@ class LambdaCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1454,9 +1613,10 @@ class FlatLambdaCDM(LambdaCDM):
     """
 
     def __init__(self, H0, Om0, Tcmb0=2.725, Neff=3.04,
-                 m_nu=u.Quantity(0.0, u.eV), name=None):
+                 m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         # Do some twiddling after the fact to get flatness
         self._Ode0 = 1.0 - self._Om0 - self._Ogamma0 - self._Onu0
         self._Ok0 = 0.0
@@ -1466,7 +1626,7 @@ class FlatLambdaCDM(LambdaCDM):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1498,7 +1658,7 @@ class FlatLambdaCDM(LambdaCDM):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1524,9 +1684,10 @@ class FlatLambdaCDM(LambdaCDM):
 
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, Tcmb0={3:.4g}, "\
-                 "Neff={4:.3g}, m_nu={5})"
+                 "Neff={4:.3g}, m_nu={5}, Ob0={6:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
 
 class wCDM(FLRW):
@@ -1571,6 +1732,10 @@ class wCDM(FLRW):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import wCDM
@@ -1583,9 +1748,10 @@ class wCDM(FLRW):
     """
 
     def __init__(self, H0, Om0, Ode0, w0=-1., Tcmb0=2.725,
-                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None):
+                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=None)
         self._w0 = float(w0)
 
     @property
@@ -1598,7 +1764,7 @@ class wCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1625,7 +1791,7 @@ class wCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1649,7 +1815,7 @@ class wCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1679,7 +1845,7 @@ class wCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1706,10 +1872,10 @@ class wCDM(FLRW):
 
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, Ode0={3:.3g}, w0={4:.3g}, "\
-                 "Tcmb0={5:.4g}, Neff={6:.3g}, m_nu={7})"
+                 "Tcmb0={5:.4g}, Neff={6:.3g}, m_nu={7}, Ob0={8:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0,
                              self._Ode0, self._w0, self._Tcmb0, self._Neff,
-                             self.m_nu)
+                             self.m_nu, _float_or_none(self._Ob0))
 
 
 class FlatwCDM(wCDM):
@@ -1750,6 +1916,10 @@ class FlatwCDM(wCDM):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import FlatwCDM
@@ -1762,9 +1932,10 @@ class FlatwCDM(wCDM):
     """
 
     def __init__(self, H0, Om0, w0=-1., Tcmb0=2.725,
-                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None):
+                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         self._w0 = float(w0)
         # Do some twiddling after the fact to get flatness
         self._Ode0 = 1.0 - self._Om0 - self._Ogamma0 - self._Onu0
@@ -1775,7 +1946,7 @@ class FlatwCDM(wCDM):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1805,7 +1976,7 @@ class FlatwCDM(wCDM):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1832,9 +2003,10 @@ class FlatwCDM(wCDM):
 
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, w0={3:.3g}, Tcmb0={4:.4g}, "\
-                 "Neff={5:.3g}, m_nu={6})"
+                 "Neff={5:.3g}, m_nu={6}, Ob0={7:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0, self._w0,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
 
 class w0waCDM(FLRW):
@@ -1883,6 +2055,10 @@ class w0waCDM(FLRW):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import w0waCDM
@@ -1895,9 +2071,10 @@ class w0waCDM(FLRW):
     """
 
     def __init__(self, H0, Om0, Ode0, w0=-1., wa=0., Tcmb0=2.725,
-                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None):
+                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         self._w0 = float(w0)
         self._wa = float(wa)
 
@@ -1916,7 +2093,7 @@ class w0waCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1943,7 +2120,7 @@ class w0waCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -1971,10 +2148,11 @@ class w0waCDM(FLRW):
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, "\
                  "Ode0={3:.3g}, w0={4:.3g}, wa={5:.3g}, Tcmb0={6:.4g}, "\
-                 "Neff={7:.3g}, m_nu={8})"
+                 "Neff={7:.3g}, m_nu={8}, Ob0={9:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0,
                              self._Ode0, self._w0, self._wa,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
 
 class Flatw0waCDM(w0waCDM):
@@ -2020,6 +2198,10 @@ class Flatw0waCDM(w0waCDM):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import Flatw0waCDM
@@ -2032,9 +2214,10 @@ class Flatw0waCDM(w0waCDM):
     """
 
     def __init__(self, H0, Om0, w0=-1., wa=0., Tcmb0=2.725,
-                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None):
+                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, 0.0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         # Do some twiddling after the fact to get flatness
         self._Ode0 = 1.0 - self._Om0 - self._Ogamma0 - self._Onu0
         self._Ok0 = 0.0
@@ -2043,9 +2226,11 @@ class Flatw0waCDM(w0waCDM):
 
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, "\
-                 "w0={3:.3g}, Tcmb0={4:.4g}, Neff={5:.3g}, m_nu={6})"
+                 "w0={3:.3g}, Tcmb0={4:.4g}, Neff={5:.3g}, m_nu={6}, "\
+                 "Ob0={7:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0, self._w0,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
 
 class wpwaCDM(FLRW):
@@ -2101,6 +2286,10 @@ class wpwaCDM(FLRW):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import wpwaCDM
@@ -2114,9 +2303,10 @@ class wpwaCDM(FLRW):
 
     def __init__(self, H0, Om0, Ode0, wp=-1., wa=0., zp=0,
                  Tcmb0=2.725, Neff=3.04, m_nu=u.Quantity(0.0, u.eV),
-                 name=None):
+                 name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         self._wp = float(wp)
         self._wa = float(wa)
         self._zp = float(zp)
@@ -2141,7 +2331,7 @@ class wpwaCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -2170,7 +2360,7 @@ class wpwaCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -2201,10 +2391,11 @@ class wpwaCDM(FLRW):
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, Ode0={3:.3g}, wp={4:.3g}, "\
                  "wa={5:.3g}, zp={6:.3g}, Tcmb0={7:.4g}, Neff={8:.3g}, "\
-                 "m_nu={9})"
+                 "m_nu={9}, Ob0={10:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0,
                              self._Ode0, self._wp, self._wa, self._zp,
-                             self._Tcmb0, self._Neff, self.m_nu)
+                             self._Tcmb0, self._Neff, self.m_nu,
+                             _float_or_none(self._Ob0))
 
 
 class w0wzCDM(FLRW):
@@ -2255,6 +2446,10 @@ class w0wzCDM(FLRW):
     name : str
         Optional name for this cosmological object.
 
+    Ob0 : float
+        Omega baryons: density of baryonic matter in units of the critical
+        density at z=0.
+
     Examples
     --------
     >>> from astropy.cosmology import w0wzCDM
@@ -2267,9 +2462,10 @@ class w0wzCDM(FLRW):
     """
 
     def __init__(self, H0, Om0, Ode0, w0=-1., wz=0., Tcmb0=2.725,
-                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None):
+                 Neff=3.04, m_nu=u.Quantity(0.0, u.eV), name=None, Ob0=None):
 
-        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name)
+        FLRW.__init__(self, H0, Om0, Ode0, Tcmb0, Neff, m_nu, name=name,
+                      Ob0=Ob0)
         self._w0 = float(w0)
         self._wz = float(wz)
 
@@ -2288,7 +2484,7 @@ class w0wzCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -2315,7 +2511,7 @@ class w0wzCDM(FLRW):
 
         Parameters
         ----------
-        z : array_like
+        z : array-like
           Input redshifts.
 
         Returns
@@ -2343,10 +2539,17 @@ class w0wzCDM(FLRW):
     def __repr__(self):
         retstr = "{0}H0={1:.3g}, Om0={2:.3g}, "\
                  "Ode0={3:.3g}, w0={4:.3g}, wz={5:.3g} Tcmb0={6:.4g}, "\
-                 "Neff={7:.3g}, m_nu={8})"
+                 "Neff={7:.3g}, m_nu={8}, Ob0={9:s})"
         return retstr.format(self._namelead(), self._H0, self._Om0,
                              self._Ode0, self._w0, self._wz, self._Tcmb0,
-                             self._Neff, self.m_nu)
+                             self._Neff, self.m_nu, _float_or_none(self._Ob0))
+
+def _float_or_none(x, digits=3):
+    """ Helper function to format a variable that can be a float or None"""
+    if x is None:
+        return str(x)
+    fmtstr = "{0:.{digits}g}".format(x, digits=digits)
+    return fmtstr.format(x)
 
 # Pre-defined cosmologies. This loops over the parameter sets in the
 # parameters module and creates a LambdaCDM or FlatLambdaCDM instance
@@ -2360,13 +2563,15 @@ for key in parameters.available:
         cosmo = FlatLambdaCDM(par['H0'], par['Om0'], Tcmb0=par['Tcmb0'],
                               Neff=par['Neff'],
                               m_nu=u.Quantity(par['m_nu'], u.eV),
-                              name=key)
+                              name=key,
+                              Ob0=par['Ob0'])
         docstr = "%s instance of FlatLambdaCDM cosmology\n\n(from %s)"
         cosmo.__doc__ = docstr % (key, par['reference'])
     else:
         cosmo = LambdaCDM(par['H0'], par['Om0'], par['Ode0'],
                           Tcmb0=par['Tcmb0'], Neff=par['Neff'],
-                          m_nu=u.Quantity(par['m_nu'], u.eV), name=key)
+                          m_nu=u.Quantity(par['m_nu'], u.eV), name=key,
+                          Ob0=par['Ob0'])
         docstr = "%s instance of LambdaCDM cosmology\n\n(from %s)"
         cosmo.__doc__ = docstr % (key, par['reference'])
     setattr(sys.modules[__name__], key, cosmo)
@@ -2421,41 +2626,5 @@ class default_cosmology(ScienceState):
             raise TypeError("default_cosmology must be a string or Cosmology instance.")
 
 
- at deprecated('0.4', alternative='astropy.cosmology.default_cosmology.get_cosmology_from_string')
-def get_cosmology_from_string(arg):
-    """ Return a cosmology instance from a string.
-    """
-    return default_cosmology.get_cosmology_from_string(arg)
-
-
- at deprecated('0.4', alternative='astropy.cosmology.default_cosmology.get')
-def get_current():
-    """ Get the current cosmology.
-
-    If no current has been set, the WMAP9 comology is returned and a
-    warning is given.
-
-    Returns
-    -------
-    cosmo : ``Cosmology`` instance
-    """
-    return default_cosmology.get()
-
-
- at deprecated('0.4', alternative='astropy.cosmology.default_cosmology.set')
-def set_current(cosmo):
-    """ Set the current cosmology.
-
-    Call this with an empty string ('') to get a list of the strings
-    that map to available pre-defined cosmologies.
-
-    Parameters
-    ----------
-    cosmo : str or ``Cosmology`` instance
-      The cosmology to use.
-    """
-    return default_cosmology.set(cosmo)
-
-
 DEFAULT_COSMOLOGY = ScienceStateAlias(
     '0.4', 'DEFAULT_COSMOLOGY', 'default_cosmology', default_cosmology)
diff --git a/astropy/cosmology/funcs.py b/astropy/cosmology/funcs.py
index 602feb0..f534fb4 100644
--- a/astropy/cosmology/funcs.py
+++ b/astropy/cosmology/funcs.py
@@ -13,16 +13,12 @@ from .core import CosmologyError
 from ..units import Quantity
 from ..utils import deprecated
 
-__all__ = ['H', 'angular_diameter_distance', 'arcsec_per_kpc_comoving',
-           'arcsec_per_kpc_proper', 'comoving_distance', 'critical_density',
-           'distmod', 'kpc_comoving_per_arcmin', 'kpc_proper_per_arcmin',
-           'lookback_time', 'luminosity_distance', 'scale_factor',
-           'z_at_value']
+__all__ = ['z_at_value']
 
 __doctest_requires__ = {'*': ['scipy.integrate']}
 
 
-def z_at_value(func, fval, zmin=0, zmax=1000, ztol=1e-5, maxfun=500):
+def z_at_value(func, fval, zmin=1e-8, zmax=1000, ztol=1e-8, maxfun=500):
     """ Find the redshift ``z`` at which ``func(z) = fval``.
 
     This finds the redshift at which one of the cosmology functions or
@@ -45,7 +41,9 @@ def z_at_value(func, fval, zmin=0, zmax=1000, ztol=1e-5, maxfun=500):
     fval : astropy.Quantity instance
        The value of ``func(z)``.
     zmin : float, optional
-       The lower search limit for ``z`` (default 0).
+       The lower search limit for ``z``.  Beware of divergences
+       in some cosmological functions, such as distance moduli,
+       at z=0 (default 1e-8).
     zmax : float, optional
        The upper search limit for ``z`` (default 1000).
     ztol : float, optional
@@ -74,10 +72,10 @@ def z_at_value(func, fval, zmin=0, zmax=1000, ztol=1e-5, maxfun=500):
     >>> import astropy.units as u
     >>> from astropy.cosmology import Planck13, z_at_value
 
-    Generate 10^6 distance moduli between 23 and 43 for which we
+    Generate 10^6 distance moduli between 24 and 43 for which we
     want to find the corresponding redshifts:
 
-    >>> Dvals = (23 + np.random.rand(1e6) * 20) * u.mag
+    >>> Dvals = (24 + np.random.rand(1e6) * 20) * u.mag
 
     Make a grid of distance moduli covering the redshift range we
     need using 50 equally log-spaced values between zmin and
@@ -86,7 +84,7 @@ def z_at_value(func, fval, zmin=0, zmax=1000, ztol=1e-5, maxfun=500):
 
     >>> zmin = z_at_value(Planck13.distmod, Dvals.min())
     >>> zmax = z_at_value(Planck13.distmod, Dvals.max())
-    >>> zgrid = np.logspace(zmin, zmax)
+    >>> zgrid = np.logspace(np.log10(zmin), np.log10(zmax), 50)
     >>> Dgrid = Planck13.distmod(zgrid)
 
     Finally interpolate to find the redshift at each distance modulus:
@@ -102,16 +100,16 @@ def z_at_value(func, fval, zmin=0, zmax=1000, ztol=1e-5, maxfun=500):
     unique solution can be found:
 
     >>> z_at_value(Planck13.age, 2 * u.Gyr)
-    3.1981191749374629
+    3.19812268...
 
     The angular diameter is not monotonic however, and there are two
     redshifts that give a value of 1500 Mpc. Use the zmin and zmax keywords
     to find the one you're interested in:
 
     >>> z_at_value(Planck13.angular_diameter_distance, 1500 * u.Mpc, zmax=1.5)
-    0.68127769625288614
+    0.6812769577...
     >>> z_at_value(Planck13.angular_diameter_distance, 1500 * u.Mpc, zmin=2.5)
-    3.7914918534022011
+    3.7914913242...
 
     Also note that the luminosity distance and distance modulus (two
     other commonly inverted quantities) are monotonic in flat and open
@@ -149,269 +147,3 @@ zmin and zmax satisfying fval = func(z).""")
                              "Try re-running with a different zmin.")
 
     return zbest
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.kpc_comoving_per_arcmin')
-def kpc_comoving_per_arcmin(z, cosmo=None):
-    """ Separation in transverse comoving kpc corresponding to an
-    arcminute at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    d : `~astropy.units.Quantity`
-      The distance in comoving kpc corresponding to an arcmin at each
-      input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.kpc_comoving_per_arcmin(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.kpc_proper_per_arcmin')
-def kpc_proper_per_arcmin(z, cosmo=None):
-    """ Separation in transverse proper kpc corresponding to an
-    arcminute at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    d : `~astropy.units.Quantity`
-      The distance in proper kpc corresponding to an arcmin at each
-      input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.kpc_proper_per_arcmin(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.arcsec_per_kpc_comoving')
-def arcsec_per_kpc_comoving(z, cosmo=None):
-    """ Angular separation in arcsec corresponding to a comoving kpc
-    at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    theta : `~astropy.units.Quantity`
-      The angular separation in arcsec corresponding to a comoving kpc
-      at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.arcsec_per_kpc_comoving(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.arcsec_per_kpc_proper')
-def arcsec_per_kpc_proper(z, cosmo=None):
-    """ Angular separation in arcsec corresponding to a proper kpc at
-    redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    theta : `~astropy.units.Quantity`
-      The angular separation in arcsec corresponding to a proper kpc
-      at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.arcsec_per_kpc_proper(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.distmod')
-def distmod(z, cosmo=None):
-    """ Distance modulus at redshift ``z``.
-
-    The distance modulus is defined as the (apparent magnitude -
-    absolute magnitude) for an object at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    distmod : `~astropy.units.Quantity`
-      Distance modulus at each input redshift.
-
-    See Also
-    --------
-    z_at_value : Find the redshift corresponding to a distance modulus.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.distmod(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.H')
-def H(z, cosmo=None):
-    """ Hubble parameter (km/s/Mpc) at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    H : `~astropy.units.Quantity`
-      Hubble parameter at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.H(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.scale_factor')
-def scale_factor(z, cosmo=None):
-    """ Scale factor at redshift ``z``.
-
-    The scale factor is defined as ``a = 1 / (1 + z)``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    scalefac : ndarray, or float if input scalar
-      Scale factor at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.scale_factor(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.critical_density')
-def critical_density(z, cosmo=None):
-    """ Critical density in grams per cubic cm at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    critdens : `~astropy.units.Quantity`
-      Critical density at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.critical_density(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.lookback_time')
-def lookback_time(z, cosmo=None):
-    """ Lookback time in Gyr to redshift ``z``.
-
-    The lookback time is the difference between the age of the
-    Universe now and the age at redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    t : `~astropy.units.Quantity`
-      Lookback time at each input redshift.
-
-    See Also
-    --------
-    z_at_value : Find the redshift corresponding to a lookback time.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.lookback_time(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.comoving_distance')
-def comoving_distance(z, cosmo=None):
-    """ Comoving distance in Mpc at redshift ``z``.
-
-    The comoving distance along the line-of-sight between two objects
-    remains constant with time for objects in the Hubble flow.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    codist : `~astropy.units.Quantity`
-      Comoving distance at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.comoving_distance(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.angular_diameter_distance')
-def angular_diameter_distance(z, cosmo=None):
-    """ Angular diameter distance in Mpc at a given redshift.
-
-    This gives the proper (sometimes called 'physical') transverse
-    distance corresponding to an angle of 1 radian for an object at
-    redshift ``z``.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    angdist : `~astropy.units.Quantity`
-      Angular diameter distance at each input redshift.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.angular_diameter_distance(z)
-
-
- at deprecated(since='0.4', alternative='<Cosmology object>.luminosity_distance')
-def luminosity_distance(z, cosmo=None):
-    """ Luminosity distance in Mpc at redshift ``z``.
-
-    This is the distance to use when converting between the bolometric
-    flux from an object at redshift ``z`` and its bolometric luminosity.
-
-    Parameters
-    ----------
-    z : array_like
-      Input redshifts.
-
-    Returns
-    -------
-    lumdist : `~astropy.units.Quantity`
-      Luminosity distance at each input redshift.
-
-    See Also
-    --------
-    z_at_value : Find the redshift corresponding to a luminosity distance.
-    """
-    if cosmo is None:
-        cosmo = _default_cosmology.get()
-    return cosmo.luminosity_distance(z)
diff --git a/astropy/cosmology/parameters.py b/astropy/cosmology/parameters.py
index 9d8948e..dffd6a4 100644
--- a/astropy/cosmology/parameters.py
+++ b/astropy/cosmology/parameters.py
@@ -8,7 +8,7 @@ Each cosmology has the following parameters defined:
     Oc0         Omega cold dark matter at z=0
     Ob0         Omega baryon at z=0
     Om0         Omega matter at z=0
-    flat        Is this assumed flat?  If not, Ode0 must be specifiec
+    flat        Is this assumed flat?  If not, Ode0 must be specified
     Ode0        Omega dark energy at z=0 if flat is False
     H0          Hubble parameter at z=0 in km/s/Mpc
     n           Density perturbation spectral index
diff --git a/astropy/cosmology/tests/test_cosmology.py b/astropy/cosmology/tests/test_cosmology.py
index 00e8aaf..d0b7bea 100644
--- a/astropy/cosmology/tests/test_cosmology.py
+++ b/astropy/cosmology/tests/test_cosmology.py
@@ -18,16 +18,6 @@ else:
     HAS_SCIPY = True
 
 
-def setup_function(function):
-    # Make sure that tests don't affect default cosmology
-    core.set_current('no_default')
-
-
-def teardown_function(function):
-    # Make sure that tests don't affect default cosmology
-    core.set_current('no_default')
-
-
 def test_init():
     """ Tests to make sure the code refuses inputs it is supposed to"""
     with pytest.raises(ValueError):
@@ -48,12 +38,24 @@ def test_init():
     with pytest.raises(ValueError):
         bad_mnu = u.Quantity([-0.3, 0.2], u.eV)  # 2, expecting 3
         cosmo = core.FlatLambdaCDM(H0=70, Om0=0.2, m_nu=bad_mnu)
+    with pytest.raises(ValueError):
+        cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27, Ob0=-0.04)
+    with pytest.raises(ValueError):
+        cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27, Ob0=0.4)
+    with pytest.raises(ValueError):
+        cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27)
+        cosmo.Ob(1)
+    with pytest.raises(ValueError):
+        cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27)
+        cosmo.Odm(1)
 
 
 def test_basic():
-    cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=2.0, Neff=3.04)
+    cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=2.0, Neff=3.04, Ob0=0.05)
     assert np.allclose(cosmo.Om0, 0.27)
     assert np.allclose(cosmo.Ode0, 0.729975, rtol=1e-4)
+    assert np.allclose(cosmo.Ob0, 0.05)
+    assert np.allclose(cosmo.Odm0, 0.27 - 0.05)
     # This next test will fail if astropy.const starts returning non-mks
     #  units by default; see the comment at the top of core.py
     assert np.allclose(cosmo.Ogamma0, 1.463285e-5, rtol=1e-4)
@@ -72,9 +74,11 @@ def test_basic():
     # Make sure setting them as quantities gives the same results
     H0 = u.Quantity(70, u.km / (u.s * u.Mpc))
     T = u.Quantity(2.0, u.K)
-    cosmo = core.FlatLambdaCDM(H0=H0, Om0=0.27, Tcmb0=T, Neff=3.04)
+    cosmo = core.FlatLambdaCDM(H0=H0, Om0=0.27, Tcmb0=T, Neff=3.04, Ob0=0.05)
     assert np.allclose(cosmo.Om0, 0.27)
     assert np.allclose(cosmo.Ode0, 0.729975, rtol=1e-4)
+    assert np.allclose(cosmo.Ob0, 0.05)
+    assert np.allclose(cosmo.Odm0, 0.27 - 0.05)
     assert np.allclose(cosmo.Ogamma0, 1.463285e-5, rtol=1e-4)
     assert np.allclose(cosmo.Onu0, 1.01026e-5, rtol=1e-4)
     assert np.allclose(cosmo.Ok0, 0.0)
@@ -100,6 +104,7 @@ def test_units():
     assert cosmo.comoving_distance(1.0).unit == u.Mpc
     assert cosmo.luminosity_distance(1.0).unit == u.Mpc
     assert cosmo.lookback_time(1.0).unit == u.Gyr
+    assert cosmo.lookback_distance(1.0).unit == u.Mpc
     assert cosmo.H0.unit == u.km / u.Mpc / u.s
     assert cosmo.H(1.0).unit == u.km / u.Mpc / u.s
     assert cosmo.Tcmb0.unit == u.K
@@ -118,57 +123,227 @@ def test_units():
     assert cosmo.distmod(1.0).unit == u.mag
 
 
+ at pytest.mark.skipif('not HAS_SCIPY')
+def test_distance_broadcast():
+    """ Test array shape broadcasting for functions with single
+    redshift inputs"""
+
+    cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27,
+                               m_nu=u.Quantity([0.0, 0.1, 0.011], u.eV))
+    z = np.linspace(0.1, 1, 6)
+    z_reshape2d = z.reshape(2, 3)
+    z_reshape3d = z.reshape(3, 2, 1)
+    # Things with units
+    methods = ['comoving_distance', 'luminosity_distance',
+               'comoving_transverse_distance', 'angular_diameter_distance',
+               'distmod', 'lookback_time', 'age', 'comoving_volume',
+               'differential_comoving_volume', 'kpc_comoving_per_arcmin']
+    for method in methods:
+        g = getattr(cosmo, method)
+        value_flat = g(z)
+        assert value_flat.shape == z.shape
+        value_2d = g(z_reshape2d)
+        assert value_2d.shape == z_reshape2d.shape
+        value_3d = g(z_reshape3d)
+        assert value_3d.shape == z_reshape3d.shape
+        assert value_flat.unit == value_2d.unit
+        assert value_flat.unit == value_3d.unit
+        assert np.allclose(value_flat.value, value_2d.flatten().value)
+        assert np.allclose(value_flat.value, value_3d.flatten().value)
+
+    # Also test unitless ones
+    methods = ['absorption_distance', 'Om', 'Ode', 'Ok', 'H',
+               'w', 'de_density_scale', 'Onu', 'Ogamma',
+               'nu_relative_density']
+    for method in methods:
+        g = getattr(cosmo, method)
+        value_flat = g(z)
+        assert value_flat.shape == z.shape
+        value_2d = g(z_reshape2d)
+        assert value_2d.shape == z_reshape2d.shape
+        value_3d = g(z_reshape3d)
+        assert value_3d.shape == z_reshape3d.shape
+        assert np.allclose(value_flat, value_2d.flatten())
+        assert np.allclose(value_flat, value_3d.flatten())
+
+    # Test some dark energy models
+    methods = ['Om', 'Ode', 'w', 'de_density_scale']
+    for tcosmo in [core.LambdaCDM(H0=70, Om0=0.27, Ode0=0.5),
+                   core.wCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2),
+                   core.w0waCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2, wa=-0.2),
+                   core.wpwaCDM(H0=70, Om0=0.27, Ode0=0.5,
+                                wp=-1.2, wa=-0.2, zp=0.9),
+                   core.w0wzCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2, wz=0.1)]:
+        for method in methods:
+            g = getattr(cosmo, method)
+            value_flat = g(z)
+            assert value_flat.shape == z.shape
+            value_2d = g(z_reshape2d)
+            assert value_2d.shape == z_reshape2d.shape
+            value_3d = g(z_reshape3d)
+            assert value_3d.shape == z_reshape3d.shape
+            assert np.allclose(value_flat, value_2d.flatten())
+            assert np.allclose(value_flat, value_3d.flatten())
+
+
+ at pytest.mark.skipif('not HAS_SCIPY')
+def test_clone():
+    """ Test clone operation"""
+
+    cosmo = core.FlatLambdaCDM(H0=70 * u.km / u.s / u.Mpc, Om0=0.27,
+                               Tcmb0=3.0 * u.K)
+    z = np.linspace(0.1, 3, 15)
+
+    # First, test with no changes, which should return same object
+    newclone = cosmo.clone()
+    assert newclone is cosmo
+
+    # Now change H0
+    #  Note that H0 affects Ode0 because it changes Ogamma0
+    newclone = cosmo.clone(H0=60 * u.km / u.s / u.Mpc)
+    assert newclone is not cosmo
+    assert newclone.__class__ == cosmo.__class__
+    assert newclone.name == cosmo.name
+    assert not np.allclose(newclone.H0.value, cosmo.H0.value)
+    assert np.allclose(newclone.H0.value, 60.0)
+    assert np.allclose(newclone.Om0, cosmo.Om0)
+    assert np.allclose(newclone.Ok0, cosmo.Ok0)
+    assert not np.allclose(newclone.Ogamma0, cosmo.Ogamma0)
+    assert not np.allclose(newclone.Onu0, cosmo.Onu0)
+    assert np.allclose(newclone.Tcmb0.value, cosmo.Tcmb0.value)
+    assert np.allclose(newclone.m_nu.value, cosmo.m_nu.value)
+    assert np.allclose(newclone.Neff, cosmo.Neff)
+
+    # Compare modified version with directly instantiated one
+    cmp = core.FlatLambdaCDM(H0=60 * u.km / u.s / u.Mpc, Om0=0.27,
+                             Tcmb0=3.0 * u.K)
+    assert newclone.__class__ == cmp.__class__
+    assert newclone.name == cmp.name
+    assert np.allclose(newclone.H0.value, cmp.H0.value)
+    assert np.allclose(newclone.Om0, cmp.Om0)
+    assert np.allclose(newclone.Ode0, cmp.Ode0)
+    assert np.allclose(newclone.Ok0, cmp.Ok0)
+    assert np.allclose(newclone.Ogamma0, cmp.Ogamma0)
+    assert np.allclose(newclone.Onu0, cmp.Onu0)
+    assert np.allclose(newclone.Tcmb0, cmp.Tcmb0)
+    assert np.allclose(newclone.m_nu.value, cmp.m_nu.value)
+    assert np.allclose(newclone.Neff, cmp.Neff)
+    assert np.allclose(newclone.Om(z), cmp.Om(z))
+    assert np.allclose(newclone.H(z).value, cmp.H(z).value)
+    assert np.allclose(newclone.luminosity_distance(z).value,
+                       cmp.luminosity_distance(z).value)
+
+    # Now try changing multiple things
+    newclone = cosmo.clone(name="New name", H0=65 * u.km / u.s / u.Mpc,
+                         Tcmb0=2.8 * u.K)
+    assert newclone.__class__ == cosmo.__class__
+    assert not newclone.name == cosmo.name
+    assert not np.allclose(newclone.H0.value, cosmo.H0.value)
+    assert np.allclose(newclone.H0.value, 65.0)
+    assert np.allclose(newclone.Om0, cosmo.Om0)
+    assert np.allclose(newclone.Ok0, cosmo.Ok0)
+    assert not np.allclose(newclone.Ogamma0, cosmo.Ogamma0)
+    assert not np.allclose(newclone.Onu0, cosmo.Onu0)
+    assert not np.allclose(newclone.Tcmb0.value, cosmo.Tcmb0.value)
+    assert np.allclose(newclone.Tcmb0.value, 2.8)
+    assert np.allclose(newclone.m_nu.value, cosmo.m_nu.value)
+    assert np.allclose(newclone.Neff, cosmo.Neff)
+
+    # And direct comparison
+    cmp = core.FlatLambdaCDM(name="New name", H0=65 * u.km / u.s / u.Mpc,
+                             Om0=0.27, Tcmb0=2.8 * u.K)
+    assert newclone.__class__ == cmp.__class__
+    assert newclone.name == cmp.name
+    assert np.allclose(newclone.H0.value, cmp.H0.value)
+    assert np.allclose(newclone.Om0, cmp.Om0)
+    assert np.allclose(newclone.Ode0, cmp.Ode0)
+    assert np.allclose(newclone.Ok0, cmp.Ok0)
+    assert np.allclose(newclone.Ogamma0, cmp.Ogamma0)
+    assert np.allclose(newclone.Onu0, cmp.Onu0)
+    assert np.allclose(newclone.Tcmb0, cmp.Tcmb0)
+    assert np.allclose(newclone.m_nu.value, cmp.m_nu.value)
+    assert np.allclose(newclone.Neff, cmp.Neff)
+    assert np.allclose(newclone.Om(z), cmp.Om(z))
+    assert np.allclose(newclone.H(z).value, cmp.H(z).value)
+    assert np.allclose(newclone.luminosity_distance(z).value,
+                       cmp.luminosity_distance(z).value)
+
+    # Try a dark energy class, make sure it can handle w params
+    cosmo = core.w0waCDM(name="test w0wa", H0=70 * u.km / u.s / u.Mpc,
+                         Om0=0.27, Ode0=0.5, wa=0.1, Tcmb0=4.0 * u.K)
+    newclone = cosmo.clone(w0=-1.1, wa=0.2)
+    assert newclone.__class__ == cosmo.__class__
+    assert newclone.name == cosmo.name
+    assert np.allclose(newclone.H0.value, cosmo.H0.value)
+    assert np.allclose(newclone.Om0, cosmo.Om0)
+    assert np.allclose(newclone.Ode0, cosmo.Ode0)
+    assert np.allclose(newclone.Ok0, cosmo.Ok0)
+    assert not np.allclose(newclone.w0, cosmo.w0)
+    assert np.allclose(newclone.w0, -1.1)
+    assert not np.allclose(newclone.wa, cosmo.wa)
+    assert np.allclose(newclone.wa, 0.2)
+
+    # Now test exception if user passes non-parameter
+    with pytest.raises(AttributeError):
+        newclone = cosmo.clone(not_an_arg=4)
+
+
 def test_repr():
     """ Test string representation of built in classes"""
     cosmo = core.LambdaCDM(70, 0.3, 0.5)
     expected = 'LambdaCDM(H0=70 km / (Mpc s), Om0=0.3, '\
-               'Ode0=0.5, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV)'
+               'Ode0=0.5, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV, '\
+               'Ob0=None)'
     assert str(cosmo) == expected
 
     cosmo = core.LambdaCDM(70, 0.3, 0.5, m_nu=u.Quantity(0.01, u.eV))
     expected = 'LambdaCDM(H0=70 km / (Mpc s), Om0=0.3, Ode0=0.5, '\
-               'Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.01  0.01  0.01] eV)'
+               'Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.01  0.01  0.01] eV, '\
+               'Ob0=None)'
     assert str(cosmo) == expected
 
-    cosmo = core.FlatLambdaCDM(50.0, 0.27)
+    cosmo = core.FlatLambdaCDM(50.0, 0.27, Ob0=0.05)
     expected = 'FlatLambdaCDM(H0=50 km / (Mpc s), Om0=0.27, '\
-               'Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV)'
+               'Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=0.05)'
     assert str(cosmo) == expected
 
     cosmo = core.wCDM(60.0, 0.27, 0.6, w0=-0.8, name='test1')
     expected = 'wCDM(name="test1", H0=60 km / (Mpc s), Om0=0.27, '\
                'Ode0=0.6, w0=-0.8, Tcmb0=2.725 K, Neff=3.04, '\
-               'm_nu=[ 0.  0.  0.] eV)'
+               'm_nu=[ 0.  0.  0.] eV, Ob0=None)'
     assert str(cosmo) == expected
 
     cosmo = core.FlatwCDM(65.0, 0.27, w0=-0.6, name='test2')
     expected = 'FlatwCDM(name="test2", H0=65 km / (Mpc s), Om0=0.27, '\
-               'w0=-0.6, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV)'
+               'w0=-0.6, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV, '\
+               'Ob0=None)'
     assert str(cosmo) == expected
 
     cosmo = core.w0waCDM(60.0, 0.25, 0.4, w0=-0.6, wa=0.1, name='test3')
     expected = 'w0waCDM(name="test3", H0=60 km / (Mpc s), Om0=0.25, '\
                'Ode0=0.4, w0=-0.6, wa=0.1, Tcmb0=2.725 K, Neff=3.04, '\
-               'm_nu=[ 0.  0.  0.] eV)'
+               'm_nu=[ 0.  0.  0.] eV, Ob0=None)'
     assert str(cosmo) == expected
 
-    cosmo = core.Flatw0waCDM(55.0, 0.35, w0=-0.9, wa=-0.2, name='test4')
+    cosmo = core.Flatw0waCDM(55.0, 0.35, w0=-0.9, wa=-0.2, name='test4',
+                             Ob0=0.0456789)
     expected = 'Flatw0waCDM(name="test4", H0=55 km / (Mpc s), Om0=0.35, '\
-               'w0=-0.9, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV)'
+               'w0=-0.9, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV, '\
+               'Ob0=0.0457)'
     assert str(cosmo) == expected
 
     cosmo = core.wpwaCDM(50.0, 0.3, 0.3, wp=-0.9, wa=-0.2,
                          zp=0.3, name='test5')
     expected = 'wpwaCDM(name="test5", H0=50 km / (Mpc s), Om0=0.3, '\
                'Ode0=0.3, wp=-0.9, wa=-0.2, zp=0.3, Tcmb0=2.725 K, '\
-               'Neff=3.04, m_nu=[ 0.  0.  0.] eV)'
+               'Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=None)'
     assert str(cosmo) == expected
 
     cosmo = core.w0wzCDM(55.0, 0.4, 0.8, w0=-1.05, wz=-0.2,
                          m_nu=u.Quantity([0.001, 0.01, 0.015], u.eV))
     expected = 'w0wzCDM(H0=55 km / (Mpc s), Om0=0.4, Ode0=0.8, w0=-1.05, '\
                'wz=-0.2 Tcmb0=2.725 K, Neff=3.04, '\
-               'm_nu=[ 0.001  0.01   0.015] eV)'
+               'm_nu=[ 0.001  0.01   0.015] eV, Ob0=None)'
     assert str(cosmo) == expected
 
 
@@ -197,6 +372,8 @@ def test_flat_z1():
                        [6729.2, 6729.6, 6729.5976], rtol=1e-4)
     assert np.allclose(cosmo.lookback_time(z).value,
                        [7.841, 7.84178, 7.843], rtol=1e-3)
+    assert np.allclose(cosmo.lookback_distance(z).value,
+                       [2404.0, 2404.24, 2404.4], rtol=1e-3)
 
 
 def test_zeroing():
@@ -207,6 +384,9 @@ def test_zeroing():
     # Ogamma0
     cosmo = core.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=0.0)
     assert np.allclose(cosmo.Ogamma([0, 1, 2, 3]), [0, 0, 0, 0])
+    # Obaryon
+    cosmo = core.LambdaCDM(H0=70, Om0=0.27, Ode0=0.73, Ob0=0.0)
+    assert np.allclose(cosmo.Ob([0, 1, 2, 3]), [0, 0, 0, 0])
 
 
 # This class is to test whether the routines work correctly
@@ -288,15 +468,23 @@ def test_varyde_lumdist_mathematica():
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
-def test_omatter():
-    # Test Om evolution
-    tcos = core.FlatLambdaCDM(70.0, 0.3)
+def test_matter():
+    # Test non-relativistic matter evolution
+    tcos = core.FlatLambdaCDM(70.0, 0.3, Ob0=0.045)
     assert np.allclose(tcos.Om0, 0.3)
     assert np.allclose(tcos.H0.value, 70.0)
     assert np.allclose(tcos.Om(0), 0.3)
+    assert np.allclose(tcos.Ob(0), 0.045)
     z = np.array([0.0, 0.5, 1.0, 2.0])
     assert np.allclose(tcos.Om(z), [0.3, 0.59112134, 0.77387435, 0.91974179],
                        rtol=1e-4)
+    assert np.allclose(tcos.Ob(z), [0.045, 0.08866820, 0.11608115,
+                                    0.13796127], rtol=1e-4)
+    assert np.allclose(tcos.Odm(z), [0.255, 0.50245314, 0.6577932, 0.78178052],
+                       rtol=1e-4)
+    # Consistency of dark and baryonic matter evolution with all
+    # non-relativistic matter
+    assert np.allclose(tcos.Ob(z) + tcos.Odm(z), tcos.Om(z))
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
@@ -487,54 +675,6 @@ def test_kpc_methods():
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
-def test_convenience():
-    # these are all for WMAP7 with Tcmb = 0
-    tcos = core.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0)
-    core.set_current(tcos)
-
-    # scalars
-    assert np.allclose(funcs.arcsec_per_kpc_comoving(3).value, 0.0317179)
-    assert funcs.arcsec_per_kpc_comoving(3).unit == u.arcsec / u.kpc
-    assert np.allclose(funcs.arcsec_per_kpc_proper(3).value, 0.1268716668)
-    assert funcs.arcsec_per_kpc_proper(3).unit == u.arcsec / u.kpc
-    assert np.allclose(funcs.kpc_comoving_per_arcmin(3).value, 1891.6753126)
-    assert funcs.kpc_comoving_per_arcmin(3).unit == u.kpc / u.arcmin
-    assert np.allclose(funcs.kpc_proper_per_arcmin(3).value, 472.918828)
-    assert funcs.kpc_proper_per_arcmin(3).unit == u.kpc / u.arcmin
-    assert np.allclose(funcs.distmod(3).value, 47.075902)
-    assert funcs.distmod(3).unit == u.mag
-    assert np.allclose(funcs.H(3).value, 299.80813491298068)
-    assert funcs.H(3).unit == u.km / (u.Mpc * u.s)
-    assert np.allclose(funcs.scale_factor(3), 0.25)
-    assert np.allclose(funcs.scale_factor([3, 4]), [0.25, 0.2])
-    assert np.allclose(funcs.critical_density(3).value, 1.6884621680232328e-28)
-    assert funcs.critical_density(3).unit == u.g / u.cm ** 3
-    assert np.allclose(funcs.lookback_time(3).value, 11.555469926558361)
-    assert funcs.lookback_time(3).unit == u.Gyr
-    assert np.allclose(funcs.lookback_time([3, 4]).value,
-                       [11.555469927, 12.17718555], rtol=1e-5)
-    assert np.allclose(funcs.comoving_distance(3).value, 6503.100697385924)
-    assert funcs.comoving_distance(3).unit == u.Mpc
-    assert np.allclose(funcs.angular_diameter_distance(3).value,
-                       1625.775174346481)
-    assert funcs.angular_diameter_distance(3).unit == u.Mpc
-    assert np.allclose(funcs.luminosity_distance(3).value, 26012.402789543696)
-    assert funcs.luminosity_distance(3).unit == u.Mpc
-
-    # arrays
-    assert np.allclose(funcs.arcsec_per_kpc_comoving([0.1, 0.5]).value,
-                       [0.4946986, 0.10876163])
-    assert np.allclose(funcs.arcsec_per_kpc_proper([0.1, 0.5]).value,
-                       [0.54416846354697479, 0.16314245192751084])
-    assert np.allclose(funcs.kpc_comoving_per_arcmin([0.1, 0.5]).value,
-                       [121.2859701, 551.66511804])
-    assert np.allclose(funcs.kpc_proper_per_arcmin([0.1, 0.5]).value,
-                       [110.25997282, 367.77674536])
-    assert np.allclose(funcs.distmod([0.1, 0.5]).value,
-                       [38.30738567, 42.27020333])
-
-
- at pytest.mark.skipif('not HAS_SCIPY')
 def test_comoving_volume():
 
     c_flat = core.LambdaCDM(H0=70, Om0=0.27, Ode0=0.73, Tcmb0=0.0)
@@ -739,21 +879,6 @@ def test_integral():
                        cosmo.inv_efunc([1.0, 2.0, 6.0]), rtol=1e-7)
 
 
-def test_current():
-    with core.default_cosmology.set('WMAP7'):
-        cosmo = core.get_current()
-        assert cosmo == core.WMAP7
-    with core.default_cosmology.set('WMAP5'):
-        core.set_current('WMAP5')
-        assert core.get_current() == core.WMAP5
-    with core.default_cosmology.set('WMAP9'):
-        core.set_current('WMAP9')
-        assert core.get_current() == core.WMAP9
-    with core.default_cosmology.set('Planck13'):
-        core.set_current('Planck13')
-        assert core.get_current() == core.Planck13
-
-
 def test_wz():
     cosmo = core.LambdaCDM(H0=70, Om0=0.3, Ode0=0.70)
     assert np.allclose(cosmo.w([0.1, 0.2, 0.5, 1.5, 2.5, 11.5]),
@@ -849,12 +974,9 @@ def test_age():
 def test_distmod():
     # WMAP7 but with Omega_relativisitic = 0
     tcos = core.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0)
-    core.set_current(tcos)
     assert np.allclose(tcos.hubble_distance.value, 4258.415596590909)
     assert np.allclose(tcos.distmod([1, 5]).value, [44.124857, 48.40167258])
     assert np.allclose(tcos.distmod([1., 5.]).value, [44.124857, 48.40167258])
-    assert np.allclose(funcs.distmod([1, 5], cosmo=tcos).value,
-                       [44.124857, 48.40167258])
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
@@ -870,7 +992,7 @@ def test_neg_distmod():
 
 @pytest.mark.skipif('not HAS_SCIPY')
 def test_critical_density():
-    # WMAP7 but with Omega_relativisitic = 0
+    # WMAP7 but with Omega_relativistic = 0
     # These tests will fail if astropy.const starts returning non-mks
     #  units by default; see the comment at the top of core.py
     tcos = core.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0)
@@ -1033,22 +1155,29 @@ def test_massivenu_density():
 
 @pytest.mark.skipif('not HAS_SCIPY')
 def test_z_at_value():
+    # These are tests of expected values, and hence have less precision
+    # than the roundtrip tests below (test_z_at_value_roundtrip);
+    # here we have to worry about the cosmological calculations
+    # giving slightly different values on different architectures,
+    # there we are checking internal consistency on the same architecture
+    # and so can be more demanding
     z_at_value = funcs.z_at_value
     cosmo = core.Planck13
     d = cosmo.luminosity_distance(3)
-    assert np.allclose(z_at_value(cosmo.luminosity_distance, d, ztol=1e-8), 3,
+    assert np.allclose(z_at_value(cosmo.luminosity_distance, d), 3,
                        rtol=1e-8)
-    assert np.allclose(z_at_value(cosmo.age, 2 * u.Gyr), 3.1981191749374)
+    assert np.allclose(z_at_value(cosmo.age, 2 * u.Gyr), 3.198122684356,
+                       rtol=1e-6)
     assert np.allclose(z_at_value(cosmo.luminosity_distance, 1e4 * u.Mpc),
-                       1.3685792789133948)
+                       1.3685790653802761, rtol=1e-6)
     assert np.allclose(z_at_value(cosmo.lookback_time, 7 * u.Gyr),
-                       0.7951983674601507)
+                       0.7951983674601507, rtol=1e-6)
     assert np.allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc,
-                                  zmax=2), 0.681277696252886)
+                                  zmax=2), 0.68127769625288614, rtol=1e-6)
     assert np.allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc,
-                                  zmin=2.5), 3.7914918534022011)
+                                  zmin=2.5), 3.7914908028272083, rtol=1e-6)
     assert np.allclose(z_at_value(cosmo.distmod, 46 * u.mag),
-                       1.9913870174451891)
+                       1.9913891680278133, rtol=1e-6)
 
     # test behaviour when the solution is outside z limits (should
     # raise a CosmologyError)
@@ -1066,24 +1195,32 @@ def test_z_at_value_roundtrip():
     """
     z = 0.5
 
-    skip = ('z_at_value', 'angular_diameter_distance_z1z2', 'CosmologyError',
-            'deprecated')
+    # Skip Ok, w, de_density_scale because in the Planck13 cosmolgy
+    # they are redshift independent and hence uninvertable,
+    # angular_diameter_distance_z1z2 takes multiple arguments, so requires
+    #  special handling
+    # clone isn't a redshift-dependent method
+    skip = ('Ok', 'angular_diameter_distance_z1z2', 'clone',
+            'de_density_scale', 'w')
+
+    import inspect
+    methods = inspect.getmembers(core.Planck13, predicate=inspect.ismethod)
 
-    core.set_current('Planck13')
-    for name in funcs.__all__:
+    for name, func in methods:
         if name.startswith('_') or name in skip:
             continue
-        f = getattr(funcs, name)
-        if not hasattr(f, '__call__'):
-            continue
         print('Round-trip testing {0}'.format(name))
-        fval = f(z)
+        fval = func(z)
         # we need zmax here to pick the right solution for
         # angular_diameter_distance and related methods.
-        assert np.allclose(z, funcs.z_at_value(f, fval, zmax=1.5))
-
-
-def test_default_reset():
-    # Check that the default is being reset after tests. This test should be
-    # updated if the default cosmology is updated.
-    assert core.get_current() == core.WMAP9
+        # Be slightly more generous with rtol than the default 1e-8
+        # used in z_at_value
+        assert np.allclose(z, funcs.z_at_value(func, fval, zmax=1.5),
+                           rtol=2e-8)
+
+    # Test angular_diameter_distance_z1z2
+    z2 = 2.0
+    func = lambda z1: core.Planck13.angular_diameter_distance_z1z2(z1, z2)
+    fval = func(z)
+    assert np.allclose(z, funcs.z_at_value(func, fval, zmax=1.5),
+                       rtol=2e-8)
diff --git a/astropy/cosmology/tests/test_pickle.py b/astropy/cosmology/tests/test_pickle.py
new file mode 100644
index 0000000..96e8844
--- /dev/null
+++ b/astropy/cosmology/tests/test_pickle.py
@@ -0,0 +1,18 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import numpy as np
+
+from ...tests.helper import pytest, pickle_protocol, check_pickling_recovery
+from ...extern.six.moves import cPickle
+from ... import cosmology as cosm
+
+originals = [cosm.FLRW]
+xfails = [False]
+
+ at pytest.mark.parametrize("original,xfail",
+                         zip(originals, xfails))
+def test_flrw(pickle_protocol, original, xfail):
+    if xfail:
+        pytest.xfail()
+    check_pickling_recovery(original, pickle_protocol)
diff --git a/astropy/extern/bundled/six.py b/astropy/extern/bundled/six.py
index 7ec7f1b..7c285b1 100644
--- a/astropy/extern/bundled/six.py
+++ b/astropy/extern/bundled/six.py
@@ -20,12 +20,13 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
+import functools
 import operator
 import sys
 import types
 
 __author__ = "Benjamin Peterson <benjamin at python.org>"
-__version__ = "1.5.2"
+__version__ = "1.7.3"
 
 
 # Useful for very coarse version differentiation.
@@ -105,14 +106,6 @@ class MovedModule(_LazyDescr):
         return _import_module(self.mod)
 
     def __getattr__(self, attr):
-        # Hack around the Django autoreloader. The reloader tries to get
-        # __file__ or __name__ of every module in sys.modules. This doesn't work
-        # well if this MovedModule is for an module that is unavailable on this
-        # machine (like winreg on Unix systems). Thus, we pretend __file__ and
-        # __name__ don't exist if the module hasn't been loaded yet. See issues
-        # #51 and #53.
-        if attr in ("__file__", "__name__") and self.mod not in sys.modules:
-            raise AttributeError
         _module = self._resolve()
         value = getattr(_module, attr)
         setattr(self, attr, value)
@@ -159,9 +152,72 @@ class MovedAttribute(_LazyDescr):
         return getattr(module, self.attr)
 
 
+class _SixMetaPathImporter(object):
+    """
+    A meta path importer to import six.moves and its submodules.
+
+    This class implements a PEP302 finder and loader. It should be compatible
+    with Python 2.5 and all existing versions of Python3
+    """
+    def __init__(self, six_module_name):
+        self.name = six_module_name
+        self.known_modules = {}
+
+    def _add_module(self, mod, *fullnames):
+        for fullname in fullnames:
+            self.known_modules[self.name + "." + fullname] = mod
+
+    def _get_module(self, fullname):
+        return self.known_modules[self.name + "." + fullname]
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.known_modules:
+            return self
+        return None
+
+    def __get_module(self, fullname):
+        try:
+            return self.known_modules[fullname]
+        except KeyError:
+            raise ImportError("This loader does not know module " + fullname)
+
+    def load_module(self, fullname):
+        try:
+            # in case of a reload
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        mod = self.__get_module(fullname)
+        if isinstance(mod, MovedModule):
+            mod = mod._resolve()
+        else:
+            mod.__loader__ = self
+        sys.modules[fullname] = mod
+        return mod
+
+    def is_package(self, fullname):
+        """
+        Return true, if the named module is a package.
+
+        We need this method to get correct spec objects with
+        Python 3.4 (see PEP451)
+        """
+        return hasattr(self.__get_module(fullname), "__path__")
+
+    def get_code(self, fullname):
+        """Return None
+
+        Required, if is_package is implemented"""
+        self.__get_module(fullname)  # eventually raises ImportError
+        return None
+    get_source = get_code  # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
 
 class _MovedItems(_LazyModule):
     """Lazy loading of moved objects"""
+    __path__ = []  # mark as package
 
 
 _moved_attributes = [
@@ -174,6 +230,8 @@ _moved_attributes = [
     MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
     MovedAttribute("reduce", "__builtin__", "functools"),
     MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("UserDict", "UserDict", "collections"),
+    MovedAttribute("UserList", "UserList", "collections"),
     MovedAttribute("UserString", "UserString", "collections"),
     MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
     MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
@@ -183,12 +241,14 @@ _moved_attributes = [
     MovedModule("configparser", "ConfigParser"),
     MovedModule("copyreg", "copy_reg"),
     MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
     MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
     MovedModule("http_cookies", "Cookie", "http.cookies"),
     MovedModule("html_entities", "htmlentitydefs", "html.entities"),
     MovedModule("html_parser", "HTMLParser", "html.parser"),
     MovedModule("http_client", "httplib", "http.client"),
     MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
     MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
     MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
     MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
@@ -222,17 +282,19 @@ _moved_attributes = [
     MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
     MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
     MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
     MovedModule("winreg", "_winreg"),
 ]
 for attr in _moved_attributes:
     setattr(_MovedItems, attr.name, attr)
     if isinstance(attr, MovedModule):
-        sys.modules[__name__ + ".moves." + attr.name] = attr
+        _importer._add_module(attr, "moves." + attr.name)
 del attr
 
 _MovedItems._moved_attributes = _moved_attributes
 
-moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves")
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
 
 
 class Module_six_moves_urllib_parse(_LazyModule):
@@ -241,6 +303,7 @@ class Module_six_moves_urllib_parse(_LazyModule):
 
 _urllib_parse_moved_attributes = [
     MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
     MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
     MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
     MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
@@ -254,6 +317,9 @@ _urllib_parse_moved_attributes = [
     MovedAttribute("unquote", "urllib", "urllib.parse"),
     MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
     MovedAttribute("urlencode", "urllib", "urllib.parse"),
+    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+    MovedAttribute("splittag", "urllib", "urllib.parse"),
+    MovedAttribute("splituser", "urllib", "urllib.parse"),
 ]
 for attr in _urllib_parse_moved_attributes:
     setattr(Module_six_moves_urllib_parse, attr.name, attr)
@@ -261,7 +327,8 @@ del attr
 
 Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
 
-sys.modules[__name__ + ".moves.urllib_parse"] = sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse")
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+                      "moves.urllib_parse", "moves.urllib.parse")
 
 
 class Module_six_moves_urllib_error(_LazyModule):
@@ -279,7 +346,8 @@ del attr
 
 Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
 
-sys.modules[__name__ + ".moves.urllib_error"] = sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error")
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+                      "moves.urllib_error", "moves.urllib.error")
 
 
 class Module_six_moves_urllib_request(_LazyModule):
@@ -327,7 +395,8 @@ del attr
 
 Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
 
-sys.modules[__name__ + ".moves.urllib_request"] = sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request")
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+                      "moves.urllib_request", "moves.urllib.request")
 
 
 class Module_six_moves_urllib_response(_LazyModule):
@@ -346,7 +415,8 @@ del attr
 
 Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
 
-sys.modules[__name__ + ".moves.urllib_response"] = sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response")
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+                      "moves.urllib_response", "moves.urllib.response")
 
 
 class Module_six_moves_urllib_robotparser(_LazyModule):
@@ -362,22 +432,24 @@ del attr
 
 Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
 
-sys.modules[__name__ + ".moves.urllib_robotparser"] = sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser")
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+                      "moves.urllib_robotparser", "moves.urllib.robotparser")
 
 
 class Module_six_moves_urllib(types.ModuleType):
     """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
-    parse = sys.modules[__name__ + ".moves.urllib_parse"]
-    error = sys.modules[__name__ + ".moves.urllib_error"]
-    request = sys.modules[__name__ + ".moves.urllib_request"]
-    response = sys.modules[__name__ + ".moves.urllib_response"]
-    robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"]
+    __path__ = []  # mark as package
+    parse = _importer._get_module("moves.urllib_parse")
+    error = _importer._get_module("moves.urllib_error")
+    request = _importer._get_module("moves.urllib_request")
+    response = _importer._get_module("moves.urllib_response")
+    robotparser = _importer._get_module("moves.urllib_robotparser")
 
     def __dir__(self):
         return ['parse', 'error', 'request', 'response', 'robotparser']
 
-
-sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib")
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+                      "moves.urllib")
 
 
 def add_move(move):
@@ -404,11 +476,6 @@ if PY3:
     _func_code = "__code__"
     _func_defaults = "__defaults__"
     _func_globals = "__globals__"
-
-    _iterkeys = "keys"
-    _itervalues = "values"
-    _iteritems = "items"
-    _iterlists = "lists"
 else:
     _meth_func = "im_func"
     _meth_self = "im_self"
@@ -418,11 +485,6 @@ else:
     _func_defaults = "func_defaults"
     _func_globals = "func_globals"
 
-    _iterkeys = "iterkeys"
-    _itervalues = "itervalues"
-    _iteritems = "iteritems"
-    _iterlists = "iterlists"
-
 
 try:
     advance_iterator = next
@@ -471,21 +533,37 @@ get_function_defaults = operator.attrgetter(_func_defaults)
 get_function_globals = operator.attrgetter(_func_globals)
 
 
-def iterkeys(d, **kw):
-    """Return an iterator over the keys of a dictionary."""
-    return iter(getattr(d, _iterkeys)(**kw))
+if PY3:
+    def iterkeys(d, **kw):
+        return iter(d.keys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.values(**kw))
+
+    def iteritems(d, **kw):
+        return iter(d.items(**kw))
+
+    def iterlists(d, **kw):
+        return iter(d.lists(**kw))
+else:
+    def iterkeys(d, **kw):
+        return iter(d.iterkeys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.itervalues(**kw))
 
-def itervalues(d, **kw):
-    """Return an iterator over the values of a dictionary."""
-    return iter(getattr(d, _itervalues)(**kw))
+    def iteritems(d, **kw):
+        return iter(d.iteritems(**kw))
 
-def iteritems(d, **kw):
-    """Return an iterator over the (key, value) pairs of a dictionary."""
-    return iter(getattr(d, _iteritems)(**kw))
+    def iterlists(d, **kw):
+        return iter(d.iterlists(**kw))
 
-def iterlists(d, **kw):
-    """Return an iterator over the (key, [values]) pairs of a dictionary."""
-    return iter(getattr(d, _iterlists)(**kw))
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+         "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+         "Return an iterator over the (key, [values]) pairs of a dictionary.")
 
 
 if PY3:
@@ -531,6 +609,8 @@ if PY3:
 
 
     def reraise(tp, value, tb=None):
+        if value is None:
+            value = tp()
         if value.__traceback__ is not tb:
             raise value.with_traceback(tb)
         raise value
@@ -611,10 +691,27 @@ if print_ is None:
 
 _add_doc(reraise, """Reraise an exception.""")
 
+if sys.version_info[0:2] < (3, 4):
+    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+              updated=functools.WRAPPER_UPDATES):
+        def wrapper(f):
+            f = functools.wraps(wrapped)(f)
+            f.__wrapped__ = wrapped
+            return f
+        return wrapper
+else:
+    wraps = functools.wraps
 
 def with_metaclass(meta, *bases):
     """Create a base class with a metaclass."""
-    return meta("NewBase", bases, {})
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+
 
 def add_metaclass(metaclass):
     """Class decorator for creating a class with a metaclass."""
@@ -630,3 +727,27 @@ def add_metaclass(metaclass):
                 orig_vars.pop(slots_var)
         return metaclass(cls.__name__, cls.__bases__, orig_vars)
     return wrapper
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = []  # required for PEP 302 and PEP 451
+__package__ = __name__  # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+    for i, importer in enumerate(sys.meta_path):
+        # Here's some real nastiness: Another "instance" of the six module might
+        # be floating around. Therefore, we can't use isinstance() to check for
+        # the six meta path importer, since the other six instance will have
+        # inserted an importer with different class.
+        if (type(importer).__name__ == "_SixMetaPathImporter" and
+            importer.name == __name__):
+            del sys.meta_path[i]
+            break
+    del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/astropy/extern/configobj.py b/astropy/extern/configobj.py
index 5a5e39d..8d1bd8c 100644
--- a/astropy/extern/configobj.py
+++ b/astropy/extern/configobj.py
@@ -7,11 +7,5 @@ currently installed version of python.
 Also, this should actually never actually show up as a docstring, because
 it should get overwritten by the appropriate configobj docstring.
 """
-from sys import version_info
 
-if version_info[0] > 2:
-    from .configobj_py3 import configobj, validate, __doc__
-else:
-    from .configobj_py2 import configobj, validate, __doc__
-
-del version_info #cleans up the namespace
+from .configobj import configobj, validate, __doc__
diff --git a/astropy/extern/configobj/__init__.py b/astropy/extern/configobj/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy/extern/configobj/configobj.py b/astropy/extern/configobj/configobj.py
new file mode 100755
index 0000000..cceaeb4
--- /dev/null
+++ b/astropy/extern/configobj/configobj.py
@@ -0,0 +1,2484 @@
+# configobj.py
+# A config file reader/writer that supports nested sections in config files.
+# Copyright (C) 2005-2014:
+# (name) : (email)
+# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
+# Nicola Larosa: nico AT tekNico DOT net
+# Rob Dennis: rdennis AT gmail DOT com
+# Eli Courtwright: eli AT courtwright DOT org
+
+# This software is licensed under the terms of the BSD license.
+# http://opensource.org/licenses/BSD-3-Clause
+
+# ConfigObj 5 - main repository for documentation and issue tracking:
+# https://github.com/DiffSK/configobj
+
+import os
+import re
+import sys
+import collections
+
+from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
+
+from ...extern import six
+# from __future__ import __version__
+
+# imported lazily to avoid startup performance hit if it isn't used
+compiler = None
+
+# A dictionary mapping BOM to
+# the encoding to decode with, and what to set the
+# encoding attribute to.
+BOMS = {
+    BOM_UTF8: ('utf_8', None),
+    BOM_UTF16_BE: ('utf16_be', 'utf_16'),
+    BOM_UTF16_LE: ('utf16_le', 'utf_16'),
+    BOM_UTF16: ('utf_16', 'utf_16'),
+    }
+# All legal variants of the BOM codecs.
+# TODO: the list of aliases is not meant to be exhaustive, is there a
+#   better way ?
+BOM_LIST = {
+    'utf_16': 'utf_16',
+    'u16': 'utf_16',
+    'utf16': 'utf_16',
+    'utf-16': 'utf_16',
+    'utf16_be': 'utf16_be',
+    'utf_16_be': 'utf16_be',
+    'utf-16be': 'utf16_be',
+    'utf16_le': 'utf16_le',
+    'utf_16_le': 'utf16_le',
+    'utf-16le': 'utf16_le',
+    'utf_8': 'utf_8',
+    'u8': 'utf_8',
+    'utf': 'utf_8',
+    'utf8': 'utf_8',
+    'utf-8': 'utf_8',
+    }
+
+# Map of encodings to the BOM to write.
+BOM_SET = {
+    'utf_8': BOM_UTF8,
+    'utf_16': BOM_UTF16,
+    'utf16_be': BOM_UTF16_BE,
+    'utf16_le': BOM_UTF16_LE,
+    None: BOM_UTF8
+    }
+
+
+def match_utf8(encoding):
+    return BOM_LIST.get(encoding.lower()) == 'utf_8'
+
+
+# Quote strings used for writing values
+squot = "'%s'"
+dquot = '"%s"'
+noquot = "%s"
+wspace_plus = ' \r\n\v\t\'"'
+tsquot = '"""%s"""'
+tdquot = "'''%s'''"
+
+# Sentinel for use in getattr calls to replace hasattr
+MISSING = object()
+
+__all__ = (
+    'DEFAULT_INDENT_TYPE',
+    'DEFAULT_INTERPOLATION',
+    'ConfigObjError',
+    'NestingError',
+    'ParseError',
+    'DuplicateError',
+    'ConfigspecError',
+    'ConfigObj',
+    'SimpleVal',
+    'InterpolationError',
+    'InterpolationLoopError',
+    'MissingInterpolationOption',
+    'RepeatSectionError',
+    'ReloadError',
+    'UnreprError',
+    'UnknownType',
+    'flatten_errors',
+    'get_extra_values'
+)
+
+DEFAULT_INTERPOLATION = 'configparser'
+DEFAULT_INDENT_TYPE = '    '
+MAX_INTERPOL_DEPTH = 10
+
+OPTION_DEFAULTS = {
+    'interpolation': True,
+    'raise_errors': False,
+    'list_values': True,
+    'create_empty': False,
+    'file_error': False,
+    'configspec': None,
+    'stringify': True,
+    # option may be set to one of ('', ' ', '\t')
+    'indent_type': None,
+    'encoding': None,
+    'default_encoding': None,
+    'unrepr': False,
+    'write_empty_values': False,
+}
+
+# this could be replaced if six is used for compatibility, or there are no
+# more assertions about items being a string
+
+
+def getObj(s):
+    global compiler
+    if compiler is None:
+        import compiler
+    s = "a=" + s
+    p = compiler.parse(s)
+    return p.getChildren()[1].getChildren()[0].getChildren()[1]
+
+
+class UnknownType(Exception):
+    pass
+
+
+class Builder(object):
+    
+    def build(self, o):
+        if m is None:
+            raise UnknownType(o.__class__.__name__)
+        return m(o)
+    
+    def build_List(self, o):
+        return list(map(self.build, o.getChildren()))
+    
+    def build_Const(self, o):
+        return o.value
+    
+    def build_Dict(self, o):
+        d = {}
+        i = iter(map(self.build, o.getChildren()))
+        for el in i:
+            d[el] = next(i)
+        return d
+    
+    def build_Tuple(self, o):
+        return tuple(self.build_List(o))
+    
+    def build_Name(self, o):
+        if o.name == 'None':
+            return None
+        if o.name == 'True':
+            return True
+        if o.name == 'False':
+            return False
+        
+        # An undefined Name
+        raise UnknownType('Undefined Name')
+    
+    def build_Add(self, o):
+        real, imag = list(map(self.build_Const, o.getChildren()))
+        try:
+            real = float(real)
+        except TypeError:
+            raise UnknownType('Add')
+        if not isinstance(imag, complex) or imag.real != 0.0:
+            raise UnknownType('Add')
+        return real+imag
+    
+    def build_Getattr(self, o):
+        parent = self.build(o.expr)
+        return getattr(parent, o.attrname)
+    
+    def build_UnarySub(self, o):
+        return -self.build_Const(o.getChildren()[0])
+    
+    def build_UnaryAdd(self, o):
+        return self.build_Const(o.getChildren()[0])
+
+
+_builder = Builder()
+
+
+def unrepr(s):
+    if not s:
+        return s
+    
+    # this is supposed to be safe
+    import ast
+    return ast.literal_eval(s)
+
+
+class ConfigObjError(SyntaxError):
+    """
+    This is the base class for all errors that ConfigObj raises.
+    It is a subclass of SyntaxError.
+    """
+    def __init__(self, message='', line_number=None, line=''):
+        self.line = line
+        self.line_number = line_number
+        SyntaxError.__init__(self, message)
+
+
+class NestingError(ConfigObjError):
+    """
+    This error indicates a level of nesting that doesn't match.
+    """
+
+
+class ParseError(ConfigObjError):
+    """
+    This error indicates that a line is badly written.
+    It is neither a valid ``key = value`` line,
+    nor a valid section marker line.
+    """
+
+
+class ReloadError(IOError):
+    """
+    A 'reload' operation failed.
+    This exception is a subclass of ``IOError``.
+    """
+    def __init__(self):
+        IOError.__init__(self, 'reload failed, filename is not set.')
+
+
+class DuplicateError(ConfigObjError):
+    """
+    The keyword or section specified already exists.
+    """
+
+
+class ConfigspecError(ConfigObjError):
+    """
+    An error occured whilst parsing a configspec.
+    """
+
+
+class InterpolationError(ConfigObjError):
+    """Base class for the two interpolation errors."""
+
+
+class InterpolationLoopError(InterpolationError):
+    """Maximum interpolation depth exceeded in string interpolation."""
+
+    def __init__(self, option):
+        InterpolationError.__init__(
+            self,
+            'interpolation loop detected in value "%s".' % option)
+
+
+class RepeatSectionError(ConfigObjError):
+    """
+    This error indicates additional sections in a section with a
+    ``__many__`` (repeated) section.
+    """
+
+
+class MissingInterpolationOption(InterpolationError):
+    """A value specified for interpolation was missing."""
+    def __init__(self, option):
+        msg = 'missing option "%s" in interpolation.' % option
+        InterpolationError.__init__(self, msg)
+
+
+class UnreprError(ConfigObjError):
+    """An error parsing in unrepr mode."""
+
+
+
+class InterpolationEngine(object):
+    """
+    A helper class to help perform string interpolation.
+
+    This class is an abstract base class; its descendants perform
+    the actual work.
+    """
+
+    # compiled regexp to use in self.interpolate()
+    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
+    _cookie = '%'
+
+    def __init__(self, section):
+        # the Section instance that "owns" this engine
+        self.section = section
+
+
+    def interpolate(self, key, value):
+        # short-cut
+        if not self._cookie in value:
+            return value
+        
+        def recursive_interpolate(key, value, section, backtrail):
+            """The function that does the actual work.
+
+            ``value``: the string we're trying to interpolate.
+            ``section``: the section in which that string was found
+            ``backtrail``: a dict to keep track of where we've been,
+            to detect and prevent infinite recursion loops
+
+            This is similar to a depth-first-search algorithm.
+            """
+            # Have we been here already?
+            if (key, section.name) in backtrail:
+                # Yes - infinite loop detected
+                raise InterpolationLoopError(key)
+            # Place a marker on our backtrail so we won't come back here again
+            backtrail[(key, section.name)] = 1
+
+            # Now start the actual work
+            match = self._KEYCRE.search(value)
+            while match:
+                # The actual parsing of the match is implementation-dependent,
+                # so delegate to our helper function
+                k, v, s = self._parse_match(match)
+                if k is None:
+                    # That's the signal that no further interpolation is needed
+                    replacement = v
+                else:
+                    # Further interpolation may be needed to obtain final value
+                    replacement = recursive_interpolate(k, v, s, backtrail)
+                # Replace the matched string with its final value
+                start, end = match.span()
+                value = ''.join((value[:start], replacement, value[end:]))
+                new_search_start = start + len(replacement)
+                # Pick up the next interpolation key, if any, for next time
+                # through the while loop
+                match = self._KEYCRE.search(value, new_search_start)
+
+            # Now safe to come back here again; remove marker from backtrail
+            del backtrail[(key, section.name)]
+
+            return value
+
+        # Back in interpolate(), all we have to do is kick off the recursive
+        # function with appropriate starting values
+        value = recursive_interpolate(key, value, self.section, {})
+        return value
+
+
+    def _fetch(self, key):
+        """Helper function to fetch values from owning section.
+
+        Returns a 2-tuple: the value, and the section where it was found.
+        """
+        # switch off interpolation before we try and fetch anything !
+        save_interp = self.section.main.interpolation
+        self.section.main.interpolation = False
+
+        # Start at section that "owns" this InterpolationEngine
+        current_section = self.section
+        while True:
+            # try the current section first
+            val = current_section.get(key)
+            if val is not None and not isinstance(val, Section):
+                break
+            # try "DEFAULT" next
+            val = current_section.get('DEFAULT', {}).get(key)
+            if val is not None and not isinstance(val, Section):
+                break
+            # move up to parent and try again
+            # top-level's parent is itself
+            if current_section.parent is current_section:
+                # reached top level, time to give up
+                break
+            current_section = current_section.parent
+
+        # restore interpolation to previous value before returning
+        self.section.main.interpolation = save_interp
+        if val is None:
+            raise MissingInterpolationOption(key)
+        return val, current_section
+
+
+    def _parse_match(self, match):
+        """Implementation-dependent helper function.
+
+        Will be passed a match object corresponding to the interpolation
+        key we just found (e.g., "%(foo)s" or "$foo"). Should look up that
+        key in the appropriate config file section (using the ``_fetch()``
+        helper function) and return a 3-tuple: (key, value, section)
+
+        ``key`` is the name of the key we're looking for
+        ``value`` is the value found for that key
+        ``section`` is a reference to the section where it was found
+
+        ``key`` and ``section`` should be None if no further
+        interpolation should be performed on the resulting value
+        (e.g., if we interpolated "$$" and returned "$").
+        """
+        raise NotImplementedError()
+    
+
+
+class ConfigParserInterpolation(InterpolationEngine):
+    """Behaves like ConfigParser."""
+    _cookie = '%'
+    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
+
+    def _parse_match(self, match):
+        key = match.group(1)
+        value, section = self._fetch(key)
+        return key, value, section
+
+
+
+class TemplateInterpolation(InterpolationEngine):
+    """Behaves like string.Template."""
+    _cookie = '$'
+    _delimiter = '$'
+    _KEYCRE = re.compile(r"""
+        \$(?:
+          (?P<escaped>\$)              |   # Two $ signs
+          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format
+          {(?P<braced>[^}]*)}              # ${name} format
+        )
+        """, re.IGNORECASE | re.VERBOSE)
+
+    def _parse_match(self, match):
+        # Valid name (in or out of braces): fetch value from section
+        key = match.group('named') or match.group('braced')
+        if key is not None:
+            value, section = self._fetch(key)
+            return key, value, section
+        # Escaped delimiter (e.g., $$): return single delimiter
+        if match.group('escaped') is not None:
+            # Return None for key and section to indicate it's time to stop
+            return None, self._delimiter, None
+        # Anything else: ignore completely, just return it unchanged
+        return None, match.group(), None
+
+
+interpolation_engines = {
+    'configparser': ConfigParserInterpolation,
+    'template': TemplateInterpolation,
+}
+
+
+def __newobj__(cls, *args):
+    # Hack for pickle
+    return cls.__new__(cls, *args) 
+
+class Section(dict):
+    """
+    A dictionary-like object that represents a section in a config file.
+    
+    It does string interpolation if the 'interpolation' attribute
+    of the 'main' object is set to True.
+    
+    Interpolation is tried first from this object, then from the 'DEFAULT'
+    section of this object, next from the parent and its 'DEFAULT' section,
+    and so on until the main object is reached.
+    
+    A Section will behave like an ordered dictionary - following the
+    order of the ``scalars`` and ``sections`` attributes.
+    You can use this to change the order of members.
+    
+    Iteration follows the order: scalars, then sections.
+    """
+
+    
+    def __setstate__(self, state):
+        dict.update(self, state[0])
+        self.__dict__.update(state[1])
+
+    def __reduce__(self):
+        state = (dict(self), self.__dict__)
+        return (__newobj__, (self.__class__,), state)
+    
+    
+    def __init__(self, parent, depth, main, indict=None, name=None):
+        """
+        * parent is the section above
+        * depth is the depth level of this section
+        * main is the main ConfigObj
+        * indict is a dictionary to initialise the section with
+        """
+        if indict is None:
+            indict = {}
+        dict.__init__(self)
+        # used for nesting level *and* interpolation
+        self.parent = parent
+        # used for the interpolation attribute
+        self.main = main
+        # level of nesting depth of this Section
+        self.depth = depth
+        # purely for information
+        self.name = name
+        #
+        self._initialise()
+        # we do this explicitly so that __setitem__ is used properly
+        # (rather than just passing to ``dict.__init__``)
+        for entry, value in indict.items():
+            self[entry] = value
+            
+            
+    def _initialise(self):
+        # the sequence of scalar values in this Section
+        self.scalars = []
+        # the sequence of sections in this Section
+        self.sections = []
+        # for comments :-)
+        self.comments = {}
+        self.inline_comments = {}
+        # the configspec
+        self.configspec = None
+        # for defaults
+        self.defaults = []
+        self.default_values = {}
+        self.extra_values = []
+        self._created = False
+
+
+    def _interpolate(self, key, value):
+        try:
+            # do we already have an interpolation engine?
+            engine = self._interpolation_engine
+        except AttributeError:
+            # not yet: first time running _interpolate(), so pick the engine
+            name = self.main.interpolation
+            if name == True:  # note that "if name:" would be incorrect here
+                # backwards-compatibility: interpolation=True means use default
+                name = DEFAULT_INTERPOLATION
+            name = name.lower()  # so that "Template", "template", etc. all work
+            class_ = interpolation_engines.get(name, None)
+            if class_ is None:
+                # invalid value for self.main.interpolation
+                self.main.interpolation = False
+                return value
+            else:
+                # save reference to engine so we don't have to do this again
+                engine = self._interpolation_engine = class_(self)
+        # let the engine do the actual work
+        return engine.interpolate(key, value)
+
+
+    def __getitem__(self, key):
+        """Fetch the item and do string interpolation."""
+        val = dict.__getitem__(self, key)
+        if self.main.interpolation: 
+            if isinstance(val, six.string_types):
+                return self._interpolate(key, val)
+            if isinstance(val, list):
+                def _check(entry):
+                    if isinstance(entry, six.string_types):
+                        return self._interpolate(key, entry)
+                    return entry
+                new = [_check(entry) for entry in val]
+                if new != val:
+                    return new
+        return val
+
+
+    def __setitem__(self, key, value, unrepr=False):
+        """
+        Correctly set a value.
+        
+        Making dictionary values Section instances.
+        (We have to special case 'Section' instances - which are also dicts)
+        
+        Keys must be strings.
+        Values need only be strings (or lists of strings) if
+        ``main.stringify`` is set.
+        
+        ``unrepr`` must be set when setting a value to a dictionary, without
+        creating a new sub-section.
+        """
+        if not isinstance(key, six.string_types):
+            raise ValueError('The key "%s" is not a string.' % key)
+        
+        # add the comment
+        if key not in self.comments:
+            self.comments[key] = []
+            self.inline_comments[key] = ''
+        # remove the entry from defaults
+        if key in self.defaults:
+            self.defaults.remove(key)
+        #
+        if isinstance(value, Section):
+            if key not in self:
+                self.sections.append(key)
+            dict.__setitem__(self, key, value)
+        elif isinstance(value, collections.Mapping) and not unrepr:
+            # First create the new depth level,
+            # then create the section
+            if key not in self:
+                self.sections.append(key)
+            new_depth = self.depth + 1
+            dict.__setitem__(
+                self,
+                key,
+                Section(
+                    self,
+                    new_depth,
+                    self.main,
+                    indict=value,
+                    name=key))
+        else:
+            if key not in self:
+                self.scalars.append(key)
+            if not self.main.stringify:
+                if isinstance(value, six.string_types):
+                    pass
+                elif isinstance(value, (list, tuple)):
+                    for entry in value:
+                        if not isinstance(entry, six.string_types):
+                            raise TypeError('Value is not a string "%s".' % entry)
+                else:
+                    raise TypeError('Value is not a string "%s".' % value)
+            dict.__setitem__(self, key, value)
+
+
+    def __delitem__(self, key):
+        """Remove items from the sequence when deleting."""
+        dict. __delitem__(self, key)
+        if key in self.scalars:
+            self.scalars.remove(key)
+        else:
+            self.sections.remove(key)
+        del self.comments[key]
+        del self.inline_comments[key]
+
+
+    def get(self, key, default=None):
+        """A version of ``get`` that doesn't bypass string interpolation."""
+        try:
+            return self[key]
+        except KeyError:
+            return default
+
+
+    def update(self, indict):
+        """
+        A version of update that uses our ``__setitem__``.
+        """
+        for entry in indict:
+            self[entry] = indict[entry]
+
+
+    def pop(self, key, default=MISSING):
+        """
+        'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
+        If key is not found, d is returned if given, otherwise KeyError is raised'
+        """
+        try:
+            val = self[key]
+        except KeyError:
+            if default is MISSING:
+                raise
+            val = default
+        else:
+            del self[key]
+        return val
+
+
+    def popitem(self):
+        """Pops the first (key,val)"""
+        sequence = (self.scalars + self.sections)
+        if not sequence:
+            raise KeyError(": 'popitem(): dictionary is empty'")
+        key = sequence[0]
+        val =  self[key]
+        del self[key]
+        return key, val
+
+
+    def clear(self):
+        """
+        A version of clear that also affects scalars/sections
+        Also clears comments and configspec.
+        
+        Leaves other attributes alone :
+            depth/main/parent are not affected
+        """
+        dict.clear(self)
+        self.scalars = []
+        self.sections = []
+        self.comments = {}
+        self.inline_comments = {}
+        self.configspec = None
+        self.defaults = []
+        self.extra_values = []
+
+
+    def setdefault(self, key, default=None):
+        """A version of setdefault that sets sequence if appropriate."""
+        try:
+            return self[key]
+        except KeyError:
+            self[key] = default
+            return self[key]
+
+
+    def items(self):
+        """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
+        return list(zip((self.scalars + self.sections), list(self.values())))
+
+
+    def keys(self):
+        """D.keys() -> list of D's keys"""
+        return (self.scalars + self.sections)
+
+
+    def values(self):
+        """D.values() -> list of D's values"""
+        return [self[key] for key in (self.scalars + self.sections)]
+
+
+    def iteritems(self):
+        """D.iteritems() -> an iterator over the (key, value) items of D"""
+        return iter(list(self.items()))
+
+
+    def iterkeys(self):
+        """D.iterkeys() -> an iterator over the keys of D"""
+        return iter((self.scalars + self.sections))
+
+    __iter__ = iterkeys
+
+
+    def itervalues(self):
+        """D.itervalues() -> an iterator over the values of D"""
+        return iter(list(self.values()))
+
+
+    def __repr__(self):
+        """x.__repr__() <==> repr(x)"""
+        def _getval(key):
+            try:
+                return self[key]
+            except MissingInterpolationOption:
+                return dict.__getitem__(self, key)
+        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key))))
+            for key in (self.scalars + self.sections)])
+
+    __str__ = __repr__
+    __str__.__doc__ = "x.__str__() <==> str(x)"
+
+
+    # Extra methods - not in a normal dictionary
+
+    def dict(self):
+        """
+        Return a deepcopy of self as a dictionary.
+        
+        All members that are ``Section`` instances are recursively turned to
+        ordinary dictionaries - by calling their ``dict`` method.
+        
+        >>> n = a.dict()
+        >>> n == a
+        1
+        >>> n is a
+        0
+        """
+        newdict = {}
+        for entry in self:
+            this_entry = self[entry]
+            if isinstance(this_entry, Section):
+                this_entry = this_entry.dict()
+            elif isinstance(this_entry, list):
+                # create a copy rather than a reference
+                this_entry = list(this_entry)
+            elif isinstance(this_entry, tuple):
+                # create a copy rather than a reference
+                this_entry = tuple(this_entry)
+            newdict[entry] = this_entry
+        return newdict
+
+
+    def merge(self, indict):
+        """
+        A recursive update - useful for merging config files.
+        
+        >>> a = '''[section1]
+        ...     option1 = True
+        ...     [[subsection]]
+        ...     more_options = False
+        ...     # end of file'''.splitlines()
+        >>> b = '''# File is user.ini
+        ...     [section1]
+        ...     option1 = False
+        ...     # end of file'''.splitlines()
+        >>> c1 = ConfigObj(b)
+        >>> c2 = ConfigObj(a)
+        >>> c2.merge(c1)
+        >>> c2
+        ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}})
+        """
+        for key, val in list(indict.items()):
+            if (key in self and isinstance(self[key], collections.Mapping) and
+                                isinstance(val, collections.Mapping)):
+                self[key].merge(val)
+            else:   
+                self[key] = val
+
+
+    def rename(self, oldkey, newkey):
+        """
+        Change a keyname to another, without changing position in sequence.
+        
+        Implemented so that transformations can be made on keys,
+        as well as on values. (used by encode and decode)
+        
+        Also renames comments.
+        """
+        if oldkey in self.scalars:
+            the_list = self.scalars
+        elif oldkey in self.sections:
+            the_list = self.sections
+        else:
+            raise KeyError('Key "%s" not found.' % oldkey)
+        pos = the_list.index(oldkey)
+        #
+        val = self[oldkey]
+        dict.__delitem__(self, oldkey)
+        dict.__setitem__(self, newkey, val)
+        the_list.remove(oldkey)
+        the_list.insert(pos, newkey)
+        comm = self.comments[oldkey]
+        inline_comment = self.inline_comments[oldkey]
+        del self.comments[oldkey]
+        del self.inline_comments[oldkey]
+        self.comments[newkey] = comm
+        self.inline_comments[newkey] = inline_comment
+
+
+    def walk(self, function, raise_errors=True,
+            call_on_sections=False, **keywargs):
+        """
+        Walk every member and call a function on the keyword and value.
+        
+        Return a dictionary of the return values
+        
+        If the function raises an exception, raise the errror
+        unless ``raise_errors=False``, in which case set the return value to
+        ``False``.
+        
+        Any unrecognised keyword arguments you pass to walk, will be pased on
+        to the function you pass in.
+        
+        Note: if ``call_on_sections`` is ``True`` then - on encountering a
+        subsection, *first* the function is called for the *whole* subsection,
+        and then recurses into it's members. This means your function must be
+        able to handle strings, dictionaries and lists. This allows you
+        to change the key of subsections as well as for ordinary members. The
+        return value when called on the whole subsection has to be discarded.
+        
+        See  the encode and decode methods for examples, including functions.
+        
+        .. admonition:: caution
+        
+            You can use ``walk`` to transform the names of members of a section
+            but you mustn't add or delete members.
+        
+        >>> config = '''[XXXXsection]
+        ... XXXXkey = XXXXvalue'''.splitlines()
+        >>> cfg = ConfigObj(config)
+        >>> cfg
+        ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
+        >>> def transform(section, key):
+        ...     val = section[key]
+        ...     newkey = key.replace('XXXX', 'CLIENT1')
+        ...     section.rename(key, newkey)
+        ...     if isinstance(val, (tuple, list, dict)):
+        ...         pass
+        ...     else:
+        ...         val = val.replace('XXXX', 'CLIENT1')
+        ...         section[newkey] = val
+        >>> cfg.walk(transform, call_on_sections=True)
+        {'CLIENT1section': {'CLIENT1key': None}}
+        >>> cfg
+        ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}})
+        """
+        out = {}
+        # scalars first
+        for i in range(len(self.scalars)):
+            entry = self.scalars[i]
+            try:
+                val = function(self, entry, **keywargs)
+                # bound again in case name has changed
+                entry = self.scalars[i]
+                out[entry] = val
+            except Exception:
+                if raise_errors:
+                    raise
+                else:
+                    entry = self.scalars[i]
+                    out[entry] = False
+        # then sections
+        for i in range(len(self.sections)):
+            entry = self.sections[i]
+            if call_on_sections:
+                try:
+                    function(self, entry, **keywargs)
+                except Exception:
+                    if raise_errors:
+                        raise
+                    else:
+                        entry = self.sections[i]
+                        out[entry] = False
+                # bound again in case name has changed
+                entry = self.sections[i]
+            # previous result is discarded
+            out[entry] = self[entry].walk(
+                function,
+                raise_errors=raise_errors,
+                call_on_sections=call_on_sections,
+                **keywargs)
+        return out
+
+
+    def as_bool(self, key):
+        """
+        Accepts a key as input. The corresponding value must be a string or
+        the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
+        retain compatibility with Python 2.2.
+        
+        If the string is one of  ``True``, ``On``, ``Yes``, or ``1`` it returns 
+        ``True``.
+        
+        If the string is one of  ``False``, ``Off``, ``No``, or ``0`` it returns 
+        ``False``.
+        
+        ``as_bool`` is not case sensitive.
+        
+        Any other input will raise a ``ValueError``.
+        
+        >>> a = ConfigObj()
+        >>> a['a'] = 'fish'
+        >>> a.as_bool('a')
+        Traceback (most recent call last):
+        ValueError: Value "fish" is neither True nor False
+        >>> a['b'] = 'True'
+        >>> a.as_bool('b')
+        1
+        >>> a['b'] = 'off'
+        >>> a.as_bool('b')
+        0
+        """
+        val = self[key]
+        if val == True:
+            return True
+        elif val == False:
+            return False
+        else:
+            try:
+                if not isinstance(val, six.string_types):
+                    # TODO: Why do we raise a KeyError here?
+                    raise KeyError()
+                else:
+                    return self.main._bools[val.lower()]
+            except KeyError:
+                raise ValueError('Value "%s" is neither True nor False' % val)
+
+
+    def as_int(self, key):
+        """
+        A convenience method which coerces the specified value to an integer.
+        
+        If the value is an invalid literal for ``int``, a ``ValueError`` will
+        be raised.
+        
+        >>> a = ConfigObj()
+        >>> a['a'] = 'fish'
+        >>> a.as_int('a')
+        Traceback (most recent call last):
+        ValueError: invalid literal for int() with base 10: 'fish'
+        >>> a['b'] = '1'
+        >>> a.as_int('b')
+        1
+        >>> a['b'] = '3.2'
+        >>> a.as_int('b')
+        Traceback (most recent call last):
+        ValueError: invalid literal for int() with base 10: '3.2'
+        """
+        return int(self[key])
+
+
+    def as_float(self, key):
+        """
+        A convenience method which coerces the specified value to a float.
+        
+        If the value is an invalid literal for ``float``, a ``ValueError`` will
+        be raised.
+        
+        >>> a = ConfigObj()
+        >>> a['a'] = 'fish'
+        >>> a.as_float('a')  #doctest: +IGNORE_EXCEPTION_DETAIL
+        Traceback (most recent call last):
+        ValueError: invalid literal for float(): fish
+        >>> a['b'] = '1'
+        >>> a.as_float('b')
+        1.0
+        >>> a['b'] = '3.2'
+        >>> a.as_float('b')  #doctest: +ELLIPSIS
+        3.2...
+        """
+        return float(self[key])
+    
+    
+    def as_list(self, key):
+        """
+        A convenience method which fetches the specified value, guaranteeing
+        that it is a list.
+        
+        >>> a = ConfigObj()
+        >>> a['a'] = 1
+        >>> a.as_list('a')
+        [1]
+        >>> a['a'] = (1,)
+        >>> a.as_list('a')
+        [1]
+        >>> a['a'] = [1]
+        >>> a.as_list('a')
+        [1]
+        """
+        result = self[key]
+        if isinstance(result, (tuple, list)):
+            return list(result)
+        return [result]
+        
+
+    def restore_default(self, key):
+        """
+        Restore (and return) default value for the specified key.
+        
+        This method will only work for a ConfigObj that was created
+        with a configspec and has been validated.
+        
+        If there is no default value for this key, ``KeyError`` is raised.
+        """
+        default = self.default_values[key]
+        dict.__setitem__(self, key, default)
+        if key not in self.defaults:
+            self.defaults.append(key)
+        return default
+
+    
+    def restore_defaults(self):
+        """
+        Recursively restore default values to all members
+        that have them.
+        
+        This method will only work for a ConfigObj that was created
+        with a configspec and has been validated.
+        
+        It doesn't delete or modify entries without default values.
+        """
+        for key in self.default_values:
+            self.restore_default(key)
+            
+        for section in self.sections:
+            self[section].restore_defaults()
+
+
+class ConfigObj(Section):
+    """An object to read, create, and write config files."""
+
+    _keyword = re.compile(r'''^ # line start
+        (\s*)                   # indentation
+        (                       # keyword
+            (?:".*?")|          # double quotes
+            (?:'.*?')|          # single quotes
+            (?:[^'"=].*?)       # no quotes
+        )
+        \s*=\s*                 # divider
+        (.*)                    # value (including list values and comments)
+        $   # line end
+        ''',
+        re.VERBOSE)
+
+    _sectionmarker = re.compile(r'''^
+        (\s*)                     # 1: indentation
+        ((?:\[\s*)+)              # 2: section marker open
+        (                         # 3: section name open
+            (?:"\s*\S.*?\s*")|    # at least one non-space with double quotes
+            (?:'\s*\S.*?\s*')|    # at least one non-space with single quotes
+            (?:[^'"\s].*?)        # at least one non-space unquoted
+        )                         # section name close
+        ((?:\s*\])+)              # 4: section marker close
+        \s*(\#.*)?                # 5: optional comment
+        $''',
+        re.VERBOSE)
+
+    # this regexp pulls list values out as a single string
+    # or single values and comments
+    # FIXME: this regex adds a '' to the end of comma terminated lists
+    #   workaround in ``_handle_value``
+    _valueexp = re.compile(r'''^
+        (?:
+            (?:
+                (
+                    (?:
+                        (?:
+                            (?:".*?")|              # double quotes
+                            (?:'.*?')|              # single quotes
+                            (?:[^'",\#][^,\#]*?)    # unquoted
+                        )
+                        \s*,\s*                     # comma
+                    )*      # match all list items ending in a comma (if any)
+                )
+                (
+                    (?:".*?")|                      # double quotes
+                    (?:'.*?')|                      # single quotes
+                    (?:[^'",\#\s][^,]*?)|           # unquoted
+                    (?:(?<!,))                      # Empty value
+                )?          # last item in a list - or string value
+            )|
+            (,)             # alternatively a single comma - empty list
+        )
+        \s*(\#.*)?          # optional comment
+        $''',
+        re.VERBOSE)
+
+    # use findall to get the members of a list value
+    _listvalueexp = re.compile(r'''
+        (
+            (?:".*?")|          # double quotes
+            (?:'.*?')|          # single quotes
+            (?:[^'",\#]?.*?)       # unquoted
+        )
+        \s*,\s*                 # comma
+        ''',
+        re.VERBOSE)
+
+    # this regexp is used for the value
+    # when lists are switched off
+    _nolistvalue = re.compile(r'''^
+        (
+            (?:".*?")|          # double quotes
+            (?:'.*?')|          # single quotes
+            (?:[^'"\#].*?)|     # unquoted
+            (?:)                # Empty value
+        )
+        \s*(\#.*)?              # optional comment
+        $''',
+        re.VERBOSE)
+
+    # regexes for finding triple quoted values on one line
+    _single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")
+    _single_line_double = re.compile(r'^"""(.*?)"""\s*(#.*)?$')
+    _multi_line_single = re.compile(r"^(.*?)'''\s*(#.*)?$")
+    _multi_line_double = re.compile(r'^(.*?)"""\s*(#.*)?$')
+
+    _triple_quote = {
+        "'''": (_single_line_single, _multi_line_single),
+        '"""': (_single_line_double, _multi_line_double),
+    }
+
+    # Used by the ``istrue`` Section method
+    _bools = {
+        'yes': True, 'no': False,
+        'on': True, 'off': False,
+        '1': True, '0': False,
+        'true': True, 'false': False,
+        }
+
+
+    def __init__(self, infile=None, options=None, configspec=None, encoding=None,
+                 interpolation=True, raise_errors=False, list_values=True,
+                 create_empty=False, file_error=False, stringify=True,
+                 indent_type=None, default_encoding=None, unrepr=False,
+                 write_empty_values=False, _inspec=False):
+        """
+        Parse a config file or create a config file object.
+        
+        ``ConfigObj(infile=None, configspec=None, encoding=None,
+                    interpolation=True, raise_errors=False, list_values=True,
+                    create_empty=False, file_error=False, stringify=True,
+                    indent_type=None, default_encoding=None, unrepr=False,
+                    write_empty_values=False, _inspec=False)``
+        """
+        self._inspec = _inspec
+        # init the superclass
+        Section.__init__(self, self, 0, self)
+        
+        infile = infile or []
+        
+        _options = {'configspec': configspec,
+                    'encoding': encoding, 'interpolation': interpolation,
+                    'raise_errors': raise_errors, 'list_values': list_values,
+                    'create_empty': create_empty, 'file_error': file_error,
+                    'stringify': stringify, 'indent_type': indent_type,
+                    'default_encoding': default_encoding, 'unrepr': unrepr,
+                    'write_empty_values': write_empty_values}
+
+        if options is None:
+            options = _options
+        else:
+            import warnings
+            warnings.warn('Passing in an options dictionary to ConfigObj() is '
+                          'deprecated. Use **options instead.',
+                          DeprecationWarning)
+            
+            # TODO: check the values too.
+            for entry in options:
+                if entry not in OPTION_DEFAULTS:
+                    raise TypeError('Unrecognised option "%s".' % entry)
+            for entry, value in list(OPTION_DEFAULTS.items()):
+                if entry not in options:
+                    options[entry] = value
+                keyword_value = _options[entry]
+                if value != keyword_value:
+                    options[entry] = keyword_value
+        
+        # XXXX this ignores an explicit list_values = True in combination
+        # with _inspec. The user should *never* do that anyway, but still...
+        if _inspec:
+            options['list_values'] = False
+        
+        self._initialise(options)
+        configspec = options['configspec']
+        self._original_configspec = configspec
+        self._load(infile, configspec)
+        
+        
+    def _load(self, infile, configspec):
+        if isinstance(infile, six.string_types):
+            self.filename = infile
+            if os.path.isfile(infile):
+                with open(infile, 'rb') as h:
+                    content = h.readlines() or []
+            elif self.file_error:
+                # raise an error if the file doesn't exist
+                raise IOError('Config file not found: "%s".' % self.filename)
+            else:
+                # file doesn't already exist
+                if self.create_empty:
+                    # this is a good test that the filename specified
+                    # isn't impossible - like on a non-existent device
+                    with open(infile, 'w') as h:
+                        h.write('')
+                content = []
+                
+        elif isinstance(infile, (list, tuple)):
+            content = list(infile)
+            
+        elif isinstance(infile, dict):
+            # initialise self
+            # the Section class handles creating subsections
+            if isinstance(infile, ConfigObj):
+                # get a copy of our ConfigObj
+                def set_section(in_section, this_section):
+                    for entry in in_section.scalars:
+                        this_section[entry] = in_section[entry]
+                    for section in in_section.sections:
+                        this_section[section] = {}
+                        set_section(in_section[section], this_section[section])
+                set_section(infile, self)
+                
+            else:
+                for entry in infile:
+                    self[entry] = infile[entry]
+            del self._errors
+            
+            if configspec is not None:
+                self._handle_configspec(configspec)
+            else:
+                self.configspec = None
+            return
+        
+        elif getattr(infile, 'read', MISSING) is not MISSING:
+            # This supports file like objects
+            content = infile.read() or []
+            # needs splitting into lines - but needs doing *after* decoding
+            # in case it's not an 8 bit encoding
+        else:
+            raise TypeError('infile must be a filename, file like object, or list of lines.')
+
+        if content:
+            # don't do it for the empty ConfigObj
+            content = self._handle_bom(content)
+            # infile is now *always* a list
+            #
+            # Set the newlines attribute (first line ending it finds)
+            # and strip trailing '\n' or '\r' from lines
+            for line in content:
+                if (not line) or (line[-1] not in ('\r', '\n')):
+                    continue
+                for end in ('\r\n', '\n', '\r'):
+                    if line.endswith(end):
+                        self.newlines = end
+                        break
+                break
+
+        assert all(isinstance(line, six.string_types) for line in content), repr(content)
+        content = [line.rstrip('\r\n') for line in content]
+            
+        self._parse(content)
+        # if we had any errors, now is the time to raise them
+        if self._errors:
+            info = "at line %s." % self._errors[0].line_number
+            if len(self._errors) > 1:
+                msg = "Parsing failed with several errors.\nFirst error %s" % info
+                error = ConfigObjError(msg)
+            else:
+                error = self._errors[0]
+            # set the errors attribute; it's a list of tuples:
+            # (error_type, message, line_number)
+            error.errors = self._errors
+            # set the config attribute
+            error.config = self
+            raise error
+        # delete private attributes
+        del self._errors
+        
+        if configspec is None:
+            self.configspec = None
+        else:
+            self._handle_configspec(configspec)
+    
+    
+    def _initialise(self, options=None):
+        if options is None:
+            options = OPTION_DEFAULTS
+            
+        # initialise a few variables
+        self.filename = None
+        self._errors = []
+        self.raise_errors = options['raise_errors']
+        self.interpolation = options['interpolation']
+        self.list_values = options['list_values']
+        self.create_empty = options['create_empty']
+        self.file_error = options['file_error']
+        self.stringify = options['stringify']
+        self.indent_type = options['indent_type']
+        self.encoding = options['encoding']
+        self.default_encoding = options['default_encoding']
+        self.BOM = False
+        self.newlines = None
+        self.write_empty_values = options['write_empty_values']
+        self.unrepr = options['unrepr']
+        
+        self.initial_comment = []
+        self.final_comment = []
+        self.configspec = None
+        
+        if self._inspec:
+            self.list_values = False
+        
+        # Clear section attributes as well
+        Section._initialise(self)
+        
+        
+    def __repr__(self):
+        def _getval(key):
+            try:
+                return self[key]
+            except MissingInterpolationOption:
+                return dict.__getitem__(self, key)
+        return ('%s({%s})' % (self.__class__.__name__,
+                ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) 
+                for key in (self.scalars + self.sections)])))
+    
+    
+    def _handle_bom(self, infile):
+        """
+        Handle any BOM, and decode if necessary.
+        
+        If an encoding is specified, that *must* be used - but the BOM should
+        still be removed (and the BOM attribute set).
+        
+        (If the encoding is wrongly specified, then a BOM for an alternative
+        encoding won't be discovered or removed.)
+        
+        If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
+        removed. The BOM attribute will be set. UTF16 will be decoded to
+        unicode.
+        
+        NOTE: This method must not be called with an empty ``infile``.
+        
+        Specifying the *wrong* encoding is likely to cause a
+        ``UnicodeDecodeError``.
+        
+        ``infile`` must always be returned as a list of lines, but may be
+        passed in as a single string.
+        """
+
+        if ((self.encoding is not None) and
+            (self.encoding.lower() not in BOM_LIST)):
+            # No need to check for a BOM
+            # the encoding specified doesn't have one
+            # just decode
+            return self._decode(infile, self.encoding)
+        
+        if isinstance(infile, (list, tuple)):
+            line = infile[0]
+        else:
+            line = infile
+
+        if isinstance(line, six.text_type):
+            # it's already decoded and there's no need to do anything
+            # else, just use the _decode utility method to handle
+            # listifying appropriately
+            return self._decode(infile, self.encoding)
+
+        if self.encoding is not None:
+            # encoding explicitly supplied
+            # And it could have an associated BOM
+            # TODO: if encoding is just UTF16 - we ought to check for both
+            # TODO: big endian and little endian versions.
+            enc = BOM_LIST[self.encoding.lower()]
+            if enc == 'utf_16':
+                # For UTF16 we try big endian and little endian
+                for BOM, (encoding, final_encoding) in list(BOMS.items()):
+                    if not final_encoding:
+                        # skip UTF8
+                        continue
+                    if infile.startswith(BOM):
+                        ### BOM discovered
+                        ##self.BOM = True
+                        # Don't need to remove BOM
+                        return self._decode(infile, encoding)
+                    
+                # If we get this far, will *probably* raise a DecodeError
+                # As it doesn't appear to start with a BOM
+                return self._decode(infile, self.encoding)
+            
+            # Must be UTF8
+            BOM = BOM_SET[enc]
+            if not line.startswith(BOM):
+                return self._decode(infile, self.encoding)
+            
+            newline = line[len(BOM):]
+            
+            # BOM removed
+            if isinstance(infile, (list, tuple)):
+                infile[0] = newline
+            else:
+                infile = newline
+            self.BOM = True
+            return self._decode(infile, self.encoding)
+        
+        # No encoding specified - so we need to check for UTF8/UTF16
+        for BOM, (encoding, final_encoding) in list(BOMS.items()):
+            if not isinstance(line, six.binary_type) or not line.startswith(BOM):
+                # didn't specify a BOM, or it's not a bytestring
+                continue
+            else:
+                # BOM discovered
+                self.encoding = final_encoding
+                if not final_encoding:
+                    self.BOM = True
+                    # UTF8
+                    # remove BOM
+                    newline = line[len(BOM):]
+                    if isinstance(infile, (list, tuple)):
+                        infile[0] = newline
+                    else:
+                        infile = newline
+                    # UTF-8
+                    if isinstance(infile, six.text_type):
+                        return infile.splitlines(True)
+                    elif isinstance(infile, six.binary_type):
+                        return infile.decode('utf-8').splitlines(True)
+                    else:
+                        return self._decode(infile, 'utf-8')
+                # UTF16 - have to decode
+                return self._decode(infile, encoding)
+            
+
+        if six.PY2 and isinstance(line, str):
+            # don't actually do any decoding, since we're on python 2 and
+            # returning a bytestring is fine
+            return self._decode(infile, None)
+        # No BOM discovered and no encoding specified, default to UTF-8
+        if isinstance(infile, six.binary_type):
+            return infile.decode('utf-8').splitlines(True)
+        else:
+            return self._decode(infile, 'utf-8')
+
+
+    def _a_to_u(self, aString):
+        """Decode ASCII strings to unicode if a self.encoding is specified."""
+        if isinstance(aString, six.binary_type) and self.encoding:
+            return aString.decode(self.encoding)
+        else:
+            return aString
+
+
+    def _decode(self, infile, encoding):
+        """
+        Decode infile to unicode. Using the specified encoding.
+        
+        if is a string, it also needs converting to a list.
+        """
+        if isinstance(infile, six.string_types):
+            return infile.splitlines(True)
+        if isinstance(infile, six.binary_type):
+            # NOTE: Could raise a ``UnicodeDecodeError``
+            if encoding:
+                return infile.decode(encoding).splitlines(True)
+            else:
+                return infile.splitlines(True)
+
+        if encoding:
+            for i, line in enumerate(infile):
+                if isinstance(line, six.binary_type):
+                    # NOTE: The isinstance test here handles mixed lists of unicode/string
+                    # NOTE: But the decode will break on any non-string values
+                    # NOTE: Or could raise a ``UnicodeDecodeError``
+                    infile[i] = line.decode(encoding)
+        return infile
+
+
+    def _decode_element(self, line):
+        """Decode element to unicode if necessary."""
+        if isinstance(line, six.binary_type) and self.default_encoding:
+            return line.decode(self.default_encoding)
+        else:
+            return line
+
+
+    # TODO: this may need to be modified
+    def _str(self, value):
+        """
+        Used by ``stringify`` within validate, to turn non-string values
+        into strings.
+        """
+        if not isinstance(value, six.string_types):
+            # intentially 'str' because it's just whatever the "normal"
+            # string type is for the python version we're dealing with
+            return str(value)
+        else:
+            return value
+
+
+    def _parse(self, infile):
+        """Actually parse the config file."""
+        temp_list_values = self.list_values
+        if self.unrepr:
+            self.list_values = False
+            
+        comment_list = []
+        done_start = False
+        this_section = self
+        maxline = len(infile) - 1
+        cur_index = -1
+        reset_comment = False
+        
+        while cur_index < maxline:
+            if reset_comment:
+                comment_list = []
+            cur_index += 1
+            line = infile[cur_index]
+            sline = line.strip()
+            # do we have anything on the line ?
+            if not sline or sline.startswith('#'):
+                reset_comment = False
+                comment_list.append(line)
+                continue
+            
+            if not done_start:
+                # preserve initial comment
+                self.initial_comment = comment_list
+                comment_list = []
+                done_start = True
+                
+            reset_comment = True
+            # first we check if it's a section marker
+            mat = self._sectionmarker.match(line)
+            if mat is not None:
+                # is a section line
+                (indent, sect_open, sect_name, sect_close, comment) = mat.groups()
+                if indent and (self.indent_type is None):
+                    self.indent_type = indent
+                cur_depth = sect_open.count('[')
+                if cur_depth != sect_close.count(']'):
+                    self._handle_error("Cannot compute the section depth",
+                                       NestingError, infile, cur_index)
+                    continue
+                
+                if cur_depth < this_section.depth:
+                    # the new section is dropping back to a previous level
+                    try:
+                        parent = self._match_depth(this_section,
+                                                   cur_depth).parent
+                    except SyntaxError:
+                        self._handle_error("Cannot compute nesting level",
+                                           NestingError, infile, cur_index)
+                        continue
+                elif cur_depth == this_section.depth:
+                    # the new section is a sibling of the current section
+                    parent = this_section.parent
+                elif cur_depth == this_section.depth + 1:
+                    # the new section is a child the current section
+                    parent = this_section
+                else:
+                    self._handle_error("Section too nested",
+                                       NestingError, infile, cur_index)
+                    continue
+                    
+                sect_name = self._unquote(sect_name)
+                if sect_name in parent:
+                    self._handle_error('Duplicate section name',
+                                       DuplicateError, infile, cur_index)
+                    continue
+                
+                # create the new section
+                this_section = Section(
+                    parent,
+                    cur_depth,
+                    self,
+                    name=sect_name)
+                parent[sect_name] = this_section
+                parent.inline_comments[sect_name] = comment
+                parent.comments[sect_name] = comment_list
+                continue
+            #
+            # it's not a section marker,
+            # so it should be a valid ``key = value`` line
+            mat = self._keyword.match(line)
+            if mat is None:
+                self._handle_error(
+                    'Invalid line ({0!r}) (matched as neither section nor keyword)'.format(line),
+                    ParseError, infile, cur_index)
+            else:
+                # is a keyword value
+                # value will include any inline comment
+                (indent, key, value) = mat.groups()
+                if indent and (self.indent_type is None):
+                    self.indent_type = indent
+                # check for a multiline value
+                if value[:3] in ['"""', "'''"]:
+                    try:
+                        value, comment, cur_index = self._multiline(
+                            value, infile, cur_index, maxline)
+                    except SyntaxError:
+                        self._handle_error(
+                            'Parse error in multiline value',
+                            ParseError, infile, cur_index)
+                        continue
+                    else:
+                        if self.unrepr:
+                            comment = ''
+                            try:
+                                value = unrepr(value)
+                            except Exception as e:
+                                if type(e) == UnknownType:
+                                    msg = 'Unknown name or type in value'
+                                else:
+                                    msg = 'Parse error from unrepr-ing multiline value'
+                                self._handle_error(msg, UnreprError, infile,
+                                    cur_index)
+                                continue
+                else:
+                    if self.unrepr:
+                        comment = ''
+                        try:
+                            value = unrepr(value)
+                        except Exception as e:
+                            if isinstance(e, UnknownType):
+                                msg = 'Unknown name or type in value'
+                            else:
+                                msg = 'Parse error from unrepr-ing value'
+                            self._handle_error(msg, UnreprError, infile,
+                                cur_index)
+                            continue
+                    else:
+                        # extract comment and lists
+                        try:
+                            (value, comment) = self._handle_value(value)
+                        except SyntaxError:
+                            self._handle_error(
+                                'Parse error in value',
+                                ParseError, infile, cur_index)
+                            continue
+                #
+                key = self._unquote(key)
+                if key in this_section:
+                    self._handle_error(
+                        'Duplicate keyword name',
+                        DuplicateError, infile, cur_index)
+                    continue
+                # add the key.
+                # we set unrepr because if we have got this far we will never
+                # be creating a new section
+                this_section.__setitem__(key, value, unrepr=True)
+                this_section.inline_comments[key] = comment
+                this_section.comments[key] = comment_list
+                continue
+        #
+        if self.indent_type is None:
+            # no indentation used, set the type accordingly
+            self.indent_type = ''
+
+        # preserve the final comment
+        if not self and not self.initial_comment:
+            self.initial_comment = comment_list
+        elif not reset_comment:
+            self.final_comment = comment_list
+        self.list_values = temp_list_values
+
+
+    def _match_depth(self, sect, depth):
+        """
+        Given a section and a depth level, walk back through the sections
+        parents to see if the depth level matches a previous section.
+        
+        Return a reference to the right section,
+        or raise a SyntaxError.
+        """
+        while depth < sect.depth:
+            if sect is sect.parent:
+                # we've reached the top level already
+                raise SyntaxError()
+            sect = sect.parent
+        if sect.depth == depth:
+            return sect
+        # shouldn't get here
+        raise SyntaxError()
+
+
+    def _handle_error(self, text, ErrorClass, infile, cur_index):
+        """
+        Handle an error according to the error settings.
+        
+        Either raise the error or store it.
+        The error will have occured at ``cur_index``
+        """
+        line = infile[cur_index]
+        cur_index += 1
+        message = '{0} at line {1}.'.format(text, cur_index)
+        error = ErrorClass(message, cur_index, line)
+        if self.raise_errors:
+            # raise the error - parsing stops here
+            raise error
+        # store the error
+        # reraise when parsing has finished
+        self._errors.append(error)
+
+
+    def _unquote(self, value):
+        """Return an unquoted version of a value"""
+        if not value:
+            # should only happen during parsing of lists
+            raise SyntaxError
+        if (value[0] == value[-1]) and (value[0] in ('"', "'")):
+            value = value[1:-1]
+        return value
+
+
+    def _quote(self, value, multiline=True):
+        """
+        Return a safely quoted version of a value.
+        
+        Raise a ConfigObjError if the value cannot be safely quoted.
+        If multiline is ``True`` (default) then use triple quotes
+        if necessary.
+        
+        * Don't quote values that don't need it.
+        * Recursively quote members of a list and return a comma joined list.
+        * Multiline is ``False`` for lists.
+        * Obey list syntax for empty and single member lists.
+        
+        If ``list_values=False`` then the value is only quoted if it contains
+        a ``\\n`` (is multiline) or '#'.
+        
+        If ``write_empty_values`` is set, and the value is an empty string, it
+        won't be quoted.
+        """
+        if multiline and self.write_empty_values and value == '':
+            # Only if multiline is set, so that it is used for values not
+            # keys, and not values that are part of a list
+            return ''
+        
+        if multiline and isinstance(value, (list, tuple)):
+            if not value:
+                return ','
+            elif len(value) == 1:
+                return self._quote(value[0], multiline=False) + ','
+            return ', '.join([self._quote(val, multiline=False)
+                for val in value])
+        if not isinstance(value, six.string_types):
+            if self.stringify:
+                # intentially 'str' because it's just whatever the "normal"
+                # string type is for the python version we're dealing with
+                value = str(value)
+            else:
+                raise TypeError('Value "%s" is not a string.' % value)
+
+        if not value:
+            return '""'
+        
+        no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value
+        need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))
+        hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)
+        check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote
+        
+        if check_for_single:
+            if not self.list_values:
+                # we don't quote if ``list_values=False``
+                quot = noquot
+            # for normal values either single or double quotes will do
+            elif '\n' in value:
+                # will only happen if multiline is off - e.g. '\n' in key
+                raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
+            elif ((value[0] not in wspace_plus) and
+                    (value[-1] not in wspace_plus) and
+                    (',' not in value)):
+                quot = noquot
+            else:
+                quot = self._get_single_quote(value)
+        else:
+            # if value has '\n' or "'" *and* '"', it will need triple quotes
+            quot = self._get_triple_quote(value)
+        
+        if quot == noquot and '#' in value and self.list_values:
+            quot = self._get_single_quote(value)
+                
+        return quot % value
+    
+    
+    def _get_single_quote(self, value):
+        if ("'" in value) and ('"' in value):
+            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
+        elif '"' in value:
+            quot = squot
+        else:
+            quot = dquot
+        return quot
+    
+    
+    def _get_triple_quote(self, value):
+        if (value.find('"""') != -1) and (value.find("'''") != -1):
+            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
+        if value.find('"""') == -1:
+            quot = tdquot
+        else:
+            quot = tsquot 
+        return quot
+
+
+    def _handle_value(self, value):
+        """
+        Given a value string, unquote, remove comment,
+        handle lists. (including empty and single member lists)
+        """
+        if self._inspec:
+            # Parsing a configspec so don't handle comments
+            return (value, '')
+        # do we look for lists in values ?
+        if not self.list_values:
+            mat = self._nolistvalue.match(value)
+            if mat is None:
+                raise SyntaxError()
+            # NOTE: we don't unquote here
+            return mat.groups()
+        #
+        mat = self._valueexp.match(value)
+        if mat is None:
+            # the value is badly constructed, probably badly quoted,
+            # or an invalid list
+            raise SyntaxError()
+        (list_values, single, empty_list, comment) = mat.groups()
+        if (list_values == '') and (single is None):
+            # change this if you want to accept empty values
+            raise SyntaxError()
+        # NOTE: note there is no error handling from here if the regex
+        # is wrong: then incorrect values will slip through
+        if empty_list is not None:
+            # the single comma - meaning an empty list
+            return ([], comment)
+        if single is not None:
+            # handle empty values
+            if list_values and not single:
+                # FIXME: the '' is a workaround because our regex now matches
+                #   '' at the end of a list if it has a trailing comma
+                single = None
+            else:
+                single = single or '""'
+                single = self._unquote(single)
+        if list_values == '':
+            # not a list value
+            return (single, comment)
+        the_list = self._listvalueexp.findall(list_values)
+        the_list = [self._unquote(val) for val in the_list]
+        if single is not None:
+            the_list += [single]
+        return (the_list, comment)
+
+
+    def _multiline(self, value, infile, cur_index, maxline):
+        """Extract the value, where we are in a multiline situation."""
+        quot = value[:3]
+        newvalue = value[3:]
+        single_line = self._triple_quote[quot][0]
+        multi_line = self._triple_quote[quot][1]
+        mat = single_line.match(value)
+        if mat is not None:
+            retval = list(mat.groups())
+            retval.append(cur_index)
+            return retval
+        elif newvalue.find(quot) != -1:
+            # somehow the triple quote is missing
+            raise SyntaxError()
+        #
+        while cur_index < maxline:
+            cur_index += 1
+            newvalue += '\n'
+            line = infile[cur_index]
+            if line.find(quot) == -1:
+                newvalue += line
+            else:
+                # end of multiline, process it
+                break
+        else:
+            # we've got to the end of the config, oops...
+            raise SyntaxError()
+        mat = multi_line.match(line)
+        if mat is None:
+            # a badly formed line
+            raise SyntaxError()
+        (value, comment) = mat.groups()
+        return (newvalue + value, comment, cur_index)
+
+
+    def _handle_configspec(self, configspec):
+        """Parse the configspec."""
+        # FIXME: Should we check that the configspec was created with the 
+        #        correct settings ? (i.e. ``list_values=False``)
+        if not isinstance(configspec, ConfigObj):
+            try:
+                configspec = ConfigObj(configspec,
+                                       raise_errors=True,
+                                       file_error=True,
+                                       _inspec=True)
+            except ConfigObjError as e:
+                # FIXME: Should these errors have a reference
+                #        to the already parsed ConfigObj ?
+                raise ConfigspecError('Parsing configspec failed: %s' % e)
+            except IOError as e:
+                raise IOError('Reading configspec failed: %s' % e)
+        
+        self.configspec = configspec
+            
+
+        
+    def _set_configspec(self, section, copy):
+        """
+        Called by validate. Handles setting the configspec on subsections
+        including sections to be validated by __many__
+        """
+        configspec = section.configspec
+        many = configspec.get('__many__')
+        if isinstance(many, dict):
+            for entry in section.sections:
+                if entry not in configspec:
+                    section[entry].configspec = many
+                    
+        for entry in configspec.sections:
+            if entry == '__many__':
+                continue
+            if entry not in section:
+                section[entry] = {}
+                section[entry]._created = True
+                if copy:
+                    # copy comments
+                    section.comments[entry] = configspec.comments.get(entry, [])
+                    section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
+                
+            # Could be a scalar when we expect a section
+            if isinstance(section[entry], Section):
+                section[entry].configspec = configspec[entry]
+                        
+
+    def _write_line(self, indent_string, entry, this_entry, comment):
+        """Write an individual line, for the write method"""
+        # NOTE: the calls to self._quote here handles non-StringType values.
+        if not self.unrepr:
+            val = self._decode_element(self._quote(this_entry))
+        else:
+            val = repr(this_entry)
+        return '%s%s%s%s%s' % (indent_string,
+                               self._decode_element(self._quote(entry, multiline=False)),
+                               self._a_to_u(' = '),
+                               val,
+                               self._decode_element(comment))
+
+
+    def _write_marker(self, indent_string, depth, entry, comment):
+        """Write a section marker line"""
+        return '%s%s%s%s%s' % (indent_string,
+                               self._a_to_u('[' * depth),
+                               self._quote(self._decode_element(entry), multiline=False),
+                               self._a_to_u(']' * depth),
+                               self._decode_element(comment))
+
+
+    def _handle_comment(self, comment):
+        """Deal with a comment."""
+        if not comment:
+            return ''
+        start = self.indent_type
+        if not comment.startswith('#'):
+            start += self._a_to_u(' # ')
+        return (start + comment)
+
+
+    # Public methods
+
+    def write(self, outfile=None, section=None):
+        """
+        Write the current ConfigObj as a file
+        
+        tekNico: FIXME: use StringIO instead of real files
+        
+        >>> filename = a.filename
+        >>> a.filename = 'test.ini'
+        >>> a.write()
+        >>> a.filename = filename
+        >>> a == ConfigObj('test.ini', raise_errors=True)
+        1
+        >>> import os
+        >>> os.remove('test.ini')
+        """
+        if self.indent_type is None:
+            # this can be true if initialised from a dictionary
+            self.indent_type = DEFAULT_INDENT_TYPE
+            
+        out = []
+        cs = self._a_to_u('#')
+        csp = self._a_to_u('# ')
+        if section is None:
+            int_val = self.interpolation
+            self.interpolation = False
+            section = self
+            for line in self.initial_comment:
+                line = self._decode_element(line)
+                stripped_line = line.strip()
+                if stripped_line and not stripped_line.startswith(cs):
+                    line = csp + line
+                out.append(line)
+                
+        indent_string = self.indent_type * section.depth
+        for entry in (section.scalars + section.sections):
+            if entry in section.defaults:
+                # don't write out default values
+                continue
+            for comment_line in section.comments[entry]:
+                comment_line = self._decode_element(comment_line.lstrip())
+                if comment_line and not comment_line.startswith(cs):
+                    comment_line = csp + comment_line
+                out.append(indent_string + comment_line)
+            this_entry = section[entry]
+            comment = self._handle_comment(section.inline_comments[entry])
+            
+            if isinstance(this_entry, Section):
+                # a section
+                out.append(self._write_marker(
+                    indent_string,
+                    this_entry.depth,
+                    entry,
+                    comment))
+                out.extend(self.write(section=this_entry))
+            else:
+                out.append(self._write_line(
+                    indent_string,
+                    entry,
+                    this_entry,
+                    comment))
+                
+        if section is self:
+            for line in self.final_comment:
+                line = self._decode_element(line)
+                stripped_line = line.strip()
+                if stripped_line and not stripped_line.startswith(cs):
+                    line = csp + line
+                out.append(line)
+            self.interpolation = int_val
+            
+        if section is not self:
+            return out
+        
+        if (self.filename is None) and (outfile is None):
+            # output a list of lines
+            # might need to encode
+            # NOTE: This will *screw* UTF16, each line will start with the BOM
+            if self.encoding:
+                out = [l.encode(self.encoding) for l in out]
+            if (self.BOM and ((self.encoding is None) or
+                (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
+                # Add the UTF8 BOM
+                if not out:
+                    out.append('')
+                out[0] = BOM_UTF8 + out[0]
+            return out
+        
+        # Turn the list to a string, joined with correct newlines
+        newline = self.newlines or os.linesep
+        if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w'
+            and sys.platform == 'win32' and newline == '\r\n'):
+            # Windows specific hack to avoid writing '\r\r\n'
+            newline = '\n'
+        output = self._a_to_u(newline).join(out)
+        if not output.endswith(newline):
+            output += newline
+
+        if isinstance(output, six.binary_type):
+            output_bytes = output
+        else:
+            output_bytes = output.encode(self.encoding or
+                                         self.default_encoding or
+                                         'ascii')
+
+        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
+            # Add the UTF8 BOM
+            output_bytes = BOM_UTF8 + output_bytes
+
+        if outfile is not None:
+            outfile.write(output_bytes)
+        else:
+            with open(self.filename, 'wb') as h:
+                h.write(output_bytes)
+
+    def validate(self, validator, preserve_errors=False, copy=False,
+                 section=None):
+        """
+        Test the ConfigObj against a configspec.
+        
+        It uses the ``validator`` object from *validate.py*.
+        
+        To run ``validate`` on the current ConfigObj, call: ::
+        
+            test = config.validate(validator)
+        
+        (Normally having previously passed in the configspec when the ConfigObj
+        was created - you can dynamically assign a dictionary of checks to the
+        ``configspec`` attribute of a section though).
+        
+        It returns ``True`` if everything passes, or a dictionary of
+        pass/fails (True/False). If every member of a subsection passes, it
+        will just have the value ``True``. (It also returns ``False`` if all
+        members fail).
+        
+        In addition, it converts the values from strings to their native
+        types if their checks pass (and ``stringify`` is set).
+        
+        If ``preserve_errors`` is ``True`` (``False`` is default) then instead
+        of a marking a fail with a ``False``, it will preserve the actual
+        exception object. This can contain info about the reason for failure.
+        For example the ``VdtValueTooSmallError`` indicates that the value
+        supplied was too small. If a value (or section) is missing it will
+        still be marked as ``False``.
+        
+        You must have the validate module to use ``preserve_errors=True``.
+        
+        You can then use the ``flatten_errors`` function to turn your nested
+        results dictionary into a flattened list of failures - useful for
+        displaying meaningful error messages.
+        """
+        if section is None:
+            if self.configspec is None:
+                raise ValueError('No configspec supplied.')
+            if preserve_errors:
+                # We do this once to remove a top level dependency on the validate module
+                # Which makes importing configobj faster
+                from validate import VdtMissingValue
+                self._vdtMissingValue = VdtMissingValue
+                
+            section = self
+
+            if copy:
+                section.initial_comment = section.configspec.initial_comment
+                section.final_comment = section.configspec.final_comment
+                section.encoding = section.configspec.encoding
+                section.BOM = section.configspec.BOM
+                section.newlines = section.configspec.newlines
+                section.indent_type = section.configspec.indent_type
+            
+        #
+        # section.default_values.clear() #??
+        configspec = section.configspec
+        self._set_configspec(section, copy)
+
+        
+        def validate_entry(entry, spec, val, missing, ret_true, ret_false):
+            section.default_values.pop(entry, None)
+                
+            try:
+                section.default_values[entry] = validator.get_default_value(configspec[entry])
+            except (KeyError, AttributeError, validator.baseErrorClass):
+                # No default, bad default or validator has no 'get_default_value'
+                # (e.g. SimpleVal)
+                pass
+            
+            try:
+                check = validator.check(spec,
+                                        val,
+                                        missing=missing
+                                        )
+            except validator.baseErrorClass as e:
+                if not preserve_errors or isinstance(e, self._vdtMissingValue):
+                    out[entry] = False
+                else:
+                    # preserve the error
+                    out[entry] = e
+                    ret_false = False
+                ret_true = False
+            else:
+                ret_false = False
+                out[entry] = True
+                if self.stringify or missing:
+                    # if we are doing type conversion
+                    # or the value is a supplied default
+                    if not self.stringify:
+                        if isinstance(check, (list, tuple)):
+                            # preserve lists
+                            check = [self._str(item) for item in check]
+                        elif missing and check is None:
+                            # convert the None from a default to a ''
+                            check = ''
+                        else:
+                            check = self._str(check)
+                    if (check != val) or missing:
+                        section[entry] = check
+                if not copy and missing and entry not in section.defaults:
+                    section.defaults.append(entry)
+            return ret_true, ret_false
+        
+        #
+        out = {}
+        ret_true = True
+        ret_false = True
+        
+        unvalidated = [k for k in section.scalars if k not in configspec]
+        incorrect_sections = [k for k in configspec.sections if k in section.scalars]        
+        incorrect_scalars = [k for k in configspec.scalars if k in section.sections]
+        
+        for entry in configspec.scalars:
+            if entry in ('__many__', '___many___'):
+                # reserved names
+                continue
+            if (not entry in section.scalars) or (entry in section.defaults):
+                # missing entries
+                # or entries from defaults
+                missing = True
+                val = None
+                if copy and entry not in section.scalars:
+                    # copy comments
+                    section.comments[entry] = (
+                        configspec.comments.get(entry, []))
+                    section.inline_comments[entry] = (
+                        configspec.inline_comments.get(entry, ''))
+                #
+            else:
+                missing = False
+                val = section[entry]
+            
+            ret_true, ret_false = validate_entry(entry, configspec[entry], val, 
+                                                 missing, ret_true, ret_false)
+        
+        many = None
+        if '__many__' in configspec.scalars:
+            many = configspec['__many__']
+        elif '___many___' in configspec.scalars:
+            many = configspec['___many___']
+        
+        if many is not None:
+            for entry in unvalidated:
+                val = section[entry]
+                ret_true, ret_false = validate_entry(entry, many, val, False,
+                                                     ret_true, ret_false)
+            unvalidated = []
+
+        for entry in incorrect_scalars:
+            ret_true = False
+            if not preserve_errors:
+                out[entry] = False
+            else:
+                ret_false = False
+                msg = 'Value %r was provided as a section' % entry
+                out[entry] = validator.baseErrorClass(msg)
+        for entry in incorrect_sections:
+            ret_true = False
+            if not preserve_errors:
+                out[entry] = False
+            else:
+                ret_false = False
+                msg = 'Section %r was provided as a single value' % entry
+                out[entry] = validator.baseErrorClass(msg)
+                
+        # Missing sections will have been created as empty ones when the
+        # configspec was read.
+        for entry in section.sections:
+            # FIXME: this means DEFAULT is not copied in copy mode
+            if section is self and entry == 'DEFAULT':
+                continue
+            if section[entry].configspec is None:
+                unvalidated.append(entry)
+                continue
+            if copy:
+                section.comments[entry] = configspec.comments.get(entry, [])
+                section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
+            check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry])
+            out[entry] = check
+            if check == False:
+                ret_true = False
+            elif check == True:
+                ret_false = False
+            else:
+                ret_true = False
+        
+        section.extra_values = unvalidated
+        if preserve_errors and not section._created:
+            # If the section wasn't created (i.e. it wasn't missing)
+            # then we can't return False, we need to preserve errors
+            ret_false = False
+        #
+        if ret_false and preserve_errors and out:
+            # If we are preserving errors, but all
+            # the failures are from missing sections / values
+            # then we can return False. Otherwise there is a
+            # real failure that we need to preserve.
+            ret_false = not any(out.values())
+        if ret_true:
+            return True
+        elif ret_false:
+            return False
+        return out
+
+
+    def reset(self):
+        """Clear ConfigObj instance and restore to 'freshly created' state."""
+        self.clear()
+        self._initialise()
+        # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload)
+        #        requires an empty dictionary
+        self.configspec = None
+        # Just to be sure ;-)
+        self._original_configspec = None
+        
+        
+    def reload(self):
+        """
+        Reload a ConfigObj from file.
+        
+        This method raises a ``ReloadError`` if the ConfigObj doesn't have
+        a filename attribute pointing to a file.
+        """
+        if not isinstance(self.filename, six.string_types):
+            raise ReloadError()
+
+        filename = self.filename
+        current_options = {}
+        for entry in OPTION_DEFAULTS:
+            if entry == 'configspec':
+                continue
+            current_options[entry] = getattr(self, entry)
+            
+        configspec = self._original_configspec
+        current_options['configspec'] = configspec
+            
+        self.clear()
+        self._initialise(current_options)
+        self._load(filename, configspec)
+        
+
+
+class SimpleVal(object):
+    """
+    A simple validator.
+    Can be used to check that all members expected are present.
+    
+    To use it, provide a configspec with all your members in (the value given
+    will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
+    method of your ``ConfigObj``. ``validate`` will return ``True`` if all
+    members are present, or a dictionary with True/False meaning
+    present/missing. (Whole missing sections will be replaced with ``False``)
+    """
+    
+    def __init__(self):
+        self.baseErrorClass = ConfigObjError
+    
+    def check(self, check, member, missing=False):
+        """A dummy check method, always returns the value unchanged."""
+        if missing:
+            raise self.baseErrorClass()
+        return member
+
+
+def flatten_errors(cfg, res, levels=None, results=None):
+    """
+    An example function that will turn a nested dictionary of results
+    (as returned by ``ConfigObj.validate``) into a flat list.
+    
+    ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
+    dictionary returned by ``validate``.
+    
+    (This is a recursive function, so you shouldn't use the ``levels`` or
+    ``results`` arguments - they are used by the function.)
+    
+    Returns a list of keys that failed. Each member of the list is a tuple::
+    
+        ([list of sections...], key, result)
+    
+    If ``validate`` was called with ``preserve_errors=False`` (the default)
+    then ``result`` will always be ``False``.
+
+    *list of sections* is a flattened list of sections that the key was found
+    in.
+    
+    If the section was missing (or a section was expected and a scalar provided
+    - or vice-versa) then key will be ``None``.
+    
+    If the value (or section) was missing then ``result`` will be ``False``.
+    
+    If ``validate`` was called with ``preserve_errors=True`` and a value
+    was present, but failed the check, then ``result`` will be the exception
+    object returned. You can use this as a string that describes the failure.
+    
+    For example *The value "3" is of the wrong type*.
+    """
+    if levels is None:
+        # first time called
+        levels = []
+        results = []
+    if res == True:
+        return sorted(results)
+    if res == False or isinstance(res, Exception):
+        results.append((levels[:], None, res))
+        if levels:
+            levels.pop()
+        return sorted(results)
+    for (key, val) in list(res.items()):
+        if val == True:
+            continue
+        if isinstance(cfg.get(key), collections.Mapping):
+            # Go down one level
+            levels.append(key)
+            flatten_errors(cfg[key], val, levels, results)
+            continue
+        results.append((levels[:], key, val))
+    #
+    # Go up one level
+    if levels:
+        levels.pop()
+    #
+    return sorted(results)
+
+
+def get_extra_values(conf, _prepend=()):
+    """
+    Find all the values and sections not in the configspec from a validated
+    ConfigObj.
+    
+    ``get_extra_values`` returns a list of tuples where each tuple represents
+    either an extra section, or an extra value.
+    
+    The tuples contain two values, a tuple representing the section the value 
+    is in and the name of the extra values. For extra values in the top level
+    section the first member will be an empty tuple. For values in the 'foo'
+    section the first member will be ``('foo',)``. For members in the 'bar'
+    subsection of the 'foo' section the first member will be ``('foo', 'bar')``.
+    
+    NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't
+    been validated it will return an empty list.
+    """
+    out = []
+    
+    out.extend([(_prepend, name) for name in conf.extra_values])
+    for name in conf.sections:
+        if name not in conf.extra_values:
+            out.extend(get_extra_values(conf[name], _prepend + (name,)))
+    return out
+
+
+"""*A programming language is a medium of expression.* - Paul Graham"""
diff --git a/astropy/extern/configobj/validate.py b/astropy/extern/configobj/validate.py
new file mode 100755
index 0000000..b7a964c
--- /dev/null
+++ b/astropy/extern/configobj/validate.py
@@ -0,0 +1,1472 @@
+# validate.py
+# A Validator object
+# Copyright (C) 2005-2014:
+# (name) : (email)
+# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
+# Mark Andrews: mark AT la-la DOT com
+# Nicola Larosa: nico AT tekNico DOT net
+# Rob Dennis: rdennis AT gmail DOT com
+# Eli Courtwright: eli AT courtwright DOT org
+
+# This software is licensed under the terms of the BSD license.
+# http://opensource.org/licenses/BSD-3-Clause
+
+# ConfigObj 5 - main repository for documentation and issue tracking:
+# https://github.com/DiffSK/configobj
+
+"""
+    The Validator object is used to check that supplied values 
+    conform to a specification.
+    
+    The value can be supplied as a string - e.g. from a config file.
+    In this case the check will also *convert* the value to
+    the required type. This allows you to add validation
+    as a transparent layer to access data stored as strings.
+    The validation checks that the data is correct *and*
+    converts it to the expected type.
+    
+    Some standard checks are provided for basic data types.
+    Additional checks are easy to write. They can be
+    provided when the ``Validator`` is instantiated or
+    added afterwards.
+    
+    The standard functions work with the following basic data types :
+    
+    * integers
+    * floats
+    * booleans
+    * strings
+    * ip_addr
+    
+    plus lists of these datatypes
+    
+    Adding additional checks is done through coding simple functions.
+    
+    The full set of standard checks are : 
+    
+    * 'integer': matches integer values (including negative)
+                 Takes optional 'min' and 'max' arguments : ::
+    
+                   integer()
+                   integer(3, 9)  # any value from 3 to 9
+                   integer(min=0) # any positive value
+                   integer(max=9)
+    
+    * 'float': matches float values
+               Has the same parameters as the integer check.
+    
+    * 'boolean': matches boolean values - ``True`` or ``False``
+                 Acceptable string values for True are :
+                   true, on, yes, 1
+                 Acceptable string values for False are :
+                   false, off, no, 0
+    
+                 Any other value raises an error.
+    
+    * 'ip_addr': matches an Internet Protocol address, v.4, represented
+                 by a dotted-quad string, i.e. '1.2.3.4'.
+    
+    * 'string': matches any string.
+                Takes optional keyword args 'min' and 'max'
+                to specify min and max lengths of the string.
+    
+    * 'list': matches any list.
+              Takes optional keyword args 'min', and 'max' to specify min and
+              max sizes of the list. (Always returns a list.)
+    
+    * 'tuple': matches any tuple.
+              Takes optional keyword args 'min', and 'max' to specify min and
+              max sizes of the tuple. (Always returns a tuple.)
+    
+    * 'int_list': Matches a list of integers.
+                  Takes the same arguments as list.
+    
+    * 'float_list': Matches a list of floats.
+                    Takes the same arguments as list.
+    
+    * 'bool_list': Matches a list of boolean values.
+                   Takes the same arguments as list.
+    
+    * 'ip_addr_list': Matches a list of IP addresses.
+                     Takes the same arguments as list.
+    
+    * 'string_list': Matches a list of strings.
+                     Takes the same arguments as list.
+    
+    * 'mixed_list': Matches a list with different types in 
+                    specific positions. List size must match
+                    the number of arguments.
+    
+                    Each position can be one of :
+                    'integer', 'float', 'ip_addr', 'string', 'boolean'
+    
+                    So to specify a list with two strings followed
+                    by two integers, you write the check as : ::
+    
+                      mixed_list('string', 'string', 'integer', 'integer')
+    
+    * 'pass': This check matches everything ! It never fails
+              and the value is unchanged.
+    
+              It is also the default if no check is specified.
+    
+    * 'option': This check matches any from a list of options.
+                You specify this check with : ::
+    
+                  option('option 1', 'option 2', 'option 3')
+    
+    You can supply a default value (returned if no value is supplied)
+    using the default keyword argument.
+    
+    You specify a list argument for default using a list constructor syntax in
+    the check : ::
+    
+        checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
+    
+    A badly formatted set of arguments will raise a ``VdtParamError``.
+"""
+
+__version__ = '1.0.1'
+
+
+__all__ = (
+    '__version__',
+    'dottedQuadToNum',
+    'numToDottedQuad',
+    'ValidateError',
+    'VdtUnknownCheckError',
+    'VdtParamError',
+    'VdtTypeError',
+    'VdtValueError',
+    'VdtValueTooSmallError',
+    'VdtValueTooBigError',
+    'VdtValueTooShortError',
+    'VdtValueTooLongError',
+    'VdtMissingValue',
+    'Validator',
+    'is_integer',
+    'is_float',
+    'is_boolean',
+    'is_list',
+    'is_tuple',
+    'is_ip_addr',
+    'is_string',
+    'is_int_list',
+    'is_bool_list',
+    'is_float_list',
+    'is_string_list',
+    'is_ip_addr_list',
+    'is_mixed_list',
+    'is_option',
+    '__docformat__',
+)
+
+
+import re
+import sys
+from pprint import pprint
+
+#TODO - #21 - six is part of the repo now, but we didn't switch over to it here
+# this could be replaced if six is used for compatibility, or there are no
+# more assertions about items being a string
+if sys.version_info < (3,):
+    string_type = basestring
+else:
+    string_type = str
+    # so tests that care about unicode on 2.x can specify unicode, and the same
+    # tests when run on 3.x won't complain about a undefined name "unicode"
+    # since all strings are unicode on 3.x we just want to pass it through
+    # unchanged
+    unicode = lambda x: x
+    # in python 3, all ints are equivalent to python 2 longs, and they'll
+    # never show "L" in the repr
+    long = int
+
+_list_arg = re.compile(r'''
+    (?:
+        ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
+            (
+                (?:
+                    \s*
+                    (?:
+                        (?:".*?")|              # double quotes
+                        (?:'.*?')|              # single quotes
+                        (?:[^'",\s\)][^,\)]*?)  # unquoted
+                    )
+                    \s*,\s*
+                )*
+                (?:
+                    (?:".*?")|              # double quotes
+                    (?:'.*?')|              # single quotes
+                    (?:[^'",\s\)][^,\)]*?)  # unquoted
+                )?                          # last one
+            )
+        \)
+    )
+''', re.VERBOSE | re.DOTALL)    # two groups
+
+_list_members = re.compile(r'''
+    (
+        (?:".*?")|              # double quotes
+        (?:'.*?')|              # single quotes
+        (?:[^'",\s=][^,=]*?)       # unquoted
+    )
+    (?:
+    (?:\s*,\s*)|(?:\s*$)            # comma
+    )
+''', re.VERBOSE | re.DOTALL)    # one group
+
+_paramstring = r'''
+    (?:
+        (
+            (?:
+                [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
+                    (?:
+                        \s*
+                        (?:
+                            (?:".*?")|              # double quotes
+                            (?:'.*?')|              # single quotes
+                            (?:[^'",\s\)][^,\)]*?)       # unquoted
+                        )
+                        \s*,\s*
+                    )*
+                    (?:
+                        (?:".*?")|              # double quotes
+                        (?:'.*?')|              # single quotes
+                        (?:[^'",\s\)][^,\)]*?)       # unquoted
+                    )?                              # last one
+                \)
+            )|
+            (?:
+                (?:".*?")|              # double quotes
+                (?:'.*?')|              # single quotes
+                (?:[^'",\s=][^,=]*?)|       # unquoted
+                (?:                         # keyword argument
+                    [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
+                    (?:
+                        (?:".*?")|              # double quotes
+                        (?:'.*?')|              # single quotes
+                        (?:[^'",\s=][^,=]*?)       # unquoted
+                    )
+                )
+            )
+        )
+        (?:
+            (?:\s*,\s*)|(?:\s*$)            # comma
+        )
+    )
+    '''
+
+_matchstring = '^%s*' % _paramstring
+
+# Python pre 2.2.1 doesn't have bool
+try:
+    bool
+except NameError:
+    def bool(val):
+        """Simple boolean equivalent function. """
+        if val:
+            return 1
+        else:
+            return 0
+
+
+def dottedQuadToNum(ip):
+    """
+    Convert decimal dotted quad string to long integer
+    
+    >>> int(dottedQuadToNum('1 '))
+    1
+    >>> int(dottedQuadToNum(' 1.2'))
+    16777218
+    >>> int(dottedQuadToNum(' 1.2.3 '))
+    16908291
+    >>> int(dottedQuadToNum('1.2.3.4'))
+    16909060
+    >>> dottedQuadToNum('255.255.255.255')
+    4294967295
+    >>> dottedQuadToNum('255.255.255.256')
+    Traceback (most recent call last):
+    ValueError: Not a good dotted-quad IP: 255.255.255.256
+    """
+    
+    # import here to avoid it when ip_addr values are not used
+    import socket, struct
+    
+    try:
+        return struct.unpack('!L',
+            socket.inet_aton(ip.strip()))[0]
+    except socket.error:
+        raise ValueError('Not a good dotted-quad IP: %s' % ip)
+    return
+
+
+def numToDottedQuad(num):
+    """
+    Convert int or long int to dotted quad string
+    
+    >>> numToDottedQuad(long(-1))
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: -1
+    >>> numToDottedQuad(long(1))
+    '0.0.0.1'
+    >>> numToDottedQuad(long(16777218))
+    '1.0.0.2'
+    >>> numToDottedQuad(long(16908291))
+    '1.2.0.3'
+    >>> numToDottedQuad(long(16909060))
+    '1.2.3.4'
+    >>> numToDottedQuad(long(4294967295))
+    '255.255.255.255'
+    >>> numToDottedQuad(long(4294967296))
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: 4294967296
+    >>> numToDottedQuad(-1)
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: -1
+    >>> numToDottedQuad(1)
+    '0.0.0.1'
+    >>> numToDottedQuad(16777218)
+    '1.0.0.2'
+    >>> numToDottedQuad(16908291)
+    '1.2.0.3'
+    >>> numToDottedQuad(16909060)
+    '1.2.3.4'
+    >>> numToDottedQuad(4294967295)
+    '255.255.255.255'
+    >>> numToDottedQuad(4294967296)
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: 4294967296
+
+    """
+    
+    # import here to avoid it when ip_addr values are not used
+    import socket, struct
+    
+    # no need to intercept here, 4294967295L is fine
+    if num > long(4294967295) or num < 0:
+        raise ValueError('Not a good numeric IP: %s' % num)
+    try:
+        return socket.inet_ntoa(
+            struct.pack('!L', long(num)))
+    except (socket.error, struct.error, OverflowError):
+        raise ValueError('Not a good numeric IP: %s' % num)
+
+
+class ValidateError(Exception):
+    """
+    This error indicates that the check failed.
+    It can be the base class for more specific errors.
+    
+    Any check function that fails ought to raise this error.
+    (or a subclass)
+    
+    >>> raise ValidateError
+    Traceback (most recent call last):
+    ValidateError
+    """
+
+
+class VdtMissingValue(ValidateError):
+    """No value was supplied to a check that needed one."""
+
+
+class VdtUnknownCheckError(ValidateError):
+    """An unknown check function was requested"""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtUnknownCheckError('yoda')
+        Traceback (most recent call last):
+        VdtUnknownCheckError: the check "yoda" is unknown.
+        """
+        ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,))
+
+
+class VdtParamError(SyntaxError):
+    """An incorrect parameter was passed"""
+
+    def __init__(self, name, value):
+        """
+        >>> raise VdtParamError('yoda', 'jedi')
+        Traceback (most recent call last):
+        VdtParamError: passed an incorrect value "jedi" for parameter "yoda".
+        """
+        SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name))
+
+
+class VdtTypeError(ValidateError):
+    """The value supplied was of the wrong type"""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtTypeError('jedi')
+        Traceback (most recent call last):
+        VdtTypeError: the value "jedi" is of the wrong type.
+        """
+        ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,))
+
+
+class VdtValueError(ValidateError):
+    """The value supplied was of the correct type, but was not an allowed value."""
+    
+    def __init__(self, value):
+        """
+        >>> raise VdtValueError('jedi')
+        Traceback (most recent call last):
+        VdtValueError: the value "jedi" is unacceptable.
+        """
+        ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,))
+
+
+class VdtValueTooSmallError(VdtValueError):
+    """The value supplied was of the correct type, but was too small."""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtValueTooSmallError('0')
+        Traceback (most recent call last):
+        VdtValueTooSmallError: the value "0" is too small.
+        """
+        ValidateError.__init__(self, 'the value "%s" is too small.' % (value,))
+
+
+class VdtValueTooBigError(VdtValueError):
+    """The value supplied was of the correct type, but was too big."""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtValueTooBigError('1')
+        Traceback (most recent call last):
+        VdtValueTooBigError: the value "1" is too big.
+        """
+        ValidateError.__init__(self, 'the value "%s" is too big.' % (value,))
+
+
+class VdtValueTooShortError(VdtValueError):
+    """The value supplied was of the correct type, but was too short."""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtValueTooShortError('jed')
+        Traceback (most recent call last):
+        VdtValueTooShortError: the value "jed" is too short.
+        """
+        ValidateError.__init__(
+            self,
+            'the value "%s" is too short.' % (value,))
+
+
+class VdtValueTooLongError(VdtValueError):
+    """The value supplied was of the correct type, but was too long."""
+
+    def __init__(self, value):
+        """
+        >>> raise VdtValueTooLongError('jedie')
+        Traceback (most recent call last):
+        VdtValueTooLongError: the value "jedie" is too long.
+        """
+        ValidateError.__init__(self, 'the value "%s" is too long.' % (value,))
+
+
+class Validator(object):
+    """
+    Validator is an object that allows you to register a set of 'checks'.
+    These checks take input and test that it conforms to the check.
+    
+    This can also involve converting the value from a string into
+    the correct datatype.
+    
+    The ``check`` method takes an input string which configures which
+    check is to be used and applies that check to a supplied value.
+    
+    An example input string would be:
+    'int_range(param1, param2)'
+    
+    You would then provide something like:
+    
+    >>> def int_range_check(value, min, max):
+    ...     # turn min and max from strings to integers
+    ...     min = int(min)
+    ...     max = int(max)
+    ...     # check that value is of the correct type.
+    ...     # possible valid inputs are integers or strings
+    ...     # that represent integers
+    ...     if not isinstance(value, (int, long, string_type)):
+    ...         raise VdtTypeError(value)
+    ...     elif isinstance(value, string_type):
+    ...         # if we are given a string
+    ...         # attempt to convert to an integer
+    ...         try:
+    ...             value = int(value)
+    ...         except ValueError:
+    ...             raise VdtValueError(value)
+    ...     # check the value is between our constraints
+    ...     if not min <= value:
+    ...          raise VdtValueTooSmallError(value)
+    ...     if not value <= max:
+    ...          raise VdtValueTooBigError(value)
+    ...     return value
+    
+    >>> fdict = {'int_range': int_range_check}
+    >>> vtr1 = Validator(fdict)
+    >>> vtr1.check('int_range(20, 40)', '30')
+    30
+    >>> vtr1.check('int_range(20, 40)', '60')
+    Traceback (most recent call last):
+    VdtValueTooBigError: the value "60" is too big.
+    
+    New functions can be added with : ::
+    
+    >>> vtr2 = Validator()       
+    >>> vtr2.functions['int_range'] = int_range_check
+    
+    Or by passing in a dictionary of functions when Validator 
+    is instantiated.
+    
+    Your functions *can* use keyword arguments,
+    but the first argument should always be 'value'.
+    
+    If the function doesn't take additional arguments,
+    the parentheses are optional in the check.
+    It can be written with either of : ::
+    
+        keyword = function_name
+        keyword = function_name()
+    
+    The first program to utilise Validator() was Michael Foord's
+    ConfigObj, an alternative to ConfigParser which supports lists and
+    can validate a config file using a config schema.
+    For more details on using Validator with ConfigObj see:
+    https://configobj.readthedocs.org/en/latest/configobj.html
+    """
+
+    # this regex does the initial parsing of the checks
+    _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
+
+    # this regex takes apart keyword arguments
+    _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$',  re.DOTALL)
+
+
+    # this regex finds keyword=list(....) type values
+    _list_arg = _list_arg
+
+    # this regex takes individual values out of lists - in one pass
+    _list_members = _list_members
+
+    # These regexes check a set of arguments for validity
+    # and then pull the members out
+    _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL)
+    _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL)
+
+
+    def __init__(self, functions=None):
+        """
+        >>> vtri = Validator()
+        """
+        self.functions = {
+            '': self._pass,
+            'integer': is_integer,
+            'float': is_float,
+            'boolean': is_boolean,
+            'ip_addr': is_ip_addr,
+            'string': is_string,
+            'list': is_list,
+            'tuple': is_tuple,
+            'int_list': is_int_list,
+            'float_list': is_float_list,
+            'bool_list': is_bool_list,
+            'ip_addr_list': is_ip_addr_list,
+            'string_list': is_string_list,
+            'mixed_list': is_mixed_list,
+            'pass': self._pass,
+            'option': is_option,
+            'force_list': force_list,
+        }
+        if functions is not None:
+            self.functions.update(functions)
+        # tekNico: for use by ConfigObj
+        self.baseErrorClass = ValidateError
+        self._cache = {}
+
+
+    def check(self, check, value, missing=False):
+        """
+        Usage: check(check, value)
+        
+        Arguments:
+            check: string representing check to apply (including arguments)
+            value: object to be checked
+        Returns value, converted to correct type if necessary
+        
+        If the check fails, raises a ``ValidateError`` subclass.
+        
+        >>> vtor.check('yoda', '')
+        Traceback (most recent call last):
+        VdtUnknownCheckError: the check "yoda" is unknown.
+        >>> vtor.check('yoda()', '')
+        Traceback (most recent call last):
+        VdtUnknownCheckError: the check "yoda" is unknown.
+        
+        >>> vtor.check('string(default="")', '', missing=True)
+        ''
+        """
+        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
+            
+        if missing:
+            if default is None:
+                # no information needed here - to be handled by caller
+                raise VdtMissingValue()
+            value = self._handle_none(default)
+        
+        if value is None:
+            return None
+        
+        return self._check_value(value, fun_name, fun_args, fun_kwargs)
+
+
+    def _handle_none(self, value):
+        if value == 'None':
+            return None
+        elif value in ("'None'", '"None"'):
+            # Special case a quoted None
+            value = self._unquote(value)
+        return value
+
+
+    def _parse_with_caching(self, check):
+        if check in self._cache:
+            fun_name, fun_args, fun_kwargs, default = self._cache[check]
+            # We call list and dict below to work with *copies* of the data
+            # rather than the original (which are mutable of course)
+            fun_args = list(fun_args)
+            fun_kwargs = dict(fun_kwargs)
+        else:
+            fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
+            fun_kwargs = dict([(str(key), value) for (key, value) in list(fun_kwargs.items())])
+            self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
+        return fun_name, fun_args, fun_kwargs, default
+        
+        
+    def _check_value(self, value, fun_name, fun_args, fun_kwargs):
+        try:
+            fun = self.functions[fun_name]
+        except KeyError:
+            raise VdtUnknownCheckError(fun_name)
+        else:
+            return fun(value, *fun_args, **fun_kwargs)
+
+
+    def _parse_check(self, check):
+        fun_match = self._func_re.match(check)
+        if fun_match:
+            fun_name = fun_match.group(1)
+            arg_string = fun_match.group(2)
+            arg_match = self._matchfinder.match(arg_string)
+            if arg_match is None:
+                # Bad syntax
+                raise VdtParamError('Bad syntax in check "%s".' % check)
+            fun_args = []
+            fun_kwargs = {}
+            # pull out args of group 2
+            for arg in self._paramfinder.findall(arg_string):
+                # args may need whitespace removing (before removing quotes)
+                arg = arg.strip()
+                listmatch = self._list_arg.match(arg)
+                if listmatch:
+                    key, val = self._list_handle(listmatch)
+                    fun_kwargs[key] = val
+                    continue
+                keymatch = self._key_arg.match(arg)
+                if keymatch:
+                    val = keymatch.group(2)
+                    if not val in ("'None'", '"None"'):
+                        # Special case a quoted None
+                        val = self._unquote(val)
+                    fun_kwargs[keymatch.group(1)] = val
+                    continue
+                
+                fun_args.append(self._unquote(arg))
+        else:
+            # allows for function names without (args)
+            return check, (), {}, None
+
+        # Default must be deleted if the value is specified too,
+        # otherwise the check function will get a spurious "default" keyword arg
+        default = fun_kwargs.pop('default', None)
+        return fun_name, fun_args, fun_kwargs, default
+
+
+    def _unquote(self, val):
+        """Unquote a value if necessary."""
+        if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]):
+            val = val[1:-1]
+        return val
+
+
+    def _list_handle(self, listmatch):
+        """Take apart a ``keyword=list('val, 'val')`` type string."""
+        out = []
+        name = listmatch.group(1)
+        args = listmatch.group(2)
+        for arg in self._list_members.findall(args):
+            out.append(self._unquote(arg))
+        return name, out
+
+
+    def _pass(self, value):
+        """
+        Dummy check that always passes
+        
+        >>> vtor.check('', 0)
+        0
+        >>> vtor.check('', '0')
+        '0'
+        """
+        return value
+    
+    
+    def get_default_value(self, check):
+        """
+        Given a check, return the default value for the check
+        (converted to the right type).
+        
+        If the check doesn't specify a default value then a
+        ``KeyError`` will be raised.
+        """
+        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
+        if default is None:
+            raise KeyError('Check "%s" has no default value.' % check)
+        value = self._handle_none(default)
+        if value is None:
+            return value
+        return self._check_value(value, fun_name, fun_args, fun_kwargs)
+
+
+def _is_num_param(names, values, to_float=False):
+    """
+    Return numbers from inputs or raise VdtParamError.
+    
+    Lets ``None`` pass through.
+    Pass in keyword argument ``to_float=True`` to
+    use float for the conversion rather than int.
+    
+    >>> _is_num_param(('', ''), (0, 1.0))
+    [0, 1]
+    >>> _is_num_param(('', ''), (0, 1.0), to_float=True)
+    [0.0, 1.0]
+    >>> _is_num_param(('a'), ('a'))
+    Traceback (most recent call last):
+    VdtParamError: passed an incorrect value "a" for parameter "a".
+    """
+    fun = to_float and float or int
+    out_params = []
+    for (name, val) in zip(names, values):
+        if val is None:
+            out_params.append(val)
+        elif isinstance(val, (int, long, float, string_type)):
+            try:
+                out_params.append(fun(val))
+            except ValueError as e:
+                raise VdtParamError(name, val)
+        else:
+            raise VdtParamError(name, val)
+    return out_params
+
+
+# built in checks
+# you can override these by setting the appropriate name
+# in Validator.functions
+# note: if the params are specified wrongly in your input string,
+#       you will also raise errors.
+
+def is_integer(value, min=None, max=None):
+    """
+    A check that tests that a given value is an integer (int, or long)
+    and optionally, between bounds. A negative value is accepted, while
+    a float will fail.
+    
+    If the value is a string, then the conversion is done - if possible.
+    Otherwise a VdtError is raised.
+    
+    >>> vtor.check('integer', '-1')
+    -1
+    >>> vtor.check('integer', '0')
+    0
+    >>> vtor.check('integer', 9)
+    9
+    >>> vtor.check('integer', 'a')
+    Traceback (most recent call last):
+    VdtTypeError: the value "a" is of the wrong type.
+    >>> vtor.check('integer', '2.2')
+    Traceback (most recent call last):
+    VdtTypeError: the value "2.2" is of the wrong type.
+    >>> vtor.check('integer(10)', '20')
+    20
+    >>> vtor.check('integer(max=20)', '15')
+    15
+    >>> vtor.check('integer(10)', '9')
+    Traceback (most recent call last):
+    VdtValueTooSmallError: the value "9" is too small.
+    >>> vtor.check('integer(10)', 9)
+    Traceback (most recent call last):
+    VdtValueTooSmallError: the value "9" is too small.
+    >>> vtor.check('integer(max=20)', '35')
+    Traceback (most recent call last):
+    VdtValueTooBigError: the value "35" is too big.
+    >>> vtor.check('integer(max=20)', 35)
+    Traceback (most recent call last):
+    VdtValueTooBigError: the value "35" is too big.
+    >>> vtor.check('integer(0, 9)', False)
+    0
+    """
+    (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
+    if not isinstance(value, (int, long, string_type)):
+        raise VdtTypeError(value)
+    if isinstance(value, string_type):
+        # if it's a string - does it represent an integer ?
+        try:
+            value = int(value)
+        except ValueError:
+            raise VdtTypeError(value)
+    if (min_val is not None) and (value < min_val):
+        raise VdtValueTooSmallError(value)
+    if (max_val is not None) and (value > max_val):
+        raise VdtValueTooBigError(value)
+    return value
+
+
+def is_float(value, min=None, max=None):
+    """
+    A check that tests that a given value is a float
+    (an integer will be accepted), and optionally - that it is between bounds.
+    
+    If the value is a string, then the conversion is done - if possible.
+    Otherwise a VdtError is raised.
+    
+    This can accept negative values.
+    
+    >>> vtor.check('float', '2')
+    2.0
+    
+    From now on we multiply the value to avoid comparing decimals
+    
+    >>> vtor.check('float', '-6.8') * 10
+    -68.0
+    >>> vtor.check('float', '12.2') * 10
+    122.0
+    >>> vtor.check('float', 8.4) * 10
+    84.0
+    >>> vtor.check('float', 'a')
+    Traceback (most recent call last):
+    VdtTypeError: the value "a" is of the wrong type.
+    >>> vtor.check('float(10.1)', '10.2') * 10
+    102.0
+    >>> vtor.check('float(max=20.2)', '15.1') * 10
+    151.0
+    >>> vtor.check('float(10.0)', '9.0')
+    Traceback (most recent call last):
+    VdtValueTooSmallError: the value "9.0" is too small.
+    >>> vtor.check('float(max=20.0)', '35.0')
+    Traceback (most recent call last):
+    VdtValueTooBigError: the value "35.0" is too big.
+    """
+    (min_val, max_val) = _is_num_param(
+        ('min', 'max'), (min, max), to_float=True)
+    if not isinstance(value, (int, long, float, string_type)):
+        raise VdtTypeError(value)
+    if not isinstance(value, float):
+        # if it's a string - does it represent a float ?
+        try:
+            value = float(value)
+        except ValueError:
+            raise VdtTypeError(value)
+    if (min_val is not None) and (value < min_val):
+        raise VdtValueTooSmallError(value)
+    if (max_val is not None) and (value > max_val):
+        raise VdtValueTooBigError(value)
+    return value
+
+
+bool_dict = {
+    True: True, 'on': True, '1': True, 'true': True, 'yes': True, 
+    False: False, 'off': False, '0': False, 'false': False, 'no': False,
+}
+
+
+def is_boolean(value):
+    """
+    Check if the value represents a boolean.
+    
+    >>> vtor.check('boolean', 0)
+    0
+    >>> vtor.check('boolean', False)
+    0
+    >>> vtor.check('boolean', '0')
+    0
+    >>> vtor.check('boolean', 'off')
+    0
+    >>> vtor.check('boolean', 'false')
+    0
+    >>> vtor.check('boolean', 'no')
+    0
+    >>> vtor.check('boolean', 'nO')
+    0
+    >>> vtor.check('boolean', 'NO')
+    0
+    >>> vtor.check('boolean', 1)
+    1
+    >>> vtor.check('boolean', True)
+    1
+    >>> vtor.check('boolean', '1')
+    1
+    >>> vtor.check('boolean', 'on')
+    1
+    >>> vtor.check('boolean', 'true')
+    1
+    >>> vtor.check('boolean', 'yes')
+    1
+    >>> vtor.check('boolean', 'Yes')
+    1
+    >>> vtor.check('boolean', 'YES')
+    1
+    >>> vtor.check('boolean', '')
+    Traceback (most recent call last):
+    VdtTypeError: the value "" is of the wrong type.
+    >>> vtor.check('boolean', 'up')
+    Traceback (most recent call last):
+    VdtTypeError: the value "up" is of the wrong type.
+    
+    """
+    if isinstance(value, string_type):
+        try:
+            return bool_dict[value.lower()]
+        except KeyError:
+            raise VdtTypeError(value)
+    # we do an equality test rather than an identity test
+    # this ensures Python 2.2 compatibilty
+    # and allows 0 and 1 to represent True and False
+    if value == False:
+        return False
+    elif value == True:
+        return True
+    else:
+        raise VdtTypeError(value)
+
+
+def is_ip_addr(value):
+    """
+    Check that the supplied value is an Internet Protocol address, v.4,
+    represented by a dotted-quad string, i.e. '1.2.3.4'.
+    
+    >>> vtor.check('ip_addr', '1 ')
+    '1'
+    >>> vtor.check('ip_addr', ' 1.2')
+    '1.2'
+    >>> vtor.check('ip_addr', ' 1.2.3 ')
+    '1.2.3'
+    >>> vtor.check('ip_addr', '1.2.3.4')
+    '1.2.3.4'
+    >>> vtor.check('ip_addr', '0.0.0.0')
+    '0.0.0.0'
+    >>> vtor.check('ip_addr', '255.255.255.255')
+    '255.255.255.255'
+    >>> vtor.check('ip_addr', '255.255.255.256')
+    Traceback (most recent call last):
+    VdtValueError: the value "255.255.255.256" is unacceptable.
+    >>> vtor.check('ip_addr', '1.2.3.4.5')
+    Traceback (most recent call last):
+    VdtValueError: the value "1.2.3.4.5" is unacceptable.
+    >>> vtor.check('ip_addr', 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+    """
+    if not isinstance(value, string_type):
+        raise VdtTypeError(value)
+    value = value.strip()
+    try:
+        dottedQuadToNum(value)
+    except ValueError:
+        raise VdtValueError(value)
+    return value
+
+
+def is_list(value, min=None, max=None):
+    """
+    Check that the value is a list of values.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    It does no check on list members.
+    
+    >>> vtor.check('list', ())
+    []
+    >>> vtor.check('list', [])
+    []
+    >>> vtor.check('list', (1, 2))
+    [1, 2]
+    >>> vtor.check('list', [1, 2])
+    [1, 2]
+    >>> vtor.check('list(3)', (1, 2))
+    Traceback (most recent call last):
+    VdtValueTooShortError: the value "(1, 2)" is too short.
+    >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6))
+    Traceback (most recent call last):
+    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
+    >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4))
+    [1, 2, 3, 4]
+    >>> vtor.check('list', 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+    >>> vtor.check('list', '12')
+    Traceback (most recent call last):
+    VdtTypeError: the value "12" is of the wrong type.
+    """
+    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
+    if isinstance(value, string_type):
+        raise VdtTypeError(value)
+    try:
+        num_members = len(value)
+    except TypeError:
+        raise VdtTypeError(value)
+    if min_len is not None and num_members < min_len:
+        raise VdtValueTooShortError(value)
+    if max_len is not None and num_members > max_len:
+        raise VdtValueTooLongError(value)
+    return list(value)
+
+
+def is_tuple(value, min=None, max=None):
+    """
+    Check that the value is a tuple of values.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    It does no check on members.
+    
+    >>> vtor.check('tuple', ())
+    ()
+    >>> vtor.check('tuple', [])
+    ()
+    >>> vtor.check('tuple', (1, 2))
+    (1, 2)
+    >>> vtor.check('tuple', [1, 2])
+    (1, 2)
+    >>> vtor.check('tuple(3)', (1, 2))
+    Traceback (most recent call last):
+    VdtValueTooShortError: the value "(1, 2)" is too short.
+    >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6))
+    Traceback (most recent call last):
+    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
+    >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4))
+    (1, 2, 3, 4)
+    >>> vtor.check('tuple', 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+    >>> vtor.check('tuple', '12')
+    Traceback (most recent call last):
+    VdtTypeError: the value "12" is of the wrong type.
+    """
+    return tuple(is_list(value, min, max))
+
+
+def is_string(value, min=None, max=None):
+    """
+    Check that the supplied value is a string.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    >>> vtor.check('string', '0')
+    '0'
+    >>> vtor.check('string', 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+    >>> vtor.check('string(2)', '12')
+    '12'
+    >>> vtor.check('string(2)', '1')
+    Traceback (most recent call last):
+    VdtValueTooShortError: the value "1" is too short.
+    >>> vtor.check('string(min=2, max=3)', '123')
+    '123'
+    >>> vtor.check('string(min=2, max=3)', '1234')
+    Traceback (most recent call last):
+    VdtValueTooLongError: the value "1234" is too long.
+    """
+    if not isinstance(value, string_type):
+        raise VdtTypeError(value)
+    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
+    try:
+        num_members = len(value)
+    except TypeError:
+        raise VdtTypeError(value)
+    if min_len is not None and num_members < min_len:
+        raise VdtValueTooShortError(value)
+    if max_len is not None and num_members > max_len:
+        raise VdtValueTooLongError(value)
+    return value
+
+
+def is_int_list(value, min=None, max=None):
+    """
+    Check that the value is a list of integers.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    Each list member is checked that it is an integer.
+    
+    >>> vtor.check('int_list', ())
+    []
+    >>> vtor.check('int_list', [])
+    []
+    >>> vtor.check('int_list', (1, 2))
+    [1, 2]
+    >>> vtor.check('int_list', [1, 2])
+    [1, 2]
+    >>> vtor.check('int_list', [1, 'a'])
+    Traceback (most recent call last):
+    VdtTypeError: the value "a" is of the wrong type.
+    """
+    return [is_integer(mem) for mem in is_list(value, min, max)]
+
+
+def is_bool_list(value, min=None, max=None):
+    """
+    Check that the value is a list of booleans.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    Each list member is checked that it is a boolean.
+    
+    >>> vtor.check('bool_list', ())
+    []
+    >>> vtor.check('bool_list', [])
+    []
+    >>> check_res = vtor.check('bool_list', (True, False))
+    >>> check_res == [True, False]
+    1
+    >>> check_res = vtor.check('bool_list', [True, False])
+    >>> check_res == [True, False]
+    1
+    >>> vtor.check('bool_list', [True, 'a'])
+    Traceback (most recent call last):
+    VdtTypeError: the value "a" is of the wrong type.
+    """
+    return [is_boolean(mem) for mem in is_list(value, min, max)]
+
+
+def is_float_list(value, min=None, max=None):
+    """
+    Check that the value is a list of floats.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    Each list member is checked that it is a float.
+    
+    >>> vtor.check('float_list', ())
+    []
+    >>> vtor.check('float_list', [])
+    []
+    >>> vtor.check('float_list', (1, 2.0))
+    [1.0, 2.0]
+    >>> vtor.check('float_list', [1, 2.0])
+    [1.0, 2.0]
+    >>> vtor.check('float_list', [1, 'a'])
+    Traceback (most recent call last):
+    VdtTypeError: the value "a" is of the wrong type.
+    """
+    return [is_float(mem) for mem in is_list(value, min, max)]
+
+
+def is_string_list(value, min=None, max=None):
+    """
+    Check that the value is a list of strings.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    Each list member is checked that it is a string.
+    
+    >>> vtor.check('string_list', ())
+    []
+    >>> vtor.check('string_list', [])
+    []
+    >>> vtor.check('string_list', ('a', 'b'))
+    ['a', 'b']
+    >>> vtor.check('string_list', ['a', 1])
+    Traceback (most recent call last):
+    VdtTypeError: the value "1" is of the wrong type.
+    >>> vtor.check('string_list', 'hello')
+    Traceback (most recent call last):
+    VdtTypeError: the value "hello" is of the wrong type.
+    """
+    if isinstance(value, string_type):
+        raise VdtTypeError(value)
+    return [is_string(mem) for mem in is_list(value, min, max)]
+
+
+def is_ip_addr_list(value, min=None, max=None):
+    """
+    Check that the value is a list of IP addresses.
+    
+    You can optionally specify the minimum and maximum number of members.
+    
+    Each list member is checked that it is an IP address.
+    
+    >>> vtor.check('ip_addr_list', ())
+    []
+    >>> vtor.check('ip_addr_list', [])
+    []
+    >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8'))
+    ['1.2.3.4', '5.6.7.8']
+    >>> vtor.check('ip_addr_list', ['a'])
+    Traceback (most recent call last):
+    VdtValueError: the value "a" is unacceptable.
+    """
+    return [is_ip_addr(mem) for mem in is_list(value, min, max)]
+
+
+def force_list(value, min=None, max=None):
+    """
+    Check that a value is a list, coercing strings into
+    a list with one member. Useful where users forget the
+    trailing comma that turns a single value into a list.
+    
+    You can optionally specify the minimum and maximum number of members.
+    A minumum of greater than one will fail if the user only supplies a
+    string.
+    
+    >>> vtor.check('force_list', ())
+    []
+    >>> vtor.check('force_list', [])
+    []
+    >>> vtor.check('force_list', 'hello')
+    ['hello']
+    """
+    if not isinstance(value, (list, tuple)):
+        value = [value]
+    return is_list(value, min, max)
+    
+    
+
+fun_dict = {
+    'integer': is_integer,
+    'float': is_float,
+    'ip_addr': is_ip_addr,
+    'string': is_string,
+    'boolean': is_boolean,
+}
+
+
+def is_mixed_list(value, *args):
+    """
+    Check that the value is a list.
+    Allow specifying the type of each member.
+    Work on lists of specific lengths.
+    
+    You specify each member as a positional argument specifying type
+    
+    Each type should be one of the following strings :
+      'integer', 'float', 'ip_addr', 'string', 'boolean'
+    
+    So you can specify a list of two strings, followed by
+    two integers as :
+    
+      mixed_list('string', 'string', 'integer', 'integer')
+    
+    The length of the list must match the number of positional
+    arguments you supply.
+    
+    >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
+    >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
+    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
+    1
+    >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True'))
+    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
+    1
+    >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True))
+    Traceback (most recent call last):
+    VdtTypeError: the value "b" is of the wrong type.
+    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a'))
+    Traceback (most recent call last):
+    VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
+    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
+    Traceback (most recent call last):
+    VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
+    >>> vtor.check(mix_str, 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+
+    >>> vtor.check('mixed_list("yoda")', ('a'))
+    Traceback (most recent call last):
+    VdtParamError: passed an incorrect value "KeyError('yoda',)" for parameter "'mixed_list'"
+    """
+    try:
+        length = len(value)
+    except TypeError:
+        raise VdtTypeError(value)
+    if length < len(args):
+        raise VdtValueTooShortError(value)
+    elif length > len(args):
+        raise VdtValueTooLongError(value)
+    try:
+        return [fun_dict[arg](val) for arg, val in zip(args, value)]
+    except KeyError as e:
+        raise VdtParamError('mixed_list', e)
+
+
+def is_option(value, *options):
+    """
+    This check matches the value to any of a set of options.
+    
+    >>> vtor.check('option("yoda", "jedi")', 'yoda')
+    'yoda'
+    >>> vtor.check('option("yoda", "jedi")', 'jed')
+    Traceback (most recent call last):
+    VdtValueError: the value "jed" is unacceptable.
+    >>> vtor.check('option("yoda", "jedi")', 0)
+    Traceback (most recent call last):
+    VdtTypeError: the value "0" is of the wrong type.
+    """
+    if not isinstance(value, string_type):
+        raise VdtTypeError(value)
+    if not value in options:
+        raise VdtValueError(value)
+    return value
+
+
+def _test(value, *args, **keywargs):
+    """
+    A function that exists for test purposes.
+    
+    >>> checks = [
+    ...     '3, 6, min=1, max=3, test=list(a, b, c)',
+    ...     '3',
+    ...     '3, 6',
+    ...     '3,',
+    ...     'min=1, test="a b c"',
+    ...     'min=5, test="a, b, c"',
+    ...     'min=1, max=3, test="a, b, c"',
+    ...     'min=-100, test=-99',
+    ...     'min=1, max=3',
+    ...     '3, 6, test="36"',
+    ...     '3, 6, test="a, b, c"',
+    ...     '3, max=3, test=list("a", "b", "c")',
+    ...     '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
+    ...     "test='x=fish(3)'",
+    ...    ]
+    >>> v = Validator({'test': _test})
+    >>> for entry in checks:
+    ...     pprint(v.check(('test(%s)' % entry), 3))
+    (3, ('3', '6'), {'max': '3', 'min': '1', 'test': ['a', 'b', 'c']})
+    (3, ('3',), {})
+    (3, ('3', '6'), {})
+    (3, ('3',), {})
+    (3, (), {'min': '1', 'test': 'a b c'})
+    (3, (), {'min': '5', 'test': 'a, b, c'})
+    (3, (), {'max': '3', 'min': '1', 'test': 'a, b, c'})
+    (3, (), {'min': '-100', 'test': '-99'})
+    (3, (), {'max': '3', 'min': '1'})
+    (3, ('3', '6'), {'test': '36'})
+    (3, ('3', '6'), {'test': 'a, b, c'})
+    (3, ('3',), {'max': '3', 'test': ['a', 'b', 'c']})
+    (3, ('3',), {'max': '3', 'test': ["'a'", 'b', 'x=(c)']})
+    (3, (), {'test': 'x=fish(3)'})
+    
+    >>> v = Validator()
+    >>> v.check('integer(default=6)', '3')
+    3
+    >>> v.check('integer(default=6)', None, True)
+    6
+    >>> v.get_default_value('integer(default=6)')
+    6
+    >>> v.get_default_value('float(default=6)')
+    6.0
+    >>> v.get_default_value('pass(default=None)')
+    >>> v.get_default_value("string(default='None')")
+    'None'
+    >>> v.get_default_value('pass')
+    Traceback (most recent call last):
+    KeyError: 'Check "pass" has no default value.'
+    >>> v.get_default_value('pass(default=list(1, 2, 3, 4))')
+    ['1', '2', '3', '4']
+    
+    >>> v = Validator()
+    >>> v.check("pass(default=None)", None, True)
+    >>> v.check("pass(default='None')", None, True)
+    'None'
+    >>> v.check('pass(default="None")', None, True)
+    'None'
+    >>> v.check('pass(default=list(1, 2, 3, 4))', None, True)
+    ['1', '2', '3', '4']
+    
+    Bug test for unicode arguments
+    >>> v = Validator()
+    >>> v.check(unicode('string(min=4)'), unicode('test')) == unicode('test')
+    True
+    
+    >>> v = Validator()
+    >>> v.get_default_value(unicode('string(min=4, default="1234")')) == unicode('1234')
+    True
+    >>> v.check(unicode('string(min=4, default="1234")'), unicode('test')) == unicode('test')
+    True
+    
+    >>> v = Validator()
+    >>> default = v.get_default_value('string(default=None)')
+    >>> default == None
+    1
+    """
+    return (value, args, keywargs)
+
+
+def _test2():
+    """
+    >>> 
+    >>> v = Validator()
+    >>> v.get_default_value('string(default="#ff00dd")')
+    '#ff00dd'
+    >>> v.get_default_value('integer(default=3) # comment')
+    3
+    """
+
+def _test3():
+    r"""
+    >>> vtor.check('string(default="")', '', missing=True)
+    ''
+    >>> vtor.check('string(default="\n")', '', missing=True)
+    '\n'
+    >>> print(vtor.check('string(default="\n")', '', missing=True))
+    <BLANKLINE>
+    <BLANKLINE>
+    >>> vtor.check('string()', '\n')
+    '\n'
+    >>> vtor.check('string(default="\n\n\n")', '', missing=True)
+    '\n\n\n'
+    >>> vtor.check('string()', 'random \n text goes here\n\n')
+    'random \n text goes here\n\n'
+    >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")',
+    ... '', missing=True)
+    ' \nrandom text\ngoes \n here\n\n '
+    >>> vtor.check("string(default='\n\n\n')", '', missing=True)
+    '\n\n\n'
+    >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True)
+    '\n'
+    >>> vtor.check("string_list()", ['foo', '\n', 'bar'])
+    ['foo', '\n', 'bar']
+    >>> vtor.check("string_list(default=list('\n'))", '', missing=True)
+    ['\n']
+    """
+    
+    
+if __name__ == '__main__':
+    # run the code tests in doctest format
+    import sys
+    import doctest
+    m = sys.modules.get('__main__')
+    globs = m.__dict__.copy()
+    globs.update({
+        'vtor': Validator(),
+    })
+
+    failures, tests = doctest.testmod(
+        m, globs=globs,
+        optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.ELLIPSIS)
+    assert not failures, '{} failures out of {} tests'.format(failures, tests)
diff --git a/astropy/extern/configobj_py2/__init__.py b/astropy/extern/configobj_py2/__init__.py
deleted file mode 100644
index f5a38a0..0000000
--- a/astropy/extern/configobj_py2/__init__.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst  
-
-"""
-This is a copy of the main portions of the  `configobj 
-<http://www.voidspace.org.uk/python/configobj.html>`_ package. This is used
-internally in the Astropy configuration system. The license for configobj is
-available  in the ``licenses/CONFIGOBJ_LICENSE.rst`` file in the Astropy
-source distribution.  
-
-This is the original 4.7.2 version of configobj, which is only compatible with
-python 2.x - the 3.x version is in ``astropy/extern/configobj-py3``.
-""" 
-
-#this holds the contents of the setup.py file used by configobj
-_configobj_setup_dot_py="""
-# setup.py
-# Install script for ConfigObj
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
-
-# This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-
-import sys
-from distutils.core import setup
-from configobj import __version__ as VERSION
-
-NAME = 'configobj'
-
-MODULES = 'configobj', 'validate'
-
-DESCRIPTION = 'Config file reading, writing and validation.'
-
-URL = 'http://www.voidspace.org.uk/python/configobj.html'
-
-DOWNLOAD_URL = "http://www.voidspace.org.uk/downloads/configobj-%s.zip" % VERSION
-
-LONG_DESCRIPTION = ""#"**ConfigObj** is a simple but powerful config file reader and writer: an *ini
-file round tripper*. Its main feature is that it is very easy to use, with a
-straightforward programmer's interface and a simple syntax for config files.
-It has lots of other features though :
-
-* Nested sections (subsections), to any level
-* List values
-* Multiple line values
-* Full Unicode support
-* String interpolation (substitution)
-* Integrated with a powerful validation system
-
-    - including automatic type checking/conversion
-    - and allowing default values
-    - repeated sections
-
-* All comments in the file are preserved
-* The order of keys/sections is preserved
-* Powerful ``unrepr`` mode for storing/retrieving Python data-types
-
-| Release 4.7.2 fixes several bugs in 4.7.1
-| Release 4.7.1 fixes a bug with the deprecated options keyword in
-| 4.7.0.
-| Release 4.7.0 improves performance adds features for validation and
-| fixes some bugs.""#"
-
-CLASSIFIERS = [
-    'Development Status :: 6 - Mature',
-    'Intended Audience :: Developers',
-    'License :: OSI Approved :: BSD License',
-    'Programming Language :: Python',
-    'Programming Language :: Python :: 2.3',
-    'Programming Language :: Python :: 2.4',
-    'Programming Language :: Python :: 2.5',
-    'Programming Language :: Python :: 2.6',
-    'Operating System :: OS Independent',
-    'Topic :: Software Development :: Libraries',
-    'Topic :: Software Development :: Libraries :: Python Modules',
-]
-
-AUTHOR = 'Michael Foord & Nicola Larosa'
-
-AUTHOR_EMAIL = 'fuzzyman at voidspace.org.uk'
-
-KEYWORDS = "config, ini, dictionary, application, admin, sysadmin, configuration, validation".split(', ')
-
-
-setup(name=NAME,
-      version=VERSION,
-      description=DESCRIPTION,
-      long_description=LONG_DESCRIPTION,
-      download_url=DOWNLOAD_URL,
-      author=AUTHOR,
-      author_email=AUTHOR_EMAIL,
-      url=URL,
-      py_modules=MODULES,
-      classifiers=CLASSIFIERS,
-      keywords=KEYWORDS
-     )
-""".replace('""#"','"""') 
-#the replacement is necessary because """ would otherwise terminate the string
diff --git a/astropy/extern/configobj_py2/configobj.py b/astropy/extern/configobj_py2/configobj.py
deleted file mode 100644
index c1f6e6d..0000000
--- a/astropy/extern/configobj_py2/configobj.py
+++ /dev/null
@@ -1,2468 +0,0 @@
-# configobj.py
-# A config file reader/writer that supports nested sections in config files.
-# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         nico AT tekNico DOT net
-
-# ConfigObj 4
-# http://www.voidspace.org.uk/python/configobj.html
-
-# Released subject to the BSD License
-# Please see http://www.voidspace.org.uk/python/license.shtml
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
-
-from __future__ import generators
-
-import os
-import re
-import sys
-
-from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
-
-
-# imported lazily to avoid startup performance hit if it isn't used
-compiler = None
-
-# A dictionary mapping BOM to
-# the encoding to decode with, and what to set the
-# encoding attribute to.
-BOMS = {
-    BOM_UTF8: ('utf_8', None),
-    BOM_UTF16_BE: ('utf16_be', 'utf_16'),
-    BOM_UTF16_LE: ('utf16_le', 'utf_16'),
-    BOM_UTF16: ('utf_16', 'utf_16'),
-    }
-# All legal variants of the BOM codecs.
-# TODO: the list of aliases is not meant to be exhaustive, is there a
-#   better way ?
-BOM_LIST = {
-    'utf_16': 'utf_16',
-    'u16': 'utf_16',
-    'utf16': 'utf_16',
-    'utf-16': 'utf_16',
-    'utf16_be': 'utf16_be',
-    'utf_16_be': 'utf16_be',
-    'utf-16be': 'utf16_be',
-    'utf16_le': 'utf16_le',
-    'utf_16_le': 'utf16_le',
-    'utf-16le': 'utf16_le',
-    'utf_8': 'utf_8',
-    'u8': 'utf_8',
-    'utf': 'utf_8',
-    'utf8': 'utf_8',
-    'utf-8': 'utf_8',
-    }
-
-# Map of encodings to the BOM to write.
-BOM_SET = {
-    'utf_8': BOM_UTF8,
-    'utf_16': BOM_UTF16,
-    'utf16_be': BOM_UTF16_BE,
-    'utf16_le': BOM_UTF16_LE,
-    None: BOM_UTF8
-    }
-
-
-def match_utf8(encoding):
-    return BOM_LIST.get(encoding.lower()) == 'utf_8'
-
-
-# Quote strings used for writing values
-squot = "'%s'"
-dquot = '"%s"'
-noquot = "%s"
-wspace_plus = ' \r\n\v\t\'"'
-tsquot = '"""%s"""'
-tdquot = "'''%s'''"
-
-# Sentinel for use in getattr calls to replace hasattr
-MISSING = object()
-
-__version__ = '4.7.2'
-
-try:
-    any
-except NameError:
-    def any(iterable):
-        for entry in iterable:
-            if entry:
-                return True
-        return False
-
-
-__all__ = (
-    '__version__',
-    'DEFAULT_INDENT_TYPE',
-    'DEFAULT_INTERPOLATION',
-    'ConfigObjError',
-    'NestingError',
-    'ParseError',
-    'DuplicateError',
-    'ConfigspecError',
-    'ConfigObj',
-    'SimpleVal',
-    'InterpolationError',
-    'InterpolationLoopError',
-    'MissingInterpolationOption',
-    'RepeatSectionError',
-    'ReloadError',
-    'UnreprError',
-    'UnknownType',
-    'flatten_errors',
-    'get_extra_values'
-)
-
-DEFAULT_INTERPOLATION = 'configparser'
-DEFAULT_INDENT_TYPE = '    '
-MAX_INTERPOL_DEPTH = 10
-
-OPTION_DEFAULTS = {
-    'interpolation': True,
-    'raise_errors': False,
-    'list_values': True,
-    'create_empty': False,
-    'file_error': False,
-    'configspec': None,
-    'stringify': True,
-    # option may be set to one of ('', ' ', '\t')
-    'indent_type': None,
-    'encoding': None,
-    'default_encoding': None,
-    'unrepr': False,
-    'write_empty_values': False,
-}
-
-
-
-def getObj(s):
-    global compiler
-    if compiler is None:
-        import compiler
-    s = "a=" + s
-    p = compiler.parse(s)
-    return p.getChildren()[1].getChildren()[0].getChildren()[1]
-
-
-class UnknownType(Exception):
-    pass
-
-
-class Builder(object):
-    
-    def build(self, o):
-        m = getattr(self, 'build_' + o.__class__.__name__, None)
-        if m is None:
-            raise UnknownType(o.__class__.__name__)
-        return m(o)
-    
-    def build_List(self, o):
-        return map(self.build, o.getChildren())
-    
-    def build_Const(self, o):
-        return o.value
-    
-    def build_Dict(self, o):
-        d = {}
-        i = iter(map(self.build, o.getChildren()))
-        for el in i:
-            d[el] = i.next()
-        return d
-    
-    def build_Tuple(self, o):
-        return tuple(self.build_List(o))
-    
-    def build_Name(self, o):
-        if o.name == 'None':
-            return None
-        if o.name == 'True':
-            return True
-        if o.name == 'False':
-            return False
-        
-        # An undefined Name
-        raise UnknownType('Undefined Name')
-    
-    def build_Add(self, o):
-        real, imag = map(self.build_Const, o.getChildren())
-        try:
-            real = float(real)
-        except TypeError:
-            raise UnknownType('Add')
-        if not isinstance(imag, complex) or imag.real != 0.0:
-            raise UnknownType('Add')
-        return real+imag
-    
-    def build_Getattr(self, o):
-        parent = self.build(o.expr)
-        return getattr(parent, o.attrname)
-    
-    def build_UnarySub(self, o):
-        return -self.build_Const(o.getChildren()[0])
-    
-    def build_UnaryAdd(self, o):
-        return self.build_Const(o.getChildren()[0])
-
-
-_builder = Builder()
-
-
-def unrepr(s):
-    if not s:
-        return s
-    return _builder.build(getObj(s))
-
-
-
-class ConfigObjError(SyntaxError):
-    """
-    This is the base class for all errors that ConfigObj raises.
-    It is a subclass of SyntaxError.
-    """
-    def __init__(self, message='', line_number=None, line=''):
-        self.line = line
-        self.line_number = line_number
-        SyntaxError.__init__(self, message)
-
-
-class NestingError(ConfigObjError):
-    """
-    This error indicates a level of nesting that doesn't match.
-    """
-
-
-class ParseError(ConfigObjError):
-    """
-    This error indicates that a line is badly written.
-    It is neither a valid ``key = value`` line,
-    nor a valid section marker line.
-    """
-
-
-class ReloadError(IOError):
-    """
-    A 'reload' operation failed.
-    This exception is a subclass of ``IOError``.
-    """
-    def __init__(self):
-        IOError.__init__(self, 'reload failed, filename is not set.')
-
-
-class DuplicateError(ConfigObjError):
-    """
-    The keyword or section specified already exists.
-    """
-
-
-class ConfigspecError(ConfigObjError):
-    """
-    An error occured whilst parsing a configspec.
-    """
-
-
-class InterpolationError(ConfigObjError):
-    """Base class for the two interpolation errors."""
-
-
-class InterpolationLoopError(InterpolationError):
-    """Maximum interpolation depth exceeded in string interpolation."""
-
-    def __init__(self, option):
-        InterpolationError.__init__(
-            self,
-            'interpolation loop detected in value "%s".' % option)
-
-
-class RepeatSectionError(ConfigObjError):
-    """
-    This error indicates additional sections in a section with a
-    ``__many__`` (repeated) section.
-    """
-
-
-class MissingInterpolationOption(InterpolationError):
-    """A value specified for interpolation was missing."""
-    def __init__(self, option):
-        msg = 'missing option "%s" in interpolation.' % option
-        InterpolationError.__init__(self, msg)
-
-
-class UnreprError(ConfigObjError):
-    """An error parsing in unrepr mode."""
-
-
-
-class InterpolationEngine(object):
-    """
-    A helper class to help perform string interpolation.
-
-    This class is an abstract base class; its descendants perform
-    the actual work.
-    """
-
-    # compiled regexp to use in self.interpolate()
-    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
-    _cookie = '%'
-
-    def __init__(self, section):
-        # the Section instance that "owns" this engine
-        self.section = section
-
-
-    def interpolate(self, key, value):
-        # short-cut
-        if not self._cookie in value:
-            return value
-        
-        def recursive_interpolate(key, value, section, backtrail):
-            """The function that does the actual work.
-
-            ``value``: the string we're trying to interpolate.
-            ``section``: the section in which that string was found
-            ``backtrail``: a dict to keep track of where we've been,
-            to detect and prevent infinite recursion loops
-
-            This is similar to a depth-first-search algorithm.
-            """
-            # Have we been here already?
-            if (key, section.name) in backtrail:
-                # Yes - infinite loop detected
-                raise InterpolationLoopError(key)
-            # Place a marker on our backtrail so we won't come back here again
-            backtrail[(key, section.name)] = 1
-
-            # Now start the actual work
-            match = self._KEYCRE.search(value)
-            while match:
-                # The actual parsing of the match is implementation-dependent,
-                # so delegate to our helper function
-                k, v, s = self._parse_match(match)
-                if k is None:
-                    # That's the signal that no further interpolation is needed
-                    replacement = v
-                else:
-                    # Further interpolation may be needed to obtain final value
-                    replacement = recursive_interpolate(k, v, s, backtrail)
-                # Replace the matched string with its final value
-                start, end = match.span()
-                value = ''.join((value[:start], replacement, value[end:]))
-                new_search_start = start + len(replacement)
-                # Pick up the next interpolation key, if any, for next time
-                # through the while loop
-                match = self._KEYCRE.search(value, new_search_start)
-
-            # Now safe to come back here again; remove marker from backtrail
-            del backtrail[(key, section.name)]
-
-            return value
-
-        # Back in interpolate(), all we have to do is kick off the recursive
-        # function with appropriate starting values
-        value = recursive_interpolate(key, value, self.section, {})
-        return value
-
-
-    def _fetch(self, key):
-        """Helper function to fetch values from owning section.
-
-        Returns a 2-tuple: the value, and the section where it was found.
-        """
-        # switch off interpolation before we try and fetch anything !
-        save_interp = self.section.main.interpolation
-        self.section.main.interpolation = False
-
-        # Start at section that "owns" this InterpolationEngine
-        current_section = self.section
-        while True:
-            # try the current section first
-            val = current_section.get(key)
-            if val is not None and not isinstance(val, Section):
-                break
-            # try "DEFAULT" next
-            val = current_section.get('DEFAULT', {}).get(key)
-            if val is not None and not isinstance(val, Section):
-                break
-            # move up to parent and try again
-            # top-level's parent is itself
-            if current_section.parent is current_section:
-                # reached top level, time to give up
-                break
-            current_section = current_section.parent
-
-        # restore interpolation to previous value before returning
-        self.section.main.interpolation = save_interp
-        if val is None:
-            raise MissingInterpolationOption(key)
-        return val, current_section
-
-
-    def _parse_match(self, match):
-        """Implementation-dependent helper function.
-
-        Will be passed a match object corresponding to the interpolation
-        key we just found (e.g., "%(foo)s" or "$foo"). Should look up that
-        key in the appropriate config file section (using the ``_fetch()``
-        helper function) and return a 3-tuple: (key, value, section)
-
-        ``key`` is the name of the key we're looking for
-        ``value`` is the value found for that key
-        ``section`` is a reference to the section where it was found
-
-        ``key`` and ``section`` should be None if no further
-        interpolation should be performed on the resulting value
-        (e.g., if we interpolated "$$" and returned "$").
-        """
-        raise NotImplementedError()
-    
-
-
-class ConfigParserInterpolation(InterpolationEngine):
-    """Behaves like ConfigParser."""
-    _cookie = '%'
-    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
-
-    def _parse_match(self, match):
-        key = match.group(1)
-        value, section = self._fetch(key)
-        return key, value, section
-
-
-
-class TemplateInterpolation(InterpolationEngine):
-    """Behaves like string.Template."""
-    _cookie = '$'
-    _delimiter = '$'
-    _KEYCRE = re.compile(r"""
-        \$(?:
-          (?P<escaped>\$)              |   # Two $ signs
-          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format
-          {(?P<braced>[^}]*)}              # ${name} format
-        )
-        """, re.IGNORECASE | re.VERBOSE)
-
-    def _parse_match(self, match):
-        # Valid name (in or out of braces): fetch value from section
-        key = match.group('named') or match.group('braced')
-        if key is not None:
-            value, section = self._fetch(key)
-            return key, value, section
-        # Escaped delimiter (e.g., $$): return single delimiter
-        if match.group('escaped') is not None:
-            # Return None for key and section to indicate it's time to stop
-            return None, self._delimiter, None
-        # Anything else: ignore completely, just return it unchanged
-        return None, match.group(), None
-
-
-interpolation_engines = {
-    'configparser': ConfigParserInterpolation,
-    'template': TemplateInterpolation,
-}
-
-
-def __newobj__(cls, *args):
-    # Hack for pickle
-    return cls.__new__(cls, *args) 
-
-class Section(dict):
-    """
-    A dictionary-like object that represents a section in a config file.
-    
-    It does string interpolation if the 'interpolation' attribute
-    of the 'main' object is set to True.
-    
-    Interpolation is tried first from this object, then from the 'DEFAULT'
-    section of this object, next from the parent and its 'DEFAULT' section,
-    and so on until the main object is reached.
-    
-    A Section will behave like an ordered dictionary - following the
-    order of the ``scalars`` and ``sections`` attributes.
-    You can use this to change the order of members.
-    
-    Iteration follows the order: scalars, then sections.
-    """
-
-    
-    def __setstate__(self, state):
-        dict.update(self, state[0])
-        self.__dict__.update(state[1])
-
-    def __reduce__(self):
-        state = (dict(self), self.__dict__)
-        return (__newobj__, (self.__class__,), state)
-    
-    
-    def __init__(self, parent, depth, main, indict=None, name=None):
-        """
-        * parent is the section above
-        * depth is the depth level of this section
-        * main is the main ConfigObj
-        * indict is a dictionary to initialise the section with
-        """
-        if indict is None:
-            indict = {}
-        dict.__init__(self)
-        # used for nesting level *and* interpolation
-        self.parent = parent
-        # used for the interpolation attribute
-        self.main = main
-        # level of nesting depth of this Section
-        self.depth = depth
-        # purely for information
-        self.name = name
-        #
-        self._initialise()
-        # we do this explicitly so that __setitem__ is used properly
-        # (rather than just passing to ``dict.__init__``)
-        for entry, value in indict.iteritems():
-            self[entry] = value
-            
-            
-    def _initialise(self):
-        # the sequence of scalar values in this Section
-        self.scalars = []
-        # the sequence of sections in this Section
-        self.sections = []
-        # for comments :-)
-        self.comments = {}
-        self.inline_comments = {}
-        # the configspec
-        self.configspec = None
-        # for defaults
-        self.defaults = []
-        self.default_values = {}
-        self.extra_values = []
-        self._created = False
-
-
-    def _interpolate(self, key, value):
-        try:
-            # do we already have an interpolation engine?
-            engine = self._interpolation_engine
-        except AttributeError:
-            # not yet: first time running _interpolate(), so pick the engine
-            name = self.main.interpolation
-            if name == True:  # note that "if name:" would be incorrect here
-                # backwards-compatibility: interpolation=True means use default
-                name = DEFAULT_INTERPOLATION
-            name = name.lower()  # so that "Template", "template", etc. all work
-            class_ = interpolation_engines.get(name, None)
-            if class_ is None:
-                # invalid value for self.main.interpolation
-                self.main.interpolation = False
-                return value
-            else:
-                # save reference to engine so we don't have to do this again
-                engine = self._interpolation_engine = class_(self)
-        # let the engine do the actual work
-        return engine.interpolate(key, value)
-
-
-    def __getitem__(self, key):
-        """Fetch the item and do string interpolation."""
-        val = dict.__getitem__(self, key)
-        if self.main.interpolation: 
-            if isinstance(val, basestring):
-                return self._interpolate(key, val)
-            if isinstance(val, list):
-                def _check(entry):
-                    if isinstance(entry, basestring):
-                        return self._interpolate(key, entry)
-                    return entry
-                new = [_check(entry) for entry in val]
-                if new != val:
-                    return new
-        return val
-
-
-    def __setitem__(self, key, value, unrepr=False):
-        """
-        Correctly set a value.
-        
-        Making dictionary values Section instances.
-        (We have to special case 'Section' instances - which are also dicts)
-        
-        Keys must be strings.
-        Values need only be strings (or lists of strings) if
-        ``main.stringify`` is set.
-        
-        ``unrepr`` must be set when setting a value to a dictionary, without
-        creating a new sub-section.
-        """
-        if not isinstance(key, basestring):
-            raise ValueError('The key "%s" is not a string.' % key)
-        
-        # add the comment
-        if key not in self.comments:
-            self.comments[key] = []
-            self.inline_comments[key] = ''
-        # remove the entry from defaults
-        if key in self.defaults:
-            self.defaults.remove(key)
-        #
-        if isinstance(value, Section):
-            if key not in self:
-                self.sections.append(key)
-            dict.__setitem__(self, key, value)
-        elif isinstance(value, dict) and not unrepr:
-            # First create the new depth level,
-            # then create the section
-            if key not in self:
-                self.sections.append(key)
-            new_depth = self.depth + 1
-            dict.__setitem__(
-                self,
-                key,
-                Section(
-                    self,
-                    new_depth,
-                    self.main,
-                    indict=value,
-                    name=key))
-        else:
-            if key not in self:
-                self.scalars.append(key)
-            if not self.main.stringify:
-                if isinstance(value, basestring):
-                    pass
-                elif isinstance(value, (list, tuple)):
-                    for entry in value:
-                        if not isinstance(entry, basestring):
-                            raise TypeError('Value is not a string "%s".' % entry)
-                else:
-                    raise TypeError('Value is not a string "%s".' % value)
-            dict.__setitem__(self, key, value)
-
-
-    def __delitem__(self, key):
-        """Remove items from the sequence when deleting."""
-        dict. __delitem__(self, key)
-        if key in self.scalars:
-            self.scalars.remove(key)
-        else:
-            self.sections.remove(key)
-        del self.comments[key]
-        del self.inline_comments[key]
-
-
-    def get(self, key, default=None):
-        """A version of ``get`` that doesn't bypass string interpolation."""
-        try:
-            return self[key]
-        except KeyError:
-            return default
-
-
-    def update(self, indict):
-        """
-        A version of update that uses our ``__setitem__``.
-        """
-        for entry in indict:
-            self[entry] = indict[entry]
-
-
-    def pop(self, key, default=MISSING):
-        """
-        'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-        If key is not found, d is returned if given, otherwise KeyError is raised'
-        """
-        try:
-            val = self[key]
-        except KeyError:
-            if default is MISSING:
-                raise
-            val = default
-        else:
-            del self[key]
-        return val
-
-
-    def popitem(self):
-        """Pops the first (key,val)"""
-        sequence = (self.scalars + self.sections)
-        if not sequence:
-            raise KeyError(": 'popitem(): dictionary is empty'")
-        key = sequence[0]
-        val =  self[key]
-        del self[key]
-        return key, val
-
-
-    def clear(self):
-        """
-        A version of clear that also affects scalars/sections
-        Also clears comments and configspec.
-        
-        Leaves other attributes alone :
-            depth/main/parent are not affected
-        """
-        dict.clear(self)
-        self.scalars = []
-        self.sections = []
-        self.comments = {}
-        self.inline_comments = {}
-        self.configspec = None
-        self.defaults = []
-        self.extra_values = []
-
-
-    def setdefault(self, key, default=None):
-        """A version of setdefault that sets sequence if appropriate."""
-        try:
-            return self[key]
-        except KeyError:
-            self[key] = default
-            return self[key]
-
-
-    def items(self):
-        """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
-        return zip((self.scalars + self.sections), self.values())
-
-
-    def keys(self):
-        """D.keys() -> list of D's keys"""
-        return (self.scalars + self.sections)
-
-
-    def values(self):
-        """D.values() -> list of D's values"""
-        return [self[key] for key in (self.scalars + self.sections)]
-
-
-    def iteritems(self):
-        """D.iteritems() -> an iterator over the (key, value) items of D"""
-        return iter(self.items())
-
-
-    def iterkeys(self):
-        """D.iterkeys() -> an iterator over the keys of D"""
-        return iter((self.scalars + self.sections))
-
-    __iter__ = iterkeys
-
-
-    def itervalues(self):
-        """D.itervalues() -> an iterator over the values of D"""
-        return iter(self.values())
-
-
-    def __repr__(self):
-        """x.__repr__() <==> repr(x)"""
-        def _getval(key):
-            try:
-                return self[key]
-            except MissingInterpolationOption:
-                return dict.__getitem__(self, key)
-        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key))))
-            for key in (self.scalars + self.sections)])
-
-    __str__ = __repr__
-    __str__.__doc__ = "x.__str__() <==> str(x)"
-
-
-    # Extra methods - not in a normal dictionary
-
-    def dict(self):
-        """
-        Return a deepcopy of self as a dictionary.
-        
-        All members that are ``Section`` instances are recursively turned to
-        ordinary dictionaries - by calling their ``dict`` method.
-        
-        >>> n = a.dict()
-        >>> n == a
-        1
-        >>> n is a
-        0
-        """
-        newdict = {}
-        for entry in self:
-            this_entry = self[entry]
-            if isinstance(this_entry, Section):
-                this_entry = this_entry.dict()
-            elif isinstance(this_entry, list):
-                # create a copy rather than a reference
-                this_entry = list(this_entry)
-            elif isinstance(this_entry, tuple):
-                # create a copy rather than a reference
-                this_entry = tuple(this_entry)
-            newdict[entry] = this_entry
-        return newdict
-
-
-    def merge(self, indict):
-        """
-        A recursive update - useful for merging config files.
-        
-        >>> a = '''[section1]
-        ...     option1 = True
-        ...     [[subsection]]
-        ...     more_options = False
-        ...     # end of file'''.splitlines()
-        >>> b = '''# File is user.ini
-        ...     [section1]
-        ...     option1 = False
-        ...     # end of file'''.splitlines()
-        >>> c1 = ConfigObj(b)
-        >>> c2 = ConfigObj(a)
-        >>> c2.merge(c1)
-        >>> c2
-        ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}})
-        """
-        for key, val in indict.items():
-            if (key in self and isinstance(self[key], dict) and
-                                isinstance(val, dict)):
-                self[key].merge(val)
-            else:   
-                self[key] = val
-
-
-    def rename(self, oldkey, newkey):
-        """
-        Change a keyname to another, without changing position in sequence.
-        
-        Implemented so that transformations can be made on keys,
-        as well as on values. (used by encode and decode)
-        
-        Also renames comments.
-        """
-        if oldkey in self.scalars:
-            the_list = self.scalars
-        elif oldkey in self.sections:
-            the_list = self.sections
-        else:
-            raise KeyError('Key "%s" not found.' % oldkey)
-        pos = the_list.index(oldkey)
-        #
-        val = self[oldkey]
-        dict.__delitem__(self, oldkey)
-        dict.__setitem__(self, newkey, val)
-        the_list.remove(oldkey)
-        the_list.insert(pos, newkey)
-        comm = self.comments[oldkey]
-        inline_comment = self.inline_comments[oldkey]
-        del self.comments[oldkey]
-        del self.inline_comments[oldkey]
-        self.comments[newkey] = comm
-        self.inline_comments[newkey] = inline_comment
-
-
-    def walk(self, function, raise_errors=True,
-            call_on_sections=False, **keywargs):
-        """
-        Walk every member and call a function on the keyword and value.
-        
-        Return a dictionary of the return values
-        
-        If the function raises an exception, raise the errror
-        unless ``raise_errors=False``, in which case set the return value to
-        ``False``.
-        
-        Any unrecognised keyword arguments you pass to walk, will be pased on
-        to the function you pass in.
-        
-        Note: if ``call_on_sections`` is ``True`` then - on encountering a
-        subsection, *first* the function is called for the *whole* subsection,
-        and then recurses into it's members. This means your function must be
-        able to handle strings, dictionaries and lists. This allows you
-        to change the key of subsections as well as for ordinary members. The
-        return value when called on the whole subsection has to be discarded.
-        
-        See  the encode and decode methods for examples, including functions.
-        
-        .. admonition:: caution
-        
-            You can use ``walk`` to transform the names of members of a section
-            but you mustn't add or delete members.
-        
-        >>> config = '''[XXXXsection]
-        ... XXXXkey = XXXXvalue'''.splitlines()
-        >>> cfg = ConfigObj(config)
-        >>> cfg
-        ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
-        >>> def transform(section, key):
-        ...     val = section[key]
-        ...     newkey = key.replace('XXXX', 'CLIENT1')
-        ...     section.rename(key, newkey)
-        ...     if isinstance(val, (tuple, list, dict)):
-        ...         pass
-        ...     else:
-        ...         val = val.replace('XXXX', 'CLIENT1')
-        ...         section[newkey] = val
-        >>> cfg.walk(transform, call_on_sections=True)
-        {'CLIENT1section': {'CLIENT1key': None}}
-        >>> cfg
-        ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}})
-        """
-        out = {}
-        # scalars first
-        for i in range(len(self.scalars)):
-            entry = self.scalars[i]
-            try:
-                val = function(self, entry, **keywargs)
-                # bound again in case name has changed
-                entry = self.scalars[i]
-                out[entry] = val
-            except Exception:
-                if raise_errors:
-                    raise
-                else:
-                    entry = self.scalars[i]
-                    out[entry] = False
-        # then sections
-        for i in range(len(self.sections)):
-            entry = self.sections[i]
-            if call_on_sections:
-                try:
-                    function(self, entry, **keywargs)
-                except Exception:
-                    if raise_errors:
-                        raise
-                    else:
-                        entry = self.sections[i]
-                        out[entry] = False
-                # bound again in case name has changed
-                entry = self.sections[i]
-            # previous result is discarded
-            out[entry] = self[entry].walk(
-                function,
-                raise_errors=raise_errors,
-                call_on_sections=call_on_sections,
-                **keywargs)
-        return out
-
-
-    def as_bool(self, key):
-        """
-        Accepts a key as input. The corresponding value must be a string or
-        the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
-        retain compatibility with Python 2.2.
-        
-        If the string is one of  ``True``, ``On``, ``Yes``, or ``1`` it returns 
-        ``True``.
-        
-        If the string is one of  ``False``, ``Off``, ``No``, or ``0`` it returns 
-        ``False``.
-        
-        ``as_bool`` is not case sensitive.
-        
-        Any other input will raise a ``ValueError``.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_bool('a')
-        Traceback (most recent call last):
-        ValueError: Value "fish" is neither True nor False
-        >>> a['b'] = 'True'
-        >>> a.as_bool('b')
-        1
-        >>> a['b'] = 'off'
-        >>> a.as_bool('b')
-        0
-        """
-        val = self[key]
-        if val == True:
-            return True
-        elif val == False:
-            return False
-        else:
-            try:
-                if not isinstance(val, basestring):
-                    # TODO: Why do we raise a KeyError here?
-                    raise KeyError()
-                else:
-                    return self.main._bools[val.lower()]
-            except KeyError:
-                raise ValueError('Value "%s" is neither True nor False' % val)
-
-
-    def as_int(self, key):
-        """
-        A convenience method which coerces the specified value to an integer.
-        
-        If the value is an invalid literal for ``int``, a ``ValueError`` will
-        be raised.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_int('a')
-        Traceback (most recent call last):
-        ValueError: invalid literal for int() with base 10: 'fish'
-        >>> a['b'] = '1'
-        >>> a.as_int('b')
-        1
-        >>> a['b'] = '3.2'
-        >>> a.as_int('b')
-        Traceback (most recent call last):
-        ValueError: invalid literal for int() with base 10: '3.2'
-        """
-        return int(self[key])
-
-
-    def as_float(self, key):
-        """
-        A convenience method which coerces the specified value to a float.
-        
-        If the value is an invalid literal for ``float``, a ``ValueError`` will
-        be raised.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_float('a')
-        Traceback (most recent call last):
-        ValueError: invalid literal for float(): fish
-        >>> a['b'] = '1'
-        >>> a.as_float('b')
-        1.0
-        >>> a['b'] = '3.2'
-        >>> a.as_float('b')
-        3.2000000000000002
-        """
-        return float(self[key])
-    
-    
-    def as_list(self, key):
-        """
-        A convenience method which fetches the specified value, guaranteeing
-        that it is a list.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 1
-        >>> a.as_list('a')
-        [1]
-        >>> a['a'] = (1,)
-        >>> a.as_list('a')
-        [1]
-        >>> a['a'] = [1]
-        >>> a.as_list('a')
-        [1]
-        """
-        result = self[key]
-        if isinstance(result, (tuple, list)):
-            return list(result)
-        return [result]
-        
-
-    def restore_default(self, key):
-        """
-        Restore (and return) default value for the specified key.
-        
-        This method will only work for a ConfigObj that was created
-        with a configspec and has been validated.
-        
-        If there is no default value for this key, ``KeyError`` is raised.
-        """
-        default = self.default_values[key]
-        dict.__setitem__(self, key, default)
-        if key not in self.defaults:
-            self.defaults.append(key)
-        return default
-
-    
-    def restore_defaults(self):
-        """
-        Recursively restore default values to all members
-        that have them.
-        
-        This method will only work for a ConfigObj that was created
-        with a configspec and has been validated.
-        
-        It doesn't delete or modify entries without default values.
-        """
-        for key in self.default_values:
-            self.restore_default(key)
-            
-        for section in self.sections:
-            self[section].restore_defaults()
-
-
-class ConfigObj(Section):
-    """An object to read, create, and write config files."""
-
-    _keyword = re.compile(r'''^ # line start
-        (\s*)                   # indentation
-        (                       # keyword
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'"=].*?)       # no quotes
-        )
-        \s*=\s*                 # divider
-        (.*)                    # value (including list values and comments)
-        $   # line end
-        ''',
-        re.VERBOSE)
-
-    _sectionmarker = re.compile(r'''^
-        (\s*)                     # 1: indentation
-        ((?:\[\s*)+)              # 2: section marker open
-        (                         # 3: section name open
-            (?:"\s*\S.*?\s*")|    # at least one non-space with double quotes
-            (?:'\s*\S.*?\s*')|    # at least one non-space with single quotes
-            (?:[^'"\s].*?)        # at least one non-space unquoted
-        )                         # section name close
-        ((?:\s*\])+)              # 4: section marker close
-        \s*(\#.*)?                # 5: optional comment
-        $''',
-        re.VERBOSE)
-
-    # this regexp pulls list values out as a single string
-    # or single values and comments
-    # FIXME: this regex adds a '' to the end of comma terminated lists
-    #   workaround in ``_handle_value``
-    _valueexp = re.compile(r'''^
-        (?:
-            (?:
-                (
-                    (?:
-                        (?:
-                            (?:".*?")|              # double quotes
-                            (?:'.*?')|              # single quotes
-                            (?:[^'",\#][^,\#]*?)    # unquoted
-                        )
-                        \s*,\s*                     # comma
-                    )*      # match all list items ending in a comma (if any)
-                )
-                (
-                    (?:".*?")|                      # double quotes
-                    (?:'.*?')|                      # single quotes
-                    (?:[^'",\#\s][^,]*?)|           # unquoted
-                    (?:(?<!,))                      # Empty value
-                )?          # last item in a list - or string value
-            )|
-            (,)             # alternatively a single comma - empty list
-        )
-        \s*(\#.*)?          # optional comment
-        $''',
-        re.VERBOSE)
-
-    # use findall to get the members of a list value
-    _listvalueexp = re.compile(r'''
-        (
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'",\#]?.*?)       # unquoted
-        )
-        \s*,\s*                 # comma
-        ''',
-        re.VERBOSE)
-
-    # this regexp is used for the value
-    # when lists are switched off
-    _nolistvalue = re.compile(r'''^
-        (
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'"\#].*?)|     # unquoted
-            (?:)                # Empty value
-        )
-        \s*(\#.*)?              # optional comment
-        $''',
-        re.VERBOSE)
-
-    # regexes for finding triple quoted values on one line
-    _single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")
-    _single_line_double = re.compile(r'^"""(.*?)"""\s*(#.*)?$')
-    _multi_line_single = re.compile(r"^(.*?)'''\s*(#.*)?$")
-    _multi_line_double = re.compile(r'^(.*?)"""\s*(#.*)?$')
-
-    _triple_quote = {
-        "'''": (_single_line_single, _multi_line_single),
-        '"""': (_single_line_double, _multi_line_double),
-    }
-
-    # Used by the ``istrue`` Section method
-    _bools = {
-        'yes': True, 'no': False,
-        'on': True, 'off': False,
-        '1': True, '0': False,
-        'true': True, 'false': False,
-        }
-
-
-    def __init__(self, infile=None, options=None, configspec=None, encoding=None,
-                 interpolation=True, raise_errors=False, list_values=True,
-                 create_empty=False, file_error=False, stringify=True,
-                 indent_type=None, default_encoding=None, unrepr=False,
-                 write_empty_values=False, _inspec=False):
-        """
-        Parse a config file or create a config file object.
-        
-        ``ConfigObj(infile=None, configspec=None, encoding=None,
-                    interpolation=True, raise_errors=False, list_values=True,
-                    create_empty=False, file_error=False, stringify=True,
-                    indent_type=None, default_encoding=None, unrepr=False,
-                    write_empty_values=False, _inspec=False)``
-        """
-        self._inspec = _inspec
-        # init the superclass
-        Section.__init__(self, self, 0, self)
-        
-        infile = infile or []
-        
-        _options = {'configspec': configspec,
-                    'encoding': encoding, 'interpolation': interpolation,
-                    'raise_errors': raise_errors, 'list_values': list_values,
-                    'create_empty': create_empty, 'file_error': file_error,
-                    'stringify': stringify, 'indent_type': indent_type,
-                    'default_encoding': default_encoding, 'unrepr': unrepr,
-                    'write_empty_values': write_empty_values}
-
-        if options is None:
-            options = _options
-        else:
-            import warnings
-            warnings.warn('Passing in an options dictionary to ConfigObj() is '
-                          'deprecated. Use **options instead.',
-                          DeprecationWarning, stacklevel=2)
-            
-            # TODO: check the values too.
-            for entry in options:
-                if entry not in OPTION_DEFAULTS:
-                    raise TypeError('Unrecognised option "%s".' % entry)
-            for entry, value in OPTION_DEFAULTS.items():
-                if entry not in options:
-                    options[entry] = value
-                keyword_value = _options[entry]
-                if value != keyword_value:
-                    options[entry] = keyword_value
-        
-        # XXXX this ignores an explicit list_values = True in combination
-        # with _inspec. The user should *never* do that anyway, but still...
-        if _inspec:
-            options['list_values'] = False
-        
-        self._initialise(options)
-        configspec = options['configspec']
-        self._original_configspec = configspec
-        self._load(infile, configspec)
-        
-        
-    def _load(self, infile, configspec):
-        if isinstance(infile, basestring):
-            self.filename = infile
-            if os.path.isfile(infile):
-                h = open(infile, 'rb')
-                infile = h.read() or []
-                h.close()
-            elif self.file_error:
-                # raise an error if the file doesn't exist
-                raise IOError('Config file not found: "%s".' % self.filename)
-            else:
-                # file doesn't already exist
-                if self.create_empty:
-                    # this is a good test that the filename specified
-                    # isn't impossible - like on a non-existent device
-                    h = open(infile, 'w')
-                    h.write('')
-                    h.close()
-                infile = []
-                
-        elif isinstance(infile, (list, tuple)):
-            infile = list(infile)
-            
-        elif isinstance(infile, dict):
-            # initialise self
-            # the Section class handles creating subsections
-            if isinstance(infile, ConfigObj):
-                # get a copy of our ConfigObj
-                def set_section(in_section, this_section):
-                    for entry in in_section.scalars:
-                        this_section[entry] = in_section[entry]
-                    for section in in_section.sections:
-                        this_section[section] = {}
-                        set_section(in_section[section], this_section[section])
-                set_section(infile, self)
-                
-            else:
-                for entry in infile:
-                    self[entry] = infile[entry]
-            del self._errors
-            
-            if configspec is not None:
-                self._handle_configspec(configspec)
-            else:
-                self.configspec = None
-            return
-        
-        elif getattr(infile, 'read', MISSING) is not MISSING:
-            # This supports file like objects
-            infile = infile.read() or []
-            # needs splitting into lines - but needs doing *after* decoding
-            # in case it's not an 8 bit encoding
-        else:
-            raise TypeError('infile must be a filename, file like object, or list of lines.')
-        
-        if infile:
-            # don't do it for the empty ConfigObj
-            infile = self._handle_bom(infile)
-            # infile is now *always* a list
-            #
-            # Set the newlines attribute (first line ending it finds)
-            # and strip trailing '\n' or '\r' from lines
-            for line in infile:
-                if (not line) or (line[-1] not in ('\r', '\n', '\r\n')):
-                    continue
-                for end in ('\r\n', '\n', '\r'):
-                    if line.endswith(end):
-                        self.newlines = end
-                        break
-                break
-
-            infile = [line.rstrip('\r\n') for line in infile]
-            
-        self._parse(infile)
-        # if we had any errors, now is the time to raise them
-        if self._errors:
-            info = "at line %s." % self._errors[0].line_number
-            if len(self._errors) > 1:
-                msg = "Parsing failed with several errors.\nFirst error %s" % info
-                error = ConfigObjError(msg)
-            else:
-                error = self._errors[0]
-            # set the errors attribute; it's a list of tuples:
-            # (error_type, message, line_number)
-            error.errors = self._errors
-            # set the config attribute
-            error.config = self
-            raise error
-        # delete private attributes
-        del self._errors
-        
-        if configspec is None:
-            self.configspec = None
-        else:
-            self._handle_configspec(configspec)
-    
-    
-    def _initialise(self, options=None):
-        if options is None:
-            options = OPTION_DEFAULTS
-            
-        # initialise a few variables
-        self.filename = None
-        self._errors = []
-        self.raise_errors = options['raise_errors']
-        self.interpolation = options['interpolation']
-        self.list_values = options['list_values']
-        self.create_empty = options['create_empty']
-        self.file_error = options['file_error']
-        self.stringify = options['stringify']
-        self.indent_type = options['indent_type']
-        self.encoding = options['encoding']
-        self.default_encoding = options['default_encoding']
-        self.BOM = False
-        self.newlines = None
-        self.write_empty_values = options['write_empty_values']
-        self.unrepr = options['unrepr']
-        
-        self.initial_comment = []
-        self.final_comment = []
-        self.configspec = None
-        
-        if self._inspec:
-            self.list_values = False
-        
-        # Clear section attributes as well
-        Section._initialise(self)
-        
-        
-    def __repr__(self):
-        def _getval(key):
-            try:
-                return self[key]
-            except MissingInterpolationOption:
-                return dict.__getitem__(self, key)
-        return ('ConfigObj({%s})' % 
-                ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) 
-                for key in (self.scalars + self.sections)]))
-    
-    
-    def _handle_bom(self, infile):
-        """
-        Handle any BOM, and decode if necessary.
-        
-        If an encoding is specified, that *must* be used - but the BOM should
-        still be removed (and the BOM attribute set).
-        
-        (If the encoding is wrongly specified, then a BOM for an alternative
-        encoding won't be discovered or removed.)
-        
-        If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
-        removed. The BOM attribute will be set. UTF16 will be decoded to
-        unicode.
-        
-        NOTE: This method must not be called with an empty ``infile``.
-        
-        Specifying the *wrong* encoding is likely to cause a
-        ``UnicodeDecodeError``.
-        
-        ``infile`` must always be returned as a list of lines, but may be
-        passed in as a single string.
-        """
-        if ((self.encoding is not None) and
-            (self.encoding.lower() not in BOM_LIST)):
-            # No need to check for a BOM
-            # the encoding specified doesn't have one
-            # just decode
-            return self._decode(infile, self.encoding)
-        
-        if isinstance(infile, (list, tuple)):
-            line = infile[0]
-        else:
-            line = infile
-        if self.encoding is not None:
-            # encoding explicitly supplied
-            # And it could have an associated BOM
-            # TODO: if encoding is just UTF16 - we ought to check for both
-            # TODO: big endian and little endian versions.
-            enc = BOM_LIST[self.encoding.lower()]
-            if enc == 'utf_16':
-                # For UTF16 we try big endian and little endian
-                for BOM, (encoding, final_encoding) in BOMS.items():
-                    if not final_encoding:
-                        # skip UTF8
-                        continue
-                    if infile.startswith(BOM):
-                        ### BOM discovered
-                        ##self.BOM = True
-                        # Don't need to remove BOM
-                        return self._decode(infile, encoding)
-                    
-                # If we get this far, will *probably* raise a DecodeError
-                # As it doesn't appear to start with a BOM
-                return self._decode(infile, self.encoding)
-            
-            # Must be UTF8
-            BOM = BOM_SET[enc]
-            if not line.startswith(BOM):
-                return self._decode(infile, self.encoding)
-            
-            newline = line[len(BOM):]
-            
-            # BOM removed
-            if isinstance(infile, (list, tuple)):
-                infile[0] = newline
-            else:
-                infile = newline
-            self.BOM = True
-            return self._decode(infile, self.encoding)
-        
-        # No encoding specified - so we need to check for UTF8/UTF16
-        for BOM, (encoding, final_encoding) in BOMS.items():
-            if not line.startswith(BOM):
-                continue
-            else:
-                # BOM discovered
-                self.encoding = final_encoding
-                if not final_encoding:
-                    self.BOM = True
-                    # UTF8
-                    # remove BOM
-                    newline = line[len(BOM):]
-                    if isinstance(infile, (list, tuple)):
-                        infile[0] = newline
-                    else:
-                        infile = newline
-                    # UTF8 - don't decode
-                    if isinstance(infile, basestring):
-                        return infile.splitlines(True)
-                    else:
-                        return infile
-                # UTF16 - have to decode
-                return self._decode(infile, encoding)
-            
-        # No BOM discovered and no encoding specified, just return
-        if isinstance(infile, basestring):
-            # infile read from a file will be a single string
-            return infile.splitlines(True)
-        return infile
-
-
-    def _a_to_u(self, aString):
-        """Decode ASCII strings to unicode if a self.encoding is specified."""
-        if self.encoding:
-            return aString.decode('ascii')
-        else:
-            return aString
-
-
-    def _decode(self, infile, encoding):
-        """
-        Decode infile to unicode. Using the specified encoding.
-        
-        if is a string, it also needs converting to a list.
-        """
-        if isinstance(infile, basestring):
-            # can't be unicode
-            # NOTE: Could raise a ``UnicodeDecodeError``
-            return infile.decode(encoding).splitlines(True)
-        for i, line in enumerate(infile):
-            if not isinstance(line, unicode):
-                # NOTE: The isinstance test here handles mixed lists of unicode/string
-                # NOTE: But the decode will break on any non-string values
-                # NOTE: Or could raise a ``UnicodeDecodeError``
-                infile[i] = line.decode(encoding)
-        return infile
-
-
-    def _decode_element(self, line):
-        """Decode element to unicode if necessary."""
-        if not self.encoding:
-            return line
-        if isinstance(line, str) and self.default_encoding:
-            return line.decode(self.default_encoding)
-        return line
-
-
-    def _str(self, value):
-        """
-        Used by ``stringify`` within validate, to turn non-string values
-        into strings.
-        """
-        if not isinstance(value, basestring):
-            return str(value)
-        else:
-            return value
-
-
-    def _parse(self, infile):
-        """Actually parse the config file."""
-        temp_list_values = self.list_values
-        if self.unrepr:
-            self.list_values = False
-            
-        comment_list = []
-        done_start = False
-        this_section = self
-        maxline = len(infile) - 1
-        cur_index = -1
-        reset_comment = False
-        
-        while cur_index < maxline:
-            if reset_comment:
-                comment_list = []
-            cur_index += 1
-            line = infile[cur_index]
-            sline = line.strip()
-            # do we have anything on the line ?
-            if not sline or sline.startswith('#'):
-                reset_comment = False
-                comment_list.append(line)
-                continue
-            
-            if not done_start:
-                # preserve initial comment
-                self.initial_comment = comment_list
-                comment_list = []
-                done_start = True
-                
-            reset_comment = True
-            # first we check if it's a section marker
-            mat = self._sectionmarker.match(line)
-            if mat is not None:
-                # is a section line
-                (indent, sect_open, sect_name, sect_close, comment) = mat.groups()
-                if indent and (self.indent_type is None):
-                    self.indent_type = indent
-                cur_depth = sect_open.count('[')
-                if cur_depth != sect_close.count(']'):
-                    self._handle_error("Cannot compute the section depth at line %s.",
-                                       NestingError, infile, cur_index)
-                    continue
-                
-                if cur_depth < this_section.depth:
-                    # the new section is dropping back to a previous level
-                    try:
-                        parent = self._match_depth(this_section,
-                                                   cur_depth).parent
-                    except SyntaxError:
-                        self._handle_error("Cannot compute nesting level at line %s.",
-                                           NestingError, infile, cur_index)
-                        continue
-                elif cur_depth == this_section.depth:
-                    # the new section is a sibling of the current section
-                    parent = this_section.parent
-                elif cur_depth == this_section.depth + 1:
-                    # the new section is a child the current section
-                    parent = this_section
-                else:
-                    self._handle_error("Section too nested at line %s.",
-                                       NestingError, infile, cur_index)
-                    
-                sect_name = self._unquote(sect_name)
-                if sect_name in parent:
-                    self._handle_error('Duplicate section name at line %s.',
-                                       DuplicateError, infile, cur_index)
-                    continue
-                
-                # create the new section
-                this_section = Section(
-                    parent,
-                    cur_depth,
-                    self,
-                    name=sect_name)
-                parent[sect_name] = this_section
-                parent.inline_comments[sect_name] = comment
-                parent.comments[sect_name] = comment_list
-                continue
-            #
-            # it's not a section marker,
-            # so it should be a valid ``key = value`` line
-            mat = self._keyword.match(line)
-            if mat is None:
-                # it neither matched as a keyword
-                # or a section marker
-                self._handle_error(
-                    'Invalid line at line "%s".',
-                    ParseError, infile, cur_index)
-            else:
-                # is a keyword value
-                # value will include any inline comment
-                (indent, key, value) = mat.groups()
-                if indent and (self.indent_type is None):
-                    self.indent_type = indent
-                # check for a multiline value
-                if value[:3] in ['"""', "'''"]:
-                    try:
-                        value, comment, cur_index = self._multiline(
-                            value, infile, cur_index, maxline)
-                    except SyntaxError:
-                        self._handle_error(
-                            'Parse error in value at line %s.',
-                            ParseError, infile, cur_index)
-                        continue
-                    else:
-                        if self.unrepr:
-                            comment = ''
-                            try:
-                                value = unrepr(value)
-                            except Exception, e:
-                                if type(e) == UnknownType:
-                                    msg = 'Unknown name or type in value at line %s.'
-                                else:
-                                    msg = 'Parse error in value at line %s.'
-                                self._handle_error(msg, UnreprError, infile,
-                                    cur_index)
-                                continue
-                else:
-                    if self.unrepr:
-                        comment = ''
-                        try:
-                            value = unrepr(value)
-                        except Exception, e:
-                            if isinstance(e, UnknownType):
-                                msg = 'Unknown name or type in value at line %s.'
-                            else:
-                                msg = 'Parse error in value at line %s.'
-                            self._handle_error(msg, UnreprError, infile,
-                                cur_index)
-                            continue
-                    else:
-                        # extract comment and lists
-                        try:
-                            (value, comment) = self._handle_value(value)
-                        except SyntaxError:
-                            self._handle_error(
-                                'Parse error in value at line %s.',
-                                ParseError, infile, cur_index)
-                            continue
-                #
-                key = self._unquote(key)
-                if key in this_section:
-                    self._handle_error(
-                        'Duplicate keyword name at line %s.',
-                        DuplicateError, infile, cur_index)
-                    continue
-                # add the key.
-                # we set unrepr because if we have got this far we will never
-                # be creating a new section
-                this_section.__setitem__(key, value, unrepr=True)
-                this_section.inline_comments[key] = comment
-                this_section.comments[key] = comment_list
-                continue
-        #
-        if self.indent_type is None:
-            # no indentation used, set the type accordingly
-            self.indent_type = ''
-
-        # preserve the final comment
-        if not self and not self.initial_comment:
-            self.initial_comment = comment_list
-        elif not reset_comment:
-            self.final_comment = comment_list
-        self.list_values = temp_list_values
-
-
-    def _match_depth(self, sect, depth):
-        """
-        Given a section and a depth level, walk back through the sections
-        parents to see if the depth level matches a previous section.
-        
-        Return a reference to the right section,
-        or raise a SyntaxError.
-        """
-        while depth < sect.depth:
-            if sect is sect.parent:
-                # we've reached the top level already
-                raise SyntaxError()
-            sect = sect.parent
-        if sect.depth == depth:
-            return sect
-        # shouldn't get here
-        raise SyntaxError()
-
-
-    def _handle_error(self, text, ErrorClass, infile, cur_index):
-        """
-        Handle an error according to the error settings.
-        
-        Either raise the error or store it.
-        The error will have occured at ``cur_index``
-        """
-        line = infile[cur_index]
-        cur_index += 1
-        message = text % cur_index
-        error = ErrorClass(message, cur_index, line)
-        if self.raise_errors:
-            # raise the error - parsing stops here
-            raise error
-        # store the error
-        # reraise when parsing has finished
-        self._errors.append(error)
-
-
-    def _unquote(self, value):
-        """Return an unquoted version of a value"""
-        if not value:
-            # should only happen during parsing of lists
-            raise SyntaxError
-        if (value[0] == value[-1]) and (value[0] in ('"', "'")):
-            value = value[1:-1]
-        return value
-
-
-    def _quote(self, value, multiline=True):
-        """
-        Return a safely quoted version of a value.
-        
-        Raise a ConfigObjError if the value cannot be safely quoted.
-        If multiline is ``True`` (default) then use triple quotes
-        if necessary.
-        
-        * Don't quote values that don't need it.
-        * Recursively quote members of a list and return a comma joined list.
-        * Multiline is ``False`` for lists.
-        * Obey list syntax for empty and single member lists.
-        
-        If ``list_values=False`` then the value is only quoted if it contains
-        a ``\\n`` (is multiline) or '#'.
-        
-        If ``write_empty_values`` is set, and the value is an empty string, it
-        won't be quoted.
-        """
-        if multiline and self.write_empty_values and value == '':
-            # Only if multiline is set, so that it is used for values not
-            # keys, and not values that are part of a list
-            return ''
-        
-        if multiline and isinstance(value, (list, tuple)):
-            if not value:
-                return ','
-            elif len(value) == 1:
-                return self._quote(value[0], multiline=False) + ','
-            return ', '.join([self._quote(val, multiline=False)
-                for val in value])
-        if not isinstance(value, basestring):
-            if self.stringify:
-                value = str(value)
-            else:
-                raise TypeError('Value "%s" is not a string.' % value)
-
-        if not value:
-            return '""'
-        
-        no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value
-        need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))
-        hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)
-        check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote
-        
-        if check_for_single:
-            if not self.list_values:
-                # we don't quote if ``list_values=False``
-                quot = noquot
-            # for normal values either single or double quotes will do
-            elif '\n' in value:
-                # will only happen if multiline is off - e.g. '\n' in key
-                raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-            elif ((value[0] not in wspace_plus) and
-                    (value[-1] not in wspace_plus) and
-                    (',' not in value)):
-                quot = noquot
-            else:
-                quot = self._get_single_quote(value)
-        else:
-            # if value has '\n' or "'" *and* '"', it will need triple quotes
-            quot = self._get_triple_quote(value)
-        
-        if quot == noquot and '#' in value and self.list_values:
-            quot = self._get_single_quote(value)
-                
-        return quot % value
-    
-    
-    def _get_single_quote(self, value):
-        if ("'" in value) and ('"' in value):
-            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-        elif '"' in value:
-            quot = squot
-        else:
-            quot = dquot
-        return quot
-    
-    
-    def _get_triple_quote(self, value):
-        if (value.find('"""') != -1) and (value.find("'''") != -1):
-            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-        if value.find('"""') == -1:
-            quot = tdquot
-        else:
-            quot = tsquot 
-        return quot
-
-
-    def _handle_value(self, value):
-        """
-        Given a value string, unquote, remove comment,
-        handle lists. (including empty and single member lists)
-        """
-        if self._inspec:
-            # Parsing a configspec so don't handle comments
-            return (value, '')
-        # do we look for lists in values ?
-        if not self.list_values:
-            mat = self._nolistvalue.match(value)
-            if mat is None:
-                raise SyntaxError()
-            # NOTE: we don't unquote here
-            return mat.groups()
-        #
-        mat = self._valueexp.match(value)
-        if mat is None:
-            # the value is badly constructed, probably badly quoted,
-            # or an invalid list
-            raise SyntaxError()
-        (list_values, single, empty_list, comment) = mat.groups()
-        if (list_values == '') and (single is None):
-            # change this if you want to accept empty values
-            raise SyntaxError()
-        # NOTE: note there is no error handling from here if the regex
-        # is wrong: then incorrect values will slip through
-        if empty_list is not None:
-            # the single comma - meaning an empty list
-            return ([], comment)
-        if single is not None:
-            # handle empty values
-            if list_values and not single:
-                # FIXME: the '' is a workaround because our regex now matches
-                #   '' at the end of a list if it has a trailing comma
-                single = None
-            else:
-                single = single or '""'
-                single = self._unquote(single)
-        if list_values == '':
-            # not a list value
-            return (single, comment)
-        the_list = self._listvalueexp.findall(list_values)
-        the_list = [self._unquote(val) for val in the_list]
-        if single is not None:
-            the_list += [single]
-        return (the_list, comment)
-
-
-    def _multiline(self, value, infile, cur_index, maxline):
-        """Extract the value, where we are in a multiline situation."""
-        quot = value[:3]
-        newvalue = value[3:]
-        single_line = self._triple_quote[quot][0]
-        multi_line = self._triple_quote[quot][1]
-        mat = single_line.match(value)
-        if mat is not None:
-            retval = list(mat.groups())
-            retval.append(cur_index)
-            return retval
-        elif newvalue.find(quot) != -1:
-            # somehow the triple quote is missing
-            raise SyntaxError()
-        #
-        while cur_index < maxline:
-            cur_index += 1
-            newvalue += '\n'
-            line = infile[cur_index]
-            if line.find(quot) == -1:
-                newvalue += line
-            else:
-                # end of multiline, process it
-                break
-        else:
-            # we've got to the end of the config, oops...
-            raise SyntaxError()
-        mat = multi_line.match(line)
-        if mat is None:
-            # a badly formed line
-            raise SyntaxError()
-        (value, comment) = mat.groups()
-        return (newvalue + value, comment, cur_index)
-
-
-    def _handle_configspec(self, configspec):
-        """Parse the configspec."""
-        # FIXME: Should we check that the configspec was created with the 
-        #        correct settings ? (i.e. ``list_values=False``)
-        if not isinstance(configspec, ConfigObj):
-            try:
-                configspec = ConfigObj(configspec,
-                                       raise_errors=True,
-                                       file_error=True,
-                                       _inspec=True)
-            except ConfigObjError, e:
-                # FIXME: Should these errors have a reference
-                #        to the already parsed ConfigObj ?
-                raise ConfigspecError('Parsing configspec failed: %s' % e)
-            except IOError, e:
-                raise IOError('Reading configspec failed: %s' % e)
-        
-        self.configspec = configspec
-            
-
-        
-    def _set_configspec(self, section, copy):
-        """
-        Called by validate. Handles setting the configspec on subsections
-        including sections to be validated by __many__
-        """
-        configspec = section.configspec
-        many = configspec.get('__many__')
-        if isinstance(many, dict):
-            for entry in section.sections:
-                if entry not in configspec:
-                    section[entry].configspec = many
-                    
-        for entry in configspec.sections:
-            if entry == '__many__':
-                continue
-            if entry not in section:
-                section[entry] = {}
-                section[entry]._created = True
-                if copy:
-                    # copy comments
-                    section.comments[entry] = configspec.comments.get(entry, [])
-                    section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
-                
-            # Could be a scalar when we expect a section
-            if isinstance(section[entry], Section):
-                section[entry].configspec = configspec[entry]
-                        
-
-    def _write_line(self, indent_string, entry, this_entry, comment):
-        """Write an individual line, for the write method"""
-        # NOTE: the calls to self._quote here handles non-StringType values.
-        if not self.unrepr:
-            val = self._decode_element(self._quote(this_entry))
-        else:
-            val = repr(this_entry)
-        return '%s%s%s%s%s' % (indent_string,
-                               self._decode_element(self._quote(entry, multiline=False)),
-                               self._a_to_u(' = '),
-                               val,
-                               self._decode_element(comment))
-
-
-    def _write_marker(self, indent_string, depth, entry, comment):
-        """Write a section marker line"""
-        return '%s%s%s%s%s' % (indent_string,
-                               self._a_to_u('[' * depth),
-                               self._quote(self._decode_element(entry), multiline=False),
-                               self._a_to_u(']' * depth),
-                               self._decode_element(comment))
-
-
-    def _handle_comment(self, comment):
-        """Deal with a comment."""
-        if not comment:
-            return ''
-        start = self.indent_type
-        if not comment.startswith('#'):
-            start += self._a_to_u(' # ')
-        return (start + comment)
-
-
-    # Public methods
-
-    def write(self, outfile=None, section=None):
-        """
-        Write the current ConfigObj as a file
-        
-        tekNico: FIXME: use StringIO instead of real files
-        
-        >>> filename = a.filename
-        >>> a.filename = 'test.ini'
-        >>> a.write()
-        >>> a.filename = filename
-        >>> a == ConfigObj('test.ini', raise_errors=True)
-        1
-        >>> import os
-        >>> os.remove('test.ini')
-        """
-        if self.indent_type is None:
-            # this can be true if initialised from a dictionary
-            self.indent_type = DEFAULT_INDENT_TYPE
-            
-        out = []
-        cs = self._a_to_u('#')
-        csp = self._a_to_u('# ')
-        if section is None:
-            int_val = self.interpolation
-            self.interpolation = False
-            section = self
-            for line in self.initial_comment:
-                line = self._decode_element(line)
-                stripped_line = line.strip()
-                if stripped_line and not stripped_line.startswith(cs):
-                    line = csp + line
-                out.append(line)
-                
-        indent_string = self.indent_type * section.depth
-        for entry in (section.scalars + section.sections):
-            if entry in section.defaults:
-                # don't write out default values
-                continue
-            for comment_line in section.comments[entry]:
-                comment_line = self._decode_element(comment_line.lstrip())
-                if comment_line and not comment_line.startswith(cs):
-                    comment_line = csp + comment_line
-                out.append(indent_string + comment_line)
-            this_entry = section[entry]
-            comment = self._handle_comment(section.inline_comments[entry])
-            
-            if isinstance(this_entry, dict):
-                # a section
-                out.append(self._write_marker(
-                    indent_string,
-                    this_entry.depth,
-                    entry,
-                    comment))
-                out.extend(self.write(section=this_entry))
-            else:
-                out.append(self._write_line(
-                    indent_string,
-                    entry,
-                    this_entry,
-                    comment))
-                
-        if section is self:
-            for line in self.final_comment:
-                line = self._decode_element(line)
-                stripped_line = line.strip()
-                if stripped_line and not stripped_line.startswith(cs):
-                    line = csp + line
-                out.append(line)
-            self.interpolation = int_val
-            
-        if section is not self:
-            return out
-        
-        if (self.filename is None) and (outfile is None):
-            # output a list of lines
-            # might need to encode
-            # NOTE: This will *screw* UTF16, each line will start with the BOM
-            if self.encoding:
-                out = [l.encode(self.encoding) for l in out]
-            if (self.BOM and ((self.encoding is None) or
-                (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
-                # Add the UTF8 BOM
-                if not out:
-                    out.append('')
-                out[0] = BOM_UTF8 + out[0]
-            return out
-        
-        # Turn the list to a string, joined with correct newlines
-        newline = self.newlines or os.linesep
-        if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w'
-            and sys.platform == 'win32' and newline == '\r\n'):
-            # Windows specific hack to avoid writing '\r\r\n'
-            newline = '\n'
-        output = self._a_to_u(newline).join(out)
-        if self.encoding:
-            output = output.encode(self.encoding)
-        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
-            # Add the UTF8 BOM
-            output = BOM_UTF8 + output
-            
-        if not output.endswith(newline):
-            output += newline
-        if outfile is not None:
-            outfile.write(output)
-        else:
-            h = open(self.filename, 'wb')
-            h.write(output)
-            h.close()
-
-
-    def validate(self, validator, preserve_errors=False, copy=False,
-                 section=None):
-        """
-        Test the ConfigObj against a configspec.
-        
-        It uses the ``validator`` object from *validate.py*.
-        
-        To run ``validate`` on the current ConfigObj, call: ::
-        
-            test = config.validate(validator)
-        
-        (Normally having previously passed in the configspec when the ConfigObj
-        was created - you can dynamically assign a dictionary of checks to the
-        ``configspec`` attribute of a section though).
-        
-        It returns ``True`` if everything passes, or a dictionary of
-        pass/fails (True/False). If every member of a subsection passes, it
-        will just have the value ``True``. (It also returns ``False`` if all
-        members fail).
-        
-        In addition, it converts the values from strings to their native
-        types if their checks pass (and ``stringify`` is set).
-        
-        If ``preserve_errors`` is ``True`` (``False`` is default) then instead
-        of a marking a fail with a ``False``, it will preserve the actual
-        exception object. This can contain info about the reason for failure.
-        For example the ``VdtValueTooSmallError`` indicates that the value
-        supplied was too small. If a value (or section) is missing it will
-        still be marked as ``False``.
-        
-        You must have the validate module to use ``preserve_errors=True``.
-        
-        You can then use the ``flatten_errors`` function to turn your nested
-        results dictionary into a flattened list of failures - useful for
-        displaying meaningful error messages.
-        """
-        if section is None:
-            if self.configspec is None:
-                raise ValueError('No configspec supplied.')
-            if preserve_errors:
-                # We do this once to remove a top level dependency on the validate module
-                # Which makes importing configobj faster
-                from validate import VdtMissingValue
-                self._vdtMissingValue = VdtMissingValue
-                
-            section = self
-
-            if copy:
-                section.initial_comment = section.configspec.initial_comment
-                section.final_comment = section.configspec.final_comment
-                section.encoding = section.configspec.encoding
-                section.BOM = section.configspec.BOM
-                section.newlines = section.configspec.newlines
-                section.indent_type = section.configspec.indent_type
-            
-        #
-        # section.default_values.clear() #??
-        configspec = section.configspec
-        self._set_configspec(section, copy)
-
-        
-        def validate_entry(entry, spec, val, missing, ret_true, ret_false):
-            section.default_values.pop(entry, None)
-                
-            try:
-                section.default_values[entry] = validator.get_default_value(configspec[entry])
-            except (KeyError, AttributeError, validator.baseErrorClass):
-                # No default, bad default or validator has no 'get_default_value'
-                # (e.g. SimpleVal)
-                pass
-            
-            try:
-                check = validator.check(spec,
-                                        val,
-                                        missing=missing
-                                        )
-            except validator.baseErrorClass, e:
-                if not preserve_errors or isinstance(e, self._vdtMissingValue):
-                    out[entry] = False
-                else:
-                    # preserve the error
-                    out[entry] = e
-                    ret_false = False
-                ret_true = False
-            else:
-                ret_false = False
-                out[entry] = True
-                if self.stringify or missing:
-                    # if we are doing type conversion
-                    # or the value is a supplied default
-                    if not self.stringify:
-                        if isinstance(check, (list, tuple)):
-                            # preserve lists
-                            check = [self._str(item) for item in check]
-                        elif missing and check is None:
-                            # convert the None from a default to a ''
-                            check = ''
-                        else:
-                            check = self._str(check)
-                    if (check != val) or missing:
-                        section[entry] = check
-                if not copy and missing and entry not in section.defaults:
-                    section.defaults.append(entry)
-            return ret_true, ret_false
-        
-        #
-        out = {}
-        ret_true = True
-        ret_false = True
-        
-        unvalidated = [k for k in section.scalars if k not in configspec]
-        incorrect_sections = [k for k in configspec.sections if k in section.scalars]        
-        incorrect_scalars = [k for k in configspec.scalars if k in section.sections]
-        
-        for entry in configspec.scalars:
-            if entry in ('__many__', '___many___'):
-                # reserved names
-                continue
-            if (not entry in section.scalars) or (entry in section.defaults):
-                # missing entries
-                # or entries from defaults
-                missing = True
-                val = None
-                if copy and entry not in section.scalars:
-                    # copy comments
-                    section.comments[entry] = (
-                        configspec.comments.get(entry, []))
-                    section.inline_comments[entry] = (
-                        configspec.inline_comments.get(entry, ''))
-                #
-            else:
-                missing = False
-                val = section[entry]
-            
-            ret_true, ret_false = validate_entry(entry, configspec[entry], val, 
-                                                 missing, ret_true, ret_false)
-        
-        many = None
-        if '__many__' in configspec.scalars:
-            many = configspec['__many__']
-        elif '___many___' in configspec.scalars:
-            many = configspec['___many___']
-        
-        if many is not None:
-            for entry in unvalidated:
-                val = section[entry]
-                ret_true, ret_false = validate_entry(entry, many, val, False,
-                                                     ret_true, ret_false)
-            unvalidated = []
-
-        for entry in incorrect_scalars:
-            ret_true = False
-            if not preserve_errors:
-                out[entry] = False
-            else:
-                ret_false = False
-                msg = 'Value %r was provided as a section' % entry
-                out[entry] = validator.baseErrorClass(msg)
-        for entry in incorrect_sections:
-            ret_true = False
-            if not preserve_errors:
-                out[entry] = False
-            else:
-                ret_false = False
-                msg = 'Section %r was provided as a single value' % entry
-                out[entry] = validator.baseErrorClass(msg)
-                
-        # Missing sections will have been created as empty ones when the
-        # configspec was read.
-        for entry in section.sections:
-            # FIXME: this means DEFAULT is not copied in copy mode
-            if section is self and entry == 'DEFAULT':
-                continue
-            if section[entry].configspec is None:
-                unvalidated.append(entry)
-                continue
-            if copy:
-                section.comments[entry] = configspec.comments.get(entry, [])
-                section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
-            check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry])
-            out[entry] = check
-            if check == False:
-                ret_true = False
-            elif check == True:
-                ret_false = False
-            else:
-                ret_true = False
-        
-        section.extra_values = unvalidated
-        if preserve_errors and not section._created:
-            # If the section wasn't created (i.e. it wasn't missing)
-            # then we can't return False, we need to preserve errors
-            ret_false = False
-        #
-        if ret_false and preserve_errors and out:
-            # If we are preserving errors, but all
-            # the failures are from missing sections / values
-            # then we can return False. Otherwise there is a
-            # real failure that we need to preserve.
-            ret_false = not any(out.values())
-        if ret_true:
-            return True
-        elif ret_false:
-            return False
-        return out
-
-
-    def reset(self):
-        """Clear ConfigObj instance and restore to 'freshly created' state."""
-        self.clear()
-        self._initialise()
-        # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload)
-        #        requires an empty dictionary
-        self.configspec = None
-        # Just to be sure ;-)
-        self._original_configspec = None
-        
-        
-    def reload(self):
-        """
-        Reload a ConfigObj from file.
-        
-        This method raises a ``ReloadError`` if the ConfigObj doesn't have
-        a filename attribute pointing to a file.
-        """
-        if not isinstance(self.filename, basestring):
-            raise ReloadError()
-
-        filename = self.filename
-        current_options = {}
-        for entry in OPTION_DEFAULTS:
-            if entry == 'configspec':
-                continue
-            current_options[entry] = getattr(self, entry)
-            
-        configspec = self._original_configspec
-        current_options['configspec'] = configspec
-            
-        self.clear()
-        self._initialise(current_options)
-        self._load(filename, configspec)
-        
-
-
-class SimpleVal(object):
-    """
-    A simple validator.
-    Can be used to check that all members expected are present.
-    
-    To use it, provide a configspec with all your members in (the value given
-    will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
-    method of your ``ConfigObj``. ``validate`` will return ``True`` if all
-    members are present, or a dictionary with True/False meaning
-    present/missing. (Whole missing sections will be replaced with ``False``)
-    """
-    
-    def __init__(self):
-        self.baseErrorClass = ConfigObjError
-    
-    def check(self, check, member, missing=False):
-        """A dummy check method, always returns the value unchanged."""
-        if missing:
-            raise self.baseErrorClass()
-        return member
-
-
-def flatten_errors(cfg, res, levels=None, results=None):
-    """
-    An example function that will turn a nested dictionary of results
-    (as returned by ``ConfigObj.validate``) into a flat list.
-    
-    ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
-    dictionary returned by ``validate``.
-    
-    (This is a recursive function, so you shouldn't use the ``levels`` or
-    ``results`` arguments - they are used by the function.)
-    
-    Returns a list of keys that failed. Each member of the list is a tuple::
-    
-        ([list of sections...], key, result)
-    
-    If ``validate`` was called with ``preserve_errors=False`` (the default)
-    then ``result`` will always be ``False``.
-
-    *list of sections* is a flattened list of sections that the key was found
-    in.
-    
-    If the section was missing (or a section was expected and a scalar provided
-    - or vice-versa) then key will be ``None``.
-    
-    If the value (or section) was missing then ``result`` will be ``False``.
-    
-    If ``validate`` was called with ``preserve_errors=True`` and a value
-    was present, but failed the check, then ``result`` will be the exception
-    object returned. You can use this as a string that describes the failure.
-    
-    For example *The value "3" is of the wrong type*.
-    """
-    if levels is None:
-        # first time called
-        levels = []
-        results = []
-    if res == True:
-        return results
-    if res == False or isinstance(res, Exception):
-        results.append((levels[:], None, res))
-        if levels:
-            levels.pop()
-        return results
-    for (key, val) in res.items():
-        if val == True:
-            continue
-        if isinstance(cfg.get(key), dict):
-            # Go down one level
-            levels.append(key)
-            flatten_errors(cfg[key], val, levels, results)
-            continue
-        results.append((levels[:], key, val))
-    #
-    # Go up one level
-    if levels:
-        levels.pop()
-    #
-    return results
-
-
-def get_extra_values(conf, _prepend=()):
-    """
-    Find all the values and sections not in the configspec from a validated
-    ConfigObj.
-    
-    ``get_extra_values`` returns a list of tuples where each tuple represents
-    either an extra section, or an extra value.
-    
-    The tuples contain two values, a tuple representing the section the value 
-    is in and the name of the extra values. For extra values in the top level
-    section the first member will be an empty tuple. For values in the 'foo'
-    section the first member will be ``('foo',)``. For members in the 'bar'
-    subsection of the 'foo' section the first member will be ``('foo', 'bar')``.
-    
-    NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't
-    been validated it will return an empty list.
-    """
-    out = []
-    
-    out.extend([(_prepend, name) for name in conf.extra_values])
-    for name in conf.sections:
-        if name not in conf.extra_values:
-            out.extend(get_extra_values(conf[name], _prepend + (name,)))
-    return out
-
-
-"""*A programming language is a medium of expression.* - Paul Graham"""
diff --git a/astropy/extern/configobj_py2/validate.py b/astropy/extern/configobj_py2/validate.py
deleted file mode 100644
index 73dbdb8..0000000
--- a/astropy/extern/configobj_py2/validate.py
+++ /dev/null
@@ -1,1450 +0,0 @@
-# validate.py
-# A Validator object
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
-
-# This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-# Basically you're free to copy, modify, distribute and relicense it,
-# So long as you keep a copy of the license with it.
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
-
-"""
-    The Validator object is used to check that supplied values 
-    conform to a specification.
-    
-    The value can be supplied as a string - e.g. from a config file.
-    In this case the check will also *convert* the value to
-    the required type. This allows you to add validation
-    as a transparent layer to access data stored as strings.
-    The validation checks that the data is correct *and*
-    converts it to the expected type.
-    
-    Some standard checks are provided for basic data types.
-    Additional checks are easy to write. They can be
-    provided when the ``Validator`` is instantiated or
-    added afterwards.
-    
-    The standard functions work with the following basic data types :
-    
-    * integers
-    * floats
-    * booleans
-    * strings
-    * ip_addr
-    
-    plus lists of these datatypes
-    
-    Adding additional checks is done through coding simple functions.
-    
-    The full set of standard checks are : 
-    
-    * 'integer': matches integer values (including negative)
-                 Takes optional 'min' and 'max' arguments : ::
-    
-                   integer()
-                   integer(3, 9)  # any value from 3 to 9
-                   integer(min=0) # any positive value
-                   integer(max=9)
-    
-    * 'float': matches float values
-               Has the same parameters as the integer check.
-    
-    * 'boolean': matches boolean values - ``True`` or ``False``
-                 Acceptable string values for True are :
-                   true, on, yes, 1
-                 Acceptable string values for False are :
-                   false, off, no, 0
-    
-                 Any other value raises an error.
-    
-    * 'ip_addr': matches an Internet Protocol address, v.4, represented
-                 by a dotted-quad string, i.e. '1.2.3.4'.
-    
-    * 'string': matches any string.
-                Takes optional keyword args 'min' and 'max'
-                to specify min and max lengths of the string.
-    
-    * 'list': matches any list.
-              Takes optional keyword args 'min', and 'max' to specify min and
-              max sizes of the list. (Always returns a list.)
-    
-    * 'tuple': matches any tuple.
-              Takes optional keyword args 'min', and 'max' to specify min and
-              max sizes of the tuple. (Always returns a tuple.)
-    
-    * 'int_list': Matches a list of integers.
-                  Takes the same arguments as list.
-    
-    * 'float_list': Matches a list of floats.
-                    Takes the same arguments as list.
-    
-    * 'bool_list': Matches a list of boolean values.
-                   Takes the same arguments as list.
-    
-    * 'ip_addr_list': Matches a list of IP addresses.
-                     Takes the same arguments as list.
-    
-    * 'string_list': Matches a list of strings.
-                     Takes the same arguments as list.
-    
-    * 'mixed_list': Matches a list with different types in 
-                    specific positions. List size must match
-                    the number of arguments.
-    
-                    Each position can be one of :
-                    'integer', 'float', 'ip_addr', 'string', 'boolean'
-    
-                    So to specify a list with two strings followed
-                    by two integers, you write the check as : ::
-    
-                      mixed_list('string', 'string', 'integer', 'integer')
-    
-    * 'pass': This check matches everything ! It never fails
-              and the value is unchanged.
-    
-              It is also the default if no check is specified.
-    
-    * 'option': This check matches any from a list of options.
-                You specify this check with : ::
-    
-                  option('option 1', 'option 2', 'option 3')
-    
-    You can supply a default value (returned if no value is supplied)
-    using the default keyword argument.
-    
-    You specify a list argument for default using a list constructor syntax in
-    the check : ::
-    
-        checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
-    
-    A badly formatted set of arguments will raise a ``VdtParamError``.
-"""
-
-__version__ = '1.0.1'
-
-
-__all__ = (
-    '__version__',
-    'dottedQuadToNum',
-    'numToDottedQuad',
-    'ValidateError',
-    'VdtUnknownCheckError',
-    'VdtParamError',
-    'VdtTypeError',
-    'VdtValueError',
-    'VdtValueTooSmallError',
-    'VdtValueTooBigError',
-    'VdtValueTooShortError',
-    'VdtValueTooLongError',
-    'VdtMissingValue',
-    'Validator',
-    'is_integer',
-    'is_float',
-    'is_boolean',
-    'is_list',
-    'is_tuple',
-    'is_ip_addr',
-    'is_string',
-    'is_int_list',
-    'is_bool_list',
-    'is_float_list',
-    'is_string_list',
-    'is_ip_addr_list',
-    'is_mixed_list',
-    'is_option',
-    '__docformat__',
-)
-
-
-import re
-
-
-_list_arg = re.compile(r'''
-    (?:
-        ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
-            (
-                (?:
-                    \s*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s\)][^,\)]*?)  # unquoted
-                    )
-                    \s*,\s*
-                )*
-                (?:
-                    (?:".*?")|              # double quotes
-                    (?:'.*?')|              # single quotes
-                    (?:[^'",\s\)][^,\)]*?)  # unquoted
-                )?                          # last one
-            )
-        \)
-    )
-''', re.VERBOSE | re.DOTALL)    # two groups
-
-_list_members = re.compile(r'''
-    (
-        (?:".*?")|              # double quotes
-        (?:'.*?')|              # single quotes
-        (?:[^'",\s=][^,=]*?)       # unquoted
-    )
-    (?:
-    (?:\s*,\s*)|(?:\s*$)            # comma
-    )
-''', re.VERBOSE | re.DOTALL)    # one group
-
-_paramstring = r'''
-    (?:
-        (
-            (?:
-                [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
-                    (?:
-                        \s*
-                        (?:
-                            (?:".*?")|              # double quotes
-                            (?:'.*?')|              # single quotes
-                            (?:[^'",\s\)][^,\)]*?)       # unquoted
-                        )
-                        \s*,\s*
-                    )*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s\)][^,\)]*?)       # unquoted
-                    )?                              # last one
-                \)
-            )|
-            (?:
-                (?:".*?")|              # double quotes
-                (?:'.*?')|              # single quotes
-                (?:[^'",\s=][^,=]*?)|       # unquoted
-                (?:                         # keyword argument
-                    [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s=][^,=]*?)       # unquoted
-                    )
-                )
-            )
-        )
-        (?:
-            (?:\s*,\s*)|(?:\s*$)            # comma
-        )
-    )
-    '''
-
-_matchstring = '^%s*' % _paramstring
-
-# Python pre 2.2.1 doesn't have bool
-try:
-    bool
-except NameError:
-    def bool(val):
-        """Simple boolean equivalent function. """
-        if val:
-            return 1
-        else:
-            return 0
-
-
-def dottedQuadToNum(ip):
-    """
-    Convert decimal dotted quad string to long integer
-    
-    >>> int(dottedQuadToNum('1 '))
-    1
-    >>> int(dottedQuadToNum(' 1.2'))
-    16777218
-    >>> int(dottedQuadToNum(' 1.2.3 '))
-    16908291
-    >>> int(dottedQuadToNum('1.2.3.4'))
-    16909060
-    >>> dottedQuadToNum('255.255.255.255')
-    4294967295L
-    >>> dottedQuadToNum('255.255.255.256')
-    Traceback (most recent call last):
-    ValueError: Not a good dotted-quad IP: 255.255.255.256
-    """
-    
-    # import here to avoid it when ip_addr values are not used
-    import socket, struct
-    
-    try:
-        return struct.unpack('!L',
-            socket.inet_aton(ip.strip()))[0]
-    except socket.error:
-        # bug in inet_aton, corrected in Python 2.4
-        if ip.strip() == '255.255.255.255':
-            return 0xFFFFFFFFL
-        else:
-            raise ValueError('Not a good dotted-quad IP: %s' % ip)
-    return
-
-
-def numToDottedQuad(num):
-    """
-    Convert long int to dotted quad string
-    
-    >>> numToDottedQuad(-1L)
-    Traceback (most recent call last):
-    ValueError: Not a good numeric IP: -1
-    >>> numToDottedQuad(1L)
-    '0.0.0.1'
-    >>> numToDottedQuad(16777218L)
-    '1.0.0.2'
-    >>> numToDottedQuad(16908291L)
-    '1.2.0.3'
-    >>> numToDottedQuad(16909060L)
-    '1.2.3.4'
-    >>> numToDottedQuad(4294967295L)
-    '255.255.255.255'
-    >>> numToDottedQuad(4294967296L)
-    Traceback (most recent call last):
-    ValueError: Not a good numeric IP: 4294967296
-    """
-    
-    # import here to avoid it when ip_addr values are not used
-    import socket, struct
-    
-    # no need to intercept here, 4294967295L is fine
-    if num > 4294967295L or num < 0:
-        raise ValueError('Not a good numeric IP: %s' % num)
-    try:
-        return socket.inet_ntoa(
-            struct.pack('!L', long(num)))
-    except (socket.error, struct.error, OverflowError):
-        raise ValueError('Not a good numeric IP: %s' % num)
-
-
-class ValidateError(Exception):
-    """
-    This error indicates that the check failed.
-    It can be the base class for more specific errors.
-    
-    Any check function that fails ought to raise this error.
-    (or a subclass)
-    
-    >>> raise ValidateError
-    Traceback (most recent call last):
-    ValidateError
-    """
-
-
-class VdtMissingValue(ValidateError):
-    """No value was supplied to a check that needed one."""
-
-
-class VdtUnknownCheckError(ValidateError):
-    """An unknown check function was requested"""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtUnknownCheckError('yoda')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        """
-        ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,))
-
-
-class VdtParamError(SyntaxError):
-    """An incorrect parameter was passed"""
-
-    def __init__(self, name, value):
-        """
-        >>> raise VdtParamError('yoda', 'jedi')
-        Traceback (most recent call last):
-        VdtParamError: passed an incorrect value "jedi" for parameter "yoda".
-        """
-        SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name))
-
-
-class VdtTypeError(ValidateError):
-    """The value supplied was of the wrong type"""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtTypeError('jedi')
-        Traceback (most recent call last):
-        VdtTypeError: the value "jedi" is of the wrong type.
-        """
-        ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,))
-
-
-class VdtValueError(ValidateError):
-    """The value supplied was of the correct type, but was not an allowed value."""
-    
-    def __init__(self, value):
-        """
-        >>> raise VdtValueError('jedi')
-        Traceback (most recent call last):
-        VdtValueError: the value "jedi" is unacceptable.
-        """
-        ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,))
-
-
-class VdtValueTooSmallError(VdtValueError):
-    """The value supplied was of the correct type, but was too small."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooSmallError('0')
-        Traceback (most recent call last):
-        VdtValueTooSmallError: the value "0" is too small.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too small.' % (value,))
-
-
-class VdtValueTooBigError(VdtValueError):
-    """The value supplied was of the correct type, but was too big."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooBigError('1')
-        Traceback (most recent call last):
-        VdtValueTooBigError: the value "1" is too big.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too big.' % (value,))
-
-
-class VdtValueTooShortError(VdtValueError):
-    """The value supplied was of the correct type, but was too short."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooShortError('jed')
-        Traceback (most recent call last):
-        VdtValueTooShortError: the value "jed" is too short.
-        """
-        ValidateError.__init__(
-            self,
-            'the value "%s" is too short.' % (value,))
-
-
-class VdtValueTooLongError(VdtValueError):
-    """The value supplied was of the correct type, but was too long."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooLongError('jedie')
-        Traceback (most recent call last):
-        VdtValueTooLongError: the value "jedie" is too long.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too long.' % (value,))
-
-
-class Validator(object):
-    """
-    Validator is an object that allows you to register a set of 'checks'.
-    These checks take input and test that it conforms to the check.
-    
-    This can also involve converting the value from a string into
-    the correct datatype.
-    
-    The ``check`` method takes an input string which configures which
-    check is to be used and applies that check to a supplied value.
-    
-    An example input string would be:
-    'int_range(param1, param2)'
-    
-    You would then provide something like:
-    
-    >>> def int_range_check(value, min, max):
-    ...     # turn min and max from strings to integers
-    ...     min = int(min)
-    ...     max = int(max)
-    ...     # check that value is of the correct type.
-    ...     # possible valid inputs are integers or strings
-    ...     # that represent integers
-    ...     if not isinstance(value, (int, long, basestring)):
-    ...         raise VdtTypeError(value)
-    ...     elif isinstance(value, basestring):
-    ...         # if we are given a string
-    ...         # attempt to convert to an integer
-    ...         try:
-    ...             value = int(value)
-    ...         except ValueError:
-    ...             raise VdtValueError(value)
-    ...     # check the value is between our constraints
-    ...     if not min <= value:
-    ...          raise VdtValueTooSmallError(value)
-    ...     if not value <= max:
-    ...          raise VdtValueTooBigError(value)
-    ...     return value
-    
-    >>> fdict = {'int_range': int_range_check}
-    >>> vtr1 = Validator(fdict)
-    >>> vtr1.check('int_range(20, 40)', '30')
-    30
-    >>> vtr1.check('int_range(20, 40)', '60')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "60" is too big.
-    
-    New functions can be added with : ::
-    
-    >>> vtr2 = Validator()       
-    >>> vtr2.functions['int_range'] = int_range_check
-    
-    Or by passing in a dictionary of functions when Validator 
-    is instantiated.
-    
-    Your functions *can* use keyword arguments,
-    but the first argument should always be 'value'.
-    
-    If the function doesn't take additional arguments,
-    the parentheses are optional in the check.
-    It can be written with either of : ::
-    
-        keyword = function_name
-        keyword = function_name()
-    
-    The first program to utilise Validator() was Michael Foord's
-    ConfigObj, an alternative to ConfigParser which supports lists and
-    can validate a config file using a config schema.
-    For more details on using Validator with ConfigObj see:
-    http://www.voidspace.org.uk/python/configobj.html
-    """
-
-    # this regex does the initial parsing of the checks
-    _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
-
-    # this regex takes apart keyword arguments
-    _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$',  re.DOTALL)
-
-
-    # this regex finds keyword=list(....) type values
-    _list_arg = _list_arg
-
-    # this regex takes individual values out of lists - in one pass
-    _list_members = _list_members
-
-    # These regexes check a set of arguments for validity
-    # and then pull the members out
-    _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL)
-    _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL)
-
-
-    def __init__(self, functions=None):
-        """
-        >>> vtri = Validator()
-        """
-        self.functions = {
-            '': self._pass,
-            'integer': is_integer,
-            'float': is_float,
-            'boolean': is_boolean,
-            'ip_addr': is_ip_addr,
-            'string': is_string,
-            'list': is_list,
-            'tuple': is_tuple,
-            'int_list': is_int_list,
-            'float_list': is_float_list,
-            'bool_list': is_bool_list,
-            'ip_addr_list': is_ip_addr_list,
-            'string_list': is_string_list,
-            'mixed_list': is_mixed_list,
-            'pass': self._pass,
-            'option': is_option,
-            'force_list': force_list,
-        }
-        if functions is not None:
-            self.functions.update(functions)
-        # tekNico: for use by ConfigObj
-        self.baseErrorClass = ValidateError
-        self._cache = {}
-
-
-    def check(self, check, value, missing=False):
-        """
-        Usage: check(check, value)
-        
-        Arguments:
-            check: string representing check to apply (including arguments)
-            value: object to be checked
-        Returns value, converted to correct type if necessary
-        
-        If the check fails, raises a ``ValidateError`` subclass.
-        
-        >>> vtor.check('yoda', '')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        >>> vtor.check('yoda()', '')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        
-        >>> vtor.check('string(default="")', '', missing=True)
-        ''
-        """
-        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
-            
-        if missing:
-            if default is None:
-                # no information needed here - to be handled by caller
-                raise VdtMissingValue()
-            value = self._handle_none(default)
-        
-        if value is None:
-            return None
-        
-        return self._check_value(value, fun_name, fun_args, fun_kwargs)
-
-
-    def _handle_none(self, value):
-        if value == 'None':
-            return None
-        elif value in ("'None'", '"None"'):
-            # Special case a quoted None
-            value = self._unquote(value)
-        return value
-
-
-    def _parse_with_caching(self, check):
-        if check in self._cache:
-            fun_name, fun_args, fun_kwargs, default = self._cache[check]
-            # We call list and dict below to work with *copies* of the data
-            # rather than the original (which are mutable of course)
-            fun_args = list(fun_args)
-            fun_kwargs = dict(fun_kwargs)
-        else:
-            fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
-            fun_kwargs = dict([(str(key), value) for (key, value) in fun_kwargs.items()])
-            self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
-        return fun_name, fun_args, fun_kwargs, default
-        
-        
-    def _check_value(self, value, fun_name, fun_args, fun_kwargs):
-        try:
-            fun = self.functions[fun_name]
-        except KeyError:
-            raise VdtUnknownCheckError(fun_name)
-        else:
-            return fun(value, *fun_args, **fun_kwargs)
-
-
-    def _parse_check(self, check):
-        fun_match = self._func_re.match(check)
-        if fun_match:
-            fun_name = fun_match.group(1)
-            arg_string = fun_match.group(2)
-            arg_match = self._matchfinder.match(arg_string)
-            if arg_match is None:
-                # Bad syntax
-                raise VdtParamError('Bad syntax in check "%s".' % check)
-            fun_args = []
-            fun_kwargs = {}
-            # pull out args of group 2
-            for arg in self._paramfinder.findall(arg_string):
-                # args may need whitespace removing (before removing quotes)
-                arg = arg.strip()
-                listmatch = self._list_arg.match(arg)
-                if listmatch:
-                    key, val = self._list_handle(listmatch)
-                    fun_kwargs[key] = val
-                    continue
-                keymatch = self._key_arg.match(arg)
-                if keymatch:
-                    val = keymatch.group(2)
-                    if not val in ("'None'", '"None"'):
-                        # Special case a quoted None
-                        val = self._unquote(val)
-                    fun_kwargs[keymatch.group(1)] = val
-                    continue
-                
-                fun_args.append(self._unquote(arg))
-        else:
-            # allows for function names without (args)
-            return check, (), {}, None
-
-        # Default must be deleted if the value is specified too,
-        # otherwise the check function will get a spurious "default" keyword arg
-        default = fun_kwargs.pop('default', None)
-        return fun_name, fun_args, fun_kwargs, default
-
-
-    def _unquote(self, val):
-        """Unquote a value if necessary."""
-        if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]):
-            val = val[1:-1]
-        return val
-
-
-    def _list_handle(self, listmatch):
-        """Take apart a ``keyword=list('val, 'val')`` type string."""
-        out = []
-        name = listmatch.group(1)
-        args = listmatch.group(2)
-        for arg in self._list_members.findall(args):
-            out.append(self._unquote(arg))
-        return name, out
-
-
-    def _pass(self, value):
-        """
-        Dummy check that always passes
-        
-        >>> vtor.check('', 0)
-        0
-        >>> vtor.check('', '0')
-        '0'
-        """
-        return value
-    
-    
-    def get_default_value(self, check):
-        """
-        Given a check, return the default value for the check
-        (converted to the right type).
-        
-        If the check doesn't specify a default value then a
-        ``KeyError`` will be raised.
-        """
-        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
-        if default is None:
-            raise KeyError('Check "%s" has no default value.' % check)
-        value = self._handle_none(default)
-        if value is None:
-            return value
-        return self._check_value(value, fun_name, fun_args, fun_kwargs)
-
-
-def _is_num_param(names, values, to_float=False):
-    """
-    Return numbers from inputs or raise VdtParamError.
-    
-    Lets ``None`` pass through.
-    Pass in keyword argument ``to_float=True`` to
-    use float for the conversion rather than int.
-    
-    >>> _is_num_param(('', ''), (0, 1.0))
-    [0, 1]
-    >>> _is_num_param(('', ''), (0, 1.0), to_float=True)
-    [0.0, 1.0]
-    >>> _is_num_param(('a'), ('a'))
-    Traceback (most recent call last):
-    VdtParamError: passed an incorrect value "a" for parameter "a".
-    """
-    fun = to_float and float or int
-    out_params = []
-    for (name, val) in zip(names, values):
-        if val is None:
-            out_params.append(val)
-        elif isinstance(val, (int, long, float, basestring)):
-            try:
-                out_params.append(fun(val))
-            except ValueError, e:
-                raise VdtParamError(name, val)
-        else:
-            raise VdtParamError(name, val)
-    return out_params
-
-
-# built in checks
-# you can override these by setting the appropriate name
-# in Validator.functions
-# note: if the params are specified wrongly in your input string,
-#       you will also raise errors.
-
-def is_integer(value, min=None, max=None):
-    """
-    A check that tests that a given value is an integer (int, or long)
-    and optionally, between bounds. A negative value is accepted, while
-    a float will fail.
-    
-    If the value is a string, then the conversion is done - if possible.
-    Otherwise a VdtError is raised.
-    
-    >>> vtor.check('integer', '-1')
-    -1
-    >>> vtor.check('integer', '0')
-    0
-    >>> vtor.check('integer', 9)
-    9
-    >>> vtor.check('integer', 'a')
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    >>> vtor.check('integer', '2.2')
-    Traceback (most recent call last):
-    VdtTypeError: the value "2.2" is of the wrong type.
-    >>> vtor.check('integer(10)', '20')
-    20
-    >>> vtor.check('integer(max=20)', '15')
-    15
-    >>> vtor.check('integer(10)', '9')
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9" is too small.
-    >>> vtor.check('integer(10)', 9)
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9" is too small.
-    >>> vtor.check('integer(max=20)', '35')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35" is too big.
-    >>> vtor.check('integer(max=20)', 35)
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35" is too big.
-    >>> vtor.check('integer(0, 9)', False)
-    0
-    """
-    (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
-    if not isinstance(value, (int, long, basestring)):
-        raise VdtTypeError(value)
-    if isinstance(value, basestring):
-        # if it's a string - does it represent an integer ?
-        try:
-            value = int(value)
-        except ValueError:
-            raise VdtTypeError(value)
-    if (min_val is not None) and (value < min_val):
-        raise VdtValueTooSmallError(value)
-    if (max_val is not None) and (value > max_val):
-        raise VdtValueTooBigError(value)
-    return value
-
-
-def is_float(value, min=None, max=None):
-    """
-    A check that tests that a given value is a float
-    (an integer will be accepted), and optionally - that it is between bounds.
-    
-    If the value is a string, then the conversion is done - if possible.
-    Otherwise a VdtError is raised.
-    
-    This can accept negative values.
-    
-    >>> vtor.check('float', '2')
-    2.0
-    
-    From now on we multiply the value to avoid comparing decimals
-    
-    >>> vtor.check('float', '-6.8') * 10
-    -68.0
-    >>> vtor.check('float', '12.2') * 10
-    122.0
-    >>> vtor.check('float', 8.4) * 10
-    84.0
-    >>> vtor.check('float', 'a')
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    >>> vtor.check('float(10.1)', '10.2') * 10
-    102.0
-    >>> vtor.check('float(max=20.2)', '15.1') * 10
-    151.0
-    >>> vtor.check('float(10.0)', '9.0')
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9.0" is too small.
-    >>> vtor.check('float(max=20.0)', '35.0')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35.0" is too big.
-    """
-    (min_val, max_val) = _is_num_param(
-        ('min', 'max'), (min, max), to_float=True)
-    if not isinstance(value, (int, long, float, basestring)):
-        raise VdtTypeError(value)
-    if not isinstance(value, float):
-        # if it's a string - does it represent a float ?
-        try:
-            value = float(value)
-        except ValueError:
-            raise VdtTypeError(value)
-    if (min_val is not None) and (value < min_val):
-        raise VdtValueTooSmallError(value)
-    if (max_val is not None) and (value > max_val):
-        raise VdtValueTooBigError(value)
-    return value
-
-
-bool_dict = {
-    True: True, 'on': True, '1': True, 'true': True, 'yes': True, 
-    False: False, 'off': False, '0': False, 'false': False, 'no': False,
-}
-
-
-def is_boolean(value):
-    """
-    Check if the value represents a boolean.
-    
-    >>> vtor.check('boolean', 0)
-    0
-    >>> vtor.check('boolean', False)
-    0
-    >>> vtor.check('boolean', '0')
-    0
-    >>> vtor.check('boolean', 'off')
-    0
-    >>> vtor.check('boolean', 'false')
-    0
-    >>> vtor.check('boolean', 'no')
-    0
-    >>> vtor.check('boolean', 'nO')
-    0
-    >>> vtor.check('boolean', 'NO')
-    0
-    >>> vtor.check('boolean', 1)
-    1
-    >>> vtor.check('boolean', True)
-    1
-    >>> vtor.check('boolean', '1')
-    1
-    >>> vtor.check('boolean', 'on')
-    1
-    >>> vtor.check('boolean', 'true')
-    1
-    >>> vtor.check('boolean', 'yes')
-    1
-    >>> vtor.check('boolean', 'Yes')
-    1
-    >>> vtor.check('boolean', 'YES')
-    1
-    >>> vtor.check('boolean', '')
-    Traceback (most recent call last):
-    VdtTypeError: the value "" is of the wrong type.
-    >>> vtor.check('boolean', 'up')
-    Traceback (most recent call last):
-    VdtTypeError: the value "up" is of the wrong type.
-    
-    """
-    if isinstance(value, basestring):
-        try:
-            return bool_dict[value.lower()]
-        except KeyError:
-            raise VdtTypeError(value)
-    # we do an equality test rather than an identity test
-    # this ensures Python 2.2 compatibilty
-    # and allows 0 and 1 to represent True and False
-    if value == False:
-        return False
-    elif value == True:
-        return True
-    else:
-        raise VdtTypeError(value)
-
-
-def is_ip_addr(value):
-    """
-    Check that the supplied value is an Internet Protocol address, v.4,
-    represented by a dotted-quad string, i.e. '1.2.3.4'.
-    
-    >>> vtor.check('ip_addr', '1 ')
-    '1'
-    >>> vtor.check('ip_addr', ' 1.2')
-    '1.2'
-    >>> vtor.check('ip_addr', ' 1.2.3 ')
-    '1.2.3'
-    >>> vtor.check('ip_addr', '1.2.3.4')
-    '1.2.3.4'
-    >>> vtor.check('ip_addr', '0.0.0.0')
-    '0.0.0.0'
-    >>> vtor.check('ip_addr', '255.255.255.255')
-    '255.255.255.255'
-    >>> vtor.check('ip_addr', '255.255.255.256')
-    Traceback (most recent call last):
-    VdtValueError: the value "255.255.255.256" is unacceptable.
-    >>> vtor.check('ip_addr', '1.2.3.4.5')
-    Traceback (most recent call last):
-    VdtValueError: the value "1.2.3.4.5" is unacceptable.
-    >>> vtor.check('ip_addr', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    """
-    if not isinstance(value, basestring):
-        raise VdtTypeError(value)
-    value = value.strip()
-    try:
-        dottedQuadToNum(value)
-    except ValueError:
-        raise VdtValueError(value)
-    return value
-
-
-def is_list(value, min=None, max=None):
-    """
-    Check that the value is a list of values.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    It does no check on list members.
-    
-    >>> vtor.check('list', ())
-    []
-    >>> vtor.check('list', [])
-    []
-    >>> vtor.check('list', (1, 2))
-    [1, 2]
-    >>> vtor.check('list', [1, 2])
-    [1, 2]
-    >>> vtor.check('list(3)', (1, 2))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2)" is too short.
-    >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
-    >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4))
-    [1, 2, 3, 4]
-    >>> vtor.check('list', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('list', '12')
-    Traceback (most recent call last):
-    VdtTypeError: the value "12" is of the wrong type.
-    """
-    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
-    if isinstance(value, basestring):
-        raise VdtTypeError(value)
-    try:
-        num_members = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if min_len is not None and num_members < min_len:
-        raise VdtValueTooShortError(value)
-    if max_len is not None and num_members > max_len:
-        raise VdtValueTooLongError(value)
-    return list(value)
-
-
-def is_tuple(value, min=None, max=None):
-    """
-    Check that the value is a tuple of values.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    It does no check on members.
-    
-    >>> vtor.check('tuple', ())
-    ()
-    >>> vtor.check('tuple', [])
-    ()
-    >>> vtor.check('tuple', (1, 2))
-    (1, 2)
-    >>> vtor.check('tuple', [1, 2])
-    (1, 2)
-    >>> vtor.check('tuple(3)', (1, 2))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2)" is too short.
-    >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
-    >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4))
-    (1, 2, 3, 4)
-    >>> vtor.check('tuple', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('tuple', '12')
-    Traceback (most recent call last):
-    VdtTypeError: the value "12" is of the wrong type.
-    """
-    return tuple(is_list(value, min, max))
-
-
-def is_string(value, min=None, max=None):
-    """
-    Check that the supplied value is a string.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    >>> vtor.check('string', '0')
-    '0'
-    >>> vtor.check('string', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('string(2)', '12')
-    '12'
-    >>> vtor.check('string(2)', '1')
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "1" is too short.
-    >>> vtor.check('string(min=2, max=3)', '123')
-    '123'
-    >>> vtor.check('string(min=2, max=3)', '1234')
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "1234" is too long.
-    """
-    if not isinstance(value, basestring):
-        raise VdtTypeError(value)
-    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
-    try:
-        num_members = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if min_len is not None and num_members < min_len:
-        raise VdtValueTooShortError(value)
-    if max_len is not None and num_members > max_len:
-        raise VdtValueTooLongError(value)
-    return value
-
-
-def is_int_list(value, min=None, max=None):
-    """
-    Check that the value is a list of integers.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is an integer.
-    
-    >>> vtor.check('int_list', ())
-    []
-    >>> vtor.check('int_list', [])
-    []
-    >>> vtor.check('int_list', (1, 2))
-    [1, 2]
-    >>> vtor.check('int_list', [1, 2])
-    [1, 2]
-    >>> vtor.check('int_list', [1, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_integer(mem) for mem in is_list(value, min, max)]
-
-
-def is_bool_list(value, min=None, max=None):
-    """
-    Check that the value is a list of booleans.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is a boolean.
-    
-    >>> vtor.check('bool_list', ())
-    []
-    >>> vtor.check('bool_list', [])
-    []
-    >>> check_res = vtor.check('bool_list', (True, False))
-    >>> check_res == [True, False]
-    1
-    >>> check_res = vtor.check('bool_list', [True, False])
-    >>> check_res == [True, False]
-    1
-    >>> vtor.check('bool_list', [True, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_boolean(mem) for mem in is_list(value, min, max)]
-
-
-def is_float_list(value, min=None, max=None):
-    """
-    Check that the value is a list of floats.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is a float.
-    
-    >>> vtor.check('float_list', ())
-    []
-    >>> vtor.check('float_list', [])
-    []
-    >>> vtor.check('float_list', (1, 2.0))
-    [1.0, 2.0]
-    >>> vtor.check('float_list', [1, 2.0])
-    [1.0, 2.0]
-    >>> vtor.check('float_list', [1, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_float(mem) for mem in is_list(value, min, max)]
-
-
-def is_string_list(value, min=None, max=None):
-    """
-    Check that the value is a list of strings.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is a string.
-    
-    >>> vtor.check('string_list', ())
-    []
-    >>> vtor.check('string_list', [])
-    []
-    >>> vtor.check('string_list', ('a', 'b'))
-    ['a', 'b']
-    >>> vtor.check('string_list', ['a', 1])
-    Traceback (most recent call last):
-    VdtTypeError: the value "1" is of the wrong type.
-    >>> vtor.check('string_list', 'hello')
-    Traceback (most recent call last):
-    VdtTypeError: the value "hello" is of the wrong type.
-    """
-    if isinstance(value, basestring):
-        raise VdtTypeError(value)
-    return [is_string(mem) for mem in is_list(value, min, max)]
-
-
-def is_ip_addr_list(value, min=None, max=None):
-    """
-    Check that the value is a list of IP addresses.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is an IP address.
-    
-    >>> vtor.check('ip_addr_list', ())
-    []
-    >>> vtor.check('ip_addr_list', [])
-    []
-    >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8'))
-    ['1.2.3.4', '5.6.7.8']
-    >>> vtor.check('ip_addr_list', ['a'])
-    Traceback (most recent call last):
-    VdtValueError: the value "a" is unacceptable.
-    """
-    return [is_ip_addr(mem) for mem in is_list(value, min, max)]
-
-
-def force_list(value, min=None, max=None):
-    """
-    Check that a value is a list, coercing strings into
-    a list with one member. Useful where users forget the
-    trailing comma that turns a single value into a list.
-    
-    You can optionally specify the minimum and maximum number of members.
-    A minumum of greater than one will fail if the user only supplies a
-    string.
-    
-    >>> vtor.check('force_list', ())
-    []
-    >>> vtor.check('force_list', [])
-    []
-    >>> vtor.check('force_list', 'hello')
-    ['hello']
-    """
-    if not isinstance(value, (list, tuple)):
-        value = [value]
-    return is_list(value, min, max)
-    
-    
-
-fun_dict = {
-    'integer': is_integer,
-    'float': is_float,
-    'ip_addr': is_ip_addr,
-    'string': is_string,
-    'boolean': is_boolean,
-}
-
-
-def is_mixed_list(value, *args):
-    """
-    Check that the value is a list.
-    Allow specifying the type of each member.
-    Work on lists of specific lengths.
-    
-    You specify each member as a positional argument specifying type
-    
-    Each type should be one of the following strings :
-      'integer', 'float', 'ip_addr', 'string', 'boolean'
-    
-    So you can specify a list of two strings, followed by
-    two integers as :
-    
-      mixed_list('string', 'string', 'integer', 'integer')
-    
-    The length of the list must match the number of positional
-    arguments you supply.
-    
-    >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
-    >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
-    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
-    1
-    >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True'))
-    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
-    1
-    >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True))
-    Traceback (most recent call last):
-    VdtTypeError: the value "b" is of the wrong type.
-    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a'))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
-    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
-    >>> vtor.check(mix_str, 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    
-    This test requires an elaborate setup, because of a change in error string
-    output from the interpreter between Python 2.2 and 2.3 .
-    
-    >>> res_seq = (
-    ...     'passed an incorrect value "',
-    ...     'yoda',
-    ...     '" for parameter "mixed_list".',
-    ... )
-    >>> res_str = "'".join(res_seq)
-    >>> try:
-    ...     vtor.check('mixed_list("yoda")', ('a'))
-    ... except VdtParamError, err:
-    ...     str(err) == res_str
-    1
-    """
-    try:
-        length = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if length < len(args):
-        raise VdtValueTooShortError(value)
-    elif length > len(args):
-        raise VdtValueTooLongError(value)
-    try:
-        return [fun_dict[arg](val) for arg, val in zip(args, value)]
-    except KeyError, e:
-        raise VdtParamError('mixed_list', e)
-
-
-def is_option(value, *options):
-    """
-    This check matches the value to any of a set of options.
-    
-    >>> vtor.check('option("yoda", "jedi")', 'yoda')
-    'yoda'
-    >>> vtor.check('option("yoda", "jedi")', 'jed')
-    Traceback (most recent call last):
-    VdtValueError: the value "jed" is unacceptable.
-    >>> vtor.check('option("yoda", "jedi")', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    """
-    if not isinstance(value, basestring):
-        raise VdtTypeError(value)
-    if not value in options:
-        raise VdtValueError(value)
-    return value
-
-
-def _test(value, *args, **keywargs):
-    """
-    A function that exists for test purposes.
-    
-    >>> checks = [
-    ...     '3, 6, min=1, max=3, test=list(a, b, c)',
-    ...     '3',
-    ...     '3, 6',
-    ...     '3,',
-    ...     'min=1, test="a b c"',
-    ...     'min=5, test="a, b, c"',
-    ...     'min=1, max=3, test="a, b, c"',
-    ...     'min=-100, test=-99',
-    ...     'min=1, max=3',
-    ...     '3, 6, test="36"',
-    ...     '3, 6, test="a, b, c"',
-    ...     '3, max=3, test=list("a", "b", "c")',
-    ...     '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
-    ...     "test='x=fish(3)'",
-    ...    ]
-    >>> v = Validator({'test': _test})
-    >>> for entry in checks:
-    ...     print v.check(('test(%s)' % entry), 3)
-    (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
-    (3, ('3',), {})
-    (3, ('3', '6'), {})
-    (3, ('3',), {})
-    (3, (), {'test': 'a b c', 'min': '1'})
-    (3, (), {'test': 'a, b, c', 'min': '5'})
-    (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
-    (3, (), {'test': '-99', 'min': '-100'})
-    (3, (), {'max': '3', 'min': '1'})
-    (3, ('3', '6'), {'test': '36'})
-    (3, ('3', '6'), {'test': 'a, b, c'})
-    (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
-    (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
-    (3, (), {'test': 'x=fish(3)'})
-    
-    >>> v = Validator()
-    >>> v.check('integer(default=6)', '3')
-    3
-    >>> v.check('integer(default=6)', None, True)
-    6
-    >>> v.get_default_value('integer(default=6)')
-    6
-    >>> v.get_default_value('float(default=6)')
-    6.0
-    >>> v.get_default_value('pass(default=None)')
-    >>> v.get_default_value("string(default='None')")
-    'None'
-    >>> v.get_default_value('pass')
-    Traceback (most recent call last):
-    KeyError: 'Check "pass" has no default value.'
-    >>> v.get_default_value('pass(default=list(1, 2, 3, 4))')
-    ['1', '2', '3', '4']
-    
-    >>> v = Validator()
-    >>> v.check("pass(default=None)", None, True)
-    >>> v.check("pass(default='None')", None, True)
-    'None'
-    >>> v.check('pass(default="None")', None, True)
-    'None'
-    >>> v.check('pass(default=list(1, 2, 3, 4))', None, True)
-    ['1', '2', '3', '4']
-    
-    Bug test for unicode arguments
-    >>> v = Validator()
-    >>> v.check(u'string(min=4)', u'test')
-    u'test'
-    
-    >>> v = Validator()
-    >>> v.get_default_value(u'string(min=4, default="1234")')
-    u'1234'
-    >>> v.check(u'string(min=4, default="1234")', u'test')
-    u'test'
-    
-    >>> v = Validator()
-    >>> default = v.get_default_value('string(default=None)')
-    >>> default == None
-    1
-    """
-    return (value, args, keywargs)
-
-
-def _test2():
-    """
-    >>> 
-    >>> v = Validator()
-    >>> v.get_default_value('string(default="#ff00dd")')
-    '#ff00dd'
-    >>> v.get_default_value('integer(default=3) # comment')
-    3
-    """
-
-def _test3():
-    r"""
-    >>> vtor.check('string(default="")', '', missing=True)
-    ''
-    >>> vtor.check('string(default="\n")', '', missing=True)
-    '\n'
-    >>> print vtor.check('string(default="\n")', '', missing=True),
-    <BLANKLINE>
-    >>> vtor.check('string()', '\n')
-    '\n'
-    >>> vtor.check('string(default="\n\n\n")', '', missing=True)
-    '\n\n\n'
-    >>> vtor.check('string()', 'random \n text goes here\n\n')
-    'random \n text goes here\n\n'
-    >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")',
-    ... '', missing=True)
-    ' \nrandom text\ngoes \n here\n\n '
-    >>> vtor.check("string(default='\n\n\n')", '', missing=True)
-    '\n\n\n'
-    >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True)
-    '\n'
-    >>> vtor.check("string_list()", ['foo', '\n', 'bar'])
-    ['foo', '\n', 'bar']
-    >>> vtor.check("string_list(default=list('\n'))", '', missing=True)
-    ['\n']
-    """
-    
-    
-if __name__ == '__main__':
-    # run the code tests in doctest format
-    import sys
-    import doctest
-    m = sys.modules.get('__main__')
-    globs = m.__dict__.copy()
-    globs.update({
-        'vtor': Validator(),
-    })
-    doctest.testmod(m, globs=globs)
diff --git a/astropy/extern/configobj_py3/__init__.py b/astropy/extern/configobj_py3/__init__.py
deleted file mode 100644
index 54e9e57..0000000
--- a/astropy/extern/configobj_py3/__init__.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst  
-
-"""
-This is a copy of the main portions of the  `configobj 
-<http://www.voidspace.org.uk/python/configobj.html>`_ package. This is used
-internally in the Astropy configuration system. The license for configobj is
-available  in the ``licenses/CONFIGOBJ_LICENSE.rst`` file in the Astropy
-source distribution.
-
-This is a version of configobj that has been modified by Zubin Mithra to be
-compatible with python 3.x.  This version is not official, but has been
-"blessed" by configobj's original author. This version of the code was
-obtained from https://bitbucket.org/zubin71/configobj-py3
-
-For a python 2.x version, see the ``astropy/extern/configobj`` directory.
-""" 
-
-#this holds the contents of the setup.py file used by configobj
-_configobj_setup_dot_py="""
-# setup.py
-# Install script for ConfigObj
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
-
-# This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-
-import sys
-from distutils.core import setup
-from configobj import __version__ as VERSION
-
-NAME = 'configobj'
-
-MODULES = 'configobj', 'validate'
-
-DESCRIPTION = 'Config file reading, writing and validation.'
-
-URL = 'http://www.voidspace.org.uk/python/configobj.html'
-
-DOWNLOAD_URL = "http://www.voidspace.org.uk/downloads/configobj-%s.zip" % VERSION
-
-LONG_DESCRIPTION = ""#"**ConfigObj** is a simple but powerful config file reader and writer: an *ini
-file round tripper*. Its main feature is that it is very easy to use, with a
-straightforward programmer's interface and a simple syntax for config files.
-It has lots of other features though :
-
-* Nested sections (subsections), to any level
-* List values
-* Multiple line values
-* Full Unicode support
-* String interpolation (substitution)
-* Integrated with a powerful validation system
-
-    - including automatic type checking/conversion
-    - and allowing default values
-    - repeated sections
-
-* All comments in the file are preserved
-* The order of keys/sections is preserved
-* Powerful ``unrepr`` mode for storing/retrieving Python data-types
-
-| Release 4.7.2 fixes several bugs in 4.7.1
-| Release 4.7.1 fixes a bug with the deprecated options keyword in
-| 4.7.0.
-| Release 4.7.0 improves performance adds features for validation and
-| fixes some bugs.""#"
-
-CLASSIFIERS = [
-    'Development Status :: 6 - Mature',
-    'Intended Audience :: Developers',
-    'License :: OSI Approved :: BSD License',
-    'Programming Language :: Python',
-    'Programming Language :: Python :: 2.3',
-    'Programming Language :: Python :: 2.4',
-    'Programming Language :: Python :: 2.5',
-    'Programming Language :: Python :: 2.6',
-    'Operating System :: OS Independent',
-    'Topic :: Software Development :: Libraries',
-    'Topic :: Software Development :: Libraries :: Python Modules',
-]
-
-AUTHOR = 'Michael Foord & Nicola Larosa'
-
-AUTHOR_EMAIL = 'fuzzyman at voidspace.org.uk'
-
-KEYWORDS = "config, ini, dictionary, application, admin, sysadmin, configuration, validation".split(', ')
-
-
-setup(name=NAME,
-      version=VERSION,
-      description=DESCRIPTION,
-      long_description=LONG_DESCRIPTION,
-      download_url=DOWNLOAD_URL,
-      author=AUTHOR,
-      author_email=AUTHOR_EMAIL,
-      url=URL,
-      py_modules=MODULES,
-      classifiers=CLASSIFIERS,
-      keywords=KEYWORDS
-     )
-""".replace('""#"','"""') 
-#the replacement is necessary because """ would otherwise terminate the string
diff --git a/astropy/extern/configobj_py3/configobj.py b/astropy/extern/configobj_py3/configobj.py
deleted file mode 100644
index 70c89f2..0000000
--- a/astropy/extern/configobj_py3/configobj.py
+++ /dev/null
@@ -1,2405 +0,0 @@
-# configobj.py
-# A config file reader/writer that supports nested sections in config files.
-# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         nico AT tekNico DOT net
-
-# ConfigObj 4
-# http://www.voidspace.org.uk/python/configobj.html
-
-# Released subject to the BSD License
-# Please see http://www.voidspace.org.uk/python/license.shtml
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
-import pdb
-
-import os
-import re
-import sys
-
-from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
-
-from ast import parse
-
-# A dictionary mapping BOM to
-# the encoding to decode with, and what to set the
-# encoding attribute to.
-BOMS = {
-    BOM_UTF8: ('utf_8', None),
-    BOM_UTF16_BE: ('utf16_be', 'utf_16'),
-    BOM_UTF16_LE: ('utf16_le', 'utf_16'),
-    BOM_UTF16: ('utf_16', 'utf_16'),
-    }
-    
-# All legal variants of the BOM codecs.
-# TODO: the list of aliases is not meant to be exhaustive, is there a
-# better way ?
-BOM_LIST = {
-    'utf_16': 'utf_16',
-    'u16': 'utf_16',
-    'utf16': 'utf_16',
-    'utf-16': 'utf_16',
-    'utf16_be': 'utf16_be',
-    'utf_16_be': 'utf16_be',
-    'utf-16be': 'utf16_be',
-    'utf16_le': 'utf16_le',
-    'utf_16_le': 'utf16_le',
-    'utf-16le': 'utf16_le',
-    'utf_8': 'utf_8',
-    'u8': 'utf_8',
-    'utf': 'utf_8',
-    'utf8': 'utf_8',
-    'utf-8': 'utf_8',
-    }
-
-# Map of encodings to the BOM to write.
-BOM_SET = {
-    'utf_8': BOM_UTF8,
-    'utf_16': BOM_UTF16,
-    'utf16_be': BOM_UTF16_BE,
-    'utf16_le': BOM_UTF16_LE,
-    None: BOM_UTF8
-    }
-
-
-def match_utf8(encoding):
-    return BOM_LIST.get(encoding.lower()) == 'utf_8'
-
-# Quote strings used for writing values
-squot = "'%s'"
-dquot = '"%s"'
-noquot = "%s"
-wspace_plus = ' \r\n\v\t\'"'
-tsquot = '"""%s"""'
-tdquot = "'''%s'''"
-
-# Sentinel for use in getattr calls to replace hasattr
-MISSING = object()
-
-__version__ = '4.7.2'
-
-try:
-    any
-except NameError:
-    def any(iterable):
-        for entry in iterable:
-            if entry:
-                return True
-        return False
-
-__all__ = (
-    '__version__',
-    'DEFAULT_INDENT_TYPE',
-    'DEFAULT_INTERPOLATION',
-    'ConfigObjError',
-    'NestingError',
-    'ParseError',
-    'DuplicateError',
-    'ConfigspecError',
-    'ConfigObj',
-    'SimpleVal',
-    'InterpolationError',
-    'InterpolationLoopError',
-    'MissingInterpolationOption',
-    'RepeatSectionError',
-    'ReloadError',
-    'UnreprError',
-    'UnknownType',
-    'flatten_errors',
-    'get_extra_values'
-)
-
-DEFAULT_INTERPOLATION = 'configparser'
-DEFAULT_INDENT_TYPE = '    '
-MAX_INTERPOL_DEPTH = 10
-
-OPTION_DEFAULTS = {
-    'interpolation': True,
-    'raise_errors': False,
-    'list_values': True,
-    'create_empty': False,
-    'file_error': False,
-    'configspec': None,
-    'stringify': True,
-    # option may be set to one of ('', ' ', '\t')
-    'indent_type': None,
-    'encoding': None,
-    'default_encoding': None,
-    'unrepr': False,
-    'write_empty_values': False,
-}
-
-def getObj(s):
-    p = parse("a=" + s)
-    obj = p.body[0].value
-    return obj
-    
-class UnknownType(Exception):
-    pass
-
-class Builder(object):
-
-    def build(self, o):
-
-        m = getattr(self, 'build_' + o.__class__.__name__, None)
-        if m is None:
-            raise UnknownType(o.__class__.__name__)
-        return m(o)
-
-    def build_List(self, o):
-        return map(self.build, o.elts)
-    
-    def build_Num(self, o):
-        return o.n
-
-    def build_Str(str, o):
-        return o.s
-
-    def build_Dict(self, o):
-        d = {}
-        items = zip(o.keys, o.values)
-        for key, value in items:
-            key = self.build(key)
-            value = self.build(value)
-            d[key] = value
-        return d
-
-    def build_Tuple(self, o):
-        return tuple(self.build_List(o))
-
-    def build_Name(self, o):
-        value = o.id
-        if value == 'None':
-            return None
-        if value == 'True':
-            return True
-        if value == 'False':
-            return False
-
-        # An undefined Name
-        raise UnknownType('Undefined Name')
-
-_builder = Builder()
-
-def unrepr(s):
-    if not s:
-        return s
-    return _builder.build(getObj(s))
-    
-    
-class ConfigObjError(SyntaxError):
-    """
-    This is the base class for all errors that ConfigObj raises.
-    It is a subclass of SyntaxError.
-    """
-    def __init__(self, message='', line_number=None, line=''):
-        self.line = line
-        self.line_number = line_number
-        SyntaxError.__init__(self, message)
-
-
-class NestingError(ConfigObjError):
-    """
-    This error indicates a level of nesting that doesn't match.
-    """
-
-
-class ParseError(ConfigObjError):
-    """
-    This error indicates that a line is badly written.
-    It is neither a valid ``key = value`` line,
-    nor a valid section marker line.
-    """
-
-
-class ReloadError(IOError):
-    """
-    A 'reload' operation failed.
-    This exception is a subclass of ``IOError``.
-    """
-    def __init__(self):
-        IOError.__init__(self, 'reload failed, filename is not set.')
-
-
-class DuplicateError(ConfigObjError):
-    """
-    The keyword or section specified already exists.
-    """
-
-
-class ConfigspecError(ConfigObjError):
-    """
-    An error occured whilst parsing a configspec.
-    """
-
-
-class InterpolationError(ConfigObjError):
-    """Base class for the two interpolation errors."""
-
-
-class InterpolationLoopError(InterpolationError):
-    """Maximum interpolation depth exceeded in string interpolation."""
-
-    def __init__(self, option):
-        InterpolationError.__init__(
-            self,
-            'interpolation loop detected in value "%s".' % option)
-
-
-class RepeatSectionError(ConfigObjError):
-    """
-    This error indicates additional sections in a section with a
-    ``__many__`` (repeated) section.
-    """
-
-
-class MissingInterpolationOption(InterpolationError):
-    """A value specified for interpolation was missing."""
-    def __init__(self, option):
-        msg = 'missing option "%s" in interpolation.' % option
-        InterpolationError.__init__(self, msg)
-
-
-class UnreprError(ConfigObjError):
-    """An error parsing in unrepr mode."""
-
-
-class InterpolationEngine(object):
-    """
-    A helper class to help perform string interpolation.
-
-    This class is an abstract base class; its descendants perform
-    the actual work.
-    """
-
-    # compiled regexp to use in self.interpolate()
-    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
-    _cookie = '%'
-
-    def __init__(self, section):
-        # the Section instance that "owns" this engine
-        self.section = section
-
-
-    def interpolate(self, key, value):
-        # short-cut
-        if not self._cookie in value:
-            return value
-        
-        def recursive_interpolate(key, value, section, backtrail):
-            """The function that does the actual work.
-
-            ``value``: the string we're trying to interpolate.
-            ``section``: the section in which that string was found
-            ``backtrail``: a dict to keep track of where we've been,
-            to detect and prevent infinite recursion loops
-
-            This is similar to a depth-first-search algorithm.
-            """
-            # Have we been here already?
-            if (key, section.name) in backtrail:
-                # Yes - infinite loop detected
-                raise InterpolationLoopError(key)
-            # Place a marker on our backtrail so we won't come back here again
-            backtrail[(key, section.name)] = 1
-
-            # Now start the actual work
-            match = self._KEYCRE.search(value)
-            while match:
-                # The actual parsing of the match is implementation-dependent,
-                # so delegate to our helper function
-                k, v, s = self._parse_match(match)
-                if k is None:
-                    # That's the signal that no further interpolation is needed
-                    replacement = v
-                else:
-                    # Further interpolation may be needed to obtain final value
-                    replacement = recursive_interpolate(k, v, s, backtrail)
-                # Replace the matched string with its final value
-                start, end = match.span()
-                value = ''.join((value[:start], replacement, value[end:]))
-                new_search_start = start + len(replacement)
-                # Pick up the next interpolation key, if any, for next time
-                # through the while loop
-                match = self._KEYCRE.search(value, new_search_start)
-
-            # Now safe to come back here again; remove marker from backtrail
-            del backtrail[(key, section.name)]
-
-            return value
-
-        # Back in interpolate(), all we have to do is kick off the recursive
-        # function with appropriate starting values
-        value = recursive_interpolate(key, value, self.section, {})
-        return value
-
-
-    def _fetch(self, key):
-        """Helper function to fetch values from owning section.
-
-        Returns a 2-tuple: the value, and the section where it was found.
-        """
-        # switch off interpolation before we try and fetch anything !
-        save_interp = self.section.main.interpolation
-        self.section.main.interpolation = False
-
-        # Start at section that "owns" this InterpolationEngine
-        current_section = self.section
-        while True:
-            # try the current section first
-            val = current_section.get(key)
-            if val is not None and not isinstance(val, Section):
-                break
-            # try "DEFAULT" next
-            val = current_section.get('DEFAULT', {}).get(key)
-            if val is not None and not isinstance(val, Section):
-                break
-            # move up to parent and try again
-            # top-level's parent is itself
-            if current_section.parent is current_section:
-                # reached top level, time to give up
-                break
-            current_section = current_section.parent
-
-        # restore interpolation to previous value before returning
-        self.section.main.interpolation = save_interp
-        if val is None:
-            raise MissingInterpolationOption(key)
-        return val, current_section
-
-
-    def _parse_match(self, match):
-        """Implementation-dependent helper function.
-
-        Will be passed a match object corresponding to the interpolation
-        key we just found (e.g., "%(foo)s" or "$foo"). Should look up that
-        key in the appropriate config file section (using the ``_fetch()``
-        helper function) and return a 3-tuple: (key, value, section)
-
-        ``key`` is the name of the key we're looking for
-        ``value`` is the value found for that key
-        ``section`` is a reference to the section where it was found
-
-        ``key`` and ``section`` should be None if no further
-        interpolation should be performed on the resulting value
-        (e.g., if we interpolated "$$" and returned "$").
-        """
-        raise NotImplementedError()
-
-
-class ConfigParserInterpolation(InterpolationEngine):
-    """Behaves like ConfigParser."""
-    _cookie = '%'
-    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
-
-    def _parse_match(self, match):
-        key = match.group(1)
-        value, section = self._fetch(key)
-        return key, value, section
-
-
-class TemplateInterpolation(InterpolationEngine):
-    """Behaves like string.Template."""
-    _cookie = '$'
-    _delimiter = '$'
-    _KEYCRE = re.compile(r"""
-        \$(?:
-          (?P<escaped>\$)              |   # Two $ signs
-          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format
-          {(?P<braced>[^}]*)}              # ${name} format
-        )
-        """, re.IGNORECASE | re.VERBOSE)
-
-    def _parse_match(self, match):
-        # Valid name (in or out of braces): fetch value from section
-        key = match.group('named') or match.group('braced')
-        if key is not None:
-            value, section = self._fetch(key)
-            return key, value, section
-        # Escaped delimiter (e.g., $$): return single delimiter
-        if match.group('escaped') is not None:
-            # Return None for key and section to indicate it's time to stop
-            return None, self._delimiter, None
-        # Anything else: ignore completely, just return it unchanged
-        return None, match.group(), None
-
-
-interpolation_engines = {
-    'configparser': ConfigParserInterpolation,
-    'template': TemplateInterpolation,
-}
-
-def __newobj__(cls, *args):
-    # Hack for pickle
-    return cls.__new__(cls, *args)
-    
-class Section(dict):
-    """
-    A dictionary-like object that represents a section in a config file.
-
-    It does string interpolation if the 'interpolation' attribute
-    of the 'main' object is set to True.
-
-    Interpolation is tried first from this object, then from the 'DEFAULT'
-    section of this object, next from the parent and its 'DEFAULT' section,
-    and so on until the main object is reached.
-
-    A Section will behave like an ordered dictionary - following the
-    order of the ``scalars`` and ``sections`` attributes.
-    You can use this to change the order of members.
-
-    Iteration follows the order: scalars, then sections.
-    """
-
-    def __setstate__(self, state):
-        dict.update(self, state[0])
-        self.__dict__.update(state[1])
-    
-    def __reduce__(self):
-        state = (dict(self), self.__dict__)
-        return (__newobj__, (self.__class__,), state)
-
-    def __init__(self, parent, depth, main, indict=None, name=None):
-        """
-        * parent is the section above
-        * depth is the depth level of this section
-        * main is the main ConfigObj
-        * indict is a dictionary to initialise the section with
-        """
-        if indict is None:
-            indict = {}
-        dict.__init__(self)
-        # used for nesting level *and* interpolation
-        self.parent = parent
-        # used for the interpolation attribute
-        self.main = main
-        # level of nesting depth of this Section
-        self.depth = depth
-        # purely for information
-        self.name = name
-        #
-        self._initialise()
-        # we do this explicitly so that __setitem__ is used properly
-        # (rather than just passing to ``dict.__init__``)
-        for entry, value in list(indict.items()):
-            self[entry] = value
-
-    def _initialise(self):
-        # the sequence of scalar values in this Section
-        self.scalars = []
-        # the sequence of sections in this Section
-        self.sections = []
-        # for comments :-)
-        self.comments = {}
-        self.inline_comments = {}
-        # the configspec
-        self.configspec = None
-        # for defaults
-        self.defaults = []
-        self.default_values = {}
-        self.extra_values = []
-        self._created = False
-
-    def _interpolate(self, key, value):
-        try:
-            # do we already have an interpolation engine?
-            engine = self._interpolation_engine
-        except AttributeError:
-            # not yet: first time running _interpolate(), so pick the engine
-            name = self.main.interpolation
-            if name == True:  # note that "if name:" would be incorrect here
-                # backwards-compatibility: interpolation=True means use default
-                name = DEFAULT_INTERPOLATION
-            name = name.lower()  # so that "Template", "template", etc. all work
-            class_ = interpolation_engines.get(name, None)
-            if class_ is None:
-                # invalid value for self.main.interpolation
-                self.main.interpolation = False
-                return value
-            else:
-                # save reference to engine so we don't have to do this again
-                engine = self._interpolation_engine = class_(self)
-        # let the engine do the actual work
-        return engine.interpolate(key, value)
-
-    def __getitem__(self, key):
-        """Fetch the item and do string interpolation."""
-        val = dict.__getitem__(self, key)
-        if self.main.interpolation: 
-            if isinstance(val, str):
-                return self._interpolate(key, val)
-            if isinstance(val, list):
-                def _check(entry):
-                    if isinstance(entry, str):
-                        return self._interpolate(key, entry)
-                    return entry
-                new = [_check(entry) for entry in val]
-                if new != val:
-                    return new
-        return val
-
-    def __setitem__(self, key, value, unrepr=False):
-        """
-        Correctly set a value.
-        
-        Making dictionary values Section instances.
-        (We have to special case 'Section' instances - which are also dicts)
-        
-        Keys must be strings.
-        Values need only be strings (or lists of strings) if
-        ``main.stringify`` is set.
-        
-        ``unrepr`` must be set when setting a value to a dictionary, without
-        creating a new sub-section.
-        """
-        if not isinstance(key, str):
-            raise ValueError('The key "%s" is not a string.' % key)
-        
-        # add the comment
-        if key not in self.comments:
-            self.comments[key] = []
-            self.inline_comments[key] = ''
-        # remove the entry from defaults
-        if key in self.defaults:
-            self.defaults.remove(key)
-        #
-        if isinstance(value, Section):
-            if key not in self:
-                self.sections.append(key)
-            dict.__setitem__(self, key, value)
-        elif isinstance(value, dict) and not unrepr:
-            # First create the new depth level,
-            # then create the section
-            if key not in self:
-                self.sections.append(key)
-            new_depth = self.depth + 1
-            dict.__setitem__(
-                self,
-                key,
-                Section(
-                    self,
-                    new_depth,
-                    self.main,
-                    indict=value,
-                    name=key))
-        else:
-            if key not in self:
-                self.scalars.append(key)
-            if not self.main.stringify:
-                if isinstance(value, str):
-                    pass
-                elif isinstance(value, (list, tuple)):
-                    for entry in value:
-                        if not isinstance(entry, str):
-                            raise TypeError('Value is not a string "%s".' % entry)
-                else:
-                    raise TypeError('Value is not a string "%s".' % value)
-            dict.__setitem__(self, key, value)
-
-
-    def __delitem__(self, key):
-        """Remove items from the sequence when deleting."""
-        dict. __delitem__(self, key)
-        if key in self.scalars:
-            self.scalars.remove(key)
-        else:
-            self.sections.remove(key)
-        del self.comments[key]
-        del self.inline_comments[key]
-
-    def get(self, key, default=None):
-        """A version of ``get`` that doesn't bypass string interpolation."""
-        try:
-            return self[key]
-        except KeyError:
-            return default
-
-
-    def update(self, indict):
-        """
-        A version of update that uses our ``__setitem__``.
-        """
-        for entry in indict:
-            self[entry] = indict[entry]
-
-
-    def pop(self, key, default=MISSING):
-        """
-        'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-        If key is not found, d is returned if given, otherwise KeyError is raised'
-        """
-        try:
-            val = self[key]
-        except KeyError:
-            if default is MISSING:
-                raise
-            val = default
-        else:
-            del self[key]
-        return val
-
-    def popitem(self):
-        """Pops the first (key,val)"""
-        sequence = (self.scalars + self.sections)
-        if not sequence:
-            raise KeyError(": 'popitem(): dictionary is empty'")
-        key = sequence[0]
-        val =  self[key]
-        del self[key]
-        return key, val
-    
-    def clear(self):
-        """
-        A version of clear that also affects scalars/sections
-        Also clears comments and configspec.
-        
-        Leaves other attributes alone :
-            depth/main/parent are not affected
-        """
-        dict.clear(self)
-        self.scalars = []
-        self.sections = []
-        self.comments = {}
-        self.inline_comments = {}
-        self.configspec = None
-        self.defaults = []
-        self.extra_values = []
-
-
-    def setdefault(self, key, default=None):
-        """A version of setdefault that sets sequence if appropriate."""
-        try:
-            return self[key]
-        except KeyError:
-            self[key] = default
-            return self[key]
-
-
-    def items(self):
-        """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
-        return list(zip((self.scalars + self.sections), list(self.values())))
-
-
-    def keys(self):
-        """D.keys() -> list of D's keys"""
-        return (self.scalars + self.sections)
-
-
-    def values(self):
-        """D.values() -> list of D's values"""
-        return [self[key] for key in (self.scalars + self.sections)]
-
-
-    def iteritems(self):
-        """D.iteritems() -> an iterator over the (key, value) items of D"""
-        return iter(list(self.items()))
-
-
-    def iterkeys(self):
-        """D.iterkeys() -> an iterator over the keys of D"""
-        return iter((self.scalars + self.sections))
-
-    __iter__ = iterkeys
-
-
-    def itervalues(self):
-        """D.itervalues() -> an iterator over the values of D"""
-        return iter(list(self.values()))
-
-
-    def __repr__(self):
-        """x.__repr__() <==> repr(x)"""
-        def _getval(key):
-            try:
-                return self[key]
-            except MissingInterpolationOption:
-                return dict.__getitem__(self, key)
-        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key))))
-            for key in (self.scalars + self.sections)])
-
-    __str__ = __repr__
-    __str__.__doc__ = "x.__str__() <==> str(x)"
-
-
-    # Extra methods - not in a normal dictionary
-
-    def dict(self):
-        """
-        Return a deepcopy of self as a dictionary.
-        
-        All members that are ``Section`` instances are recursively turned to
-        ordinary dictionaries - by calling their ``dict`` method.
-        
-        >>> n = a.dict()
-        >>> n == a
-        1
-        >>> n is a
-        0
-        """
-        newdict = {}
-        for entry in self:
-            this_entry = self[entry]
-            if isinstance(this_entry, Section):
-                this_entry = this_entry.dict()
-            elif isinstance(this_entry, list):
-                # create a copy rather than a reference
-                this_entry = list(this_entry)
-            elif isinstance(this_entry, tuple):
-                # create a copy rather than a reference
-                this_entry = tuple(this_entry)
-            newdict[entry] = this_entry
-        return newdict
-
-
-    def merge(self, indict):
-        """
-        A recursive update - useful for merging config files.
-        
-        >>> a = '''[section1]
-        ...     option1 = True
-        ...     [[subsection]]
-        ...     more_options = False
-        ...     # end of file'''.splitlines()
-        >>> b = '''# File is user.ini
-        ...     [section1]
-        ...     option1 = False
-        ...     # end of file'''.splitlines()
-        >>> c1 = ConfigObj(b)
-        >>> c2 = ConfigObj(a)
-        >>> c2.merge(c1)
-        >>> c2
-        ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}})
-        """
-        for key, val in list(indict.items()):
-            if (key in self and isinstance(self[key], dict) and
-                                isinstance(val, dict)):
-                self[key].merge(val)
-            else:   
-                self[key] = val
-
-
-    def rename(self, oldkey, newkey):
-        """
-        Change a keyname to another, without changing position in sequence.
-        
-        Implemented so that transformations can be made on keys,
-        as well as on values. (used by encode and decode)
-        
-        Also renames comments.
-        """
-        if oldkey in self.scalars:
-            the_list = self.scalars
-        elif oldkey in self.sections:
-            the_list = self.sections
-        else:
-            raise KeyError('Key "%s" not found.' % oldkey)
-        pos = the_list.index(oldkey)
-        #
-        val = self[oldkey]
-        dict.__delitem__(self, oldkey)
-        dict.__setitem__(self, newkey, val)
-        the_list.remove(oldkey)
-        the_list.insert(pos, newkey)
-        comm = self.comments[oldkey]
-        inline_comment = self.inline_comments[oldkey]
-        del self.comments[oldkey]
-        del self.inline_comments[oldkey]
-        self.comments[newkey] = comm
-        self.inline_comments[newkey] = inline_comment
-    
-    def walk(self, function, raise_errors=True,
-            call_on_sections=False, **keywargs):
-        """
-        Walk every member and call a function on the keyword and value.
-        
-        Return a dictionary of the return values
-        
-        If the function raises an exception, raise the errror
-        unless ``raise_errors=False``, in which case set the return value to
-        ``False``.
-        
-        Any unrecognised keyword arguments you pass to walk, will be pased on
-        to the function you pass in.
-        
-        Note: if ``call_on_sections`` is ``True`` then - on encountering a
-        subsection, *first* the function is called for the *whole* subsection,
-        and then recurses into it's members. This means your function must be
-        able to handle strings, dictionaries and lists. This allows you
-        to change the key of subsections as well as for ordinary members. The
-        return value when called on the whole subsection has to be discarded.
-        
-        See  the encode and decode methods for examples, including functions.
-        
-        .. admonition:: caution
-        
-            You can use ``walk`` to transform the names of members of a section
-            but you mustn't add or delete members.
-        
-        >>> config = '''[XXXXsection]
-        ... XXXXkey = XXXXvalue'''.splitlines()
-        >>> cfg = ConfigObj(config)
-        >>> cfg
-        ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
-        >>> def transform(section, key):
-        ...     val = section[key]
-        ...     newkey = key.replace('XXXX', 'CLIENT1')
-        ...     section.rename(key, newkey)
-        ...     if isinstance(val, (tuple, list, dict)):
-        ...         pass
-        ...     else:
-        ...         val = val.replace('XXXX', 'CLIENT1')
-        ...         section[newkey] = val
-        >>> cfg.walk(transform, call_on_sections=True)
-        {'CLIENT1section': {'CLIENT1key': None}}
-        >>> cfg
-        ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}})
-        """
-        out = {}
-        # scalars first
-        for i in range(len(self.scalars)):
-            entry = self.scalars[i]
-            try:
-                val = function(self, entry, **keywargs)
-                # bound again in case name has changed
-                entry = self.scalars[i]
-                out[entry] = val
-            except Exception:
-                if raise_errors:
-                    raise
-                else:
-                    entry = self.scalars[i]
-                    out[entry] = False
-        # then sections
-        for i in range(len(self.sections)):
-            entry = self.sections[i]
-            if call_on_sections:
-                try:
-                    function(self, entry, **keywargs)
-                except Exception:
-                    if raise_errors:
-                        raise
-                    else:
-                        entry = self.sections[i]
-                        out[entry] = False
-                # bound again in case name has changed
-                entry = self.sections[i]
-            # previous result is discarded
-            out[entry] = self[entry].walk(
-                function,
-                raise_errors=raise_errors,
-                call_on_sections=call_on_sections,
-                **keywargs)
-        return out
-    
-    def as_bool(self, key):
-        """
-        Accepts a key as input. The corresponding value must be a string or
-        the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
-        retain compatibility with Python 2.2.
-        
-        If the string is one of  ``True``, ``On``, ``Yes``, or ``1`` it returns 
-        ``True``.
-        
-        If the string is one of  ``False``, ``Off``, ``No``, or ``0`` it returns 
-        ``False``.
-        
-        ``as_bool`` is not case sensitive.
-        
-        Any other input will raise a ``ValueError``.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_bool('a')
-        Traceback (most recent call last):
-        ValueError: Value "fish" is neither True nor False
-        >>> a['b'] = 'True'
-        >>> a.as_bool('b')
-        1
-        >>> a['b'] = 'off'
-        >>> a.as_bool('b')
-        0
-        """
-        val = self[key]
-        if val == True:
-            return True
-        elif val == False:
-            return False
-        else:
-            try:
-                if not isinstance(val, str):
-                    # TODO: Why do we raise a KeyError here?
-                    raise KeyError()
-                else:
-                    return self.main._bools[val.lower()]
-            except KeyError:
-                raise ValueError('Value "%s" is neither True nor False' % val)
-    
-    def as_int(self, key):
-        """
-        A convenience method which coerces the specified value to an integer.
-        
-        If the value is an invalid literal for ``int``, a ``ValueError`` will
-        be raised.
-        
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_int('a')
-        Traceback (most recent call last):
-        ValueError: invalid literal for int() with base 10: 'fish'
-        >>> a['b'] = '1'
-        >>> a.as_int('b')
-        1
-        >>> a['b'] = '3.2'
-        >>> a.as_int('b')
-        Traceback (most recent call last):
-        ValueError: invalid literal for int() with base 10: '3.2'
-        """
-        return int(self[key])
-    
-    def as_float(self, key):
-        """
-        A convenience method which coerces the specified value to a float.
-
-        If the value is an invalid literal for ``float``, a ``ValueError`` will
-        be raised.
-
-        >>> a = ConfigObj()
-        >>> a['a'] = 'fish'
-        >>> a.as_float('a')
-        Traceback (most recent call last):
-        ValueError: invalid literal for float(): fish
-        >>> a['b'] = '1'
-        >>> a.as_float('b')
-        1.0
-        >>> a['b'] = '3.2'
-        >>> a.as_float('b')
-        3.2000000000000002
-        """
-        return float(self[key])
-
-    def as_list(self, key):
-        """
-        A convenience method which fetches the specified value, guaranteeing
-        that it is a list.
-
-        >>> a = ConfigObj()
-        >>> a['a'] = 1
-        >>> a.as_list('a')
-        [1]
-        >>> a['a'] = (1,)
-        >>> a.as_list('a')
-        [1]
-        >>> a['a'] = [1]
-        >>> a.as_list('a')
-        [1]
-        """
-        result = self[key]
-        if isinstance(result, (tuple, list)):
-            return list(result)
-        return [result]
-
-    def restore_default(self, key):
-        """
-        Restore (and return) default value for the specified key.
-
-        This method will only work for a ConfigObj that was created
-        with a configspec and has been validated.
-
-        If there is no default value for this key, ``KeyError`` is raised.
-        """
-        default = self.default_values[key]
-        dict.__setitem__(self, key, default)
-        if key not in self.defaults:
-            self.defaults.append(key)
-        return default
-
-    def restore_defaults(self):
-        """
-        Recursively restore default values to all members
-        that have them.
-
-        This method will only work for a ConfigObj that was created
-        with a configspec and has been validated.
-
-        It doesn't delete or modify entries without default values.
-        """
-        for key in self.default_values:
-            self.restore_default(key)
-
-        for section in self.sections:
-            self[section].restore_defaults()
-
-
-class ConfigObj(Section):
-    """An object to read, create, and write config files."""
-
-    _keyword = re.compile(r'''^ # line start
-        (\s*)                   # indentation
-        (                       # keyword
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'"=].*?)       # no quotes
-        )
-        \s*=\s*                 # divider
-        (.*)                    # value (including list values and comments)
-        $   # line end
-        ''',
-        re.VERBOSE)
-
-    _sectionmarker = re.compile(r'''^
-        (\s*)                     # 1: indentation
-        ((?:\[\s*)+)              # 2: section marker open
-        (                         # 3: section name open
-            (?:"\s*\S.*?\s*")|    # at least one non-space with double quotes
-            (?:'\s*\S.*?\s*')|    # at least one non-space with single quotes
-            (?:[^'"\s].*?)        # at least one non-space unquoted
-        )                         # section name close
-        ((?:\s*\])+)              # 4: section marker close
-        \s*(\#.*)?                # 5: optional comment
-        $''',
-        re.VERBOSE)
-
-    # this regexp pulls list values out as a single string
-    # or single values and comments
-    # FIXME: this regex adds a '' to the end of comma terminated lists
-    #   workaround in ``_handle_value``
-    _valueexp = re.compile(r'''^
-        (?:
-            (?:
-                (
-                    (?:
-                        (?:
-                            (?:".*?")|              # double quotes
-                            (?:'.*?')|              # single quotes
-                            (?:[^'",\#][^,\#]*?)    # unquoted
-                        )
-                        \s*,\s*                     # comma
-                    )*      # match all list items ending in a comma (if any)
-                )
-                (
-                    (?:".*?")|                      # double quotes
-                    (?:'.*?')|                      # single quotes
-                    (?:[^'",\#\s][^,]*?)|           # unquoted
-                    (?:(?<!,))                      # Empty value
-                )?          # last item in a list - or string value
-            )|
-            (,)             # alternatively a single comma - empty list
-        )
-        \s*(\#.*)?          # optional comment
-        $''',
-        re.VERBOSE)
-
-    # use findall to get the members of a list value
-    _listvalueexp = re.compile(r'''
-        (
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'",\#]?.*?)       # unquoted
-        )
-        \s*,\s*                 # comma
-        ''',
-        re.VERBOSE)
-
-    # this regexp is used for the value
-    # when lists are switched off
-    _nolistvalue = re.compile(r'''^
-        (
-            (?:".*?")|          # double quotes
-            (?:'.*?')|          # single quotes
-            (?:[^'"\#].*?)|     # unquoted
-            (?:)                # Empty value
-        )
-        \s*(\#.*)?              # optional comment
-        $''',
-        re.VERBOSE)
-
-    # regexes for finding triple quoted values on one line
-    _single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")
-    _single_line_double = re.compile(r'^"""(.*?)"""\s*(#.*)?$')
-    _multi_line_single = re.compile(r"^(.*?)'''\s*(#.*)?$")
-    _multi_line_double = re.compile(r'^(.*?)"""\s*(#.*)?$')
-
-    _triple_quote = {
-        "'''": (_single_line_single, _multi_line_single),
-        '"""': (_single_line_double, _multi_line_double),
-    }
-
-    # Used by the ``istrue`` Section method
-    _bools = {
-        'yes': True, 'no': False,
-        'on': True, 'off': False,
-        '1': True, '0': False,
-        'true': True, 'false': False,
-        }
-
-    def __init__(self, infile=None, options=None, configspec=None, encoding=None,
-                 interpolation=True, raise_errors=False, list_values=True,
-                 create_empty=False, file_error=False, stringify=True,
-                 indent_type=None, default_encoding=None, unrepr=False,
-                 write_empty_values=False, _inspec=False):
-        """
-        Parse a config file or create a config file object.
-        
-        ``ConfigObj(infile=None, configspec=None, encoding=None,
-                    interpolation=True, raise_errors=False, list_values=True,
-                    create_empty=False, file_error=False, stringify=True,
-                    indent_type=None, default_encoding=None, unrepr=False,
-                    write_empty_values=False, _inspec=False)``
-        """
-        self._inspec = _inspec
-        # init the superclass
-        Section.__init__(self, self, 0, self)
-        
-        infile = infile or []
-        
-        _options = {'configspec': configspec,
-                    'encoding': encoding, 'interpolation': interpolation,
-                    'raise_errors': raise_errors, 'list_values': list_values,
-                    'create_empty': create_empty, 'file_error': file_error,
-                    'stringify': stringify, 'indent_type': indent_type,
-                    'default_encoding': default_encoding, 'unrepr': unrepr,
-                    'write_empty_values': write_empty_values}
-
-        if options is None:
-            options = _options
-        else:
-            import warnings
-            warnings.warn('Passing in an options dictionary to ConfigObj() is '
-                          'deprecated. Use **options instead.',
-                          DeprecationWarning, stacklevel=2)
-            
-            # TODO: check the values too.
-            for entry in options:
-                if entry not in OPTION_DEFAULTS:
-                    raise TypeError('Unrecognised option "%s".' % entry)
-            for entry, value in list(OPTION_DEFAULTS.items()):
-                if entry not in options:
-                    options[entry] = value
-                keyword_value = _options[entry]
-                if value != keyword_value:
-                    options[entry] = keyword_value
-        
-        # XXXX this ignores an explicit list_values = True in combination
-        # with _inspec. The user should *never* do that anyway, but still...
-        if _inspec:
-            options['list_values'] = False
-        
-        self._initialise(options)
-        configspec = options['configspec']
-        self._original_configspec = configspec
-        self._load(infile, configspec)
-    
-    def _load(self, infile, configspec):
-
-        if isinstance(infile, str):
-            self.filename = infile
-            if os.path.isfile(infile):
-                h = open(infile, 'rb')
-                infile = h.read() or []
-                h.close()
-            elif self.file_error:
-                # raise an error if the file doesn't exist
-                raise IOError('Config file not found: "%s".' % self.filename)
-            else:
-                # file doesn't already exist
-                if self.create_empty:
-                    # this is a good test that the filename specified
-                    # isn't impossible - like on a non-existent device
-                    h = open(infile, 'w')
-                    h.write('')
-                    h.close()
-                infile = []        
-        elif isinstance(infile, (list, tuple)):
-            infile = list(infile)
-        elif isinstance(infile, dict):
-            # initialise self
-            # the Section class handles creating subsections
-            if isinstance(infile, ConfigObj):
-                # get a copy of our ConfigObj
-                def set_section(in_section, this_section):
-                    for entry in in_section.scalars:
-                        this_section[entry] = in_section[entry]
-                    for section in in_section.sections:
-                        this_section[section] = {}
-                        set_section(in_section[section], this_section[section])
-                set_section(infile, self)
-                
-            else:
-                for entry in infile:
-                    self[entry] = infile[entry]
-            del self._errors
-            
-            if configspec is not None:
-                self._handle_configspec(configspec)
-            else:
-                self.configspec = None
-            return
-        
-        elif getattr(infile, 'read', MISSING) is not MISSING:
-            # This supports file like objects
-            infile = infile.read() or []
-            # needs splitting into lines - but needs doing *after* decoding
-            # in case it's not an 8 bit encoding
-        else:
-            raise TypeError('infile must be a filename, file like object, or list of lines.')
-        
-        if infile:
-            # don't do it for the empty ConfigObj
-            infile = self._handle_bom(infile)
-            # infile is now *always* a list
-            #
-            # Set the newlines attribute (first line ending it finds)
-            # and strip trailing '\n' or '\r' from lines
-            for line in infile:
-                if (not line) or (line[-1] not in ('\r', '\n', '\r\n')):
-                    continue
-                for end in ('\r\n', '\n', '\r'):
-                    if line.endswith(end):
-                        self.newlines = end
-                        break
-                break
-
-            infile = [line.rstrip('\r\n') for line in infile]
-
-            
-        self._parse(infile)
-        # if we had any errors, now is the time to raise them
-        if self._errors:
-            info = "at line %s." % self._errors[0].line_number
-            if len(self._errors) > 1:
-                msg = "Parsing failed with several errors.\nFirst error %s" % info
-                error = ConfigObjError(msg)
-            else:
-                error = self._errors[0]
-            # set the errors attribute; it's a list of tuples:
-            # (error_type, message, line_number)
-            error.errors = self._errors
-            # set the config attribute
-            error.config = self
-            raise error
-        # delete private attributes
-        del self._errors
-        
-        if configspec is None:
-            self.configspec = None
-        else:
-            self._handle_configspec(configspec)
-    
-    def _initialise(self, options=None):
-        if options is None:
-            options = OPTION_DEFAULTS
-            
-        # initialise a few variables
-        self.filename = None
-        self._errors = []
-        self.raise_errors = options['raise_errors']
-        self.interpolation = options['interpolation']
-        self.list_values = options['list_values']
-        self.create_empty = options['create_empty']
-        self.file_error = options['file_error']
-        self.stringify = options['stringify']
-        self.indent_type = options['indent_type']
-        self.encoding = options['encoding']
-        self.default_encoding = options['default_encoding']
-        self.BOM = False
-        self.newlines = None
-        self.write_empty_values = options['write_empty_values']
-        self.unrepr = options['unrepr']
-        
-        self.initial_comment = []
-        self.final_comment = []
-        self.configspec = None
-        
-        if self._inspec:
-            self.list_values = False
-        
-        # Clear section attributes as well
-        Section._initialise(self)
-    
-    def __repr__(self):
-        def _getval(key):
-            try:
-                return self[key]
-            except MissingInterpolationOption:
-                return dict.__getitem__(self, key)
-        return ('ConfigObj({%s})' % 
-                ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) 
-                for key in (self.scalars + self.sections)]))
-    
-    def _handle_bom(self, infile):
-        """
-        Handle any BOM, and decode if necessary.
-        
-        If an encoding is specified, that *must* be used - but the BOM should
-        still be removed (and the BOM attribute set).
-        
-        (If the encoding is wrongly specified, then a BOM for an alternative
-        encoding won't be discovered or removed.)
-        
-        If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
-        removed. The BOM attribute will be set. UTF16 will be decoded to
-        unicode.
-        
-        NOTE: This method must not be called with an empty ``infile``.
-        
-        Specifying the *wrong* encoding is likely to cause a
-        ``UnicodeDecodeError``.
-        
-        ``infile`` must always be returned as a list of lines, but may be
-        passed in as a single string.
-        """
-        if ((self.encoding is not None) and
-            (self.encoding.lower() not in BOM_LIST)):
-            # No need to check for a BOM
-            # the encoding specified doesn't have one
-            # just decode
-            return self._decode(infile, self.encoding)
-        
-        if isinstance(infile, (list, tuple)):
-            line = infile[0]
-        else:
-            line = infile
-        if self.encoding is not None:
-            # encoding explicitly supplied
-            # And it could have an associated BOM
-            # TODO: if encoding is just UTF16 - we ought to check for both
-            # TODO: big endian and little endian versions.
-            enc = BOM_LIST[self.encoding.lower()]
-            if enc == 'utf_16':
-                # For UTF16 we try big endian and little endian
-                for BOM, (encoding, final_encoding) in list(BOMS.items()):
-                    if not final_encoding:
-                        # skip UTF8
-                        continue
-                    if isinstance(infile, bytes) and infile.startswith(BOM):
-                        ### BOM discovered
-                        ##self.BOM = True
-                        # Don't need to remove BOM
-                        return self._decode(infile, encoding)
-                    
-                # If we get this far, will *probably* raise a DecodeError
-                # As it doesn't appear to start with a BOM
-                return self._decode(infile, self.encoding)
-            
-            # Must be UTF8
-            BOM = BOM_SET[enc]
-            if isinstance(line, bytes) and not line.startswith(BOM):
-                return self._decode(infile, self.encoding)
-            
-            newline = line[len(BOM):]
-            
-            # BOM removed
-            if isinstance(infile, (list, tuple)):
-                infile[0] = newline
-            else:
-                infile = newline
-            self.BOM = True
-            return self._decode(infile, self.encoding)
-        
-        # No encoding specified - so we need to check for UTF8/UTF16
-        for BOM, (encoding, final_encoding) in list(BOMS.items()):
-            if isinstance(line, bytes) and not line.startswith(BOM):
-                continue
-            else:
-                # BOM discovered
-                # self.encoding = final_encoding
-                if not final_encoding:
-                    self.BOM = True
-                    # UTF8
-                    # remove BOM
-                    newline = line[len(BOM):]
-                    if isinstance(infile, (list, tuple)):
-                        infile[0] = newline
-                    else:
-                        infile = newline
-                    # UTF8 - don't decode
-                    if isinstance(infile, str):
-                        return infile.splitlines(True)
-                    else:
-                        return infile
-                
-                infile = self._decode(infile, encoding)
-                if isinstance(infile, str):
-                    # infile read from a file will be a single string
-                    return infile.splitlines(True)
-                return self._decode(infile, encoding)
-                # UTF16 - have to decode
-
-            
-        # No BOM discovered and no encoding specified, just return
-        if isinstance(infile, str):
-            # infile read from a file will be a single string
-            return infile.splitlines(True)
-        
-        if isinstance(infile, bytes):
-            return self._decode(infile, self.encoding)
-        return infile
-
-    def _decode(self, infile, encoding):
-        """
-        Decode infile to unicode. Using the specified encoding.
-
-        if is a string, it also needs converting to a list.
-        """
-        
-        encoding = encoding or 'utf-8'
-        
-        # If `infile` is a Unicode string, return as such
-        if isinstance(infile, str):
-            return infile
-            
-        # If `infile` is bytes type; decode and split
-        if isinstance(infile, bytes):
-            return infile.decode(encoding).splitlines(True)
-
-        # If `infile` is a mix of bytes and unicode strings
-        for i, line in enumerate(infile):
-            if isinstance(line, bytes):
-                infile[i] = line.decode(encoding)
-        return infile
-    
-    def _decode_element(self, line):
-        """Decode element to unicode if necessary."""
-        if not self.encoding:
-            return line
-        if isinstance(line, bytes) and self.default_encoding:
-            return line.decode(self.default_encoding)
-        return line
-
-    def _str(self, value):
-        """
-        Used by ``stringify`` within validate, to turn non-string values
-        into strings.
-        """
-        
-        # Bytes type string should NOT be stringified at any cost.
-        if isinstance(value, bytes):
-            return value
-        if not isinstance(value, str):
-            return str(value)
-        else:
-            return value
-
-    def _parse(self, infile):
-        """Actually parse the config file."""
-        
-        temp_list_values = self.list_values
-        if self.unrepr:
-            self.list_values = False
-            
-        comment_list = []
-        done_start = False
-        this_section = self
-        maxline = len(infile) - 1
-        cur_index = -1
-        reset_comment = False
-        
-        while cur_index < maxline:
-            if reset_comment:
-                comment_list = []
-            cur_index += 1
-            line = infile[cur_index]
-            sline = line.strip()
-            # do we have anything on the line ?
-            if not sline or sline.startswith('#'):
-                reset_comment = False
-                comment_list.append(line)
-                continue
-            
-            if not done_start:
-                # preserve initial comment
-                self.initial_comment = comment_list
-                comment_list = []
-                done_start = True
-                
-            reset_comment = True
-            # first we check if it's a section marker
-            mat = self._sectionmarker.match(line)
-            if mat is not None:
-                # is a section line
-                (indent, sect_open, sect_name, sect_close, comment) = mat.groups()
-                if indent and (self.indent_type is None):
-                    self.indent_type = indent
-                cur_depth = sect_open.count('[')
-                if cur_depth != sect_close.count(']'):
-                    self._handle_error("Cannot compute the section depth at line %s.",
-                                       NestingError, infile, cur_index)
-                    continue
-                
-                if cur_depth < this_section.depth:
-                    # the new section is dropping back to a previous level
-                    try:
-                        parent = self._match_depth(this_section,
-                                                   cur_depth).parent
-                    except SyntaxError:
-                        self._handle_error("Cannot compute nesting level at line %s.",
-                                           NestingError, infile, cur_index)
-                        continue
-                elif cur_depth == this_section.depth:
-                    # the new section is a sibling of the current section
-                    parent = this_section.parent
-                elif cur_depth == this_section.depth + 1:
-                    # the new section is a child the current section
-                    parent = this_section
-                else:
-                    self._handle_error("Section too nested at line %s.",
-                                       NestingError, infile, cur_index)
-                    
-                sect_name = self._unquote(sect_name)
-                if sect_name in parent:
-                    self._handle_error('Duplicate section name at line %s.',
-                                       DuplicateError, infile, cur_index)
-                    continue
-                
-                # create the new section
-                this_section = Section(
-                    parent,
-                    cur_depth,
-                    self,
-                    name=sect_name)
-                parent[sect_name] = this_section
-                parent.inline_comments[sect_name] = comment
-                parent.comments[sect_name] = comment_list
-                continue
-            #
-            # it's not a section marker,
-            # so it should be a valid ``key = value`` line
-            mat = self._keyword.match(line)
-            if mat is None:
-                # it neither matched as a keyword
-                # or a section marker
-                self._handle_error(
-                    'Invalid line at line "%s".',
-                    ParseError, infile, cur_index)
-            else:
-                # is a keyword value
-                # value will include any inline comment
-                (indent, key, value) = mat.groups()
-                if indent and (self.indent_type is None):
-                    self.indent_type = indent
-                # check for a multiline value
-                if value[:3] in ['"""', "'''"]:
-                    try:
-                        value, comment, cur_index = self._multiline(
-                            value, infile, cur_index, maxline)
-                    except SyntaxError:
-                        self._handle_error(
-                            'Parse error in value at line %s.',
-                            ParseError, infile, cur_index)
-                        continue
-                    else:
-                        if self.unrepr:
-                            comment = ''
-                            try:
-                                value = unrepr(value)
-                            except Exception as e:
-                                if type(e) == UnknownType:
-                                    msg = 'Unknown name or type in value at line %s.'
-                                else:
-                                    msg = 'Parse error in value at line %s.'
-                                self._handle_error(msg, UnreprError, infile,
-                                    cur_index)
-                                continue
-                else:
-                    if self.unrepr:
-                        comment = ''
-                        try:
-                            value = unrepr(value)
-                        except Exception as e:
-                            if isinstance(e, UnknownType):
-                                msg = 'Unknown name or type in value at line %s.'
-                            else:
-                                msg = 'Parse error in value at line %s.'
-                            self._handle_error(msg, UnreprError, infile,
-                                cur_index)
-                            continue
-                    else:
-                        # extract comment and lists
-                        try:
-                            (value, comment) = self._handle_value(value)
-                        except SyntaxError:
-                            self._handle_error(
-                                'Parse error in value at line %s.',
-                                ParseError, infile, cur_index)
-                            continue
-                #
-                key = self._unquote(key)
-                if key in this_section:
-                    self._handle_error(
-                        'Duplicate keyword name at line %s.',
-                        DuplicateError, infile, cur_index)
-                    continue
-                # add the key.
-                # we set unrepr because if we have got this far we will never
-                # be creating a new section
-                this_section.__setitem__(key, value, unrepr=True)
-                this_section.inline_comments[key] = comment
-                this_section.comments[key] = comment_list
-                continue
-        #
-        if self.indent_type is None:
-            # no indentation used, set the type accordingly
-            self.indent_type = ''
-
-        # preserve the final comment
-        if not self and not self.initial_comment:
-            self.initial_comment = comment_list
-        elif not reset_comment:
-            self.final_comment = comment_list
-        self.list_values = temp_list_values
-    
-    def _match_depth(self, sect, depth):
-        """
-        Given a section and a depth level, walk back through the sections
-        parents to see if the depth level matches a previous section.
-        
-        Return a reference to the right section,
-        or raise a SyntaxError.
-        """
-        while depth < sect.depth:
-            if sect is sect.parent:
-                # we've reached the top level already
-                raise SyntaxError()
-            sect = sect.parent
-        if sect.depth == depth:
-            return sect
-        # shouldn't get here
-        raise SyntaxError()
-    
-    def _handle_error(self, text, ErrorClass, infile, cur_index):
-        """
-        Handle an error according to the error settings.
-        
-        Either raise the error or store it.
-        The error will have occured at ``cur_index``
-        """
-        line = infile[cur_index]
-        cur_index += 1
-        message = text % cur_index
-        error = ErrorClass(message, cur_index, line)
-        if self.raise_errors:
-            # raise the error - parsing stops here
-            raise error
-        # store the error
-        # reraise when parsing has finished
-        self._errors.append(error)
-    
-    def _unquote(self, value):
-        """Return an unquoted version of a value"""
-        if not value:
-            # should only happen during parsing of lists
-            raise SyntaxError
-        if (value[0] == value[-1]) and (value[0] in ('"', "'")):
-            value = value[1:-1]
-        return value
-    
-    def _quote(self, value, multiline=True):
-        """
-        Return a safely quoted version of a value.
-
-        Raise a ConfigObjError if the value cannot be safely quoted.
-        If multiline is ``True`` (default) then use triple quotes
-        if necessary.
-
-        * Don't quote values that don't need it.
-        * Recursively quote members of a list and return a comma joined list.
-        * Multiline is ``False`` for lists.
-        * Obey list syntax for empty and single member lists.
-
-        If ``list_values=False`` then the value is only quoted if it contains
-        a ``\\n`` (is multiline) or '#'.
-
-        If ``write_empty_values`` is set, and the value is an empty string, it
-        won't be quoted.
-        """
-        if multiline and self.write_empty_values and value == '':
-            # Only if multiline is set, so that it is used for values not
-            # keys, and not values that are part of a list
-            return ''
-
-        if multiline and isinstance(value, (list, tuple)):
-            if not value:
-                return ','
-            elif len(value) == 1:
-                return self._quote(value[0], multiline=False) + ','
-            return ', '.join([self._quote(val, multiline=False)
-                for val in value])
-        if not isinstance(value, str):
-            if self.stringify and not isinstance(value, bytes):
-                value = str(value)
-            else:
-                raise TypeError('Value "%s" is not a string.' % value)
-
-        if not value:
-            return '""'
-
-        no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value
-        need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))
-        hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)
-        check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote
-
-        if check_for_single:
-            if not self.list_values:
-                # we don't quote if ``list_values=False``
-                quot = noquot
-            # for normal values either single or double quotes will do
-            elif '\n' in value:
-                # will only happen if multiline is off - e.g. '\n' in key
-                raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-            elif ((value[0] not in wspace_plus) and
-                    (value[-1] not in wspace_plus) and
-                    (',' not in value)):
-                quot = noquot
-            else:
-                quot = self._get_single_quote(value)
-        else:
-            # if value has '\n' or "'" *and* '"', it will need triple quotes
-            quot = self._get_triple_quote(value)
-
-        if quot == noquot and '#' in value and self.list_values:
-            quot = self._get_single_quote(value)
-
-        return quot % value
-
-    def _get_single_quote(self, value):
-        if ("'" in value) and ('"' in value):
-            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-        elif '"' in value:
-            quot = squot
-        else:
-            quot = dquot
-        return quot
-
-    def _get_triple_quote(self, value):
-        if (value.find('"""') != -1) and (value.find("'''") != -1):
-            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
-        if value.find('"""') == -1:
-            quot = tdquot
-        else:
-            quot = tsquot 
-        return quot
-
-    def _handle_value(self, value):
-        """
-        Given a value string, unquote, remove comment,
-        handle lists. (including empty and single member lists)
-        """
-        if self._inspec:
-            # Parsing a configspec so don't handle comments
-            return (value, '')
-        # do we look for lists in values ?
-        if not self.list_values:
-            mat = self._nolistvalue.match(value)
-            if mat is None:
-                raise SyntaxError()
-            # NOTE: we don't unquote here
-            return mat.groups()
-        #
-        mat = self._valueexp.match(value)
-        if mat is None:
-            # the value is badly constructed, probably badly quoted,
-            # or an invalid list
-            raise SyntaxError()
-        (list_values, single, empty_list, comment) = mat.groups()
-        if (list_values == '') and (single is None):
-            # change this if you want to accept empty values
-            raise SyntaxError()
-        # NOTE: note there is no error handling from here if the regex
-        # is wrong: then incorrect values will slip through
-        if empty_list is not None:
-            # the single comma - meaning an empty list
-            return ([], comment)
-        if single is not None:
-            # handle empty values
-            if list_values and not single:
-                # FIXME: the '' is a workaround because our regex now matches
-                #   '' at the end of a list if it has a trailing comma
-                single = None
-            else:
-                single = single or '""'
-                single = self._unquote(single)
-        if list_values == '':
-            # not a list value
-            return (single, comment)
-        the_list = self._listvalueexp.findall(list_values)
-        the_list = [self._unquote(val) for val in the_list]
-        if single is not None:
-            the_list += [single]
-        return (the_list, comment)
-
-    def _multiline(self, value, infile, cur_index, maxline):
-        """Extract the value, where we are in a multiline situation."""
-        quot = value[:3]
-        newvalue = value[3:]
-        single_line = self._triple_quote[quot][0]
-        multi_line = self._triple_quote[quot][1]
-        mat = single_line.match(value)
-        if mat is not None:
-            retval = list(mat.groups())
-            retval.append(cur_index)
-            return retval
-        elif newvalue.find(quot) != -1:
-            # somehow the triple quote is missing
-            raise SyntaxError()
-        #
-        while cur_index < maxline:
-            cur_index += 1
-            newvalue += '\n'
-            line = infile[cur_index]
-            if line.find(quot) == -1:
-                newvalue += line
-            else:
-                # end of multiline, process it
-                break
-        else:
-            # we've got to the end of the config, oops...
-            raise SyntaxError()
-        mat = multi_line.match(line)
-        if mat is None:
-            # a badly formed line
-            raise SyntaxError()
-        (value, comment) = mat.groups()
-        return (newvalue + value, comment, cur_index)
-
-    def _handle_configspec(self, configspec):
-        """Parse the configspec."""
-        # FIXME: Should we check that the configspec was created with the 
-        #        correct settings ? (i.e. ``list_values=False``)
-        if not isinstance(configspec, ConfigObj):
-            try:
-                configspec = ConfigObj(configspec,
-                                       raise_errors=True,
-                                       file_error=True,
-                                       _inspec=True)
-            except ConfigObjError as e:
-                # FIXME: Should these errors have a reference
-                #        to the already parsed ConfigObj ?
-                raise ConfigspecError('Parsing configspec failed: %s' % e)
-            except IOError as e:
-                raise IOError('Reading configspec failed: %s' % e)
-
-        self.configspec = configspec
-
-    def _set_configspec(self, section, copy):
-        """
-        Called by validate. Handles setting the configspec on subsections
-        including sections to be validated by __many__
-        """
-        configspec = section.configspec
-        many = configspec.get('__many__')
-        if isinstance(many, dict):
-            for entry in section.sections:
-                if entry not in configspec:
-                    section[entry].configspec = many
-
-        for entry in configspec.sections:
-            if entry == '__many__':
-                continue
-            if entry not in section:
-                section[entry] = {}
-                section[entry]._created = True
-                if copy:
-                    # copy comments
-                    section.comments[entry] = configspec.comments.get(entry, [])
-                    section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
-
-            # Could be a scalar when we expect a section
-            if isinstance(section[entry], Section):
-                section[entry].configspec = configspec[entry]
-
-    def _write_line(self, indent_string, entry, this_entry, comment):
-        """Write an individual line, for the write method"""
-        # NOTE: the calls to self._quote here handles non-StringType values.
-        if not self.unrepr:
-            val = self._decode_element(self._quote(this_entry))
-        else:
-            val = repr(this_entry)
-        return '%s%s%s%s%s' % (indent_string,
-                               self._decode_element(self._quote(entry, multiline=False)),
-                               ' = ',
-                               val,
-                               self._decode_element(comment))
-
-    def _write_marker(self, indent_string, depth, entry, comment):
-        """Write a section marker line"""
-        return '%s%s%s%s%s' % (indent_string,
-                               '[' * depth,
-                               self._quote(self._decode_element(entry), multiline=False),
-                               ']' * depth,
-                               self._decode_element(comment))
-    
-    def _handle_comment(self, comment):
-        """Deal with a comment."""
-        if not comment:
-            return ''
-        start = self.indent_type
-        if not comment.startswith('#'):
-            start += ' # '
-        return (start + comment)
-
-    # Public methods
-
-    def write(self, outfile=None, section=None):
-        """
-        Write the current ConfigObj as a file
-        
-        tekNico: FIXME: use StringIO instead of real files
-        
-        >>> filename = a.filename
-        >>> a.filename = 'test.ini'
-        >>> a.write()
-        >>> a.filename = filename
-        >>> a == ConfigObj('test.ini', raise_errors=True)
-        1
-        >>> import os
-        >>> os.remove('test.ini')
-        """
-        if self.indent_type is None:
-            # this can be true if initialised from a dictionary
-            self.indent_type = DEFAULT_INDENT_TYPE
-            
-        out = []
-        cs = '#'
-        csp = '# '
-        if section is None:
-            int_val = self.interpolation
-            self.interpolation = False
-            section = self
-            for line in self.initial_comment:
-                line = self._decode_element(line)
-                stripped_line = line.strip()
-                if stripped_line and not stripped_line.startswith(cs):
-                    line = csp + line
-                out.append(line)
-                
-        indent_string = self.indent_type * section.depth
-        for entry in (section.scalars + section.sections):
-            if entry in section.defaults:
-                # don't write out default values
-                continue
-            for comment_line in section.comments[entry]:
-                comment_line = self._decode_element(comment_line.lstrip())
-                if comment_line and not comment_line.startswith(cs):
-                    comment_line = csp + comment_line
-                out.append(indent_string + comment_line)
-            this_entry = section[entry]
-            comment = self._handle_comment(section.inline_comments[entry])
-            
-            if isinstance(this_entry, dict):
-                # a section
-                out.append(self._write_marker(
-                    indent_string,
-                    this_entry.depth,
-                    entry,
-                    comment))
-                out.extend(self.write(section=this_entry))
-            else:
-                out.append(self._write_line(
-                    indent_string,
-                    entry,
-                    this_entry,
-                    comment))
-                
-        if section is self:
-            for line in self.final_comment:
-                line = self._decode_element(line)
-                stripped_line = line.strip()
-                if stripped_line and not stripped_line.startswith(cs):
-                    line = csp + line
-                out.append(line)
-            self.interpolation = int_val
-            
-        if section is not self:
-            return out
-        
-        if (self.filename is None) and (outfile is None):
-            
-            # output a list of lines
-            # might need to encode
-            # NOTE: This will *screw* UTF16, each line will start with the BOM
-            if self.encoding:
-                out = [l.encode(self.encoding) for l in out]
-            if (self.BOM and ((self.encoding is None) or
-                (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
-                # Add the UTF8 BOM
-                if not out:
-                    out.append('')
-                out[0] = BOM_UTF8 + out[0]
-            return out
-            
-        
-        # Turn the list to a string, joined with correct newlines
-        newline = self.newlines or os.linesep
-        if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w'
-            and sys.platform == 'win32' and newline == '\r\n'):
-            # Windows specific hack to avoid writing '\r\r\n'
-            newline = '\n'
-        output = newline.join(out)
-        if self.encoding:
-            output = output.encode(self.encoding)
-            
-        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
-            # Add the UTF8 BOM
-            output = BOM_UTF8 + output
-              
-        if not output.endswith(newline):
-            output += newline
-        if outfile is not None:
-            outfile.write(output)
-        else:
-            h = open(self.filename, 'wb')
-            output = output.encode() # encoding the data to bytes
-            h.write(output)
-            h.close()
-    
-    def validate(self, validator, preserve_errors=False, copy=False,
-                 section=None):
-        """
-        Test the ConfigObj against a configspec.
-        
-        It uses the ``validator`` object from *validate.py*.
-        
-        To run ``validate`` on the current ConfigObj, call: ::
-        
-            test = config.validate(validator)
-        
-        (Normally having previously passed in the configspec when the ConfigObj
-        was created - you can dynamically assign a dictionary of checks to the
-        ``configspec`` attribute of a section though).
-        
-        It returns ``True`` if everything passes, or a dictionary of
-        pass/fails (True/False). If every member of a subsection passes, it
-        will just have the value ``True``. (It also returns ``False`` if all
-        members fail).
-        
-        In addition, it converts the values from strings to their native
-        types if their checks pass (and ``stringify`` is set).
-        
-        If ``preserve_errors`` is ``True`` (``False`` is default) then instead
-        of a marking a fail with a ``False``, it will preserve the actual
-        exception object. This can contain info about the reason for failure.
-        For example the ``VdtValueTooSmallError`` indicates that the value
-        supplied was too small. If a value (or section) is missing it will
-        still be marked as ``False``.
-        
-        You must have the validate module to use ``preserve_errors=True``.
-        
-        You can then use the ``flatten_errors`` function to turn your nested
-        results dictionary into a flattened list of failures - useful for
-        displaying meaningful error messages.
-        """
-        if section is None:
-            if self.configspec is None:
-                raise ValueError('No configspec supplied.')
-            if preserve_errors:
-                # We do this once to remove a top level dependency on the validate module
-                # Which makes importing configobj faster
-                from validate import VdtMissingValue
-                self._vdtMissingValue = VdtMissingValue
-                
-            section = self
-
-            if copy:
-                section.initial_comment = section.configspec.initial_comment
-                section.final_comment = section.configspec.final_comment
-                section.encoding = section.configspec.encoding
-                section.BOM = section.configspec.BOM
-                section.newlines = section.configspec.newlines
-                section.indent_type = section.configspec.indent_type
-            
-        #
-        # section.default_values.clear() #??
-        configspec = section.configspec
-        self._set_configspec(section, copy)
-    
-        def validate_entry(entry, spec, val, missing, ret_true, ret_false):
-            section.default_values.pop(entry, None)
-
-            try:
-                section.default_values[entry] = validator.get_default_value(configspec[entry])
-            except (KeyError, AttributeError, validator.baseErrorClass):
-                # No default, bad default or validator has no 'get_default_value'
-                # (e.g. SimpleVal)
-                pass
-
-            try:
-                check = validator.check(spec,
-                                        val,
-                                        missing=missing
-                                        )
-            except validator.baseErrorClass as e:
-                if not preserve_errors or isinstance(e, self._vdtMissingValue):
-                    out[entry] = False
-                else:
-                    # preserve the error
-                    out[entry] = e
-                    ret_false = False
-                ret_true = False
-            else:
-                ret_false = False
-                out[entry] = True
-                if self.stringify or missing:
-                    # if we are doing type conversion
-                    # or the value is a supplied default
-                    if not self.stringify:
-                        if isinstance(check, (list, tuple)):
-                            # preserve lists
-                            check = [self._str(item) for item in check]
-                        elif missing and check is None:
-                            # convert the None from a default to a ''
-                            check = ''
-                        else:
-                            check = self._str(check)
-                    if (check != val) or missing:
-                        section[entry] = check
-                if not copy and missing and entry not in section.defaults:
-                    section.defaults.append(entry)
-            return ret_true, ret_false
-
-        #
-        out = {}
-        ret_true = True
-        ret_false = True
-
-        unvalidated = [k for k in section.scalars if k not in configspec]
-        incorrect_sections = [k for k in configspec.sections if k in section.scalars]
-        incorrect_scalars = [k for k in configspec.scalars if k in section.sections]
-
-        for entry in configspec.scalars:
-            if entry in ('__many__', '___many___'):
-                # reserved names
-                continue
-            if (not entry in section.scalars) or (entry in section.defaults):
-                # missing entries
-                # or entries from defaults
-                missing = True
-                val = None
-                if copy and entry not in section.scalars:
-                    # copy comments
-                    section.comments[entry] = (
-                        configspec.comments.get(entry, []))
-                    section.inline_comments[entry] = (
-                        configspec.inline_comments.get(entry, ''))
-                #
-            else:
-                missing = False
-                val = section[entry]
-
-            ret_true, ret_false = validate_entry(entry, configspec[entry], val,
-                                                 missing, ret_true, ret_false)
-
-        many = None
-        if '__many__' in configspec.scalars:
-            many = configspec['__many__']
-        elif '___many___' in configspec.scalars:
-            many = configspec['___many___']
-
-        if many is not None:
-            for entry in unvalidated:
-                val = section[entry]
-                ret_true, ret_false = validate_entry(entry, many, val, False,
-                                                     ret_true, ret_false)
-            unvalidated = []
-
-        for entry in incorrect_scalars:
-            ret_true = False
-            if not preserve_errors:
-                out[entry] = False
-            else:
-                ret_false = False
-                msg = 'Value %r was provided as a section' % entry
-                out[entry] = validator.baseErrorClass(msg)
-        for entry in incorrect_sections:
-            ret_true = False
-            if not preserve_errors:
-                out[entry] = False
-            else:
-                ret_false = False
-                msg = 'Section %r was provided as a single value' % entry
-                out[entry] = validator.baseErrorClass(msg)
-
-        # Missing sections will have been created as empty ones when the
-        # configspec was read.
-        for entry in section.sections:
-            # FIXME: this means DEFAULT is not copied in copy mode
-            if section is self and entry == 'DEFAULT':
-                continue
-            if section[entry].configspec is None:
-                unvalidated.append(entry)
-                continue
-            if copy:
-                section.comments[entry] = configspec.comments.get(entry, [])
-                section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
-            check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry])
-            out[entry] = check
-            if check == False:
-                ret_true = False
-            elif check == True:
-                ret_false = False
-            else:
-                ret_true = False
-
-        section.extra_values = unvalidated
-        if preserve_errors and not section._created:
-            # If the section wasn't created (i.e. it wasn't missing)
-            # then we can't return False, we need to preserve errors
-            ret_false = False
-        #
-        if ret_false and preserve_errors and out:
-            # If we are preserving errors, but all
-            # the failures are from missing sections / values
-            # then we can return False. Otherwise there is a
-            # real failure that we need to preserve.
-            ret_false = not any(out.values())
-        if ret_true:
-            return True
-        elif ret_false:
-            return False
-        return out
-
-    
-    def reset(self):
-        """Clear ConfigObj instance and restore to 'freshly created' state."""
-        self.clear()
-        self._initialise()
-        # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload)
-        #        requires an empty dictionary
-        self.configspec = None
-        # Just to be sure ;-)
-        self._original_configspec = None
-
-    def reload(self):
-        """
-        Reload a ConfigObj from file.
-
-        This method raises a ``ReloadError`` if the ConfigObj doesn't have
-        a filename attribute pointing to a file.
-        """
-        if not isinstance(self.filename, str):
-            raise ReloadError()
-
-        filename = self.filename
-        current_options = {}
-        for entry in OPTION_DEFAULTS:
-            if entry == 'configspec':
-                continue
-            current_options[entry] = getattr(self, entry)
-
-        configspec = self._original_configspec
-        current_options['configspec'] = configspec
-
-        self.clear()
-        self._initialise(current_options)
-        self._load(filename, configspec)
-
-class SimpleVal(object):
-    """
-    A simple validator.
-    Can be used to check that all members expected are present.
-
-    To use it, provide a configspec with all your members in (the value given
-    will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
-    method of your ``ConfigObj``. ``validate`` will return ``True`` if all
-    members are present, or a dictionary with True/False meaning
-    present/missing. (Whole missing sections will be replaced with ``False``)
-    """
-
-    def __init__(self):
-        self.baseErrorClass = ConfigObjError
-
-    def check(self, check, member, missing=False):
-        """A dummy check method, always returns the value unchanged."""
-        if missing:
-            raise self.baseErrorClass()
-        return member
-
-def flatten_errors(cfg, res, levels=None, results=None):
-    """
-    An example function that will turn a nested dictionary of results
-    (as returned by ``ConfigObj.validate``) into a flat list.
-
-    ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
-    dictionary returned by ``validate``.
-
-    (This is a recursive function, so you shouldn't use the ``levels`` or
-    ``results`` arguments - they are used by the function.)
-
-    Returns a list of keys that failed. Each member of the list is a tuple::
-
-        ([list of sections...], key, result)
-
-    If ``validate`` was called with ``preserve_errors=False`` (the default)
-    then ``result`` will always be ``False``.
-
-    *list of sections* is a flattened list of sections that the key was found
-    in.
-
-    If the section was missing (or a section was expected and a scalar provided
-    - or vice-versa) then key will be ``None``.
-
-    If the value (or section) was missing then ``result`` will be ``False``.
-
-    If ``validate`` was called with ``preserve_errors=True`` and a value
-    was present, but failed the check, then ``result`` will be the exception
-    object returned. You can use this as a string that describes the failure.
-
-    For example *The value "3" is of the wrong type*.
-    """
-    if levels is None:
-        # first time called
-        levels = []
-        results = []
-    if res == True:
-        return results
-    if res == False or isinstance(res, Exception):
-        results.append((levels[:], None, res))
-        if levels:
-            levels.pop()
-        return results
-    for (key, val) in list(res.items()):
-        if val == True:
-            continue
-        if isinstance(cfg.get(key), dict):
-            # Go down one level
-            levels.append(key)
-            flatten_errors(cfg[key], val, levels, results)
-            continue
-        results.append((levels[:], key, val))
-    #
-    # Go up one level
-    if levels:
-        levels.pop()
-    #
-    return results
-
-def get_extra_values(conf, _prepend=()):
-    """
-    Find all the values and sections not in the configspec from a validated
-    ConfigObj.
-
-    ``get_extra_values`` returns a list of tuples where each tuple represents
-    either an extra section, or an extra value.
-
-    The tuples contain two values, a tuple representing the section the value 
-    is in and the name of the extra values. For extra values in the top level
-    section the first member will be an empty tuple. For values in the 'foo'
-    section the first member will be ``('foo',)``. For members in the 'bar'
-    subsection of the 'foo' section the first member will be ``('foo', 'bar')``.
-
-    NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't
-    been validated it will return an empty list.
-    """
-    out = []
-
-    out.extend([(_prepend, name) for name in conf.extra_values])
-    for name in conf.sections:
-        if name not in conf.extra_values:
-            out.extend(get_extra_values(conf[name], _prepend + (name,)))
-    return out
-
-
-"""*A programming language is a medium of expression.* - Paul Graham"""
\ No newline at end of file
diff --git a/astropy/extern/configobj_py3/validate.py b/astropy/extern/configobj_py3/validate.py
deleted file mode 100644
index af12814..0000000
--- a/astropy/extern/configobj_py3/validate.py
+++ /dev/null
@@ -1,1419 +0,0 @@
-# validate.py
-# A Validator object
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
-
-# This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-# Basically you're free to copy, modify, distribute and relicense it,
-# So long as you keep a copy of the license with it.
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
-
-"""
-    The Validator object is used to check that supplied values 
-    conform to a specification.
-    
-    The value can be supplied as a string - e.g. from a config file.
-    In this case the check will also *convert* the value to
-    the required type. This allows you to add validation
-    as a transparent layer to access data stored as strings.
-    The validation checks that the data is correct *and*
-    converts it to the expected type.
-    
-    Some standard checks are provided for basic data types.
-    Additional checks are easy to write. They can be
-    provided when the ``Validator`` is instantiated or
-    added afterwards.
-    
-    The standard functions work with the following basic data types :
-    
-    * integers
-    * floats
-    * booleans
-    * strings
-    * ip_addr
-    
-    plus lists of these datatypes
-    
-    Adding additional checks is done through coding simple functions.
-    
-    The full set of standard checks are : 
-    
-    * 'integer': matches integer values (including negative)
-                 Takes optional 'min' and 'max' arguments : ::
-    
-                   integer()
-                   integer(3, 9)  # any value from 3 to 9
-                   integer(min=0) # any positive value
-                   integer(max=9)
-    
-    * 'float': matches float values
-               Has the same parameters as the integer check.
-    
-    * 'boolean': matches boolean values - ``True`` or ``False``
-                 Acceptable string values for True are :
-                   true, on, yes, 1
-                 Acceptable string values for False are :
-                   false, off, no, 0
-    
-                 Any other value raises an error.
-    
-    * 'ip_addr': matches an Internet Protocol address, v.4, represented
-                 by a dotted-quad string, i.e. '1.2.3.4'.
-    
-    * 'string': matches any string.
-                Takes optional keyword args 'min' and 'max'
-                to specify min and max lengths of the string.
-    
-    * 'list': matches any list.
-              Takes optional keyword args 'min', and 'max' to specify min and
-              max sizes of the list. (Always returns a list.)
-    
-    * 'tuple': matches any tuple.
-              Takes optional keyword args 'min', and 'max' to specify min and
-              max sizes of the tuple. (Always returns a tuple.)
-    
-    * 'int_list': Matches a list of integers.
-                  Takes the same arguments as list.
-    
-    * 'float_list': Matches a list of floats.
-                    Takes the same arguments as list.
-    
-    * 'bool_list': Matches a list of boolean values.
-                   Takes the same arguments as list.
-    
-    * 'ip_addr_list': Matches a list of IP addresses.
-                     Takes the same arguments as list.
-    
-    * 'string_list': Matches a list of strings.
-                     Takes the same arguments as list.
-    
-    * 'mixed_list': Matches a list with different types in 
-                    specific positions. List size must match
-                    the number of arguments.
-    
-                    Each position can be one of :
-                    'integer', 'float', 'ip_addr', 'string', 'boolean'
-    
-                    So to specify a list with two strings followed
-                    by two integers, you write the check as : ::
-    
-                      mixed_list('string', 'string', 'integer', 'integer')
-    
-    * 'pass': This check matches everything ! It never fails
-              and the value is unchanged.
-    
-              It is also the default if no check is specified.
-    
-    * 'option': This check matches any from a list of options.
-                You specify this check with : ::
-    
-                  option('option 1', 'option 2', 'option 3')
-    
-    You can supply a default value (returned if no value is supplied)
-    using the default keyword argument.
-    
-    You specify a list argument for default using a list constructor syntax in
-    the check : ::
-    
-        checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
-    
-    A badly formatted set of arguments will raise a ``VdtParamError``.
-"""
-
-__version__ = '1.0.1'
-
-
-__all__ = (
-    '__version__',
-    'dottedQuadToNum',
-    'numToDottedQuad',
-    'ValidateError',
-    'VdtUnknownCheckError',
-    'VdtParamError',
-    'VdtTypeError',
-    'VdtValueError',
-    'VdtValueTooSmallError',
-    'VdtValueTooBigError',
-    'VdtValueTooShortError',
-    'VdtValueTooLongError',
-    'VdtMissingValue',
-    'Validator',
-    'is_integer',
-    'is_float',
-    'is_boolean',
-    'is_list',
-    'is_tuple',
-    'is_ip_addr',
-    'is_string',
-    'is_int_list',
-    'is_bool_list',
-    'is_float_list',
-    'is_string_list',
-    'is_ip_addr_list',
-    'is_mixed_list',
-    'is_option',
-    '__docformat__',
-)
-
-
-
-import re
-
-
-_list_arg = re.compile(r'''
-    (?:
-        ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
-            (
-                (?:
-                    \s*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s\)][^,\)]*?)  # unquoted
-                    )
-                    \s*,\s*
-                )*
-                (?:
-                    (?:".*?")|              # double quotes
-                    (?:'.*?')|              # single quotes
-                    (?:[^'",\s\)][^,\)]*?)  # unquoted
-                )?                          # last one
-            )
-        \)
-    )
-''', re.VERBOSE | re.DOTALL)    # two groups
-
-_list_members = re.compile(r'''
-    (
-        (?:".*?")|              # double quotes
-        (?:'.*?')|              # single quotes
-        (?:[^'",\s=][^,=]*?)       # unquoted
-    )
-    (?:
-    (?:\s*,\s*)|(?:\s*$)            # comma
-    )
-''', re.VERBOSE | re.DOTALL)    # one group
-
-_paramstring = r'''
-    (?:
-        (
-            (?:
-                [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
-                    (?:
-                        \s*
-                        (?:
-                            (?:".*?")|              # double quotes
-                            (?:'.*?')|              # single quotes
-                            (?:[^'",\s\)][^,\)]*?)       # unquoted
-                        )
-                        \s*,\s*
-                    )*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s\)][^,\)]*?)       # unquoted
-                    )?                              # last one
-                \)
-            )|
-            (?:
-                (?:".*?")|              # double quotes
-                (?:'.*?')|              # single quotes
-                (?:[^'",\s=][^,=]*?)|       # unquoted
-                (?:                         # keyword argument
-                    [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
-                    (?:
-                        (?:".*?")|              # double quotes
-                        (?:'.*?')|              # single quotes
-                        (?:[^'",\s=][^,=]*?)       # unquoted
-                    )
-                )
-            )
-        )
-        (?:
-            (?:\s*,\s*)|(?:\s*$)            # comma
-        )
-    )
-    '''
-
-_matchstring = '^%s*' % _paramstring
-
-def dottedQuadToNum(ip):
-    """
-    Convert decimal dotted quad string to long integer
-    
-    >>> int(dottedQuadToNum('1 '))
-    1
-    >>> int(dottedQuadToNum(' 1.2'))
-    16777218
-    >>> int(dottedQuadToNum(' 1.2.3 '))
-    16908291
-    >>> int(dottedQuadToNum('1.2.3.4'))
-    16909060
-    >>> dottedQuadToNum('255.255.255.255')
-    4294967295L
-    >>> dottedQuadToNum('255.255.255.256')
-    Traceback (most recent call last):
-    ValueError: Not a good dotted-quad IP: 255.255.255.256
-    """
-    
-    # import here to avoid it when ip_addr values are not used
-    import socket, struct
-    
-    try:
-        return struct.unpack('!L',
-            socket.inet_aton(ip.strip()))[0]
-    except socket.error:
-        # bug in inet_aton, corrected in Python 2.4
-        if ip.strip() == '255.255.255.255':
-            return 0xFFFFFFFF
-        else:
-            raise ValueError('Not a good dotted-quad IP: %s' % ip)
-    return
-
-def numToDottedQuad(num):
-    """
-    Convert long int to dotted quad string
-    
-    >>> numToDottedQuad(-1L)
-    Traceback (most recent call last):
-    ValueError: Not a good numeric IP: -1
-    >>> numToDottedQuad(1L)
-    '0.0.0.1'
-    >>> numToDottedQuad(16777218L)
-    '1.0.0.2'
-    >>> numToDottedQuad(16908291L)
-    '1.2.0.3'
-    >>> numToDottedQuad(16909060L)
-    '1.2.3.4'
-    >>> numToDottedQuad(4294967295L)
-    '255.255.255.255'
-    >>> numToDottedQuad(4294967296L)
-    Traceback (most recent call last):
-    ValueError: Not a good numeric IP: 4294967296
-    """
-    
-    # import here to avoid it when ip_addr values are not used
-    import socket, struct
-    
-    # no need to intercept here, 4294967295L is fine
-    if num > 4294967295 or num < 0:
-        raise ValueError('Not a good numeric IP: %s' % num)
-    try:
-        return socket.inet_ntoa(
-            struct.pack('!L', int(num)))
-    except (socket.error, struct.error, OverflowError):
-        raise ValueError('Not a good numeric IP: %s' % num)
-
-class ValidateError(Exception):
-    """
-    This error indicates that the check failed.
-    It can be the base class for more specific errors.
-
-    Any check function that fails ought to raise this error.
-    (or a subclass)
-
-    >>> raise ValidateError
-    Traceback (most recent call last):
-    ValidateError
-    """
-
-class VdtMissingValue(ValidateError):
-    """No value was supplied to a check that needed one."""
-
-
-class VdtUnknownCheckError(ValidateError):
-    """An unknown check function was requested"""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtUnknownCheckError('yoda')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        """
-        ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,))
-
-
-class VdtParamError(SyntaxError):
-    """An incorrect parameter was passed"""
-
-    def __init__(self, name, value):
-        """
-        >>> raise VdtParamError('yoda', 'jedi')
-        Traceback (most recent call last):
-        VdtParamError: passed an incorrect value "jedi" for parameter "yoda".
-        """
-        SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name))
-
-
-class VdtTypeError(ValidateError):
-    """The value supplied was of the wrong type"""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtTypeError('jedi')
-        Traceback (most recent call last):
-        VdtTypeError: the value "jedi" is of the wrong type.
-        """
-        ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,))
-
-
-class VdtValueError(ValidateError):
-    """The value supplied was of the correct type, but was not an allowed value."""
-    
-    def __init__(self, value):
-        """
-        >>> raise VdtValueError('jedi')
-        Traceback (most recent call last):
-        VdtValueError: the value "jedi" is unacceptable.
-        """
-        ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,))
-
-
-class VdtValueTooSmallError(VdtValueError):
-    """The value supplied was of the correct type, but was too small."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooSmallError('0')
-        Traceback (most recent call last):
-        VdtValueTooSmallError: the value "0" is too small.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too small.' % (value,))
-
-
-class VdtValueTooBigError(VdtValueError):
-    """The value supplied was of the correct type, but was too big."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooBigError('1')
-        Traceback (most recent call last):
-        VdtValueTooBigError: the value "1" is too big.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too big.' % (value,))
-
-
-class VdtValueTooShortError(VdtValueError):
-    """The value supplied was of the correct type, but was too short."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooShortError('jed')
-        Traceback (most recent call last):
-        VdtValueTooShortError: the value "jed" is too short.
-        """
-        ValidateError.__init__(
-            self,
-            'the value "%s" is too short.' % (value,))
-
-
-class VdtValueTooLongError(VdtValueError):
-    """The value supplied was of the correct type, but was too long."""
-
-    def __init__(self, value):
-        """
-        >>> raise VdtValueTooLongError('jedie')
-        Traceback (most recent call last):
-        VdtValueTooLongError: the value "jedie" is too long.
-        """
-        ValidateError.__init__(self, 'the value "%s" is too long.' % (value,))
-
-class Validator(object):
-    """
-    Validator is an object that allows you to register a set of 'checks'.
-    These checks take input and test that it conforms to the check.
-    
-    This can also involve converting the value from a string into
-    the correct datatype.
-    
-    The ``check`` method takes an input string which configures which
-    check is to be used and applies that check to a supplied value.
-    
-    An example input string would be:
-    'int_range(param1, param2)'
-    
-    You would then provide something like:
-    
-    >>> def int_range_check(value, min, max):
-    ...     # turn min and max from strings to integers
-    ...     min = int(min)
-    ...     max = int(max)
-    ...     # check that value is of the correct type.
-    ...     # possible valid inputs are integers or strings
-    ...     # that represent integers
-    ...     if not isinstance(value, (int, long, str)):
-    ...         raise VdtTypeError(value)
-    ...     elif isinstance(value, str):
-    ...         # if we are given a string
-    ...         # attempt to convert to an integer
-    ...         try:
-    ...             value = int(value)
-    ...         except ValueError:
-    ...             raise VdtValueError(value)
-    ...     # check the value is between our constraints
-    ...     if not min <= value:
-    ...          raise VdtValueTooSmallError(value)
-    ...     if not value <= max:
-    ...          raise VdtValueTooBigError(value)
-    ...     return value
-    
-    >>> fdict = {'int_range': int_range_check}
-    >>> vtr1 = Validator(fdict)
-    >>> vtr1.check('int_range(20, 40)', '30')
-    30
-    >>> vtr1.check('int_range(20, 40)', '60')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "60" is too big.
-    
-    New functions can be added with : ::
-    
-    >>> vtr2 = Validator()       
-    >>> vtr2.functions['int_range'] = int_range_check
-    
-    Or by passing in a dictionary of functions when Validator 
-    is instantiated.
-    
-    Your functions *can* use keyword arguments,
-    but the first argument should always be 'value'.
-    
-    If the function doesn't take additional arguments,
-    the parentheses are optional in the check.
-    It can be written with either of : ::
-    
-        keyword = function_name
-        keyword = function_name()
-    
-    The first program to utilise Validator() was Michael Foord's
-    ConfigObj, an alternative to ConfigParser which supports lists and
-    can validate a config file using a config schema.
-    For more details on using Validator with ConfigObj see:
-    http://www.voidspace.org.uk/python/configobj.html
-    """
-
-    # this regex does the initial parsing of the checks
-    _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
-
-    # this regex takes apart keyword arguments
-    _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$',  re.DOTALL)
-
-
-    # this regex finds keyword=list(....) type values
-    _list_arg = _list_arg
-
-    # this regex takes individual values out of lists - in one pass
-    _list_members = _list_members
-
-    # These regexes check a set of arguments for validity
-    # and then pull the members out
-    _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL)
-    _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL)
-
-
-    def __init__(self, functions=None):
-        """
-        >>> vtri = Validator()
-        """
-        self.functions = {
-            '': self._pass,
-            'integer': is_integer,
-            'float': is_float,
-            'boolean': is_boolean,
-            'ip_addr': is_ip_addr,
-            'string': is_string,
-            'list': is_list,
-            'tuple': is_tuple,
-            'int_list': is_int_list,
-            'float_list': is_float_list,
-            'bool_list': is_bool_list,
-            'ip_addr_list': is_ip_addr_list,
-            'string_list': is_string_list,
-            'mixed_list': is_mixed_list,
-            'pass': self._pass,
-            'option': is_option,
-            'force_list': force_list,
-        }
-        if functions is not None:
-            self.functions.update(functions)
-        # tekNico: for use by ConfigObj
-        self.baseErrorClass = ValidateError
-        self._cache = {}
-
-
-    def check(self, check, value, missing=False):
-        """
-        Usage: check(check, value)
-        
-        Arguments:
-            check: string representing check to apply (including arguments)
-            value: object to be checked
-        Returns value, converted to correct type if necessary
-        
-        If the check fails, raises a ``ValidateError`` subclass.
-        
-        >>> vtor.check('yoda', '')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        >>> vtor.check('yoda()', '')
-        Traceback (most recent call last):
-        VdtUnknownCheckError: the check "yoda" is unknown.
-        
-        >>> vtor.check('string(default="")', '', missing=True)
-        ''
-        """
-        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
-            
-        if missing:
-            if default is None:
-                # no information needed here - to be handled by caller
-                raise VdtMissingValue()
-            value = self._handle_none(default)
-        
-        if value is None:
-            return None
-        
-        return self._check_value(value, fun_name, fun_args, fun_kwargs)
-
-
-    def _handle_none(self, value):
-        if value == 'None':
-            return None
-        elif value in ("'None'", '"None"'):
-            # Special case a quoted None
-            value = self._unquote(value)
-        return value
-
-
-    def _parse_with_caching(self, check):
-        if check in self._cache:
-            fun_name, fun_args, fun_kwargs, default = self._cache[check]
-            # We call list and dict below to work with *copies* of the data
-            # rather than the original (which are mutable of course)
-            fun_args = list(fun_args)
-            fun_kwargs = dict(fun_kwargs)
-        else:
-            fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
-            fun_kwargs = dict([(str(key), value) for (key, value) in list(fun_kwargs.items())])
-            self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
-        return fun_name, fun_args, fun_kwargs, default
-        
-        
-    def _check_value(self, value, fun_name, fun_args, fun_kwargs):
-        try:
-            fun = self.functions[fun_name]
-        except KeyError:
-            raise VdtUnknownCheckError(fun_name)
-        else:
-            return fun(value, *fun_args, **fun_kwargs)
-
-
-    def _parse_check(self, check):
-        fun_match = self._func_re.match(check)
-        if fun_match:
-            fun_name = fun_match.group(1)
-            arg_string = fun_match.group(2)
-            arg_match = self._matchfinder.match(arg_string)
-            if arg_match is None:
-                # Bad syntax
-                raise VdtParamError('Bad syntax in check "%s".' % check)
-            fun_args = []
-            fun_kwargs = {}
-            # pull out args of group 2
-            for arg in self._paramfinder.findall(arg_string):
-                # args may need whitespace removing (before removing quotes)
-                arg = arg.strip()
-                listmatch = self._list_arg.match(arg)
-                if listmatch:
-                    key, val = self._list_handle(listmatch)
-                    fun_kwargs[key] = val
-                    continue
-                keymatch = self._key_arg.match(arg)
-                if keymatch:
-                    val = keymatch.group(2)
-                    if not val in ("'None'", '"None"'):
-                        # Special case a quoted None
-                        val = self._unquote(val)
-                    fun_kwargs[keymatch.group(1)] = val
-                    continue
-                
-                fun_args.append(self._unquote(arg))
-        else:
-            # allows for function names without (args)
-            return check, (), {}, None
-
-        # Default must be deleted if the value is specified too,
-        # otherwise the check function will get a spurious "default" keyword arg
-        default = fun_kwargs.pop('default', None)
-        return fun_name, fun_args, fun_kwargs, default
-
-
-    def _unquote(self, val):
-        """Unquote a value if necessary."""
-        if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]):
-            val = val[1:-1]
-        return val
-
-
-    def _list_handle(self, listmatch):
-        """Take apart a ``keyword=list('val, 'val')`` type string."""
-        out = []
-        name = listmatch.group(1)
-        args = listmatch.group(2)
-        for arg in self._list_members.findall(args):
-            out.append(self._unquote(arg))
-        return name, out
-
-
-    def _pass(self, value):
-        """
-        Dummy check that always passes
-        
-        >>> vtor.check('', 0)
-        0
-        >>> vtor.check('', '0')
-        '0'
-        """
-        return value
-    
-    
-    def get_default_value(self, check):
-        """
-        Given a check, return the default value for the check
-        (converted to the right type).
-        
-        If the check doesn't specify a default value then a
-        ``KeyError`` will be raised.
-        """
-        fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
-        if default is None:
-            raise KeyError('Check "%s" has no default value.' % check)
-        value = self._handle_none(default)
-        if value is None:
-            return value
-        return self._check_value(value, fun_name, fun_args, fun_kwargs)
-
-def _is_num_param(names, values, to_float=False):
-    """
-    Return numbers from inputs or raise VdtParamError.
-    
-    Lets ``None`` pass through.
-    Pass in keyword argument ``to_float=True`` to
-    use float for the conversion rather than int.
-    
-    >>> _is_num_param(('', ''), (0, 1.0))
-    [0, 1]
-    >>> _is_num_param(('', ''), (0, 1.0), to_float=True)
-    [0.0, 1.0]
-    >>> _is_num_param(('a'), ('a'))
-    Traceback (most recent call last):
-    VdtParamError: passed an incorrect value "a" for parameter "a".
-    """
-    fun = to_float and float or int
-    out_params = []
-    for (name, val) in zip(names, values):
-        if val is None:
-            out_params.append(val)
-        elif isinstance(val, (int, int, float, str)):
-            try:
-                out_params.append(fun(val))
-            except ValueError as e:
-                raise VdtParamError(name, val)
-        else:
-            raise VdtParamError(name, val)
-    return out_params
-
-# built in checks
-# you can override these by setting the appropriate name
-# in Validator.functions
-# note: if the params are specified wrongly in your input string,
-#       you will also raise errors.
-
-def is_integer(value, min=None, max=None):
-    """
-    A check that tests that a given value is an integer (int, or long)
-    and optionally, between bounds. A negative value is accepted, while
-    a float will fail.
-    
-    If the value is a string, then the conversion is done - if possible.
-    Otherwise a VdtError is raised.
-    
-    >>> vtor.check('integer', '-1')
-    -1
-    >>> vtor.check('integer', '0')
-    0
-    >>> vtor.check('integer', 9)
-    9
-    >>> vtor.check('integer', 'a')
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    >>> vtor.check('integer', '2.2')
-    Traceback (most recent call last):
-    VdtTypeError: the value "2.2" is of the wrong type.
-    >>> vtor.check('integer(10)', '20')
-    20
-    >>> vtor.check('integer(max=20)', '15')
-    15
-    >>> vtor.check('integer(10)', '9')
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9" is too small.
-    >>> vtor.check('integer(10)', 9)
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9" is too small.
-    >>> vtor.check('integer(max=20)', '35')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35" is too big.
-    >>> vtor.check('integer(max=20)', 35)
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35" is too big.
-    >>> vtor.check('integer(0, 9)', False)
-    0
-    """
-    (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
-    if not isinstance(value, (int, int, str)):
-        raise VdtTypeError(value)
-    if isinstance(value, str):
-        # if it's a string - does it represent an integer ?
-        try:
-            value = int(value)
-        except ValueError:
-            raise VdtTypeError(value)
-    if (min_val is not None) and (value < min_val):
-        raise VdtValueTooSmallError(value)
-    if (max_val is not None) and (value > max_val):
-        raise VdtValueTooBigError(value)
-    return value
-
-def is_float(value, min=None, max=None):
-    """
-    A check that tests that a given value is a float
-    (an integer will be accepted), and optionally - that it is between bounds.
-    
-    If the value is a string, then the conversion is done - if possible.
-    Otherwise a VdtError is raised.
-    
-    This can accept negative values.
-    
-    >>> vtor.check('float', '2')
-    2.0
-    
-    From now on we multiply the value to avoid comparing decimals
-    
-    >>> vtor.check('float', '-6.8') * 10
-    -68.0
-    >>> vtor.check('float', '12.2') * 10
-    122.0
-    >>> vtor.check('float', 8.4) * 10
-    84.0
-    >>> vtor.check('float', 'a')
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    >>> vtor.check('float(10.1)', '10.2') * 10
-    102.0
-    >>> vtor.check('float(max=20.2)', '15.1') * 10
-    151.0
-    >>> vtor.check('float(10.0)', '9.0')
-    Traceback (most recent call last):
-    VdtValueTooSmallError: the value "9.0" is too small.
-    >>> vtor.check('float(max=20.0)', '35.0')
-    Traceback (most recent call last):
-    VdtValueTooBigError: the value "35.0" is too big.
-    """
-    (min_val, max_val) = _is_num_param(
-        ('min', 'max'), (min, max), to_float=True)
-    if not isinstance(value, (int, int, float, str)):
-        raise VdtTypeError(value)
-    if not isinstance(value, float):
-        # if it's a string - does it represent a float ?
-        try:
-            value = float(value)
-        except ValueError:
-            raise VdtTypeError(value)
-    if (min_val is not None) and (value < min_val):
-        raise VdtValueTooSmallError(value)
-    if (max_val is not None) and (value > max_val):
-        raise VdtValueTooBigError(value)
-    return value
-
-bool_dict = {
-    True: True, 'on': True, '1': True, 'true': True, 'yes': True, 
-    False: False, 'off': False, '0': False, 'false': False, 'no': False,
-}
-
-def is_boolean(value):
-    """
-    Check if the value represents a boolean.
-    
-    >>> vtor.check('boolean', 0)
-    0
-    >>> vtor.check('boolean', False)
-    0
-    >>> vtor.check('boolean', '0')
-    0
-    >>> vtor.check('boolean', 'off')
-    0
-    >>> vtor.check('boolean', 'false')
-    0
-    >>> vtor.check('boolean', 'no')
-    0
-    >>> vtor.check('boolean', 'nO')
-    0
-    >>> vtor.check('boolean', 'NO')
-    0
-    >>> vtor.check('boolean', 1)
-    1
-    >>> vtor.check('boolean', True)
-    1
-    >>> vtor.check('boolean', '1')
-    1
-    >>> vtor.check('boolean', 'on')
-    1
-    >>> vtor.check('boolean', 'true')
-    1
-    >>> vtor.check('boolean', 'yes')
-    1
-    >>> vtor.check('boolean', 'Yes')
-    1
-    >>> vtor.check('boolean', 'YES')
-    1
-    >>> vtor.check('boolean', '')
-    Traceback (most recent call last):
-    VdtTypeError: the value "" is of the wrong type.
-    >>> vtor.check('boolean', 'up')
-    Traceback (most recent call last):
-    VdtTypeError: the value "up" is of the wrong type.
-    
-    """
-    if isinstance(value, str):
-        try:
-            return bool_dict[value.lower()]
-        except KeyError:
-            raise VdtTypeError(value)
-    # we do an equality test rather than an identity test
-    # this ensures Python 2.2 compatibilty
-    # and allows 0 and 1 to represent True and False
-    if value == False:
-        return False
-    elif value == True:
-        return True
-    else:
-        raise VdtTypeError(value)
-
-def is_ip_addr(value):
-    """
-    Check that the supplied value is an Internet Protocol address, v.4,
-    represented by a dotted-quad string, i.e. '1.2.3.4'.
-
-    >>> vtor.check('ip_addr', '1 ')
-    '1'
-    >>> vtor.check('ip_addr', ' 1.2')
-    '1.2'
-    >>> vtor.check('ip_addr', ' 1.2.3 ')
-    '1.2.3'
-    >>> vtor.check('ip_addr', '1.2.3.4')
-    '1.2.3.4'
-    >>> vtor.check('ip_addr', '0.0.0.0')
-    '0.0.0.0'
-    >>> vtor.check('ip_addr', '255.255.255.255')
-    '255.255.255.255'
-    >>> vtor.check('ip_addr', '255.255.255.256')
-    Traceback (most recent call last):
-    VdtValueError: the value "255.255.255.256" is unacceptable.
-    >>> vtor.check('ip_addr', '1.2.3.4.5')
-    Traceback (most recent call last):
-    VdtValueError: the value "1.2.3.4.5" is unacceptable.
-    >>> vtor.check('ip_addr', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    """
-    if not isinstance(value, str):
-        raise VdtTypeError(value)
-    value = value.strip()
-    try:
-        dottedQuadToNum(value)
-    except ValueError:
-        raise VdtValueError(value)
-    return value
-    
-def is_list(value, min=None, max=None):
-    """
-    Check that the value is a list of values.
-
-    You can optionally specify the minimum and maximum number of members.
-
-    It does no check on list members.
-
-    >>> vtor.check('list', ())
-    []
-    >>> vtor.check('list', [])
-    []
-    >>> vtor.check('list', (1, 2))
-    [1, 2]
-    >>> vtor.check('list', [1, 2])
-    [1, 2]
-    >>> vtor.check('list(3)', (1, 2))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2)" is too short.
-    >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
-    >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4))
-    [1, 2, 3, 4]
-    >>> vtor.check('list', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('list', '12')
-    Traceback (most recent call last):
-    VdtTypeError: the value "12" is of the wrong type.
-    """
-    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
-    if isinstance(value, str):
-        raise VdtTypeError(value)
-    try:
-        num_members = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if min_len is not None and num_members < min_len:
-        raise VdtValueTooShortError(value)
-    if max_len is not None and num_members > max_len:
-        raise VdtValueTooLongError(value)
-    return list(value)
-
-def is_tuple(value, min=None, max=None):
-    """
-    Check that the value is a tuple of values.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    It does no check on members.
-    
-    >>> vtor.check('tuple', ())
-    ()
-    >>> vtor.check('tuple', [])
-    ()
-    >>> vtor.check('tuple', (1, 2))
-    (1, 2)
-    >>> vtor.check('tuple', [1, 2])
-    (1, 2)
-    >>> vtor.check('tuple(3)', (1, 2))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2)" is too short.
-    >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
-    >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4))
-    (1, 2, 3, 4)
-    >>> vtor.check('tuple', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('tuple', '12')
-    Traceback (most recent call last):
-    VdtTypeError: the value "12" is of the wrong type.
-    """
-    return tuple(is_list(value, min, max))
-    
-def is_string(value, min=None, max=None):
-    """
-    Check that the supplied value is a string.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    >>> vtor.check('string', '0')
-    '0'
-    >>> vtor.check('string', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    >>> vtor.check('string(2)', '12')
-    '12'
-    >>> vtor.check('string(2)', '1')
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "1" is too short.
-    >>> vtor.check('string(min=2, max=3)', '123')
-    '123'
-    >>> vtor.check('string(min=2, max=3)', '1234')
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "1234" is too long.
-    """
-    if not isinstance(value, str):
-        raise VdtTypeError(value)
-    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
-    try:
-        num_members = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if min_len is not None and num_members < min_len:
-        raise VdtValueTooShortError(value)
-    if max_len is not None and num_members > max_len:
-        raise VdtValueTooLongError(value)
-    return value
-
-
-def is_int_list(value, min=None, max=None):
-    """
-    Check that the value is a list of integers.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is an integer.
-    
-    >>> vtor.check('int_list', ())
-    []
-    >>> vtor.check('int_list', [])
-    []
-    >>> vtor.check('int_list', (1, 2))
-    [1, 2]
-    >>> vtor.check('int_list', [1, 2])
-    [1, 2]
-    >>> vtor.check('int_list', [1, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_integer(mem) for mem in is_list(value, min, max)]
-
-
-def is_bool_list(value, min=None, max=None):
-    """
-    Check that the value is a list of booleans.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is a boolean.
-    
-    >>> vtor.check('bool_list', ())
-    []
-    >>> vtor.check('bool_list', [])
-    []
-    >>> check_res = vtor.check('bool_list', (True, False))
-    >>> check_res == [True, False]
-    1
-    >>> check_res = vtor.check('bool_list', [True, False])
-    >>> check_res == [True, False]
-    1
-    >>> vtor.check('bool_list', [True, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_boolean(mem) for mem in is_list(value, min, max)]
-
-
-def is_float_list(value, min=None, max=None):
-    """
-    Check that the value is a list of floats.
-
-    You can optionally specify the minimum and maximum number of members.
-
-    Each list member is checked that it is a float.
-
-    >>> vtor.check('float_list', ())
-    []
-    >>> vtor.check('float_list', [])
-    []
-    >>> vtor.check('float_list', (1, 2.0))
-    [1.0, 2.0]
-    >>> vtor.check('float_list', [1, 2.0])
-    [1.0, 2.0]
-    >>> vtor.check('float_list', [1, 'a'])
-    Traceback (most recent call last):
-    VdtTypeError: the value "a" is of the wrong type.
-    """
-    return [is_float(mem) for mem in is_list(value, min, max)]
-
-def is_string_list(value, min=None, max=None):
-    """
-    Check that the value is a list of strings.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is a string.
-    
-    >>> vtor.check('string_list', ())
-    []
-    >>> vtor.check('string_list', [])
-    []
-    >>> vtor.check('string_list', ('a', 'b'))
-    ['a', 'b']
-    >>> vtor.check('string_list', ['a', 1])
-    Traceback (most recent call last):
-    VdtTypeError: the value "1" is of the wrong type.
-    >>> vtor.check('string_list', 'hello')
-    Traceback (most recent call last):
-    VdtTypeError: the value "hello" is of the wrong type.
-    """
-    if isinstance(value, str):
-        raise VdtTypeError(value)
-    return [is_string(mem) for mem in is_list(value, min, max)]
-
-def is_ip_addr_list(value, min=None, max=None):
-    """
-    Check that the value is a list of IP addresses.
-    
-    You can optionally specify the minimum and maximum number of members.
-    
-    Each list member is checked that it is an IP address.
-    
-    >>> vtor.check('ip_addr_list', ())
-    []
-    >>> vtor.check('ip_addr_list', [])
-    []
-    >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8'))
-    ['1.2.3.4', '5.6.7.8']
-    >>> vtor.check('ip_addr_list', ['a'])
-    Traceback (most recent call last):
-    VdtValueError: the value "a" is unacceptable.
-    """
-    return [is_ip_addr(mem) for mem in is_list(value, min, max)]
-
-def force_list(value, min=None, max=None):
-    """
-    Check that a value is a list, coercing strings into
-    a list with one member. Useful where users forget the
-    trailing comma that turns a single value into a list.
-    
-    You can optionally specify the minimum and maximum number of members.
-    A minumum of greater than one will fail if the user only supplies a
-    string.
-    
-    >>> vtor.check('force_list', ())
-    []
-    >>> vtor.check('force_list', [])
-    []
-    >>> vtor.check('force_list', 'hello')
-    ['hello']
-    """
-    if not isinstance(value, (list, tuple)):
-        value = [value]
-    return is_list(value, min, max)
-
-fun_dict = {
-    'integer': is_integer,
-    'float': is_float,
-    'ip_addr': is_ip_addr,
-    'string': is_string,
-    'boolean': is_boolean,
-}
-
-
-def is_mixed_list(value, *args):
-    """
-    Check that the value is a list.
-    Allow specifying the type of each member.
-    Work on lists of specific lengths.
-    
-    You specify each member as a positional argument specifying type
-    
-    Each type should be one of the following strings :
-      'integer', 'float', 'ip_addr', 'string', 'boolean'
-    
-    So you can specify a list of two strings, followed by
-    two integers as :
-    
-      mixed_list('string', 'string', 'integer', 'integer')
-    
-    The length of the list must match the number of positional
-    arguments you supply.
-    
-    >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
-    >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
-    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
-    1
-    >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True'))
-    >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
-    1
-    >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True))
-    Traceback (most recent call last):
-    VdtTypeError: the value "b" is of the wrong type.
-    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a'))
-    Traceback (most recent call last):
-    VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
-    >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
-    Traceback (most recent call last):
-    VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
-    >>> vtor.check(mix_str, 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    
-    This test requires an elaborate setup, because of a change in error string
-    output from the interpreter between Python 2.2 and 2.3 .
-    
-    >>> res_seq = (
-    ...     'passed an incorrect value "',
-    ...     'yoda',
-    ...     '" for parameter "mixed_list".',
-    ... )
-    >>> res_str = "'".join(res_seq)
-    >>> try:
-    ...     vtor.check('mixed_list("yoda")', ('a'))
-    ... except VdtParamError, err:
-    ...     str(err) == res_str
-    1
-    """
-    try:
-        length = len(value)
-    except TypeError:
-        raise VdtTypeError(value)
-    if length < len(args):
-        raise VdtValueTooShortError(value)
-    elif length > len(args):
-        raise VdtValueTooLongError(value)
-    try:
-        return [fun_dict[arg](val) for arg, val in zip(args, value)]
-    except KeyError as e:
-        raise VdtParamError('mixed_list', e)
-
-
-def is_option(value, *options):
-    """
-    This check matches the value to any of a set of options.
-    
-    >>> vtor.check('option("yoda", "jedi")', 'yoda')
-    'yoda'
-    >>> vtor.check('option("yoda", "jedi")', 'jed')
-    Traceback (most recent call last):
-    VdtValueError: the value "jed" is unacceptable.
-    >>> vtor.check('option("yoda", "jedi")', 0)
-    Traceback (most recent call last):
-    VdtTypeError: the value "0" is of the wrong type.
-    """
-    if not isinstance(value, str):
-        raise VdtTypeError(value)
-    if not value in options:
-        raise VdtValueError(value)
-    return value
-
-def _test(value, *args, **keywargs):
-    """
-    A function that exists for test purposes.
-    
-    >>> checks = [
-    ...     '3, 6, min=1, max=3, test=list(a, b, c)',
-    ...     '3',
-    ...     '3, 6',
-    ...     '3,',
-    ...     'min=1, test="a b c"',
-    ...     'min=5, test="a, b, c"',
-    ...     'min=1, max=3, test="a, b, c"',
-    ...     'min=-100, test=-99',
-    ...     'min=1, max=3',
-    ...     '3, 6, test="36"',
-    ...     '3, 6, test="a, b, c"',
-    ...     '3, max=3, test=list("a", "b", "c")',
-    ...     '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
-    ...     "test='x=fish(3)'",
-    ...    ]
-    >>> v = Validator({'test': _test})
-    >>> for entry in checks:
-    ...     print v.check(('test(%s)' % entry), 3)
-    (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
-    (3, ('3',), {})
-    (3, ('3', '6'), {})
-    (3, ('3',), {})
-    (3, (), {'test': 'a b c', 'min': '1'})
-    (3, (), {'test': 'a, b, c', 'min': '5'})
-    (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
-    (3, (), {'test': '-99', 'min': '-100'})
-    (3, (), {'max': '3', 'min': '1'})
-    (3, ('3', '6'), {'test': '36'})
-    (3, ('3', '6'), {'test': 'a, b, c'})
-    (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
-    (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
-    (3, (), {'test': 'x=fish(3)'})
-    
-    >>> v = Validator()
-    >>> v.check('integer(default=6)', '3')
-    3
-    >>> v.check('integer(default=6)', None, True)
-    6
-    >>> v.get_default_value('integer(default=6)')
-    6
-    >>> v.get_default_value('float(default=6)')
-    6.0
-    >>> v.get_default_value('pass(default=None)')
-    >>> v.get_default_value("string(default='None')")
-    'None'
-    >>> v.get_default_value('pass')
-    Traceback (most recent call last):
-    KeyError: 'Check "pass" has no default value.'
-    >>> v.get_default_value('pass(default=list(1, 2, 3, 4))')
-    ['1', '2', '3', '4']
-    
-    >>> v = Validator()
-    >>> v.check("pass(default=None)", None, True)
-    >>> v.check("pass(default='None')", None, True)
-    'None'
-    >>> v.check('pass(default="None")', None, True)
-    'None'
-    >>> v.check('pass(default=list(1, 2, 3, 4))', None, True)
-    ['1', '2', '3', '4']
-    
-    Bug test for unicode arguments
-    >>> v = Validator()
-    >>> v.check(u'string(min=4)', u'test')
-    u'test'
-    
-    >>> v = Validator()
-    >>> v.get_default_value(u'string(min=4, default="1234")')
-    u'1234'
-    >>> v.check(u'string(min=4, default="1234")', u'test')
-    u'test'
-    
-    >>> v = Validator()
-    >>> default = v.get_default_value('string(default=None)')
-    >>> default == None
-    1
-    """
-    return (value, args, keywargs)
-
-
-def _test2():
-    """
-    >>> 
-    >>> v = Validator()
-    >>> v.get_default_value('string(default="#ff00dd")')
-    '#ff00dd'
-    >>> v.get_default_value('integer(default=3) # comment')
-    3
-    """
-
-def _test3():
-    r"""
-    >>> vtor.check('string(default="")', '', missing=True)
-    ''
-    >>> vtor.check('string(default="\n")', '', missing=True)
-    '\n'
-    >>> print vtor.check('string(default="\n")', '', missing=True),
-    <BLANKLINE>
-    >>> vtor.check('string()', '\n')
-    '\n'
-    >>> vtor.check('string(default="\n\n\n")', '', missing=True)
-    '\n\n\n'
-    >>> vtor.check('string()', 'random \n text goes here\n\n')
-    'random \n text goes here\n\n'
-    >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")',
-    ... '', missing=True)
-    ' \nrandom text\ngoes \n here\n\n '
-    >>> vtor.check("string(default='\n\n\n')", '', missing=True)
-    '\n\n\n'
-    >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True)
-    '\n'
-    >>> vtor.check("string_list()", ['foo', '\n', 'bar'])
-    ['foo', '\n', 'bar']
-    >>> vtor.check("string_list(default=list('\n'))", '', missing=True)
-    ['\n']
-    """
-
-if __name__ == '__main__':
-    # run the code tests in doctest format
-    import sys
-    import doctest
-    m = sys.modules.get('__main__')
-    globs = m.__dict__.copy()
-    globs.update({
-        'vtor': Validator(),
-    })
-    doctest.testmod(m, globs=globs)
\ No newline at end of file
diff --git a/astropy/extern/six.py b/astropy/extern/six.py
index e95bdfb..1274700 100644
--- a/astropy/extern/six.py
+++ b/astropy/extern/six.py
@@ -8,7 +8,7 @@ import imp
 from distutils.version import StrictVersion
 
 
-_SIX_MIN_VERSION = StrictVersion('1.5.0')
+_SIX_MIN_VERSION = StrictVersion('1.7.3')
 
 # Update this to prevent Astropy from using its bundled copy of six
 # (but only if some other version of at least _SIX_MIN_VERSION can
diff --git a/astropy/io/ascii/__init__.py b/astropy/io/ascii/__init__.py
index b5430a4..f905c30 100644
--- a/astropy/io/ascii/__init__.py
+++ b/astropy/io/ascii/__init__.py
@@ -6,6 +6,7 @@
 from __future__ import absolute_import, division, print_function
 
 from .core import (InconsistentTableError,
+                   ParameterError,
                    NoType, StrType, NumType, FloatType, IntType, AllType,
                    Column,
                    BaseInputter, ContinuationLinesInputter,
@@ -17,13 +18,20 @@ from .core import (InconsistentTableError,
                    convert_numpy,
                    masked
                    )
-from .basic import (Basic,
+from .basic import (Basic, BasicHeader, BasicData,
                     Rdb,
                     Csv,
                     Tab,
                     NoHeader,
                     CommentedHeader)
+from .fastbasic import (FastBasic,
+                        FastCsv,
+                        FastTab,
+                        FastNoHeader,
+                        FastCommentedHeader,
+                        FastRdb)
 from .cds import Cds
+from .ecsv import Ecsv
 from .latex import Latex, AASTex, latexdicts
 from .html import HTML
 from .ipac import Ipac
diff --git a/astropy/io/ascii/basic.py b/astropy/io/ascii/basic.py
index 2b538ed..b3fb166 100644
--- a/astropy/io/ascii/basic.py
+++ b/astropy/io/ascii/basic.py
@@ -13,9 +13,29 @@ from __future__ import absolute_import, division, print_function
 
 import re
 
-import numpy as np
-
 from . import core
+from ...table.column import col_getattr
+
+class BasicHeader(core.BaseHeader):
+    '''Basic table Header Reader
+
+    Set a few defaults for common ascii table formats
+    (start at line 0, comments begin with ``#`` and possibly white space)
+    '''
+    start_line = 0
+    comment = r'\s*#'
+    write_comment = '# '
+
+
+class BasicData(core.BaseData):
+    '''Basic table Data Reader
+
+    Set a few defaults for common ascii table formats
+    (start at line 1, comments begin with ``#`` and possibly white space)
+    '''
+    start_line = 1
+    comment = r'\s*#'
+    write_comment = '# '
 
 
 class Basic(core.BaseReader):
@@ -47,17 +67,24 @@ class Basic(core.BaseReader):
     _format_name = 'basic'
     _description = 'Basic table with custom delimiters'
 
-    def __init__(self):
-        core.BaseReader.__init__(self)
-        self.header.splitter.delimiter = ' '
-        self.data.splitter.delimiter = ' '
-        self.header.start_line = 0
-        self.data.start_line = 1
-        self.header.comment = r'\s*#'
-        self.header.write_comment = '# '
-        self.data.comment = r'\s*#'
-        self.data.write_comment = '# '
+    header_class = BasicHeader
+    data_class = BasicData
+
+
+class NoHeaderHeader(BasicHeader):
+    '''Reader for table header without a header
+
+    Set the start of header line number to `None`, which tells the basic
+    reader there is no header line.
+    '''
+    start_line = None
 
+class NoHeaderData(BasicData):
+    '''Reader for table data without a header
+
+    Data starts at first uncommented line since there is no header line.
+    '''
+    start_line = 0
 
 class NoHeader(Basic):
     """Read a table with no header line.  Columns are autonamed using
@@ -70,14 +97,11 @@ class NoHeader(Basic):
     """
     _format_name = 'no_header'
     _description = 'Basic table with no headers'
-
-    def __init__(self):
-        Basic.__init__(self)
-        self.header.start_line = None
-        self.data.start_line = 0
+    header_class = NoHeaderHeader
+    data_class = NoHeaderData
 
 
-class CommentedHeaderHeader(core.BaseHeader):
+class CommentedHeaderHeader(BasicHeader):
     """Header class for which the column definition line starts with the
     comment character.  See the :class:`CommentedHeader` class  for an example.
     """
@@ -94,7 +118,7 @@ class CommentedHeaderHeader(core.BaseHeader):
         lines.append(self.write_comment + self.splitter.join(self.colnames))
 
 
-class CommentedHeader(core.BaseReader):
+class CommentedHeader(Basic):
     """Read a file where the column names are given in a line that begins with
     the header comment character. ``header_start`` can be used to specify the
     line index of column names, and it can be a negative index (for example -1
@@ -109,26 +133,43 @@ class CommentedHeader(core.BaseReader):
     _format_name = 'commented_header'
     _description = 'Column names in a commented line'
 
-    def __init__(self):
-        core.BaseReader.__init__(self)
-        self.header = CommentedHeaderHeader()
-        self.header.data = self.data
-        self.data.header = self.header
-        self.header.splitter.delimiter = ' '
-        self.data.splitter.delimiter = ' '
-        self.header.start_line = 0
-        self.data.start_line = 0
-        self.header.comment = r'\s*#'
-        self.header.write_comment = '# '
-        self.data.comment = r'\s*#'
-        self.data.write_comment = '# '
+    header_class = CommentedHeaderHeader
+    data_class = NoHeaderData
+
+    def write_header(self, lines, meta):
+        """
+        Write comment lines after, rather than before, the header.
+        """
+        self.header.write(lines)
+        self.header.write_comments(lines, meta)
+
+
+class TabHeaderSplitter(core.DefaultSplitter):
+    '''Split lines on tab and do not remove whitespace'''
+    delimiter = '\t'
+    process_line = None
+
+
+class TabDataSplitter(TabHeaderSplitter):
+    '''Don't strip data value whitespace since that is significant in TSV tables'''
+    process_val = None
+    skipinitialspace = False
+
+class TabHeader(BasicHeader):
+    '''Reader for header of tables with tab separated header'''
+    splitter_class = TabHeaderSplitter
+
+
+class TabData(BasicData):
+    '''Reader for data of tables with tab separated data '''
+    splitter_class = TabDataSplitter
 
 
 class Tab(Basic):
     """Read a tab-separated file.  Unlike the :class:`Basic` reader, whitespace is
     not stripped from the beginning and end of either lines or individual column
     values.
-    
+
     Example::
 
       col1 <tab> col2 <tab> col3
@@ -137,17 +178,28 @@ class Tab(Basic):
     """
     _format_name = 'tab'
     _description = 'Basic table with tab-separated values'
+    header_class = TabHeader
+    data_class = TabData
+
+
+class CsvSplitter(core.DefaultSplitter):
+    '''Split on comma for CSV (comma-separated-value) tables'''
+    delimiter = ','
+
 
-    def __init__(self):
-        Basic.__init__(self)
-        self.header.splitter.delimiter = '\t'
-        self.data.splitter.delimiter = '\t'
-        # Don't strip line whitespace since that includes tabs
-        self.header.splitter.process_line = None
-        self.data.splitter.process_line = None
-        # Don't strip data value whitespace since that is significant in TSV tables
-        self.data.splitter.process_val = None
-        self.data.splitter.skipinitialspace = False
+class CsvHeader(BasicHeader):
+    '''Header that uses the :class:`astropy.io.ascii.basic.CsvSplitter`'''
+    splitter_class = CsvSplitter
+    comment = None
+    write_comment = None
+
+
+class CsvData(BasicData):
+    '''Data that uses the :class:`astropy.io.ascii.basic.CsvSplitter`'''
+    splitter_class = CsvSplitter
+    fill_values = [(core.masked, '')]
+    comment = None
+    write_comment = None
 
 
 class Csv(Basic):
@@ -160,7 +212,7 @@ class Csv(Basic):
       2,38.12321,-88.1321,2.2,17.0
 
     Plain csv (comma separated value) files typically contain as many entries
-    as there are columns on each line. In contrast, common spreadsheed editors
+    as there are columns on each line. In contrast, common spreadsheet editors
     stop writing if all remaining cells on a line are empty, which can lead to
     lines where the rightmost entries are missing. This Reader can deal with
     such files.
@@ -176,17 +228,11 @@ class Csv(Basic):
       2,38.12321,-88.1321,2.2,17.0
     """
     _format_name = 'csv'
-    _io_registry_suffix = '.csv'
     _io_registry_can_write = True
     _description = 'Comma-separated-values'
 
-    def __init__(self):
-        core.BaseReader.__init__(self)
-        self.data.splitter.delimiter = ','
-        self.header.splitter.delimiter = ','
-        self.header.start_line = 0
-        self.data.start_line = 1
-        self.data.fill_values = [(core.masked, '')]
+    header_class = CsvHeader
+    data_class = CsvData
 
     def inconsistent_handler(self, str_vals, ncols):
         '''Adjust row if it is too short.
@@ -206,41 +252,16 @@ class Csv(Basic):
         return str_vals
 
 
-class Rdb(Tab):
-    """Read a tab-separated file with an extra line after the column definition
-    line.  The RDB format meets this definition.  Example::
-
-      col1 <tab> col2 <tab> col3
-      N <tab> S <tab> N
-      1 <tab> 2 <tab> 5
-
-    In this reader the second line is just ignored.
-    """
-    _format_name = 'rdb'
-    _io_registry_format_aliases = ['rdb']
-    _io_registry_suffix = '.rdb'
-    _description = 'Tab-separated with a type definition header line'
-
-    def __init__(self):
-        Tab.__init__(self)
-        self.header = RdbHeader()
-        self.header.start_line = 0
-        self.header.comment = r'\s*#'
-        self.header.write_comment = '# '
-        self.header.splitter.delimiter = '\t'
-        self.header.splitter.process_line = None
-        self.header.data = self.data
-        self.data.header = self.header
-        self.data.start_line = 2
-
-
-class RdbHeader(core.BaseHeader):
+class RdbHeader(TabHeader):
+    '''Header for RDB tables'''
     col_type_map = {'n': core.NumType,
                     's': core.StrType}
 
+
     def get_type_map_key(self, col):
         return col.raw_type[-1]
 
+
     def get_cols(self, lines):
         """Initialize the header Column objects from the table ``lines``.
 
@@ -269,12 +290,37 @@ class RdbHeader(core.BaseHeader):
             col.raw_type = raw_type
             col.type = self.get_col_type(col)
 
+
     def write(self, lines):
         lines.append(self.splitter.join(self.colnames))
         rdb_types = []
         for col in self.cols:
             # Check if dtype.kind is string or unicode.  See help(np.core.numerictypes)
-            rdb_type = 'S' if col.dtype.kind in ('S', 'U') else 'N'
+            rdb_type = 'S' if col_getattr(col, 'dtype').kind in ('S', 'U') else 'N'
             rdb_types.append(rdb_type)
 
         lines.append(self.splitter.join(rdb_types))
+
+
+class RdbData(TabData):
+    '''Data reader for RDB data. Starts reading at line 2.'''
+    start_line = 2
+
+
+class Rdb(Tab):
+    """Read a tab-separated file with an extra line after the column definition
+    line.  The RDB format meets this definition.  Example::
+
+      col1 <tab> col2 <tab> col3
+      N <tab> S <tab> N
+      1 <tab> 2 <tab> 5
+
+    In this reader the second line is just ignored.
+    """
+    _format_name = 'rdb'
+    _io_registry_format_aliases = ['rdb']
+    _io_registry_suffix = '.rdb'
+    _description = 'Tab-separated with a type definition header line'
+
+    header_class = RdbHeader
+    data_class = RdbData
diff --git a/astropy/io/ascii/cds.py b/astropy/io/ascii/cds.py
index 62540ee..4f9aa0c 100644
--- a/astropy/io/ascii/cds.py
+++ b/astropy/io/ascii/cds.py
@@ -30,6 +30,9 @@ class CdsHeader(core.BaseHeader):
                     'i': core.IntType,
                     'a': core.StrType}
 
+    'The ReadMe file to construct header from.'
+    readme = None
+
     def get_type_map_key(self, col):
         match = re.match(r'\d*(\S)', col.raw_type.lower())
         if not match:
@@ -37,20 +40,6 @@ class CdsHeader(core.BaseHeader):
                 col.raw_type, col.name))
         return match.group(1)
 
-    def __init__(self, readme=None):
-        """Initialize ReadMe filename.
-
-        :param readme: The ReadMe file to construct header from.
-        :type readme: String
-
-        CDS tables have their header information in a separate file
-        named "ReadMe". The ``get_cols`` method will read the contents
-        of the ReadMe file given by ``self.readme`` and set the various
-        properties needed to read the data file. The data file name
-        will be the ``table`` passed to the ``read`` method.
-        """
-        core.BaseHeader.__init__(self)
-        self.readme = readme
 
     def get_cols(self, lines):
         """Initialize the header Column objects from the table ``lines`` for a CDS
@@ -234,12 +223,12 @@ class Cds(core.BaseReader):
       >>> table = ascii.read("t/vizier/table1.dat", readme="t/vizier/ReadMe")
       >>> table = ascii.read("t/cds/multi/lhs2065.dat", readme="t/cds/multi/ReadMe")
       >>> table = ascii.read("t/cds/glob/lmxbrefs.dat", readme="t/cds/glob/ReadMe")
-      
-    The table name and the CDS ReadMe file can be entered as URLs.  This can be used 
-    to directly load tables from the Internet.  For example, Vizier tables from the 
+
+    The table name and the CDS ReadMe file can be entered as URLs.  This can be used
+    to directly load tables from the Internet.  For example, Vizier tables from the
     CDS::
 
-      >>> table = ascii.read("ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/snrs.dat", 
+      >>> table = ascii.read("ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/snrs.dat",
       ...             readme="ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/ReadMe")
 
     If the header (ReadMe) and data are stored in a single file and there
@@ -287,10 +276,12 @@ class Cds(core.BaseReader):
     _io_registry_can_write = False
     _description = 'CDS format table'
 
+    data_class = CdsData
+    header_class = CdsHeader
+
     def __init__(self, readme=None):
-        core.BaseReader.__init__(self)
-        self.header = CdsHeader(readme)
-        self.data = CdsData()
+        super(Cds, self).__init__()
+        self.header.readme = readme
 
     def write(self, table=None):
         """Not available for the Cds class (raises NotImplementedError)"""
diff --git a/astropy/io/ascii/connect.py b/astropy/io/ascii/connect.py
index 0c78684..4ad2a9a 100644
--- a/astropy/io/ascii/connect.py
+++ b/astropy/io/ascii/connect.py
@@ -4,6 +4,7 @@
 from __future__ import absolute_import, division, print_function
 
 import re
+import functools
 
 from .. import registry as io_registry
 from ...table import Table
@@ -56,15 +57,37 @@ def _get_connectors_table():
 
         io_format = 'ascii.' + cls._format_name
         description = getattr(cls, '_description', '')
-        class_link = ':class:`~{}.{}`'.format(cls.__module__, cls.__name__)
+        class_link = ':class:`~{0}.{1}`'.format(cls.__module__, cls.__name__)
         suffix = getattr(cls, '_io_registry_suffix', '')
         can_write = 'Yes' if getattr(cls, '_io_registry_can_write', True) else ''
 
         rows.append((io_format, suffix, can_write,
-                     '{}: {}'.format(class_link, description)))
+                     '{0}: {1}'.format(class_link, description)))
     out = Table(list(zip(*rows)), names=('Format', 'Suffix', 'Write', 'Description'))
     for colname in ('Format', 'Description'):
         width = max(len(x) for x in out[colname])
-        out[colname].format = '%-{}s'.format(width)
+        out[colname].format = '%-{0}s'.format(width)
 
     return out
+
+
+# Specific
+# ========
+
+def read_csv(filename, **kwargs):
+    from .ui import read
+    kwargs['format'] = 'csv'
+    return read(filename, **kwargs)
+
+
+def write_csv(table, filename, **kwargs):
+    from .ui import write
+    kwargs['format'] = 'csv'
+    return write(table, filename, **kwargs)
+
+
+csv_identify = functools.partial(io_identify, '.csv')
+
+io_registry.register_reader('csv', Table, read_csv)
+io_registry.register_writer('csv', Table, write_csv)
+io_registry.register_identifier('csv', Table, csv_identify)
diff --git a/astropy/io/ascii/core.py b/astropy/io/ascii/core.py
index f3da6d8..deb16fa 100644
--- a/astropy/io/ascii/core.py
+++ b/astropy/io/ascii/core.py
@@ -17,6 +17,7 @@ import itertools
 import functools
 import numpy
 import warnings
+import copy
 
 from ...extern import six
 from ...extern.six.moves import zip
@@ -24,6 +25,7 @@ from ...extern.six.moves import cStringIO as StringIO
 from ...utils.exceptions import AstropyWarning
 
 from ...table import Table
+from ...table.column import col_getattr, col_setattr, col_iter_str_vals
 from ...utils.compat import ignored
 from ...utils.data import get_readable_fileobj
 from ...utils import OrderedDict
@@ -32,6 +34,9 @@ from . import connect
 # Global dictionary mapping format arg to the corresponding Reader class
 FORMAT_CLASSES = {}
 
+# Similar dictionary for fast readers
+FAST_CLASSES = {}
+
 class MaskedConstant(numpy.ma.core.MaskedConstant):
     """A trivial extension of numpy.ma.masked
 
@@ -64,6 +69,20 @@ class OptionalTableImportError(ImportError):
     an ImportError.
     """
 
+class ParameterError(NotImplementedError):
+    """
+    Indicates that a reader cannot handle a passed parameter.
+
+    The C-based fast readers in ``io.ascii`` raise an instance of
+    this error class upon encountering a parameter that the
+    C engine cannot handle.
+    """
+
+class FastOptionsError(NotImplementedError):
+    """
+    Indicates that one of the specified options for fast
+    reading is invalid.
+    """
 
 class NoType(object):
     """
@@ -92,6 +111,12 @@ class FloatType(NumType):
     """
 
 
+class BoolType(NoType):
+    """
+    Describes boolean data.
+    """
+
+
 class IntType(NumType):
     """
     Describes integer data.
@@ -114,12 +139,14 @@ class Column(object):
 
     * **name** : column name
     * **type** : column type (NoType, StrType, NumType, FloatType, IntType)
+    * **dtype** : numpy dtype (optional, overrides **type** if set)
     * **str_vals** : list of column values as strings
     * **data** : list of converted column values
     """
     def __init__(self, name):
         self.name = name
-        self.type = NoType
+        self.type = NoType  # Generic type (Int, Float, Str etc)
+        self.dtype = None  # Numpy dtype if available
         self.str_vals = []
         self.fill_values = {}
 
@@ -245,6 +272,9 @@ class DefaultSplitter(BaseSplitter):
     escapechar = None
     quoting = csv.QUOTE_MINIMAL
     skipinitialspace = True
+    csv_writer = None
+    csv_writer_out = StringIO()
+
 
     def process_line(self, line):
         """Remove whitespace at the beginning or end of line.  This is especially useful for
@@ -254,9 +284,6 @@ class DefaultSplitter(BaseSplitter):
             line = _replace_tab_with_space(line, self.escapechar, self.quotechar)
         return line.strip()
 
-    def __init__(self):
-        self.csv_writer = None
-        self.csv_writer_out = StringIO()
 
     def __call__(self, lines):
         """Return an iterator over the table ``lines``, where each iterator output
@@ -362,10 +389,11 @@ class BaseHeader(object):
     comment = None
     splitter_class = DefaultSplitter
     names = None
+    write_comment = False
     write_spacer_lines = ['ASCII_TABLE_WRITE_SPACER_LINE']
 
     def __init__(self):
-        self.splitter = self.__class__.splitter_class()
+        self.splitter = self.splitter_class()
 
     def _set_cols_from_names(self):
         self.cols = [Column(name=x) for x in self.names]
@@ -374,8 +402,17 @@ class BaseHeader(object):
         """
         Extract any table-level metadata, e.g. keywords, comments, column metadata, from
         the table ``lines`` and update the OrderedDict ``meta`` in place.  This base
-        method does nothing.
+        method extracts comment lines and stores them in ``meta`` for output.
         """
+        if self.comment:
+            re_comment = re.compile(self.comment)
+            comment_lines = [x for x in lines if re_comment.match(x)]
+        else:
+            comment_lines = []
+        comment_lines = [re.sub('^' + self.comment, '', x).strip()
+                         for x in comment_lines]
+        if comment_lines:
+            meta.setdefault('table', {})['comments'] = comment_lines
 
     def get_cols(self, lines):
         """Initialize the header Column objects from the table ``lines``.
@@ -419,17 +456,23 @@ class BaseHeader(object):
             if line and (not self.comment or not re_comment.match(line)):
                 yield line
 
+    def write_comments(self, lines, meta):
+        if self.write_comment is not False:
+            for comment in meta.get('comments', []):
+                lines.append(self.write_comment + comment)
+
     def write(self, lines):
         if self.start_line is not None:
             for i, spacer_line in zip(range(self.start_line),
                                       itertools.cycle(self.write_spacer_lines)):
                 lines.append(spacer_line)
-            lines.append(self.splitter.join([x.name for x in self.cols]))
+            lines.append(self.splitter.join([col_getattr(x, 'name') for x in self.cols]))
 
     @property
     def colnames(self):
         """Return the column names of the table"""
-        return tuple(col.name for col in self.cols)
+        return tuple(col.name if isinstance(col, Column) else col_getattr(col, 'name')
+                     for col in self.cols)
 
     def get_type_map_key(self, col):
         return col.raw_type
@@ -442,6 +485,35 @@ class BaseHeader(object):
             raise ValueError('Unknown data type ""%s"" for column "%s"' % (
                 col.raw_type, col.name))
 
+    def check_column_names(self, names, strict_names, guessing):
+        """Check column names.
+
+        This must be done before applying the names transformation
+        so that guessing will fail appropriately if `names` is supplied.
+        For instance if the basic reader is given a table with no column header
+        row.
+
+        :param names: user-supplied list of column names
+        :param strict_names: whether to impose extra requirements on names
+        """
+        if strict_names:
+            # Impose strict requirements on column names (normally used in guessing)
+            bads = [" ", ",", "|", "\t", "'", '"']
+            for name in self.colnames:
+                if (_is_number(name) or
+                    len(name) == 0 or
+                    name[0] in bads or
+                    name[-1] in bads):
+                    raise ValueError('Column name {0!r} does not meet strict name requirements'
+                                     .format(name))
+        # When guessing require at least two columns
+        if guessing and len(self.colnames) <= 1:
+            raise ValueError
+
+        if names is not None and len(names) != len(self.colnames):
+            raise ValueError('Length of names argument ({0}) does not match number'
+                             ' of table columns ({1})'.format(len(names), len(self.colnames)))
+
 
 class BaseData(object):
     """Base table data reader.
@@ -458,16 +530,18 @@ class BaseData(object):
     write_spacer_lines = ['ASCII_TABLE_WRITE_SPACER_LINE']
     fill_include_names = None
     fill_exclude_names = None
+    # Currently, the default matches the numpy default for masked values.
+    fill_values = [(masked, '--')]
+    formats = {}
 
     def __init__(self):
         # Need to make sure fill_values list is instance attribute, not class attribute.
         # On read, this will be overwritten by the default in the ui.read (thus, in
         # the current implementation there can be no different default for different
         # Readers). On write, ui.py does not specify a default, so this line here matters.
-        # Currently, the default matches the numpy default for masked values. 
-        self.fill_values = [(masked, '--')]
-        self.formats = {}
-        self.splitter = self.__class__.splitter_class()
+        self.fill_values = copy.copy(self.fill_values)
+        self.formats = copy.copy(self.formats)
+        self.splitter = self.splitter_class()
 
     def process_lines(self, lines):
         """Strip out comment lines and blank lines from list of ``lines``
@@ -576,6 +650,15 @@ class BaseData(object):
                     for i in col.mask.nonzero()[0]:
                         col.str_vals[i] = mask_val
 
+    def str_vals(self):
+        '''convert all values in table to a list of lists of strings'''
+        self._set_fill_values(self.cols)
+        self._set_col_formats()
+        for col in self.cols:
+            col.str_vals = list(col_iter_str_vals(col))
+        self._replace_vals(self.cols)
+        return [col.str_vals for col in self.cols]
+
     def write(self, lines):
         if hasattr(self.start_line, '__call__'):
             raise TypeError('Start_line attribute cannot be callable for write()')
@@ -585,12 +668,7 @@ class BaseData(object):
         while len(lines) < data_start_line:
             lines.append(itertools.cycle(self.write_spacer_lines))
 
-        self._set_fill_values(self.cols)
-        self._set_col_formats()
-        for col in self.cols:
-            col.str_vals = list(col.iter_str_vals())
-        self._replace_vals(self.cols)
-        col_str_iters = [col.str_vals for col in self.cols]
+        col_str_iters = self.str_vals()
         for vals in zip(*col_str_iters):
             lines.append(self.splitter.join(vals))
 
@@ -598,8 +676,8 @@ class BaseData(object):
         """
         """
         for col in self.cols:
-            if col.name in self.formats:
-                col.format = self.formats[col.name]
+            if col_getattr(col, 'name') in self.formats:
+                col_setattr(col, 'format', self.formats[col.name])
 
 
 def convert_numpy(numpy_type):
@@ -618,13 +696,35 @@ def convert_numpy(numpy_type):
         converter_type = IntType
     elif 'float' in type_name:
         converter_type = FloatType
+    elif 'bool' in type_name:
+        converter_type = BoolType
     elif 'str' in type_name:
         converter_type = StrType
     else:
         converter_type = AllType
 
-    def converter(vals):
+    def bool_converter(vals):
+        """
+        Convert values "False" and "True" to bools.  Raise an exception
+        for any other string values.
+        """
+        # Try a smaller subset first for a long array
+        if len(vals) > 10000:
+            svals = numpy.asarray(vals[:1000])
+            if not numpy.all((svals == 'False') | (svals == 'True')):
+                raise ValueError('bool input strings must be only False or True')
+        vals = numpy.asarray(vals)
+        trues = vals == 'True'
+        falses = vals == 'False'
+        if not numpy.all(trues | falses):
+            raise ValueError('bool input strings must be only False or True')
+        return trues
+
+    def generic_converter(vals):
         return numpy.array(vals, numpy_type)
+
+    converter = bool_converter if converter_type is BoolType else generic_converter
+
     return converter, converter_type
 
 
@@ -656,8 +756,14 @@ class BaseOutputter(object):
 
     def _convert_vals(self, cols):
         for col in cols:
-            converters = self.converters.get(col.name,
-                                             self.default_converters)
+            # If a specific dtype was specified for a column, then use that
+            # to set the defaults, otherwise use the generic defaults.
+            default_converters = ([convert_numpy(col.dtype)] if col.dtype
+                                  else self.default_converters)
+
+            # If the user supplied a specific convert then that takes precedence over defaults
+            converters = self.converters.get(col.name, default_converters)
+
             col.converters = self._validate_and_copy(col, converters)
 
             while not hasattr(col, 'data'):
@@ -703,6 +809,8 @@ class TableOutputter(BaseOutputter):
             for attr in ('format', 'unit', 'description'):
                 if hasattr(col, attr):
                     setattr(out_col, attr, getattr(col, attr))
+            if hasattr(col, 'meta'):
+                out_col.meta.update(col.meta)
 
         return out
 
@@ -715,6 +823,10 @@ class MetaBaseReader(type):
         if format is None:
             return
 
+        fast = dct.get('_fast')
+        if fast is not None:
+            FAST_CLASSES[format] = cls
+
         FORMAT_CLASSES[format] = cls
 
         io_formats = ['ascii.' + format] + dct.get('_io_registry_format_aliases', [])
@@ -738,36 +850,17 @@ def _is_number(x):
         return True
     return False
 
-
-def _apply_include_exclude_names(table, names, include_names, exclude_names, strict_names):
+def _apply_include_exclude_names(table, names, include_names, exclude_names):
     """Apply names, include_names and exclude_names to a table.
 
     :param table: input table (Reader object, NumPy struct array, list of lists, etc)
     :param names: list of names to override those in table (default=None uses existing names)
     :param include_names: list of names to include in output (default=None selects all names)
-    :param exclude_names: list of names to exlude from output (applied after ``include_names``)
-    :param strict_names: apply strict checks on column names
+    :param exclude_names: list of names to exclude from output (applied after ``include_names``)
     """
-    # Check column names.  This must be done before applying the names transformation
-    # so that guessing will fail appropriately if `names` is supplied.  For instance
-    # if the basic reader is given a table with no column header row.
-    if strict_names:
-        # Impose strict requirements on column names (normally used in guessing)
-        bads = [" ", ",", "|", "\t", "'", '"']
-        for name in table.colnames:
-            if (_is_number(name) or
-                    len(name) == 0 or
-                    name[0] in bads or
-                    name[-1] in bads):
-                raise ValueError('Column name {0!r} does not meet strict name requirements'
-                                 .format(name))
 
     if names is not None:
         # Rename table column names to those passed by user
-        if len(names) != len(table.colnames):
-            raise ValueError('Length of names argument ({0}) does not match number'
-                             ' of table columns ({1})'.format(len(names), len(table.colnames)))
-
         # Temporarily rename with names that are not in `names` or `table.colnames`.
         # This ensures that rename succeeds regardless of existing names.
         xxxs = 'x' * max(len(name) for name in list(names) + list(table.colnames))
@@ -806,12 +899,18 @@ class BaseReader(object):
     include_names = None
     exclude_names = None
     strict_names = False
+    guessing = False
+
+    header_class = BaseHeader
+    data_class = BaseData
+    inputter_class = BaseInputter
+    outputter_class = TableOutputter
 
     def __init__(self):
-        self.header = BaseHeader()
-        self.data = BaseData()
-        self.inputter = BaseInputter()
-        self.outputter = TableOutputter()
+        self.header = self.header_class()
+        self.data = self.data_class()
+        self.inputter = self.inputter_class()
+        self.outputter = self.outputter_class()
         # Data and Header instances benefit from a little cross-coupling.  Header may need to
         # know about number of data columns for auto-column name generation and Data may
         # need to know about header (e.g. for fixed-width tables where widths are spec'd in header.
@@ -848,10 +947,6 @@ class BaseReader(object):
             if os.linesep not in table + '':
                 self.data.table_name = os.path.basename(table)
 
-        # Same from __init__.  ??? Do these need to be here?
-        self.data.header = self.header
-        self.header.data = self.data
-
         # Get a list of the lines (rows) in the table
         self.lines = self.inputter.get_lines(table)
 
@@ -864,23 +959,27 @@ class BaseReader(object):
         # Get the table column definitions
         self.header.get_cols(self.lines)
 
-        cols = self.header.cols
+        # Make sure columns are valid
+        self.header.check_column_names(self.names, self.strict_names, self.guessing)
+
+        self.cols = cols = self.header.cols
         self.data.splitter.cols = cols
+        n_cols = len(cols)
 
         for i, str_vals in enumerate(self.data.get_str_vals()):
-            if len(str_vals) != len(cols):
-                str_vals = self.inconsistent_handler(str_vals, len(cols))
+            if len(str_vals) != n_cols:
+                str_vals = self.inconsistent_handler(str_vals, n_cols)
 
                 # if str_vals is None, we skip this row
                 if str_vals is None:
                     continue
 
                 # otherwise, we raise an error only if it is still inconsistent
-                if len(str_vals) != len(cols):
+                if len(str_vals) != n_cols:
                     errmsg = ('Number of header columns (%d) inconsistent with '
                               'data columns (%d) at data line %d\n'
                               'Header values: %s\n'
-                              'Data values: %s' % (len(cols), len(str_vals), i,
+                              'Data values: %s' % (n_cols, len(str_vals), i,
                                                    [x.name for x in cols], str_vals))
                     raise InconsistentTableError(errmsg)
 
@@ -889,10 +988,11 @@ class BaseReader(object):
 
         self.data.masks(cols)
         table = self.outputter(cols, self.meta)
+        if hasattr(self.header, 'table_meta'):
+            table.meta.update(self.header.table_meta)
         self.cols = self.header.cols
 
-        _apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names,
-                                     self.strict_names)
+        _apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names)
 
         return table
 
@@ -920,7 +1020,7 @@ class BaseReader(object):
     def comment_lines(self):
         """Return lines in the table that match header.comment regexp"""
         if not hasattr(self, 'lines'):
-            raise ValueError('Table must be read prior to accessing the header_comment_lines')
+            raise ValueError('Table must be read prior to accessing the header comment lines')
         if self.header.comment:
             re_comment = re.compile(self.header.comment)
             comment_lines = [x for x in self.lines if re_comment.match(x)]
@@ -928,6 +1028,10 @@ class BaseReader(object):
             comment_lines = []
         return comment_lines
 
+    def write_header(self, lines, meta):
+        self.header.write_comments(lines, meta)
+        self.header.write(lines)
+
     def write(self, table):
         """Write ``table`` as list of strings.
 
@@ -935,16 +1039,22 @@ class BaseReader(object):
         :returns: list of strings corresponding to ASCII table
         """
 
-        _apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names,
-                                     self.strict_names)
+        # Check column names before altering
+        self.header.cols = list(six.itervalues(table.columns))
+        self.header.check_column_names(self.names, self.strict_names, False)
+
+        _apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names)
 
+        # Now use altered columns
+        new_cols = list(six.itervalues(table.columns))
         # link information about the columns to the writer object (i.e. self)
-        self.header.cols = list(six.itervalues(table.columns))
-        self.data.cols = list(six.itervalues(table.columns))
+        self.header.cols = new_cols
+        self.data.cols = new_cols
+        self.header.table_meta = table.meta
 
         # Write header and data to lines list
         lines = []
-        self.header.write(lines)
+        self.write_header(lines, table.meta)
         self.data.write(lines)
 
         return lines
@@ -1017,12 +1127,19 @@ def _get_reader(Reader, Inputter=None, Outputter=None, **kwargs):
     because it depends only on the "core" module.
     """
 
+    from .fastbasic import FastBasic
+    if issubclass(Reader, FastBasic): # Fast readers handle args separately
+        if Inputter is not None:
+            kwargs['Inputter'] = Inputter
+        return Reader(**kwargs)
+
+    if 'fast_reader' in kwargs:
+        del kwargs['fast_reader'] # ignore fast_reader parameter for slow readers
     reader_kwargs = dict([k, v] for k, v in kwargs.items() if k not in extra_reader_pars)
     reader = Reader(**reader_kwargs)
 
     if Inputter is not None:
         reader.inputter = Inputter()
-    reader.outputter = TableOutputter()
 
     if Outputter is not None:
         reader.outputter = Outputter()
@@ -1054,7 +1171,7 @@ def _get_reader(Reader, Inputter=None, Outputter=None, **kwargs):
             # However, position_line is given as absolute number and not relative to header_start.
             # So, ignore this Reader here.
             if (('data_start' not in kwargs) and (default_header_length is not None)
-                    and reader._format_name != 'fixed_width_two_line'):
+                    and reader._format_name not in ['fixed_width_two_line', 'commented_header']):
                 reader.data.start_line = reader.header.start_line + default_header_length
         elif kwargs['header_start'] is not None:
             # User trying to set a None header start to some value other than None
@@ -1074,7 +1191,7 @@ def _get_reader(Reader, Inputter=None, Outputter=None, **kwargs):
     # Strict names is normally set only within the guessing process to
     # indicate that column names cannot be numeric or have certain
     # characters at the beginning or end.  It gets used in
-    # core._apply_include_exclude_names().
+    # BaseHeader.check_column_names().
     if 'strict_names' in kwargs:
         reader.strict_names = kwargs['strict_names']
     if 'fill_values' in kwargs:
@@ -1093,11 +1210,20 @@ extra_writer_pars = ('delimiter', 'comment', 'quotechar', 'formats',
                      'fill_exclude_names')
 
 
-def _get_writer(Writer, **kwargs):
+def _get_writer(Writer, fast_writer, **kwargs):
     """Initialize a table writer allowing for common customizations. This
     routine is for internal (package) use only and is useful because it depends
     only on the "core" module. """
 
+    from .fastbasic import FastBasic
+
+    if issubclass(Writer, FastBasic): # Fast writers handle args separately
+        return Writer(**kwargs)
+    elif fast_writer and 'fast_{0}'.format(Writer._format_name) in FAST_CLASSES:
+        # Switch to fast writer
+        kwargs['fast_writer'] = fast_writer
+        return FAST_CLASSES['fast_{0}'.format(Writer._format_name)](**kwargs)
+
     writer_kwargs = dict([k, v] for k, v in kwargs.items() if k not in extra_writer_pars)
     writer = Writer(**writer_kwargs)
 
@@ -1117,9 +1243,7 @@ def _get_writer(Writer, **kwargs):
             # Restore the default SplitterClass process_val method which strips
             # whitespace.  This may have been changed in the Writer
             # initialization (e.g. Rdb and Tab)
-            Class = writer.data.splitter.__class__
-            obj = writer.data.splitter
-            writer.data.splitter.process_val = Class.process_val.__get__(obj, Class)
+            writer.data.splitter.process_val = lambda x: x.strip()
         else:
             writer.data.splitter.process_val = None
     if 'names' in kwargs:
diff --git a/astropy/io/ascii/cparser.c b/astropy/io/ascii/cparser.c
new file mode 100644
index 0000000..3dad656
--- /dev/null
+++ b/astropy/io/ascii/cparser.c
@@ -0,0 +1,28150 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+    x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__astropy__io__ascii__cparser
+#define __PYX_HAVE_API__astropy__io__ascii__cparser
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "src/tokenizer.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
+    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
+    (sizeof(type) > sizeof(Py_ssize_t) &&               \
+          likely(v < (type)PY_SSIZE_T_MAX ||            \
+                 v == (type)PY_SSIZE_T_MAX)  &&         \
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
+                                v == (type)PY_SSIZE_T_MIN)))  ||  \
+    (sizeof(type) == sizeof(Py_ssize_t) &&              \
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
+                               v == (type)PY_SSIZE_T_MAX)))  )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "astropy/io/ascii/cparser.pyx",
+  "__init__.pxd",
+  "type.pxd",
+};
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk;
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "astropy/io/ascii/cparser.pyx":113
+ *     ]))
+ * 
+ * cdef class FileString:             # <<<<<<<<<<<<<<
+ *     """
+ *     A wrapper class for a memory-mapped file pointer.
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString {
+  PyObject_HEAD
+  PyObject *fhandle;
+  PyObject *mmap;
+  void *mmap_ptr;
+  Py_buffer buf;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":162
+ *             ptr = tmp
+ * 
+ * cdef class CParser:             # <<<<<<<<<<<<<<
+ *     """
+ *     A fast Cython parser class which uses underlying C code
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *__pyx_vtab;
+  tokenizer_t *tokenizer;
+  PyObject *names;
+  int data_start;
+  PyObject *data_end;
+  PyObject *include_names;
+  PyObject *exclude_names;
+  PyObject *fill_values;
+  PyObject *fill_empty;
+  PyObject *fill_include_names;
+  PyObject *fill_exclude_names;
+  PyObject *fill_names;
+  int fill_extra_cols;
+  PyObject *source_bytes;
+  char *source_ptr;
+  PyObject *parallel;
+  PyObject *use_cols;
+  int width;
+  PyObject *source;
+  PyObject *header_start;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":805
+ *     reconvert_queue.put(reconvert_cols) # return to the queue for other processes
+ * 
+ * cdef class FastWriter:             # <<<<<<<<<<<<<<
+ *     """
+ *     A fast Cython writing class for writing tables
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_vtab;
+  PyObject *table;
+  PyObject *use_names;
+  PyObject *fill_values;
+  PyObject *fill_cols;
+  PyObject *col_iters;
+  PyObject *formats;
+  PyObject *format_funcs;
+  PyObject *types;
+  PyObject *line_comments;
+  PyObject *quotechar;
+  PyObject *delimiter;
+  int strip_whitespace;
+  PyObject *comment;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":148
+ *         return self.mmap[i]
+ * 
+ *     def splitlines(self):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a generator yielding lines from the memory map.
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines {
+  PyObject_HEAD
+  int __pyx_v_line_len;
+  int __pyx_v_map_len;
+  char *__pyx_v_ptr;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self;
+  char *__pyx_v_tmp;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":382
+ *                                   try_string, num_rows)
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         cdef int source_len = len(self.source)
+ *         self.tokenizer.source_pos = 0
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel {
+  PyObject_HEAD
+  PyObject *__pyx_v_col_chunks;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":396
+ * 
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in             # <<<<<<<<<<<<<<
+ *                          self.names), [])
+ * 
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *__pyx_outer_scope;
+  PyObject *__pyx_v_name;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+  PyObject *(*__pyx_t_2)(PyObject *);
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":496
+ * 
+ *             if self.data_end < 0: # no data
+ *                 chunks = [dict((name, []) for name in self.names)]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 line_no = 0
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *__pyx_outer_scope;
+  PyObject *__pyx_v_name;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+  PyObject *(*__pyx_t_2)(PyObject *);
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":512
+ *         for name in self.get_names():
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):             # <<<<<<<<<<<<<<
+ *                 ret[name] = ma.concatenate(col_chunks)
+ *             else:
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *__pyx_outer_scope;
+  PyObject *__pyx_v_col_chunk;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk {
+  PyObject_HEAD
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self;
+};
+
+
+/* "astropy/io/ascii/cparser.pyx":781
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())             # <<<<<<<<<<<<<<
+ *         line_comments = self._get_comments(chunk_tokenizer)
+ *     else:
+ */
+struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *__pyx_outer_scope;
+  PyObject *__pyx_v_name;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+  PyObject *(*__pyx_t_2)(PyObject *);
+};
+
+
+
+/* "astropy/io/ascii/cparser.pyx":162
+ *             ptr = tmp
+ * 
+ * cdef class CParser:             # <<<<<<<<<<<<<<
+ *     """
+ *     A fast Cython parser class which uses underlying C code
+ */
+
+struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser {
+  PyObject *(*get_error)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *, PyObject *, PyObject *);
+  PyObject *(*raise_error)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *);
+  PyObject *(*setup_tokenizer)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *, int __pyx_skip_dispatch);
+  PyObject *(*_set_fill_values)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *);
+  PyObject *(*_get_comments)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *);
+  PyObject *(*_convert_data)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, PyObject *, PyObject *, PyObject *, PyObject *);
+  PyArrayObject *(*_convert_int)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int);
+  PyArrayObject *(*_convert_float)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int);
+  PyObject *(*_convert_str)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int);
+};
+static struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *__pyx_vtabptr_7astropy_2io_5ascii_7cparser_CParser;
+
+
+/* "astropy/io/ascii/cparser.pyx":805
+ *     reconvert_queue.put(reconvert_cols) # return to the queue for other processes
+ * 
+ * cdef class FastWriter:             # <<<<<<<<<<<<<<
+ *     """
+ *     A fast Cython writing class for writing tables
+ */
+
+struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter {
+  PyObject *(*_write_comments)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *, PyObject *);
+};
+static struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_vtabptr_7astropy_2io_5ascii_7cparser_FastWriter;
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {                            \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_XDECREF(tmp);                              \
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {                             \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_DECREF(tmp);                               \
+    } while (0)
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+                                  int lineno, const char *filename,
+                                  int full_traceback);
+
+#include <string.h>
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+         const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+         const char* encoding, const char* errors,
+         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyCallable_Check(obj)   ((obj)->ob_type->tp_call != NULL)
+#else
+#define __Pyx_PyCallable_Check(obj)   PyCallable_Check(obj)
+#endif
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+    int result = PySequence_Contains(seq, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000
+static CYTHON_INLINE PyObject* __Pyx_PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name) {
+    PyObject *res;
+    PyTypeObject *tp = Py_TYPE(obj);
+#if PY_MAJOR_VERSION < 3
+    if (unlikely(PyInstance_Check(obj)))
+        return __Pyx_PyObject_GetAttrStr(obj, attr_name);
+#endif
+    res = _PyType_Lookup(tp, attr_name);
+    if (likely(res)) {
+        descrgetfunc f = Py_TYPE(res)->tp_descr_get;
+        if (!f) {
+            Py_INCREF(res);
+        } else {
+            res = f(res, obj, (PyObject *)tp);
+        }
+    } else {
+        PyErr_SetObject(PyExc_AttributeError, attr_name);
+    }
+    return res;
+}
+#else
+#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n)
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+#if PY_MAJOR_VERSION < 3
+#define __Pyx_PyString_Join __Pyx_PyBytes_Join
+#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
+#else
+#define __Pyx_PyString_Join PyUnicode_Join
+#define __Pyx_PyBaseString_Join PyUnicode_Join
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+    #if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyBytes_Join _PyString_Join
+    #else
+    #define __Pyx_PyBytes_Join _PyBytes_Join
+    #endif
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values);
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len)) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
+
+#ifndef __PYX_FORCE_INIT_THREADS
+  #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject* none = _PyList_Extend((PyListObject*)L, v);
+    if (unlikely(!none))
+        return -1;
+    Py_DECREF(none);
+    return 0;
+#else
+    return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+    int result = PyDict_Contains(dict, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            PyObject* args = PyTuple_Pack(1, key);
+            if (likely(args))
+                PyErr_SetObject(PyExc_KeyError, args);
+            Py_XDECREF(args);
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+#define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound) \
+    __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound)
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+        PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact);
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name);
+
+#define __Pyx_PyObject_Pop(L) (PyList_CheckExact(L) ? \
+    __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L))
+static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L);
+static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L);
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj);
+#if CYTHON_COMPILING_IN_PYPY
+#define __Pyx_PyObject_AsDouble(obj) \
+(likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \
+ likely(PyInt_CheckExact(obj)) ? \
+ PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
+#else
+#define __Pyx_PyObject_AsDouble(obj) \
+((likely(PyFloat_CheckExact(obj))) ? \
+ PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj))
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL)
+static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_setattro))
+        return tp->tp_setattro(obj, attr_name, value);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_setattr))
+        return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value);
+#endif
+    return PyObject_SetAttr(obj, attr_name, value);
+}
+#else
+#define __Pyx_PyObject_DelAttrStr(o,n)   PyObject_DelAttr(o,n)
+#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
+#endif
+
+#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL)
+static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+               __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop);
+static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop);
+#else
+#define __Pyx_PyList_GetSlice(seq, start, stop)   PySequence_GetSlice(seq, start, stop)
+#define __Pyx_PyTuple_GetSlice(seq, start, stop)  PySequence_GetSlice(seq, start, stop)
+#endif
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD  0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD   0x02
+#define __Pyx_CYFUNCTION_CCLASS        0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+    (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+    (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+    ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+    ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+    PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+    PyObject *func_weakreflist;
+#endif
+    PyObject *func_dict;
+    PyObject *func_name;
+    PyObject *func_qualname;
+    PyObject *func_doc;
+    PyObject *func_globals;
+    PyObject *func_code;
+    PyObject *func_closure;
+    PyObject *func_classobj;
+    void *defaults;
+    int defaults_pyobjects;
+    int flags;
+    PyObject *defaults_tuple;
+    PyObject *defaults_kwdict;
+    PyObject *(*defaults_getter)(PyObject *);
+    PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+    __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+                                      int flags, PyObject* qualname,
+                                      PyObject *self,
+                                      PyObject *module, PyObject *globals,
+                                      PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+                                                         size_t size,
+                                                         int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+                                                            PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+                                                             PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+                                                              PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases);
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname,
+                                           PyObject *mkw, PyObject *modname, PyObject *doc);
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict,
+                                      PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_char(char value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+#define __Pyx_Generator_USED
+#include <structmember.h>
+#include <frameobject.h>
+typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
+typedef struct {
+    PyObject_HEAD
+    __pyx_generator_body_t body;
+    PyObject *closure;
+    PyObject *exc_type;
+    PyObject *exc_value;
+    PyObject *exc_traceback;
+    PyObject *gi_weakreflist;
+    PyObject *classobj;
+    PyObject *yieldfrom;
+    PyObject *gi_name;
+    PyObject *gi_qualname;
+    int resume_label;
+    char is_running;
+} __pyx_GeneratorObject;
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+                                                  PyObject *closure, PyObject *name, PyObject *qualname);
+static int __pyx_Generator_init(void);
+static int __Pyx_Generator_clear(PyObject* self);
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
+#else
+#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
+#endif
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_get_error(CYTHON_UNUSED struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_num_rows, PyObject *__pyx_v_msg); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_raise_error(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_msg); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_setup_tokenizer(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__set_fill_values(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__get_comments(CYTHON_UNUSED struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_data(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string, PyObject *__pyx_v_num_rows); /* proto*/
+static PyArrayObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_int(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows); /* proto*/
+static PyArrayObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_float(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_str(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows); /* proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_10FastWriter__write_comments(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output); /* proto*/
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'libc' */
+
+/* Module declarations from 'astropy.io.ascii.cparser' */
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser_FileString = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser_CParser = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser_FastWriter = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk = 0;
+static PyTypeObject *__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr = 0;
+#define __Pyx_MODULE_NAME "astropy.io.ascii.cparser"
+int __pyx_module_is_main_astropy__io__ascii__cparser = 0;
+
+/* Implementation of 'astropy.io.ascii.cparser' */
+static PyObject *__pyx_builtin_ImportError;
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_open;
+static PyObject *__pyx_builtin_IOError;
+static PyObject *__pyx_builtin_NotImplementedError;
+static PyObject *__pyx_builtin_ord;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_chr;
+static PyObject *__pyx_builtin_any;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line); /* proto */
+static PyObject *__pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda2(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self, PyObject *__pyx_v_fname); /* proto */
+static void __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_2__dealloc__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_4__len__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_6__getitem__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_8splitlines(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source, PyObject *__pyx_v_strip_line_whitespace, PyObject *__pyx_v_strip_line_fields, PyObject *__pyx_v_delimiter, PyObject *__pyx_v_comment, PyObject *__pyx_v_quotechar, PyObject *__pyx_v_header_start, PyObject *__pyx_v_data_start, PyObject *__pyx_v_data_end, PyObject *__pyx_v_names, PyObject *__pyx_v_include_names, PyObject *__pyx_v_ [...]
+static void __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_2__dealloc__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_4setup_tokenizer(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6read_header(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_8read(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_genexpr(PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_3genexpr(PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_6genexpr(PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_10_read_parallel(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12get_names(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14set_names(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_names); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_16__reduce__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_4__del__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_4__del__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser__copy_cparser(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_src_ptr, PyObject *__pyx_v_source_bytes, PyObject *__pyx_v_use_cols, PyObject *__pyx_v_fill_names, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_strip_whitespace_lines, PyObject *__pyx_v_strip_whitespace_fields, PyObject *__pyx_v_kwargs); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_11_read_chunk_genexpr(PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_2_read_chunk(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string, PyObject *__pyx_v_queue, PyObject *__pyx_v_reconvert_queue, PyObject *__pyx_v_i); /* proto */
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_table, PyObject *__pyx_v_delimiter, PyObject *__pyx_v_comment, PyObject *__pyx_v_quotechar, PyObject *__pyx_v_formats, PyObject *__pyx_v_strip_whitespace, CYTHON_UNUSED PyObject *__pyx_v_names, PyObject *__pyx_v_include_names, PyObject *__pyx_v_exclude_names, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_fill_include_names, P [...]
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_2_write_header(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output, PyObject *__pyx_v_writer, PyObject *__pyx_v_header_output, PyObject *__pyx_v_output_types); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_4write(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output, PyObject *__pyx_v_header_output, PyObject *__pyx_v_output_types); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_4get_fill_values(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_read); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda4(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val); /* proto */
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_6auto_format_func(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_FileString(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_CParser(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_FastWriter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_[] = ",";
+static char __pyx_k_0[] = "0";
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_N[] = "N";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_S[] = "S";
+static char __pyx_k_U[] = "U";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_e[] = "e";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_r[] = "r";
+static char __pyx_k_w[] = "w";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k__2[] = "\"";
+static char __pyx_k__3[] = "";
+static char __pyx_k_el[] = "el";
+static char __pyx_k_ma[] = "ma";
+static char __pyx_k_np[] = "np";
+static char __pyx_k_nt[] = "nt";
+static char __pyx_k_os[] = "os";
+static char __pyx_k_0_1[] = "{0}: {1}";
+static char __pyx_k_PY2[] = "PY2";
+static char __pyx_k__10[] = "\000";
+static char __pyx_k__11[] = "\n";
+static char __pyx_k__12[] = "\r";
+static char __pyx_k__16[] = "\001";
+static char __pyx_k__27[] = "# ";
+static char __pyx_k__29[] = " ";
+static char __pyx_k__30[] = "--";
+static char __pyx_k_any[] = "any";
+static char __pyx_k_chr[] = "chr";
+static char __pyx_k_col[] = "col";
+static char __pyx_k_csv[] = "csv";
+static char __pyx_k_doc[] = "__doc__";
+static char __pyx_k_end[] = "end";
+static char __pyx_k_err[] = "err";
+static char __pyx_k_get[] = "get";
+static char __pyx_k_int[] = "int_";
+static char __pyx_k_ord[] = "ord";
+static char __pyx_k_out[] = "out";
+static char __pyx_k_pop[] = "pop";
+static char __pyx_k_put[] = "put";
+static char __pyx_k_six[] = "six";
+static char __pyx_k_str[] = "str";
+static char __pyx_k_val[] = "val";
+static char __pyx_k_Full[] = "Full";
+static char __pyx_k_args[] = "args";
+static char __pyx_k_ceil[] = "ceil";
+static char __pyx_k_copy[] = "copy";
+static char __pyx_k_core[] = "core";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_exit[] = "__exit__";
+static char __pyx_k_join[] = "join";
+static char __pyx_k_kind[] = "kind";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mask[] = "mask";
+static char __pyx_k_math[] = "math";
+static char __pyx_k_meta[] = "meta";
+static char __pyx_k_mmap[] = "mmap";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_open[] = "open";
+static char __pyx_k_prot[] = "prot";
+static char __pyx_k_read[] = "read";
+static char __pyx_k_self[] = "self";
+static char __pyx_k_send[] = "send";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_Empty[] = "Empty";
+static char __pyx_k_Queue[] = "Queue";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_ascii[] = "ascii";
+static char __pyx_k_close[] = "close";
+static char __pyx_k_col_0[] = "col{0}";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_enter[] = "__enter__";
+static char __pyx_k_float[] = "float_";
+static char __pyx_k_fname[] = "fname";
+static char __pyx_k_force[] = "force";
+static char __pyx_k_names[] = "names";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_queue[] = "queue";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_table[] = "table";
+static char __pyx_k_throw[] = "throw";
+static char __pyx_k_write[] = "write";
+static char __pyx_k_append[] = "append";
+static char __pyx_k_encode[] = "encode";
+static char __pyx_k_extern[] = "extern";
+static char __pyx_k_fileno[] = "fileno";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_kwargs[] = "kwargs";
+static char __pyx_k_lambda[] = "<lambda>";
+static char __pyx_k_masked[] = "masked";
+static char __pyx_k_module[] = "__module__";
+static char __pyx_k_output[] = "output";
+static char __pyx_k_parser[] = "parser";
+static char __pyx_k_pprint[] = "pprint";
+static char __pyx_k_source[] = "source";
+static char __pyx_k_target[] = "target";
+static char __pyx_k_tolist[] = "tolist";
+static char __pyx_k_writer[] = "writer";
+static char __pyx_k_IOError[] = "IOError";
+static char __pyx_k_Process[] = "Process";
+static char __pyx_k_columns[] = "columns";
+static char __pyx_k_comment[] = "comment";
+static char __pyx_k_formats[] = "formats";
+static char __pyx_k_genexpr[] = "genexpr";
+static char __pyx_k_linesep[] = "linesep";
+static char __pyx_k_prepare[] = "__prepare__";
+static char __pyx_k_quoting[] = "quoting";
+static char __pyx_k_replace[] = "replace";
+static char __pyx_k_src_ptr[] = "src_ptr";
+static char __pyx_k_try_int[] = "try_int";
+static char __pyx_k_callable[] = "callable";
+static char __pyx_k_colnames[] = "colnames";
+static char __pyx_k_comments[] = "comments";
+static char __pyx_k_data_end[] = "data_end";
+static char __pyx_k_format_2[] = "format_";
+static char __pyx_k_no_error[] = "no error";
+static char __pyx_k_parallel[] = "parallel";
+static char __pyx_k_qualname[] = "__qualname__";
+static char __pyx_k_use_cols[] = "use_cols";
+static char __pyx_k_writerow[] = "writerow";
+static char __pyx_k_ERR_CODES[] = "ERR_CODES";
+static char __pyx_k_Exception[] = "Exception";
+static char __pyx_k_MaskError[] = "MaskError";
+static char __pyx_k_PROT_READ[] = "PROT_READ";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_cpu_count[] = "cpu_count";
+static char __pyx_k_delimiter[] = "delimiter";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_get_names[] = "get_names";
+static char __pyx_k_iteritems[] = "iteritems";
+static char __pyx_k_metaclass[] = "__metaclass__";
+static char __pyx_k_quotechar[] = "quotechar";
+static char __pyx_k_terminate[] = "terminate";
+static char __pyx_k_try_float[] = "try_float";
+static char __pyx_k_writerows[] = "writerows";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_data_start[] = "data_start";
+static char __pyx_k_escapechar[] = "escapechar";
+static char __pyx_k_fill_empty[] = "fill_empty";
+static char __pyx_k_fill_names[] = "fill_names";
+static char __pyx_k_itervalues[] = "itervalues";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_read_chunk[] = "_read_chunk";
+static char __pyx_k_splitlines[] = "splitlines";
+static char __pyx_k_try_string[] = "try_string";
+static char __pyx_k_utils_data[] = "utils.data";
+static char __pyx_k_ImportError[] = "ImportError";
+static char __pyx_k_concatenate[] = "concatenate";
+static char __pyx_k_doublequote[] = "doublequote";
+static char __pyx_k_fast_reader[] = "fast_reader";
+static char __pyx_k_fast_writer[] = "fast_writer";
+static char __pyx_k_fill_values[] = "fill_values";
+static char __pyx_k_format_func[] = "format_func";
+static char __pyx_k_CParserError[] = "CParserError";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_copy_cparser[] = "_copy_cparser";
+static char __pyx_k_format_funcs[] = "_format_funcs";
+static char __pyx_k_header_start[] = "header_start";
+static char __pyx_k_masked_array[] = "masked_array";
+static char __pyx_k_output_types[] = "output_types";
+static char __pyx_k_source_bytes[] = "source_bytes";
+static char __pyx_k_string_types[] = "string_types";
+static char __pyx_k_write_header[] = "_write_header";
+static char __pyx_k_QUOTE_MINIMAL[] = "QUOTE_MINIMAL";
+static char __pyx_k_exclude_names[] = "exclude_names";
+static char __pyx_k_header_output[] = "header_output";
+static char __pyx_k_include_names[] = "include_names";
+static char __pyx_k_line_comments[] = "line_comments";
+static char __pyx_k_read_parallel[] = "_read_parallel";
+static char __pyx_k_unknown_error[] = "unknown error";
+static char __pyx_k_ParameterError[] = "ParameterError";
+static char __pyx_k_lineterminator[] = "lineterminator";
+static char __pyx_k_overflow_error[] = "overflow error";
+static char __pyx_k_reconvert_cols[] = "reconvert_cols";
+static char __pyx_k_chunk_tokenizer[] = "chunk_tokenizer";
+static char __pyx_k_fill_extra_cols[] = "fill_extra_cols";
+static char __pyx_k_get_fill_values[] = "get_fill_values";
+static char __pyx_k_multiprocessing[] = "multiprocessing";
+static char __pyx_k_reconvert_queue[] = "reconvert_queue";
+static char __pyx_k_setup_tokenizer[] = "setup_tokenizer";
+static char __pyx_k_FastOptionsError[] = "FastOptionsError";
+static char __pyx_k_auto_format_func[] = "auto_format_func";
+static char __pyx_k_strip_whitespace[] = "strip_whitespace";
+static char __pyx_k_difference_update[] = "difference_update";
+static char __pyx_k_strip_line_fields[] = "strip_line_fields";
+static char __pyx_k_fill_exclude_names[] = "fill_exclude_names";
+static char __pyx_k_fill_include_names[] = "fill_include_names";
+static char __pyx_k_use_fast_converter[] = "use_fast_converter";
+static char __pyx_k_NotImplementedError[] = "NotImplementedError";
+static char __pyx_k_intersection_update[] = "intersection_update";
+static char __pyx_k_get_readable_fileobj[] = "get_readable_fileobj";
+static char __pyx_k_FileString_splitlines[] = "FileString.splitlines";
+static char __pyx_k_invalid_line_supplied[] = "invalid line supplied";
+static char __pyx_k_strip_line_whitespace[] = "strip_line_whitespace";
+static char __pyx_k_type_conversion_error[] = "type conversion error";
+static char __pyx_k_InconsistentTableError[] = "InconsistentTableError";
+static char __pyx_k_strip_whitespace_lines[] = "strip_whitespace_lines";
+static char __pyx_k_strip_whitespace_fields[] = "strip_whitespace_fields";
+static char __pyx_k_astropy_io_ascii_cparser[] = "astropy.io.ascii.cparser";
+static char __pyx_k_read_chunk_locals_genexpr[] = "_read_chunk.<locals>.genexpr";
+static char __pyx_k_Column_0_failed_to_convert[] = "Column {0} failed to convert";
+static char __pyx_k_File_0_could_not_be_opened[] = "File \"{0}\" could not be opened";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_read_parallel_locals_genexpr[] = "_read_parallel.<locals>.genexpr";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/io/ascii/cparser.pyx";
+static char __pyx_k_auto_format_func_locals_lambda[] = "auto_format_func.<locals>.<lambda>";
+static char __pyx_k_An_instance_of_this_class_is_th[] = "\n    An instance of this class is thrown when an error occurs\n    during C parsing.\n    ";
+static char __pyx_k_Input_table_must_be_a_file_like[] = "Input \"table\" must be a file-like object, a string (filename or data), or an iterable";
+static char __pyx_k_Unable_to_parse_format_string_0[] = "Unable to parse format string {0}";
+static char __pyx_k_an_error_occurred_while_parsing[] = "an error occurred while parsing table data";
+static char __pyx_k_fast_reader_cannot_be_False_for[] = "fast_reader cannot be False for fast readers";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Format_function_for_value_0_fail[] = "Format function for value {0} failed: {1}";
+static char __pyx_k_Format_function_for_value_0_retu[] = "Format function for value {0} returned {1} instead of string type";
+static char __pyx_k_Format_of_fill_values_must_be_ba[] = "Format of fill_values must be (<bad>, <fill>, <optional col1>, ...)";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Invalid_parameter_in_fast_reader[] = "Invalid parameter in fast_reader dict";
+static char __pyx_k_Multiprocessing_is_not_yet_suppo[] = "Multiprocessing is not yet supported on Windows";
+static char __pyx_k_No_data_lines_found_C_reader_can[] = "No data lines found, C reader cannot autogenerate column names";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_an_error_occurred_while_advancin[] = "an error occurred while advancing to the first header line";
+static char __pyx_k_an_error_occurred_while_tokenizi[] = "an error occurred while tokenizing the header line";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_not_enough_columns_found_in_line[] = "not enough columns found in line {0} of data";
+static char __pyx_k_too_many_columns_found_in_line_0[] = "too many columns found in line {0} of data";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static char __pyx_k_an_error_occurred_while_advancin_2[] = "an error occurred while advancing to the first line of data";
+static char __pyx_k_an_error_occurred_while_tokenizi_2[] = "an error occurred while tokenizing the first line of data";
+static PyObject *__pyx_kp_s_;
+static PyObject *__pyx_kp_s_0;
+static PyObject *__pyx_kp_s_0_1;
+static PyObject *__pyx_kp_s_An_instance_of_this_class_is_th;
+static PyObject *__pyx_n_s_CParserError;
+static PyObject *__pyx_kp_s_Column_0_failed_to_convert;
+static PyObject *__pyx_n_s_ERR_CODES;
+static PyObject *__pyx_n_s_Empty;
+static PyObject *__pyx_n_s_Exception;
+static PyObject *__pyx_n_s_FastOptionsError;
+static PyObject *__pyx_n_s_FileString_splitlines;
+static PyObject *__pyx_kp_s_File_0_could_not_be_opened;
+static PyObject *__pyx_kp_s_Format_function_for_value_0_fail;
+static PyObject *__pyx_kp_s_Format_function_for_value_0_retu;
+static PyObject *__pyx_kp_s_Format_of_fill_values_must_be_ba;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_Full;
+static PyObject *__pyx_n_s_IOError;
+static PyObject *__pyx_n_s_ImportError;
+static PyObject *__pyx_n_s_InconsistentTableError;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Input_table_must_be_a_file_like;
+static PyObject *__pyx_kp_s_Invalid_parameter_in_fast_reader;
+static PyObject *__pyx_n_s_MaskError;
+static PyObject *__pyx_kp_s_Multiprocessing_is_not_yet_suppo;
+static PyObject *__pyx_n_s_N;
+static PyObject *__pyx_kp_s_No_data_lines_found_C_reader_can;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_NotImplementedError;
+static PyObject *__pyx_n_s_PROT_READ;
+static PyObject *__pyx_n_s_PY2;
+static PyObject *__pyx_n_s_ParameterError;
+static PyObject *__pyx_n_s_Process;
+static PyObject *__pyx_n_s_QUOTE_MINIMAL;
+static PyObject *__pyx_n_s_Queue;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_S;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_n_s_U;
+static PyObject *__pyx_kp_s_Unable_to_parse_format_string_0;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__10;
+static PyObject *__pyx_kp_s__11;
+static PyObject *__pyx_kp_s__12;
+static PyObject *__pyx_kp_s__16;
+static PyObject *__pyx_kp_s__2;
+static PyObject *__pyx_kp_s__27;
+static PyObject *__pyx_kp_s__29;
+static PyObject *__pyx_kp_b__3;
+static PyObject *__pyx_kp_s__3;
+static PyObject *__pyx_kp_s__30;
+static PyObject *__pyx_kp_s_an_error_occurred_while_advancin;
+static PyObject *__pyx_kp_s_an_error_occurred_while_advancin_2;
+static PyObject *__pyx_kp_s_an_error_occurred_while_parsing;
+static PyObject *__pyx_kp_s_an_error_occurred_while_tokenizi;
+static PyObject *__pyx_kp_s_an_error_occurred_while_tokenizi_2;
+static PyObject *__pyx_n_s_any;
+static PyObject *__pyx_n_s_append;
+static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_ascii;
+static PyObject *__pyx_n_s_astropy_io_ascii_cparser;
+static PyObject *__pyx_n_s_auto_format_func;
+static PyObject *__pyx_n_s_auto_format_func_locals_lambda;
+static PyObject *__pyx_n_s_callable;
+static PyObject *__pyx_n_s_ceil;
+static PyObject *__pyx_n_s_chr;
+static PyObject *__pyx_n_s_chunk_tokenizer;
+static PyObject *__pyx_n_s_close;
+static PyObject *__pyx_n_s_col;
+static PyObject *__pyx_kp_s_col_0;
+static PyObject *__pyx_n_s_colnames;
+static PyObject *__pyx_n_s_columns;
+static PyObject *__pyx_n_s_comment;
+static PyObject *__pyx_n_s_comments;
+static PyObject *__pyx_n_s_concatenate;
+static PyObject *__pyx_n_s_copy;
+static PyObject *__pyx_n_s_copy_cparser;
+static PyObject *__pyx_n_s_core;
+static PyObject *__pyx_n_s_cpu_count;
+static PyObject *__pyx_n_s_csv;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_data_end;
+static PyObject *__pyx_n_s_data_start;
+static PyObject *__pyx_n_s_delimiter;
+static PyObject *__pyx_n_s_difference_update;
+static PyObject *__pyx_n_s_doc;
+static PyObject *__pyx_n_s_doublequote;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_e;
+static PyObject *__pyx_n_s_el;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_encode;
+static PyObject *__pyx_n_s_end;
+static PyObject *__pyx_n_s_enter;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_err;
+static PyObject *__pyx_n_s_escapechar;
+static PyObject *__pyx_n_s_exclude_names;
+static PyObject *__pyx_n_s_exit;
+static PyObject *__pyx_n_s_extern;
+static PyObject *__pyx_n_s_fast_reader;
+static PyObject *__pyx_kp_s_fast_reader_cannot_be_False_for;
+static PyObject *__pyx_n_s_fast_writer;
+static PyObject *__pyx_n_s_fileno;
+static PyObject *__pyx_n_s_fill_empty;
+static PyObject *__pyx_n_s_fill_exclude_names;
+static PyObject *__pyx_n_s_fill_extra_cols;
+static PyObject *__pyx_n_s_fill_include_names;
+static PyObject *__pyx_n_s_fill_names;
+static PyObject *__pyx_n_s_fill_values;
+static PyObject *__pyx_n_s_float;
+static PyObject *__pyx_n_s_fname;
+static PyObject *__pyx_n_s_force;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_format_2;
+static PyObject *__pyx_n_s_format_func;
+static PyObject *__pyx_n_s_format_funcs;
+static PyObject *__pyx_n_s_formats;
+static PyObject *__pyx_n_s_genexpr;
+static PyObject *__pyx_n_s_get;
+static PyObject *__pyx_n_s_get_fill_values;
+static PyObject *__pyx_n_s_get_names;
+static PyObject *__pyx_n_s_get_readable_fileobj;
+static PyObject *__pyx_n_s_header_output;
+static PyObject *__pyx_n_s_header_start;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_include_names;
+static PyObject *__pyx_n_s_int;
+static PyObject *__pyx_n_s_intersection_update;
+static PyObject *__pyx_kp_s_invalid_line_supplied;
+static PyObject *__pyx_n_s_iteritems;
+static PyObject *__pyx_n_s_itervalues;
+static PyObject *__pyx_n_s_join;
+static PyObject *__pyx_n_s_kind;
+static PyObject *__pyx_n_s_kwargs;
+static PyObject *__pyx_n_s_l;
+static PyObject *__pyx_n_s_lambda;
+static PyObject *__pyx_n_s_line_comments;
+static PyObject *__pyx_n_s_linesep;
+static PyObject *__pyx_n_s_lineterminator;
+static PyObject *__pyx_n_s_ma;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_mask;
+static PyObject *__pyx_n_s_masked;
+static PyObject *__pyx_n_s_masked_array;
+static PyObject *__pyx_n_s_math;
+static PyObject *__pyx_n_s_meta;
+static PyObject *__pyx_n_s_metaclass;
+static PyObject *__pyx_n_s_mmap;
+static PyObject *__pyx_n_s_module;
+static PyObject *__pyx_n_s_multiprocessing;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_names;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_kp_s_no_error;
+static PyObject *__pyx_kp_s_not_enough_columns_found_in_line;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_nt;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_open;
+static PyObject *__pyx_n_s_ord;
+static PyObject *__pyx_n_s_os;
+static PyObject *__pyx_n_s_out;
+static PyObject *__pyx_n_s_output;
+static PyObject *__pyx_n_s_output_types;
+static PyObject *__pyx_kp_s_overflow_error;
+static PyObject *__pyx_n_s_parallel;
+static PyObject *__pyx_n_s_parser;
+static PyObject *__pyx_n_s_pop;
+static PyObject *__pyx_n_s_pprint;
+static PyObject *__pyx_n_s_prepare;
+static PyObject *__pyx_n_s_prot;
+static PyObject *__pyx_n_s_put;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_qualname;
+static PyObject *__pyx_n_s_queue;
+static PyObject *__pyx_n_s_quotechar;
+static PyObject *__pyx_n_s_quoting;
+static PyObject *__pyx_n_s_r;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_read;
+static PyObject *__pyx_n_s_read_chunk;
+static PyObject *__pyx_n_s_read_chunk_locals_genexpr;
+static PyObject *__pyx_n_s_read_parallel;
+static PyObject *__pyx_n_s_read_parallel_locals_genexpr;
+static PyObject *__pyx_n_s_reconvert_cols;
+static PyObject *__pyx_n_s_reconvert_queue;
+static PyObject *__pyx_n_s_replace;
+static PyObject *__pyx_n_s_self;
+static PyObject *__pyx_n_s_send;
+static PyObject *__pyx_n_s_setup_tokenizer;
+static PyObject *__pyx_n_s_six;
+static PyObject *__pyx_n_s_source;
+static PyObject *__pyx_n_s_source_bytes;
+static PyObject *__pyx_n_s_splitlines;
+static PyObject *__pyx_n_s_src_ptr;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_str;
+static PyObject *__pyx_n_s_string_types;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_strip_line_fields;
+static PyObject *__pyx_n_s_strip_line_whitespace;
+static PyObject *__pyx_n_s_strip_whitespace;
+static PyObject *__pyx_n_s_strip_whitespace_fields;
+static PyObject *__pyx_n_s_strip_whitespace_lines;
+static PyObject *__pyx_n_s_table;
+static PyObject *__pyx_n_s_target;
+static PyObject *__pyx_n_s_terminate;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_throw;
+static PyObject *__pyx_n_s_tolist;
+static PyObject *__pyx_kp_s_too_many_columns_found_in_line_0;
+static PyObject *__pyx_n_s_try_float;
+static PyObject *__pyx_n_s_try_int;
+static PyObject *__pyx_n_s_try_string;
+static PyObject *__pyx_kp_s_type_conversion_error;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_kp_s_unknown_error;
+static PyObject *__pyx_n_s_use_cols;
+static PyObject *__pyx_n_s_use_fast_converter;
+static PyObject *__pyx_n_s_utils_data;
+static PyObject *__pyx_n_s_val;
+static PyObject *__pyx_n_s_w;
+static PyObject *__pyx_n_s_write;
+static PyObject *__pyx_n_s_write_header;
+static PyObject *__pyx_n_s_writer;
+static PyObject *__pyx_n_s_writerow;
+static PyObject *__pyx_n_s_writerows;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_k__28;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__21;
+static PyObject *__pyx_slice__23;
+static PyObject *__pyx_slice__26;
+static PyObject *__pyx_slice__31;
+static PyObject *__pyx_slice__32;
+static PyObject *__pyx_slice__34;
+static PyObject *__pyx_slice__35;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__38;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__40;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__42;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+static PyObject *__pyx_codeobj__50;
+
+/* "astropy/io/ascii/cparser.pyx":107
+ *     "no error",
+ *     "invalid line supplied",
+ *     lambda line: "too many columns found in line {0} of data".format(line),             # <<<<<<<<<<<<<<
+ *     lambda line: "not enough columns found in line {0} of data".format(line),
+ *     "type conversion error",
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_8lambda1(PyObject *__pyx_self, PyObject *__pyx_v_line); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_8lambda1 = {"lambda1", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_8lambda1, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_8lambda1(PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda1 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda1(__pyx_self, ((PyObject *)__pyx_v_line));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda1", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_too_many_columns_found_in_line_0, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_line); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_line);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_line);
+    __Pyx_GIVEREF(__pyx_v_line);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.lambda1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":108
+ *     "invalid line supplied",
+ *     lambda line: "too many columns found in line {0} of data".format(line),
+ *     lambda line: "not enough columns found in line {0} of data".format(line),             # <<<<<<<<<<<<<<
+ *     "type conversion error",
+ *     "overflow error"
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_9lambda2(PyObject *__pyx_self, PyObject *__pyx_v_line); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_9lambda2 = {"lambda2", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_9lambda2, METH_O, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_9lambda2(PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda2 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda2(__pyx_self, ((PyObject *)__pyx_v_line));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_7astropy_2io_5ascii_7cparser_lambda2(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda2", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_not_enough_columns_found_in_line, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_line); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_line);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_line);
+    __Pyx_GIVEREF(__pyx_v_line);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.lambda2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":123
+ *         Py_buffer buf
+ * 
+ *     def __cinit__(self, fname):             # <<<<<<<<<<<<<<
+ *         self.fhandle = open(fname, 'r')
+ *         if not self.fhandle:
+ */
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_fname = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_fname,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fname)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_fname = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FileString.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString___cinit__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_self), __pyx_v_fname);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self, PyObject *__pyx_v_fname) {
+  Py_ssize_t __pyx_v_buf_len;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  int __pyx_t_9;
+  void *__pyx_t_10;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":124
+ * 
+ *     def __cinit__(self, fname):
+ *         self.fhandle = open(fname, 'r')             # <<<<<<<<<<<<<<
+ *         if not self.fhandle:
+ *             raise IOError('File "{0}" could not be opened'.format(fname))
+ */
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_fname);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_fname);
+  __Pyx_GIVEREF(__pyx_v_fname);
+  __Pyx_INCREF(__pyx_n_s_r);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_r);
+  __Pyx_GIVEREF(__pyx_n_s_r);
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->fhandle);
+  __Pyx_DECREF(__pyx_v_self->fhandle);
+  __pyx_v_self->fhandle = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":125
+ *     def __cinit__(self, fname):
+ *         self.fhandle = open(fname, 'r')
+ *         if not self.fhandle:             # <<<<<<<<<<<<<<
+ *             raise IOError('File "{0}" could not be opened'.format(fname))
+ *         self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)
+ */
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_self->fhandle); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = ((!__pyx_t_3) != 0);
+  if (__pyx_t_4) {
+
+    /* "astropy/io/ascii/cparser.pyx":126
+ *         self.fhandle = open(fname, 'r')
+ *         if not self.fhandle:
+ *             raise IOError('File "{0}" could not be opened'.format(fname))             # <<<<<<<<<<<<<<
+ *         self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)
+ *         cdef Py_ssize_t buf_len = len(self.mmap)
+ */
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_File_0_could_not_be_opened, __pyx_n_s_format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_1, function);
+      }
+    }
+    if (!__pyx_t_5) {
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_fname); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+    } else {
+      __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+      __Pyx_INCREF(__pyx_v_fname);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_fname);
+      __Pyx_GIVEREF(__pyx_v_fname);
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_IOError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":127
+ *         if not self.fhandle:
+ *             raise IOError('File "{0}" could not be opened'.format(fname))
+ *         self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)             # <<<<<<<<<<<<<<
+ *         cdef Py_ssize_t buf_len = len(self.mmap)
+ *         if six.PY2:
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_mmap); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_mmap); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->fhandle, __pyx_n_s_fileno); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  if (__pyx_t_5) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_mmap); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_PROT_READ); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_prot, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_GIVEREF(__pyx_t_7);
+  __Pyx_GOTREF(__pyx_v_self->mmap);
+  __Pyx_DECREF(__pyx_v_self->mmap);
+  __pyx_v_self->mmap = __pyx_t_7;
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":128
+ *             raise IOError('File "{0}" could not be opened'.format(fname))
+ *         self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)
+ *         cdef Py_ssize_t buf_len = len(self.mmap)             # <<<<<<<<<<<<<<
+ *         if six.PY2:
+ *             PyObject_AsReadBuffer(self.mmap, &self.mmap_ptr, &buf_len)
+ */
+  __pyx_t_7 = __pyx_v_self->mmap;
+  __Pyx_INCREF(__pyx_t_7);
+  __pyx_t_8 = PyObject_Length(__pyx_t_7); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_v_buf_len = __pyx_t_8;
+
+  /* "astropy/io/ascii/cparser.pyx":129
+ *         self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)
+ *         cdef Py_ssize_t buf_len = len(self.mmap)
+ *         if six.PY2:             # <<<<<<<<<<<<<<
+ *             PyObject_AsReadBuffer(self.mmap, &self.mmap_ptr, &buf_len)
+ *         else:
+ */
+  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_PY2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_4) {
+
+    /* "astropy/io/ascii/cparser.pyx":130
+ *         cdef Py_ssize_t buf_len = len(self.mmap)
+ *         if six.PY2:
+ *             PyObject_AsReadBuffer(self.mmap, &self.mmap_ptr, &buf_len)             # <<<<<<<<<<<<<<
+ *         else:
+ *             PyObject_GetBuffer(self.mmap, &self.buf, PyBUF_SIMPLE)
+ */
+    __pyx_t_2 = __pyx_v_self->mmap;
+    __Pyx_INCREF(__pyx_t_2);
+    PyObject_AsReadBuffer(__pyx_t_2, (&__pyx_v_self->mmap_ptr), (&__pyx_v_buf_len));
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":132
+ *             PyObject_AsReadBuffer(self.mmap, &self.mmap_ptr, &buf_len)
+ *         else:
+ *             PyObject_GetBuffer(self.mmap, &self.buf, PyBUF_SIMPLE)             # <<<<<<<<<<<<<<
+ *             self.mmap_ptr = self.buf.buf
+ * 
+ */
+    __pyx_t_2 = __pyx_v_self->mmap;
+    __Pyx_INCREF(__pyx_t_2);
+    __pyx_t_9 = PyObject_GetBuffer(__pyx_t_2, (&__pyx_v_self->buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":133
+ *         else:
+ *             PyObject_GetBuffer(self.mmap, &self.buf, PyBUF_SIMPLE)
+ *             self.mmap_ptr = self.buf.buf             # <<<<<<<<<<<<<<
+ * 
+ *     def __dealloc__(self):
+ */
+    __pyx_t_10 = __pyx_v_self->buf.buf;
+    __pyx_v_self->mmap_ptr = __pyx_t_10;
+  }
+  __pyx_L4:;
+
+  /* "astropy/io/ascii/cparser.pyx":123
+ *         Py_buffer buf
+ * 
+ *     def __cinit__(self, fname):             # <<<<<<<<<<<<<<
+ *         self.fhandle = open(fname, 'r')
+ *         if not self.fhandle:
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FileString.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":135
+ *             self.mmap_ptr = self.buf.buf
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ *         if self.mmap:
+ *             if not six.PY2: # free buffer memory to prevent a resource leak
+ */
+
+/* Python wrapper */
+static void __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_2__dealloc__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_2__dealloc__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":136
+ * 
+ *     def __dealloc__(self):
+ *         if self.mmap:             # <<<<<<<<<<<<<<
+ *             if not six.PY2: # free buffer memory to prevent a resource leak
+ *                 PyBuffer_Release(&self.buf)
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->mmap); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":137
+ *     def __dealloc__(self):
+ *         if self.mmap:
+ *             if not six.PY2: # free buffer memory to prevent a resource leak             # <<<<<<<<<<<<<<
+ *                 PyBuffer_Release(&self.buf)
+ *             self.mmap.close()
+ */
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_PY2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = ((!__pyx_t_1) != 0);
+    if (__pyx_t_4) {
+
+      /* "astropy/io/ascii/cparser.pyx":138
+ *         if self.mmap:
+ *             if not six.PY2: # free buffer memory to prevent a resource leak
+ *                 PyBuffer_Release(&self.buf)             # <<<<<<<<<<<<<<
+ *             self.mmap.close()
+ *             self.fhandle.close()
+ */
+      PyBuffer_Release((&__pyx_v_self->buf));
+      goto __pyx_L4;
+    }
+    __pyx_L4:;
+
+    /* "astropy/io/ascii/cparser.pyx":139
+ *             if not six.PY2: # free buffer memory to prevent a resource leak
+ *                 PyBuffer_Release(&self.buf)
+ *             self.mmap.close()             # <<<<<<<<<<<<<<
+ *             self.fhandle.close()
+ * 
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->mmap, __pyx_n_s_close); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_5) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":140
+ *                 PyBuffer_Release(&self.buf)
+ *             self.mmap.close()
+ *             self.fhandle.close()             # <<<<<<<<<<<<<<
+ * 
+ *     def __len__(self):
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->fhandle, __pyx_n_s_close); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_5) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":135
+ *             self.mmap_ptr = self.buf.buf
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ *         if self.mmap:
+ *             if not six.PY2: # free buffer memory to prevent a resource leak
+ */
+
+  /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_WriteUnraisable("astropy.io.ascii.cparser.FileString.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "astropy/io/ascii/cparser.pyx":142
+ *             self.fhandle.close()
+ * 
+ *     def __len__(self):             # <<<<<<<<<<<<<<
+ *         return len(self.mmap)
+ * 
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_5__len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_5__len__(PyObject *__pyx_v_self) {
+  Py_ssize_t __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_4__len__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static Py_ssize_t __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_4__len__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self) {
+  Py_ssize_t __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__len__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":143
+ * 
+ *     def __len__(self):
+ *         return len(self.mmap)             # <<<<<<<<<<<<<<
+ * 
+ *     def __getitem__(self, i):
+ */
+  __pyx_t_1 = __pyx_v_self->mmap;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_2;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":142
+ *             self.fhandle.close()
+ * 
+ *     def __len__(self):             # <<<<<<<<<<<<<<
+ *         return len(self.mmap)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FileString.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":145
+ *         return len(self.mmap)
+ * 
+ *     def __getitem__(self, i):             # <<<<<<<<<<<<<<
+ *         return self.mmap[i]
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_i); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_6__getitem__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_self), ((PyObject *)__pyx_v_i));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_6__getitem__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":146
+ * 
+ *     def __getitem__(self, i):
+ *         return self.mmap[i]             # <<<<<<<<<<<<<<
+ * 
+ *     def splitlines(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_self->mmap, __pyx_v_i); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":145
+ *         return len(self.mmap)
+ * 
+ *     def __getitem__(self, i):             # <<<<<<<<<<<<<<
+ *         return self.mmap[i]
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FileString.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_10FileString_10generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "astropy/io/ascii/cparser.pyx":148
+ *         return self.mmap[i]
+ * 
+ *     def splitlines(self):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a generator yielding lines from the memory map.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_9splitlines(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_7astropy_2io_5ascii_7cparser_10FileString_8splitlines[] = "\n        Return a generator yielding lines from the memory map.\n        ";
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_9splitlines(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("splitlines (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_8splitlines(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FileString_8splitlines(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_self) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *__pyx_cur_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("splitlines", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+  __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+  __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+  {
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_7astropy_2io_5ascii_7cparser_10FileString_10generator, (PyObject *) __pyx_cur_scope, __pyx_n_s_splitlines, __pyx_n_s_FileString_splitlines); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_cur_scope);
+    __Pyx_RefNannyFinishContext();
+    return (PyObject *) gen;
+  }
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FileString.splitlines", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_10FileString_10generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *__pyx_cur_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)__pyx_generator->closure);
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("None", 0);
+  switch (__pyx_generator->resume_label) {
+    case 0: goto __pyx_L3_first_run;
+    case 1: goto __pyx_L6_resume_from_yield;
+    default: /* CPython raises the right error here */
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __pyx_L3_first_run:;
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":152
+ *         Return a generator yielding lines from the memory map.
+ *         """
+ *         cdef char *ptr = <char *>self.mmap_ptr             # <<<<<<<<<<<<<<
+ *         cdef char *tmp
+ *         cdef int line_len
+ */
+  __pyx_cur_scope->__pyx_v_ptr = ((char *)__pyx_cur_scope->__pyx_v_self->mmap_ptr);
+
+  /* "astropy/io/ascii/cparser.pyx":155
+ *         cdef char *tmp
+ *         cdef int line_len
+ *         cdef int map_len = len(self.mmap)             # <<<<<<<<<<<<<<
+ * 
+ *         while ptr:
+ */
+  __pyx_t_1 = __pyx_cur_scope->__pyx_v_self->mmap;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_cur_scope->__pyx_v_map_len = __pyx_t_2;
+
+  /* "astropy/io/ascii/cparser.pyx":157
+ *         cdef int map_len = len(self.mmap)
+ * 
+ *         while ptr:             # <<<<<<<<<<<<<<
+ *             tmp = get_line(ptr, &line_len, map_len)
+ *             yield ptr[:line_len].decode('ascii')
+ */
+  while (1) {
+    __pyx_t_3 = (__pyx_cur_scope->__pyx_v_ptr != 0);
+    if (!__pyx_t_3) break;
+
+    /* "astropy/io/ascii/cparser.pyx":158
+ * 
+ *         while ptr:
+ *             tmp = get_line(ptr, &line_len, map_len)             # <<<<<<<<<<<<<<
+ *             yield ptr[:line_len].decode('ascii')
+ *             ptr = tmp
+ */
+    __pyx_cur_scope->__pyx_v_tmp = get_line(__pyx_cur_scope->__pyx_v_ptr, (&__pyx_cur_scope->__pyx_v_line_len), __pyx_cur_scope->__pyx_v_map_len);
+
+    /* "astropy/io/ascii/cparser.pyx":159
+ *         while ptr:
+ *             tmp = get_line(ptr, &line_len, map_len)
+ *             yield ptr[:line_len].decode('ascii')             # <<<<<<<<<<<<<<
+ *             ptr = tmp
+ * 
+ */
+    __pyx_t_1 = __Pyx_decode_c_string(__pyx_cur_scope->__pyx_v_ptr, 0, __pyx_cur_scope->__pyx_v_line_len, NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    __Pyx_XGIVEREF(__pyx_r);
+    __Pyx_RefNannyFinishContext();
+    /* return from generator, yielding value */
+    __pyx_generator->resume_label = 1;
+    return __pyx_r;
+    __pyx_L6_resume_from_yield:;
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":160
+ *             tmp = get_line(ptr, &line_len, map_len)
+ *             yield ptr[:line_len].decode('ascii')
+ *             ptr = tmp             # <<<<<<<<<<<<<<
+ * 
+ * cdef class CParser:
+ */
+    __pyx_cur_scope->__pyx_v_ptr = __pyx_cur_scope->__pyx_v_tmp;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":148
+ *         return self.mmap[i]
+ * 
+ *     def splitlines(self):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a generator yielding lines from the memory map.
+ */
+
+  /* function exit code */
+  PyErr_SetNone(PyExc_StopIteration);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("splitlines", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_generator->resume_label = -1;
+  __Pyx_Generator_clear((PyObject*)__pyx_generator);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+}
+
+/* "astropy/io/ascii/cparser.pyx":191
+ *         object header_start
+ * 
+ *     def __cinit__(self, source, strip_line_whitespace, strip_line_fields,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment=None,
+ */
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_source = 0;
+  PyObject *__pyx_v_strip_line_whitespace = 0;
+  PyObject *__pyx_v_strip_line_fields = 0;
+  PyObject *__pyx_v_delimiter = 0;
+  PyObject *__pyx_v_comment = 0;
+  PyObject *__pyx_v_quotechar = 0;
+  PyObject *__pyx_v_header_start = 0;
+  PyObject *__pyx_v_data_start = 0;
+  PyObject *__pyx_v_data_end = 0;
+  PyObject *__pyx_v_names = 0;
+  PyObject *__pyx_v_include_names = 0;
+  PyObject *__pyx_v_exclude_names = 0;
+  PyObject *__pyx_v_fill_values = 0;
+  PyObject *__pyx_v_fill_include_names = 0;
+  PyObject *__pyx_v_fill_exclude_names = 0;
+  PyObject *__pyx_v_fill_extra_cols = 0;
+  PyObject *__pyx_v_fast_reader = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_strip_line_whitespace,&__pyx_n_s_strip_line_fields,&__pyx_n_s_delimiter,&__pyx_n_s_comment,&__pyx_n_s_quotechar,&__pyx_n_s_header_start,&__pyx_n_s_data_start,&__pyx_n_s_data_end,&__pyx_n_s_names,&__pyx_n_s_include_names,&__pyx_n_s_exclude_names,&__pyx_n_s_fill_values,&__pyx_n_s_fill_include_names,&__pyx_n_s_fill_exclude_names,&__pyx_n_s_fill_extra_cols,&__pyx_n_s_fast_reader,0};
+    PyObject* values[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+    values[3] = ((PyObject *)__pyx_kp_s_);
+
+    /* "astropy/io/ascii/cparser.pyx":193
+ *     def __cinit__(self, source, strip_line_whitespace, strip_line_fields,
+ *                   delimiter=',',
+ *                   comment=None,             # <<<<<<<<<<<<<<
+ *                   quotechar='"',
+ *                   header_start=0,
+ */
+    values[4] = ((PyObject *)Py_None);
+    values[5] = ((PyObject *)__pyx_kp_s__2);
+    values[6] = ((PyObject *)__pyx_int_0);
+    values[7] = ((PyObject *)__pyx_int_1);
+
+    /* "astropy/io/ascii/cparser.pyx":197
+ *                   header_start=0,
+ *                   data_start=1,
+ *                   data_end=None,             # <<<<<<<<<<<<<<
+ *                   names=None,
+ *                   include_names=None,
+ */
+    values[8] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":198
+ *                   data_start=1,
+ *                   data_end=None,
+ *                   names=None,             # <<<<<<<<<<<<<<
+ *                   include_names=None,
+ *                   exclude_names=None,
+ */
+    values[9] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":199
+ *                   data_end=None,
+ *                   names=None,
+ *                   include_names=None,             # <<<<<<<<<<<<<<
+ *                   exclude_names=None,
+ *                   fill_values=('', '0'),
+ */
+    values[10] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":200
+ *                   names=None,
+ *                   include_names=None,
+ *                   exclude_names=None,             # <<<<<<<<<<<<<<
+ *                   fill_values=('', '0'),
+ *                   fill_include_names=None,
+ */
+    values[11] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":201
+ *                   include_names=None,
+ *                   exclude_names=None,
+ *                   fill_values=('', '0'),             # <<<<<<<<<<<<<<
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,
+ */
+    values[12] = ((PyObject *)__pyx_tuple__4);
+
+    /* "astropy/io/ascii/cparser.pyx":202
+ *                   exclude_names=None,
+ *                   fill_values=('', '0'),
+ *                   fill_include_names=None,             # <<<<<<<<<<<<<<
+ *                   fill_exclude_names=None,
+ *                   fill_extra_cols=0,
+ */
+    values[13] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":203
+ *                   fill_values=('', '0'),
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,             # <<<<<<<<<<<<<<
+ *                   fill_extra_cols=0,
+ *                   fast_reader=True):
+ */
+    values[14] = ((PyObject *)Py_None);
+    values[15] = ((PyObject *)__pyx_int_0);
+
+    /* "astropy/io/ascii/cparser.pyx":205
+ *                   fill_exclude_names=None,
+ *                   fill_extra_cols=0,
+ *                   fast_reader=True):             # <<<<<<<<<<<<<<
+ * 
+ *         # Handle fast_reader parameter (True or dict specifying options)
+ */
+    values[16] = ((PyObject *)Py_True);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case 17: values[16] = PyTuple_GET_ITEM(__pyx_args, 16);
+        case 16: values[15] = PyTuple_GET_ITEM(__pyx_args, 15);
+        case 15: values[14] = PyTuple_GET_ITEM(__pyx_args, 14);
+        case 14: values[13] = PyTuple_GET_ITEM(__pyx_args, 13);
+        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
+        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
+        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
+        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_source)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strip_line_whitespace)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 17, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strip_line_fields)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 17, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_delimiter);
+          if (value) { values[3] = value; kw_args--; }
+        }
+        case  4:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_comment);
+          if (value) { values[4] = value; kw_args--; }
+        }
+        case  5:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_quotechar);
+          if (value) { values[5] = value; kw_args--; }
+        }
+        case  6:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_header_start);
+          if (value) { values[6] = value; kw_args--; }
+        }
+        case  7:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data_start);
+          if (value) { values[7] = value; kw_args--; }
+        }
+        case  8:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data_end);
+          if (value) { values[8] = value; kw_args--; }
+        }
+        case  9:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_names);
+          if (value) { values[9] = value; kw_args--; }
+        }
+        case 10:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_include_names);
+          if (value) { values[10] = value; kw_args--; }
+        }
+        case 11:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_exclude_names);
+          if (value) { values[11] = value; kw_args--; }
+        }
+        case 12:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_values);
+          if (value) { values[12] = value; kw_args--; }
+        }
+        case 13:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_include_names);
+          if (value) { values[13] = value; kw_args--; }
+        }
+        case 14:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_exclude_names);
+          if (value) { values[14] = value; kw_args--; }
+        }
+        case 15:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_extra_cols);
+          if (value) { values[15] = value; kw_args--; }
+        }
+        case 16:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fast_reader);
+          if (value) { values[16] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case 17: values[16] = PyTuple_GET_ITEM(__pyx_args, 16);
+        case 16: values[15] = PyTuple_GET_ITEM(__pyx_args, 15);
+        case 15: values[14] = PyTuple_GET_ITEM(__pyx_args, 14);
+        case 14: values[13] = PyTuple_GET_ITEM(__pyx_args, 13);
+        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
+        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
+        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
+        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_source = values[0];
+    __pyx_v_strip_line_whitespace = values[1];
+    __pyx_v_strip_line_fields = values[2];
+    __pyx_v_delimiter = values[3];
+    __pyx_v_comment = values[4];
+    __pyx_v_quotechar = values[5];
+    __pyx_v_header_start = values[6];
+    __pyx_v_data_start = values[7];
+    __pyx_v_data_end = values[8];
+    __pyx_v_names = values[9];
+    __pyx_v_include_names = values[10];
+    __pyx_v_exclude_names = values[11];
+    __pyx_v_fill_values = values[12];
+    __pyx_v_fill_include_names = values[13];
+    __pyx_v_fill_exclude_names = values[14];
+    __pyx_v_fill_extra_cols = values[15];
+    __pyx_v_fast_reader = values[16];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 17, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser___cinit__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), __pyx_v_source, __pyx_v_strip_line_whitespace, __pyx_v_strip_line_fields, __pyx_v_delimiter, __pyx_v_comment, __pyx_v_quotechar, __pyx_v_header_start, __pyx_v_data_start, __pyx_v_data_end, __pyx_v_names, __pyx_v_include_names, __pyx_v_exclude_names, __pyx_v_fill_values, __pyx_v_fill_include_names, __pyx_v_fill_exclude_names, __pyx_v_fill_extra_cols [...]
+
+  /* "astropy/io/ascii/cparser.pyx":191
+ *         object header_start
+ * 
+ *     def __cinit__(self, source, strip_line_whitespace, strip_line_fields,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment=None,
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source, PyObject *__pyx_v_strip_line_whitespace, PyObject *__pyx_v_strip_line_fields, PyObject *__pyx_v_delimiter, PyObject *__pyx_v_comment, PyObject *__pyx_v_quotechar, PyObject *__pyx_v_header_start, PyObject *__pyx_v_data_start, PyObject *__pyx_v_data_end, PyObject *__pyx_v_names, PyObject *__pyx_v_include_names, PyObject *__pyx_v_ [...]
+  PyObject *__pyx_v_use_fast_converter = NULL;
+  PyObject *__pyx_v_parallel = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  char __pyx_t_6;
+  char __pyx_t_7;
+  char __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_t_11;
+  int __pyx_t_12;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+  __Pyx_INCREF(__pyx_v_comment);
+  __Pyx_INCREF(__pyx_v_fast_reader);
+
+  /* "astropy/io/ascii/cparser.pyx":208
+ * 
+ *         # Handle fast_reader parameter (True or dict specifying options)
+ *         if fast_reader is True or fast_reader == 'force':             # <<<<<<<<<<<<<<
+ *             fast_reader = {}
+ *         elif fast_reader is False: # shouldn't happen
+ */
+  __pyx_t_2 = (__pyx_v_fast_reader == Py_True);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (!__pyx_t_3) {
+  } else {
+    __pyx_t_1 = __pyx_t_3;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_fast_reader, __pyx_n_s_force, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_t_3;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":209
+ *         # Handle fast_reader parameter (True or dict specifying options)
+ *         if fast_reader is True or fast_reader == 'force':
+ *             fast_reader = {}             # <<<<<<<<<<<<<<
+ *         elif fast_reader is False: # shouldn't happen
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")
+ */
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF_SET(__pyx_v_fast_reader, __pyx_t_4);
+    __pyx_t_4 = 0;
+    goto __pyx_L3;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":210
+ *         if fast_reader is True or fast_reader == 'force':
+ *             fast_reader = {}
+ *         elif fast_reader is False: # shouldn't happen             # <<<<<<<<<<<<<<
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")
+ *         # parallel and use_fast_reader are False by default
+ */
+  __pyx_t_1 = (__pyx_v_fast_reader == Py_False);
+  __pyx_t_3 = (__pyx_t_1 != 0);
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":211
+ *             fast_reader = {}
+ *         elif fast_reader is False: # shouldn't happen
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")             # <<<<<<<<<<<<<<
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)
+ */
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_core); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ParameterError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":213
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)             # <<<<<<<<<<<<<<
+ *         parallel = fast_reader.pop('parallel', False)
+ *         if fast_reader:
+ */
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_fast_reader, __pyx_n_s_pop); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_use_fast_converter = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":214
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)
+ *         parallel = fast_reader.pop('parallel', False)             # <<<<<<<<<<<<<<
+ *         if fast_reader:
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ */
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_fast_reader, __pyx_n_s_pop); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_v_parallel = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":215
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)
+ *         parallel = fast_reader.pop('parallel', False)
+ *         if fast_reader:             # <<<<<<<<<<<<<<
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ *         if parallel and os.name == 'nt':
+ */
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_fast_reader); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":216
+ *         parallel = fast_reader.pop('parallel', False)
+ *         if fast_reader:
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")             # <<<<<<<<<<<<<<
+ *         if parallel and os.name == 'nt':
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")
+ */
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_core); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_FastOptionsError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":217
+ *         if fast_reader:
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ *         if parallel and os.name == 'nt':             # <<<<<<<<<<<<<<
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")
+ * 
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_parallel); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+  } else {
+    __pyx_t_3 = __pyx_t_1;
+    goto __pyx_L8_bool_binop_done;
+  }
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_os); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_1 = (__Pyx_PyString_Equals(__pyx_t_5, __pyx_n_s_nt, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = __pyx_t_1;
+  __pyx_L8_bool_binop_done:;
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":218
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ *         if parallel and os.name == 'nt':
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")             # <<<<<<<<<<<<<<
+ * 
+ *         if comment is None:
+ */
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":220
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")
+ * 
+ *         if comment is None:             # <<<<<<<<<<<<<<
+ *             comment = '\x00' # tokenizer ignores all comments if comment='\x00'
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),
+ */
+  __pyx_t_3 = (__pyx_v_comment == Py_None);
+  __pyx_t_1 = (__pyx_t_3 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":221
+ * 
+ *         if comment is None:
+ *             comment = '\x00' # tokenizer ignores all comments if comment='\x00'             # <<<<<<<<<<<<<<
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),
+ *                                           fill_extra_cols,
+ */
+    __Pyx_INCREF(__pyx_kp_s__10);
+    __Pyx_DECREF_SET(__pyx_v_comment, __pyx_kp_s__10);
+    goto __pyx_L10;
+  }
+  __pyx_L10:;
+
+  /* "astropy/io/ascii/cparser.pyx":222
+ *         if comment is None:
+ *             comment = '\x00' # tokenizer ignores all comments if comment='\x00'
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),             # <<<<<<<<<<<<<<
+ *                                           fill_extra_cols,
+ *                                           strip_line_whitespace,
+ */
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_delimiter);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_delimiter);
+  __Pyx_GIVEREF(__pyx_v_delimiter);
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_6 = __Pyx_PyInt_As_char(__pyx_t_4); if (unlikely((__pyx_t_6 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_comment);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_comment);
+  __Pyx_GIVEREF(__pyx_v_comment);
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_7 = __Pyx_PyInt_As_char(__pyx_t_5); if (unlikely((__pyx_t_7 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_quotechar);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_quotechar);
+  __Pyx_GIVEREF(__pyx_v_quotechar);
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_8 = __Pyx_PyInt_As_char(__pyx_t_4); if (unlikely((__pyx_t_8 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":223
+ *             comment = '\x00' # tokenizer ignores all comments if comment='\x00'
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),
+ *                                           fill_extra_cols,             # <<<<<<<<<<<<<<
+ *                                           strip_line_whitespace,
+ *                                           strip_line_fields,
+ */
+  __pyx_t_9 = __Pyx_PyInt_As_int(__pyx_v_fill_extra_cols); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":224
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),
+ *                                           fill_extra_cols,
+ *                                           strip_line_whitespace,             # <<<<<<<<<<<<<<
+ *                                           strip_line_fields,
+ *                                           use_fast_converter)
+ */
+  __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_v_strip_line_whitespace); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":225
+ *                                           fill_extra_cols,
+ *                                           strip_line_whitespace,
+ *                                           strip_line_fields,             # <<<<<<<<<<<<<<
+ *                                           use_fast_converter)
+ *         self.source = None
+ */
+  __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_strip_line_fields); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":226
+ *                                           strip_line_whitespace,
+ *                                           strip_line_fields,
+ *                                           use_fast_converter)             # <<<<<<<<<<<<<<
+ *         self.source = None
+ *         if source is not None:
+ */
+  __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_use_fast_converter); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":222
+ *         if comment is None:
+ *             comment = '\x00' # tokenizer ignores all comments if comment='\x00'
+ *         self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),             # <<<<<<<<<<<<<<
+ *                                           fill_extra_cols,
+ *                                           strip_line_whitespace,
+ */
+  __pyx_v_self->tokenizer = create_tokenizer(__pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_t_12);
+
+  /* "astropy/io/ascii/cparser.pyx":227
+ *                                           strip_line_fields,
+ *                                           use_fast_converter)
+ *         self.source = None             # <<<<<<<<<<<<<<
+ *         if source is not None:
+ *             self.setup_tokenizer(source)
+ */
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->source);
+  __Pyx_DECREF(__pyx_v_self->source);
+  __pyx_v_self->source = Py_None;
+
+  /* "astropy/io/ascii/cparser.pyx":228
+ *                                           use_fast_converter)
+ *         self.source = None
+ *         if source is not None:             # <<<<<<<<<<<<<<
+ *             self.setup_tokenizer(source)
+ *         self.header_start = header_start
+ */
+  __pyx_t_1 = (__pyx_v_source != Py_None);
+  __pyx_t_3 = (__pyx_t_1 != 0);
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":229
+ *         self.source = None
+ *         if source is not None:
+ *             self.setup_tokenizer(source)             # <<<<<<<<<<<<<<
+ *         self.header_start = header_start
+ *         self.data_start = data_start
+ */
+    __pyx_t_4 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->setup_tokenizer(__pyx_v_self, __pyx_v_source, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L11;
+  }
+  __pyx_L11:;
+
+  /* "astropy/io/ascii/cparser.pyx":230
+ *         if source is not None:
+ *             self.setup_tokenizer(source)
+ *         self.header_start = header_start             # <<<<<<<<<<<<<<
+ *         self.data_start = data_start
+ *         self.data_end = data_end
+ */
+  __Pyx_INCREF(__pyx_v_header_start);
+  __Pyx_GIVEREF(__pyx_v_header_start);
+  __Pyx_GOTREF(__pyx_v_self->header_start);
+  __Pyx_DECREF(__pyx_v_self->header_start);
+  __pyx_v_self->header_start = __pyx_v_header_start;
+
+  /* "astropy/io/ascii/cparser.pyx":231
+ *             self.setup_tokenizer(source)
+ *         self.header_start = header_start
+ *         self.data_start = data_start             # <<<<<<<<<<<<<<
+ *         self.data_end = data_end
+ *         self.names = names
+ */
+  __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_data_start); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->data_start = __pyx_t_12;
+
+  /* "astropy/io/ascii/cparser.pyx":232
+ *         self.header_start = header_start
+ *         self.data_start = data_start
+ *         self.data_end = data_end             # <<<<<<<<<<<<<<
+ *         self.names = names
+ *         self.include_names = include_names
+ */
+  __Pyx_INCREF(__pyx_v_data_end);
+  __Pyx_GIVEREF(__pyx_v_data_end);
+  __Pyx_GOTREF(__pyx_v_self->data_end);
+  __Pyx_DECREF(__pyx_v_self->data_end);
+  __pyx_v_self->data_end = __pyx_v_data_end;
+
+  /* "astropy/io/ascii/cparser.pyx":233
+ *         self.data_start = data_start
+ *         self.data_end = data_end
+ *         self.names = names             # <<<<<<<<<<<<<<
+ *         self.include_names = include_names
+ *         self.exclude_names = exclude_names
+ */
+  __Pyx_INCREF(__pyx_v_names);
+  __Pyx_GIVEREF(__pyx_v_names);
+  __Pyx_GOTREF(__pyx_v_self->names);
+  __Pyx_DECREF(__pyx_v_self->names);
+  __pyx_v_self->names = __pyx_v_names;
+
+  /* "astropy/io/ascii/cparser.pyx":234
+ *         self.data_end = data_end
+ *         self.names = names
+ *         self.include_names = include_names             # <<<<<<<<<<<<<<
+ *         self.exclude_names = exclude_names
+ *         self.fill_values = fill_values
+ */
+  __Pyx_INCREF(__pyx_v_include_names);
+  __Pyx_GIVEREF(__pyx_v_include_names);
+  __Pyx_GOTREF(__pyx_v_self->include_names);
+  __Pyx_DECREF(__pyx_v_self->include_names);
+  __pyx_v_self->include_names = __pyx_v_include_names;
+
+  /* "astropy/io/ascii/cparser.pyx":235
+ *         self.names = names
+ *         self.include_names = include_names
+ *         self.exclude_names = exclude_names             # <<<<<<<<<<<<<<
+ *         self.fill_values = fill_values
+ *         self.fill_include_names = fill_include_names
+ */
+  __Pyx_INCREF(__pyx_v_exclude_names);
+  __Pyx_GIVEREF(__pyx_v_exclude_names);
+  __Pyx_GOTREF(__pyx_v_self->exclude_names);
+  __Pyx_DECREF(__pyx_v_self->exclude_names);
+  __pyx_v_self->exclude_names = __pyx_v_exclude_names;
+
+  /* "astropy/io/ascii/cparser.pyx":236
+ *         self.include_names = include_names
+ *         self.exclude_names = exclude_names
+ *         self.fill_values = fill_values             # <<<<<<<<<<<<<<
+ *         self.fill_include_names = fill_include_names
+ *         self.fill_exclude_names = fill_exclude_names
+ */
+  __Pyx_INCREF(__pyx_v_fill_values);
+  __Pyx_GIVEREF(__pyx_v_fill_values);
+  __Pyx_GOTREF(__pyx_v_self->fill_values);
+  __Pyx_DECREF(__pyx_v_self->fill_values);
+  __pyx_v_self->fill_values = __pyx_v_fill_values;
+
+  /* "astropy/io/ascii/cparser.pyx":237
+ *         self.exclude_names = exclude_names
+ *         self.fill_values = fill_values
+ *         self.fill_include_names = fill_include_names             # <<<<<<<<<<<<<<
+ *         self.fill_exclude_names = fill_exclude_names
+ *         self.fill_names = None
+ */
+  __Pyx_INCREF(__pyx_v_fill_include_names);
+  __Pyx_GIVEREF(__pyx_v_fill_include_names);
+  __Pyx_GOTREF(__pyx_v_self->fill_include_names);
+  __Pyx_DECREF(__pyx_v_self->fill_include_names);
+  __pyx_v_self->fill_include_names = __pyx_v_fill_include_names;
+
+  /* "astropy/io/ascii/cparser.pyx":238
+ *         self.fill_values = fill_values
+ *         self.fill_include_names = fill_include_names
+ *         self.fill_exclude_names = fill_exclude_names             # <<<<<<<<<<<<<<
+ *         self.fill_names = None
+ *         self.fill_extra_cols = fill_extra_cols
+ */
+  __Pyx_INCREF(__pyx_v_fill_exclude_names);
+  __Pyx_GIVEREF(__pyx_v_fill_exclude_names);
+  __Pyx_GOTREF(__pyx_v_self->fill_exclude_names);
+  __Pyx_DECREF(__pyx_v_self->fill_exclude_names);
+  __pyx_v_self->fill_exclude_names = __pyx_v_fill_exclude_names;
+
+  /* "astropy/io/ascii/cparser.pyx":239
+ *         self.fill_include_names = fill_include_names
+ *         self.fill_exclude_names = fill_exclude_names
+ *         self.fill_names = None             # <<<<<<<<<<<<<<
+ *         self.fill_extra_cols = fill_extra_cols
+ * 
+ */
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->fill_names);
+  __Pyx_DECREF(__pyx_v_self->fill_names);
+  __pyx_v_self->fill_names = Py_None;
+
+  /* "astropy/io/ascii/cparser.pyx":240
+ *         self.fill_exclude_names = fill_exclude_names
+ *         self.fill_names = None
+ *         self.fill_extra_cols = fill_extra_cols             # <<<<<<<<<<<<<<
+ * 
+ *         # parallel=True indicates that we should use the CPU count
+ */
+  __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_fill_extra_cols); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->fill_extra_cols = __pyx_t_12;
+
+  /* "astropy/io/ascii/cparser.pyx":243
+ * 
+ *         # parallel=True indicates that we should use the CPU count
+ *         if parallel is True:             # <<<<<<<<<<<<<<
+ *             parallel = multiprocessing.cpu_count()
+ *         # If parallel = 1 or 0, don't use multiprocessing
+ */
+  __pyx_t_3 = (__pyx_v_parallel == Py_True);
+  __pyx_t_1 = (__pyx_t_3 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":244
+ *         # parallel=True indicates that we should use the CPU count
+ *         if parallel is True:
+ *             parallel = multiprocessing.cpu_count()             # <<<<<<<<<<<<<<
+ *         # If parallel = 1 or 0, don't use multiprocessing
+ *         elif parallel is not False and parallel < 2:
+ */
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_multiprocessing); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_cpu_count); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_13))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_13);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_13, function);
+      }
+    }
+    if (__pyx_t_5) {
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_13); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_DECREF_SET(__pyx_v_parallel, __pyx_t_4);
+    __pyx_t_4 = 0;
+    goto __pyx_L12;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":246
+ *             parallel = multiprocessing.cpu_count()
+ *         # If parallel = 1 or 0, don't use multiprocessing
+ *         elif parallel is not False and parallel < 2:             # <<<<<<<<<<<<<<
+ *             parallel = False
+ *         self.parallel = parallel
+ */
+  __pyx_t_3 = (__pyx_v_parallel != Py_False);
+  __pyx_t_2 = (__pyx_t_3 != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L13_bool_binop_done;
+  }
+  __pyx_t_4 = PyObject_RichCompare(__pyx_v_parallel, __pyx_int_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L13_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":247
+ *         # If parallel = 1 or 0, don't use multiprocessing
+ *         elif parallel is not False and parallel < 2:
+ *             parallel = False             # <<<<<<<<<<<<<<
+ *         self.parallel = parallel
+ * 
+ */
+    __Pyx_INCREF(Py_False);
+    __Pyx_DECREF_SET(__pyx_v_parallel, Py_False);
+    goto __pyx_L12;
+  }
+  __pyx_L12:;
+
+  /* "astropy/io/ascii/cparser.pyx":248
+ *         elif parallel is not False and parallel < 2:
+ *             parallel = False
+ *         self.parallel = parallel             # <<<<<<<<<<<<<<
+ * 
+ *     def __dealloc__(self):
+ */
+  __Pyx_INCREF(__pyx_v_parallel);
+  __Pyx_GIVEREF(__pyx_v_parallel);
+  __Pyx_GOTREF(__pyx_v_self->parallel);
+  __Pyx_DECREF(__pyx_v_self->parallel);
+  __pyx_v_self->parallel = __pyx_v_parallel;
+
+  /* "astropy/io/ascii/cparser.pyx":191
+ *         object header_start
+ * 
+ *     def __cinit__(self, source, strip_line_whitespace, strip_line_fields,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment=None,
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_use_fast_converter);
+  __Pyx_XDECREF(__pyx_v_parallel);
+  __Pyx_XDECREF(__pyx_v_comment);
+  __Pyx_XDECREF(__pyx_v_fast_reader);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":250
+ *         self.parallel = parallel
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ *         if self.tokenizer:
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup
+ */
+
+/* Python wrapper */
+static void __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_2__dealloc__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_2__dealloc__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":251
+ * 
+ *     def __dealloc__(self):
+ *         if self.tokenizer:             # <<<<<<<<<<<<<<
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->tokenizer != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":252
+ *     def __dealloc__(self):
+ *         if self.tokenizer:
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup             # <<<<<<<<<<<<<<
+ * 
+ *     cdef get_error(self, code, num_rows, msg):
+ */
+    delete_tokenizer(__pyx_v_self->tokenizer);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":250
+ *         self.parallel = parallel
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ *         if self.tokenizer:
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "astropy/io/ascii/cparser.pyx":254
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup
+ * 
+ *     cdef get_error(self, code, num_rows, msg):             # <<<<<<<<<<<<<<
+ *         err_msg = ERR_CODES.get(code, "unknown error")
+ * 
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_get_error(CYTHON_UNUSED struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_num_rows, PyObject *__pyx_v_msg) {
+  PyObject *__pyx_v_err_msg = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_error", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":255
+ * 
+ *     cdef get_error(self, code, num_rows, msg):
+ *         err_msg = ERR_CODES.get(code, "unknown error")             # <<<<<<<<<<<<<<
+ * 
+ *         # error code is lambda function taking current line as input
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_ERR_CODES); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_2) {
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+  }
+  __Pyx_INCREF(__pyx_v_code);
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_v_code);
+  __Pyx_GIVEREF(__pyx_v_code);
+  __Pyx_INCREF(__pyx_kp_s_unknown_error);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_kp_s_unknown_error);
+  __Pyx_GIVEREF(__pyx_kp_s_unknown_error);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_err_msg = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":258
+ * 
+ *         # error code is lambda function taking current line as input
+ *         if callable(err_msg):             # <<<<<<<<<<<<<<
+ *             err_msg = err_msg(num_rows + 1)
+ * 
+ */
+  __pyx_t_6 = __Pyx_PyCallable_Check(__pyx_v_err_msg); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = (__pyx_t_6 != 0);
+  if (__pyx_t_7) {
+
+    /* "astropy/io/ascii/cparser.pyx":259
+ *         # error code is lambda function taking current line as input
+ *         if callable(err_msg):
+ *             err_msg = err_msg(num_rows + 1)             # <<<<<<<<<<<<<<
+ * 
+ *         return CParserError("{0}: {1}".format(msg, err_msg))
+ */
+    __pyx_t_3 = PyNumber_Add(__pyx_v_num_rows, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_err_msg);
+    __pyx_t_5 = __pyx_v_err_msg; __pyx_t_2 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_2)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_2);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_2) {
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_GOTREF(__pyx_t_1);
+    } else {
+      __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+      PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __pyx_t_3 = 0;
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF_SET(__pyx_v_err_msg, __pyx_t_1);
+    __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":261
+ *             err_msg = err_msg(num_rows + 1)
+ * 
+ *         return CParserError("{0}: {1}".format(msg, err_msg))             # <<<<<<<<<<<<<<
+ * 
+ *     cdef raise_error(self, msg):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_CParserError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_0_1, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_9 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  if (__pyx_t_2) {
+    PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+  }
+  __Pyx_INCREF(__pyx_v_msg);
+  PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_4, __pyx_v_msg);
+  __Pyx_GIVEREF(__pyx_v_msg);
+  __Pyx_INCREF(__pyx_v_err_msg);
+  PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_4, __pyx_v_err_msg);
+  __Pyx_GIVEREF(__pyx_v_err_msg);
+  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_5, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    __pyx_t_8 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":254
+ *             delete_tokenizer(self.tokenizer) # perform C memory cleanup
+ * 
+ *     cdef get_error(self, code, num_rows, msg):             # <<<<<<<<<<<<<<
+ *         err_msg = ERR_CODES.get(code, "unknown error")
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.get_error", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_err_msg);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":263
+ *         return CParserError("{0}: {1}".format(msg, err_msg))
+ * 
+ *     cdef raise_error(self, msg):             # <<<<<<<<<<<<<<
+ *         raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)
+ * 
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_raise_error(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_msg) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("raise_error", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":264
+ * 
+ *     cdef raise_error(self, msg):
+ *         raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef setup_tokenizer(self, source):
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->tokenizer->code); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->tokenizer->num_rows); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->get_error(__pyx_v_self, __pyx_t_1, __pyx_t_2, __pyx_v_msg); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":263
+ *         return CParserError("{0}: {1}".format(msg, err_msg))
+ * 
+ *     cdef raise_error(self, msg):             # <<<<<<<<<<<<<<
+ *         raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.raise_error", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":266
+ *         raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)
+ * 
+ *     cpdef setup_tokenizer(self, source):             # <<<<<<<<<<<<<<
+ *         cdef FileString fstring
+ * 
+ */
+
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5setup_tokenizer(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_setup_tokenizer(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *__pyx_v_fstring = 0;
+  PyObject *__pyx_v_file_obj = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_t_8;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  int __pyx_t_15;
+  char *__pyx_t_16;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("setup_tokenizer", 0);
+  __Pyx_INCREF(__pyx_v_source);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_setup_tokenizer); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5setup_tokenizer)) {
+      __Pyx_XDECREF(__pyx_r);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_4)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+        }
+      }
+      if (!__pyx_t_4) {
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+      } else {
+        __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+        __Pyx_INCREF(__pyx_v_source);
+        PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_source);
+        __Pyx_GIVEREF(__pyx_v_source);
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":269
+ *         cdef FileString fstring
+ * 
+ *         if isinstance(source, six.string_types): # filename or data             # <<<<<<<<<<<<<<
+ *             if '\n' not in source and '\r' not in source: # filename
+ *                 fstring = FileString(source)
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_string_types); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_6 = PyObject_IsInstance(__pyx_v_source, __pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_7 = (__pyx_t_6 != 0);
+  if (__pyx_t_7) {
+
+    /* "astropy/io/ascii/cparser.pyx":270
+ * 
+ *         if isinstance(source, six.string_types): # filename or data
+ *             if '\n' not in source and '\r' not in source: # filename             # <<<<<<<<<<<<<<
+ *                 fstring = FileString(source)
+ *                 self.tokenizer.source = <char *>fstring.mmap_ptr
+ */
+    __pyx_t_6 = (__Pyx_PySequence_Contains(__pyx_kp_s__11, __pyx_v_source, Py_NE)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = (__pyx_t_6 != 0);
+    if (__pyx_t_8) {
+    } else {
+      __pyx_t_7 = __pyx_t_8;
+      goto __pyx_L5_bool_binop_done;
+    }
+    __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_kp_s__12, __pyx_v_source, Py_NE)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = (__pyx_t_8 != 0);
+    __pyx_t_7 = __pyx_t_6;
+    __pyx_L5_bool_binop_done:;
+    if (__pyx_t_7) {
+
+      /* "astropy/io/ascii/cparser.pyx":271
+ *         if isinstance(source, six.string_types): # filename or data
+ *             if '\n' not in source and '\r' not in source: # filename
+ *                 fstring = FileString(source)             # <<<<<<<<<<<<<<
+ *                 self.tokenizer.source = <char *>fstring.mmap_ptr
+ *                 self.source_ptr = <char *>fstring.mmap_ptr
+ */
+      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_INCREF(__pyx_v_source);
+      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_source);
+      __Pyx_GIVEREF(__pyx_v_source);
+      __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_7astropy_2io_5ascii_7cparser_FileString)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_v_fstring = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_t_1);
+      __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":272
+ *             if '\n' not in source and '\r' not in source: # filename
+ *                 fstring = FileString(source)
+ *                 self.tokenizer.source = <char *>fstring.mmap_ptr             # <<<<<<<<<<<<<<
+ *                 self.source_ptr = <char *>fstring.mmap_ptr
+ *                 self.source = fstring
+ */
+      __pyx_v_self->tokenizer->source = ((char *)__pyx_v_fstring->mmap_ptr);
+
+      /* "astropy/io/ascii/cparser.pyx":273
+ *                 fstring = FileString(source)
+ *                 self.tokenizer.source = <char *>fstring.mmap_ptr
+ *                 self.source_ptr = <char *>fstring.mmap_ptr             # <<<<<<<<<<<<<<
+ *                 self.source = fstring
+ *                 self.tokenizer.source_len = len(fstring)
+ */
+      __pyx_v_self->source_ptr = ((char *)__pyx_v_fstring->mmap_ptr);
+
+      /* "astropy/io/ascii/cparser.pyx":274
+ *                 self.tokenizer.source = <char *>fstring.mmap_ptr
+ *                 self.source_ptr = <char *>fstring.mmap_ptr
+ *                 self.source = fstring             # <<<<<<<<<<<<<<
+ *                 self.tokenizer.source_len = len(fstring)
+ *                 return
+ */
+      __Pyx_INCREF(((PyObject *)__pyx_v_fstring));
+      __Pyx_GIVEREF(((PyObject *)__pyx_v_fstring));
+      __Pyx_GOTREF(__pyx_v_self->source);
+      __Pyx_DECREF(__pyx_v_self->source);
+      __pyx_v_self->source = ((PyObject *)__pyx_v_fstring);
+
+      /* "astropy/io/ascii/cparser.pyx":275
+ *                 self.source_ptr = <char *>fstring.mmap_ptr
+ *                 self.source = fstring
+ *                 self.tokenizer.source_len = len(fstring)             # <<<<<<<<<<<<<<
+ *                 return
+ *             # Otherwise, source is the actual data so we leave it be
+ */
+      __pyx_t_9 = PyObject_Length(((PyObject *)__pyx_v_fstring)); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_self->tokenizer->source_len = __pyx_t_9;
+
+      /* "astropy/io/ascii/cparser.pyx":276
+ *                 self.source = fstring
+ *                 self.tokenizer.source_len = len(fstring)
+ *                 return             # <<<<<<<<<<<<<<
+ *             # Otherwise, source is the actual data so we leave it be
+ *         elif hasattr(source, 'read'): # file-like object
+ */
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+      goto __pyx_L0;
+    }
+    goto __pyx_L3;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":278
+ *                 return
+ *             # Otherwise, source is the actual data so we leave it be
+ *         elif hasattr(source, 'read'): # file-like object             # <<<<<<<<<<<<<<
+ *             with get_readable_fileobj(source) as file_obj:
+ *                 source = file_obj.read()
+ */
+  __pyx_t_7 = PyObject_HasAttr(__pyx_v_source, __pyx_n_s_read); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = (__pyx_t_7 != 0);
+  if (__pyx_t_6) {
+
+    /* "astropy/io/ascii/cparser.pyx":279
+ *             # Otherwise, source is the actual data so we leave it be
+ *         elif hasattr(source, 'read'): # file-like object
+ *             with get_readable_fileobj(source) as file_obj:             # <<<<<<<<<<<<<<
+ *                 source = file_obj.read()
+ *         elif isinstance(source, FileString):
+ */
+    /*with:*/ {
+      __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_get_readable_fileobj); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+        __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+        if (likely(__pyx_t_3)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+          __Pyx_INCREF(__pyx_t_3);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_2, function);
+        }
+      }
+      if (!__pyx_t_3) {
+        __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_source); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+      } else {
+        __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+        __Pyx_INCREF(__pyx_v_source);
+        PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_source);
+        __Pyx_GIVEREF(__pyx_v_source);
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_10 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_exit); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_5 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_enter); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+        __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
+        if (likely(__pyx_t_3)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+          __Pyx_INCREF(__pyx_t_3);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_5, function);
+        }
+      }
+      if (__pyx_t_3) {
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      } else {
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      /*try:*/ {
+        {
+          __Pyx_ExceptionSave(&__pyx_t_11, &__pyx_t_12, &__pyx_t_13);
+          __Pyx_XGOTREF(__pyx_t_11);
+          __Pyx_XGOTREF(__pyx_t_12);
+          __Pyx_XGOTREF(__pyx_t_13);
+          /*try:*/ {
+            __pyx_v_file_obj = __pyx_t_5;
+            __pyx_t_5 = 0;
+
+            /* "astropy/io/ascii/cparser.pyx":280
+ *         elif hasattr(source, 'read'): # file-like object
+ *             with get_readable_fileobj(source) as file_obj:
+ *                 source = file_obj.read()             # <<<<<<<<<<<<<<
+ *         elif isinstance(source, FileString):
+ *             self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)
+ */
+            __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_file_obj, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L11_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __pyx_t_2 = NULL;
+            if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+              __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
+              if (likely(__pyx_t_2)) {
+                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+                __Pyx_INCREF(__pyx_t_2);
+                __Pyx_INCREF(function);
+                __Pyx_DECREF_SET(__pyx_t_1, function);
+              }
+            }
+            if (__pyx_t_2) {
+              __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L11_error;}
+              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            } else {
+              __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L11_error;}
+            }
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            __Pyx_DECREF_SET(__pyx_v_source, __pyx_t_5);
+            __pyx_t_5 = 0;
+          }
+          __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+          __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+          goto __pyx_L18_try_end;
+          __pyx_L11_error:;
+          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+          __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":279
+ *             # Otherwise, source is the actual data so we leave it be
+ *         elif hasattr(source, 'read'): # file-like object
+ *             with get_readable_fileobj(source) as file_obj:             # <<<<<<<<<<<<<<
+ *                 source = file_obj.read()
+ *         elif isinstance(source, FileString):
+ */
+          /*except:*/ {
+            __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.setup_tokenizer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+            if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_1, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L13_except_error;}
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_GOTREF(__pyx_t_2);
+            __pyx_t_3 = PyTuple_Pack(3, __pyx_t_5, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L13_except_error;}
+            __Pyx_GOTREF(__pyx_t_3);
+            __pyx_t_14 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_3, NULL);
+            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+            if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L13_except_error;}
+            __Pyx_GOTREF(__pyx_t_14);
+            __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_14);
+            __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+            if (__pyx_t_6 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L13_except_error;}
+            __pyx_t_7 = ((!(__pyx_t_6 != 0)) != 0);
+            if (__pyx_t_7) {
+              __Pyx_GIVEREF(__pyx_t_5);
+              __Pyx_GIVEREF(__pyx_t_1);
+              __Pyx_XGIVEREF(__pyx_t_2);
+              __Pyx_ErrRestore(__pyx_t_5, __pyx_t_1, __pyx_t_2);
+              __pyx_t_5 = 0; __pyx_t_1 = 0; __pyx_t_2 = 0; 
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L13_except_error;}
+            }
+            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            goto __pyx_L12_exception_handled;
+          }
+          __pyx_L13_except_error:;
+          __Pyx_XGIVEREF(__pyx_t_11);
+          __Pyx_XGIVEREF(__pyx_t_12);
+          __Pyx_XGIVEREF(__pyx_t_13);
+          __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+          goto __pyx_L1_error;
+          __pyx_L12_exception_handled:;
+          __Pyx_XGIVEREF(__pyx_t_11);
+          __Pyx_XGIVEREF(__pyx_t_12);
+          __Pyx_XGIVEREF(__pyx_t_13);
+          __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+          __pyx_L18_try_end:;
+        }
+      }
+      /*finally:*/ {
+        /*normal exit:*/{
+          if (__pyx_t_10) {
+            __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__13, NULL);
+            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+            if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_13);
+            __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+          }
+          goto __pyx_L10;
+        }
+        __pyx_L10:;
+      }
+      goto __pyx_L22;
+      __pyx_L7_error:;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L1_error;
+      __pyx_L22:;
+    }
+    goto __pyx_L3;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":281
+ *             with get_readable_fileobj(source) as file_obj:
+ *                 source = file_obj.read()
+ *         elif isinstance(source, FileString):             # <<<<<<<<<<<<<<
+ *             self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)
+ *             self.source = source
+ */
+  __pyx_t_7 = __Pyx_TypeCheck(__pyx_v_source, ((PyObject*)__pyx_ptype_7astropy_2io_5ascii_7cparser_FileString)); 
+  __pyx_t_6 = (__pyx_t_7 != 0);
+  if (__pyx_t_6) {
+
+    /* "astropy/io/ascii/cparser.pyx":282
+ *                 source = file_obj.read()
+ *         elif isinstance(source, FileString):
+ *             self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)             # <<<<<<<<<<<<<<
+ *             self.source = source
+ *             self.tokenizer.source_len = len(source)
+ */
+    __pyx_v_self->tokenizer->source = ((char *)((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)__pyx_v_source)->mmap_ptr);
+
+    /* "astropy/io/ascii/cparser.pyx":283
+ *         elif isinstance(source, FileString):
+ *             self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)
+ *             self.source = source             # <<<<<<<<<<<<<<
+ *             self.tokenizer.source_len = len(source)
+ *             return
+ */
+    __Pyx_INCREF(__pyx_v_source);
+    __Pyx_GIVEREF(__pyx_v_source);
+    __Pyx_GOTREF(__pyx_v_self->source);
+    __Pyx_DECREF(__pyx_v_self->source);
+    __pyx_v_self->source = __pyx_v_source;
+
+    /* "astropy/io/ascii/cparser.pyx":284
+ *             self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)
+ *             self.source = source
+ *             self.tokenizer.source_len = len(source)             # <<<<<<<<<<<<<<
+ *             return
+ *         else:
+ */
+    __pyx_t_9 = PyObject_Length(__pyx_v_source); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_self->tokenizer->source_len = __pyx_t_9;
+
+    /* "astropy/io/ascii/cparser.pyx":285
+ *             self.source = source
+ *             self.tokenizer.source_len = len(source)
+ *             return             # <<<<<<<<<<<<<<
+ *         else:
+ *             try:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":287
+ *             return
+ *         else:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 source = '\n'.join(source) # iterable sequence of lines
+ *             except TypeError:
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_10, &__pyx_t_13, &__pyx_t_12);
+      __Pyx_XGOTREF(__pyx_t_10);
+      __Pyx_XGOTREF(__pyx_t_13);
+      __Pyx_XGOTREF(__pyx_t_12);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":288
+ *         else:
+ *             try:
+ *                 source = '\n'.join(source) # iterable sequence of lines             # <<<<<<<<<<<<<<
+ *             except TypeError:
+ *                 raise TypeError('Input "table" must be a file-like object, a '
+ */
+        __pyx_t_2 = __Pyx_PyString_Join(__pyx_kp_s__11, __pyx_v_source); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L23_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF_SET(__pyx_v_source, __pyx_t_2);
+        __pyx_t_2 = 0;
+      }
+      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+      __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+      goto __pyx_L30_try_end;
+      __pyx_L23_error:;
+      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":289
+ *             try:
+ *                 source = '\n'.join(source) # iterable sequence of lines
+ *             except TypeError:             # <<<<<<<<<<<<<<
+ *                 raise TypeError('Input "table" must be a file-like object, a '
+ *                                 'string (filename or data), or an iterable')
+ */
+      __pyx_t_15 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+      if (__pyx_t_15) {
+        __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.setup_tokenizer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_1, &__pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L25_except_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_GOTREF(__pyx_t_5);
+
+        /* "astropy/io/ascii/cparser.pyx":290
+ *                 source = '\n'.join(source) # iterable sequence of lines
+ *             except TypeError:
+ *                 raise TypeError('Input "table" must be a file-like object, a '             # <<<<<<<<<<<<<<
+ *                                 'string (filename or data), or an iterable')
+ *         # Create a reference to the Python object so its char * pointer remains valid
+ */
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L25_except_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L25_except_error;}
+      }
+      goto __pyx_L25_except_error;
+      __pyx_L25_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_10);
+      __Pyx_XGIVEREF(__pyx_t_13);
+      __Pyx_XGIVEREF(__pyx_t_12);
+      __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_13, __pyx_t_12);
+      goto __pyx_L1_error;
+      __pyx_L30_try_end:;
+    }
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":293
+ *                                 'string (filename or data), or an iterable')
+ *         # Create a reference to the Python object so its char * pointer remains valid
+ *         self.source = source             # <<<<<<<<<<<<<<
+ * 
+ *         # encode in ASCII for char * handling
+ */
+  __Pyx_INCREF(__pyx_v_source);
+  __Pyx_GIVEREF(__pyx_v_source);
+  __Pyx_GOTREF(__pyx_v_self->source);
+  __Pyx_DECREF(__pyx_v_self->source);
+  __pyx_v_self->source = __pyx_v_source;
+
+  /* "astropy/io/ascii/cparser.pyx":296
+ * 
+ *         # encode in ASCII for char * handling
+ *         self.source_bytes = self.source.encode('ascii')             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source = self.source_bytes
+ *         self.tokenizer.source_len = len(self.source_bytes)
+ */
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->source, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (!(likely(PyBytes_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->source_bytes);
+  __Pyx_DECREF(__pyx_v_self->source_bytes);
+  __pyx_v_self->source_bytes = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":297
+ *         # encode in ASCII for char * handling
+ *         self.source_bytes = self.source.encode('ascii')
+ *         self.tokenizer.source = self.source_bytes             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source_len = len(self.source_bytes)
+ * 
+ */
+  __pyx_t_16 = __Pyx_PyObject_AsString(__pyx_v_self->source_bytes); if (unlikely((!__pyx_t_16) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->tokenizer->source = __pyx_t_16;
+
+  /* "astropy/io/ascii/cparser.pyx":298
+ *         self.source_bytes = self.source.encode('ascii')
+ *         self.tokenizer.source = self.source_bytes
+ *         self.tokenizer.source_len = len(self.source_bytes)             # <<<<<<<<<<<<<<
+ * 
+ *     def read_header(self):
+ */
+  __pyx_t_1 = __pyx_v_self->source_bytes;
+  __Pyx_INCREF(__pyx_t_1);
+  if (unlikely(__pyx_t_1 == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_9 = PyBytes_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_self->tokenizer->source_len = __pyx_t_9;
+
+  /* "astropy/io/ascii/cparser.pyx":266
+ *         raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)
+ * 
+ *     cpdef setup_tokenizer(self, source):             # <<<<<<<<<<<<<<
+ *         cdef FileString fstring
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.setup_tokenizer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_fstring);
+  __Pyx_XDECREF(__pyx_v_file_obj);
+  __Pyx_XDECREF(__pyx_v_source);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5setup_tokenizer(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5setup_tokenizer(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("setup_tokenizer (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_4setup_tokenizer(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_4setup_tokenizer(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("setup_tokenizer", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_7astropy_2io_5ascii_7cparser_7CParser_setup_tokenizer(__pyx_v_self, __pyx_v_source, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.setup_tokenizer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":300
+ *         self.tokenizer.source_len = len(self.source_bytes)
+ * 
+ *     def read_header(self):             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source_pos = 0
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_7read_header(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_7read_header(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read_header (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6read_header(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6read_header(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_v_c = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *(*__pyx_t_8)(PyObject *);
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read_header", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":301
+ * 
+ *     def read_header(self):
+ *         self.tokenizer.source_pos = 0             # <<<<<<<<<<<<<<
+ * 
+ *         if self.names:
+ */
+  __pyx_v_self->tokenizer->source_pos = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":303
+ *         self.tokenizer.source_pos = 0
+ * 
+ *         if self.names:             # <<<<<<<<<<<<<<
+ *             self.width = len(self.names)
+ * 
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->names); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":304
+ * 
+ *         if self.names:
+ *             self.width = len(self.names)             # <<<<<<<<<<<<<<
+ * 
+ *         # header_start is a valid line number
+ */
+    __pyx_t_2 = __pyx_v_self->names;
+    __Pyx_INCREF(__pyx_t_2);
+    __pyx_t_3 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_self->width = __pyx_t_3;
+    goto __pyx_L3;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":307
+ * 
+ *         # header_start is a valid line number
+ *         elif self.header_start is not None and self.header_start >= 0:             # <<<<<<<<<<<<<<
+ *             if skip_lines(self.tokenizer, self.header_start, 1) != 0:
+ *                 self.raise_error("an error occurred while advancing to the "
+ */
+  __pyx_t_4 = (__pyx_v_self->header_start != Py_None);
+  __pyx_t_5 = (__pyx_t_4 != 0);
+  if (__pyx_t_5) {
+  } else {
+    __pyx_t_1 = __pyx_t_5;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_self->header_start, __pyx_int_0, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __pyx_t_5;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":308
+ *         # header_start is a valid line number
+ *         elif self.header_start is not None and self.header_start >= 0:
+ *             if skip_lines(self.tokenizer, self.header_start, 1) != 0:             # <<<<<<<<<<<<<<
+ *                 self.raise_error("an error occurred while advancing to the "
+ *                                  "first header line")
+ */
+    __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_v_self->header_start); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = ((skip_lines(__pyx_v_self->tokenizer, __pyx_t_6, 1) != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":309
+ *         elif self.header_start is not None and self.header_start >= 0:
+ *             if skip_lines(self.tokenizer, self.header_start, 1) != 0:
+ *                 self.raise_error("an error occurred while advancing to the "             # <<<<<<<<<<<<<<
+ *                                  "first header line")
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:
+ */
+      __pyx_t_2 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->raise_error(__pyx_v_self, __pyx_kp_s_an_error_occurred_while_advancin); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "astropy/io/ascii/cparser.pyx":311
+ *                 self.raise_error("an error occurred while advancing to the "
+ *                                  "first header line")
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:             # <<<<<<<<<<<<<<
+ *                 self.raise_error("an error occurred while tokenizing the header line")
+ *             self.names = []
+ */
+    __pyx_t_1 = ((tokenize(__pyx_v_self->tokenizer, -1, 1, 0) != 0) != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":312
+ *                                  "first header line")
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:
+ *                 self.raise_error("an error occurred while tokenizing the header line")             # <<<<<<<<<<<<<<
+ *             self.names = []
+ *             name = ''
+ */
+      __pyx_t_2 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->raise_error(__pyx_v_self, __pyx_kp_s_an_error_occurred_while_tokenizi); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "astropy/io/ascii/cparser.pyx":313
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:
+ *                 self.raise_error("an error occurred while tokenizing the header line")
+ *             self.names = []             # <<<<<<<<<<<<<<
+ *             name = ''
+ * 
+ */
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __Pyx_GOTREF(__pyx_v_self->names);
+    __Pyx_DECREF(__pyx_v_self->names);
+    __pyx_v_self->names = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":314
+ *                 self.raise_error("an error occurred while tokenizing the header line")
+ *             self.names = []
+ *             name = ''             # <<<<<<<<<<<<<<
+ * 
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ */
+    __Pyx_INCREF(__pyx_kp_s__3);
+    __pyx_v_name = __pyx_kp_s__3;
+
+    /* "astropy/io/ascii/cparser.pyx":316
+ *             name = ''
+ * 
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string             # <<<<<<<<<<<<<<
+ *                 c = self.tokenizer.output_cols[0][i] # next char in header string
+ *                 if not c: # zero byte -- field terminator
+ */
+    __pyx_t_2 = __Pyx_PyInt_From_int((__pyx_v_self->tokenizer->output_len[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
+      __pyx_t_7 = __pyx_t_2; __Pyx_INCREF(__pyx_t_7); __pyx_t_3 = 0;
+      __pyx_t_8 = NULL;
+    } else {
+      __pyx_t_3 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    for (;;) {
+      if (likely(!__pyx_t_8)) {
+        if (likely(PyList_CheckExact(__pyx_t_7))) {
+          if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_7, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_7, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_2 = __pyx_t_8(__pyx_t_7);
+        if (unlikely(!__pyx_t_2)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_2);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2);
+      __pyx_t_2 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":317
+ * 
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ *                 c = self.tokenizer.output_cols[0][i] # next char in header string             # <<<<<<<<<<<<<<
+ *                 if not c: # zero byte -- field terminator
+ *                     if name:
+ */
+      __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_v_i); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyInt_From_char(((__pyx_v_self->tokenizer->output_cols[0])[__pyx_t_9])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_XDECREF_SET(__pyx_v_c, __pyx_t_2);
+      __pyx_t_2 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":318
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ *                 c = self.tokenizer.output_cols[0][i] # next char in header string
+ *                 if not c: # zero byte -- field terminator             # <<<<<<<<<<<<<<
+ *                     if name:
+ *                         # replace empty placeholder with ''
+ */
+      __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_c); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = ((!__pyx_t_1) != 0);
+      if (__pyx_t_5) {
+
+        /* "astropy/io/ascii/cparser.pyx":319
+ *                 c = self.tokenizer.output_cols[0][i] # next char in header string
+ *                 if not c: # zero byte -- field terminator
+ *                     if name:             # <<<<<<<<<<<<<<
+ *                         # replace empty placeholder with ''
+ *                         self.names.append(name.replace('\x01', ''))
+ */
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_name); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__pyx_t_5) {
+
+          /* "astropy/io/ascii/cparser.pyx":321
+ *                     if name:
+ *                         # replace empty placeholder with ''
+ *                         self.names.append(name.replace('\x01', ''))             # <<<<<<<<<<<<<<
+ *                         name = ''
+ *                     else:
+ */
+          __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_name, __pyx_n_s_replace); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_10);
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_self->names, __pyx_t_10); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":322
+ *                         # replace empty placeholder with ''
+ *                         self.names.append(name.replace('\x01', ''))
+ *                         name = ''             # <<<<<<<<<<<<<<
+ *                     else:
+ *                         break # end of string
+ */
+          __Pyx_INCREF(__pyx_kp_s__3);
+          __Pyx_DECREF_SET(__pyx_v_name, __pyx_kp_s__3);
+          goto __pyx_L11;
+        }
+        /*else*/ {
+
+          /* "astropy/io/ascii/cparser.pyx":324
+ *                         name = ''
+ *                     else:
+ *                         break # end of string             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     name += chr(c)
+ */
+          goto __pyx_L9_break;
+        }
+        __pyx_L11:;
+        goto __pyx_L10;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":326
+ *                         break # end of string
+ *                 else:
+ *                     name += chr(c)             # <<<<<<<<<<<<<<
+ *             self.width = len(self.names)
+ * 
+ */
+        __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_10);
+        __Pyx_INCREF(__pyx_v_c);
+        PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_c);
+        __Pyx_GIVEREF(__pyx_v_c);
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+        __pyx_t_10 = PyNumber_InPlaceAdd(__pyx_v_name, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_10);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF_SET(__pyx_v_name, __pyx_t_10);
+        __pyx_t_10 = 0;
+      }
+      __pyx_L10:;
+
+      /* "astropy/io/ascii/cparser.pyx":316
+ *             name = ''
+ * 
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string             # <<<<<<<<<<<<<<
+ *                 c = self.tokenizer.output_cols[0][i] # next char in header string
+ *                 if not c: # zero byte -- field terminator
+ */
+    }
+    __pyx_L9_break:;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":327
+ *                 else:
+ *                     name += chr(c)
+ *             self.width = len(self.names)             # <<<<<<<<<<<<<<
+ * 
+ *         else:
+ */
+    __pyx_t_7 = __pyx_v_self->names;
+    __Pyx_INCREF(__pyx_t_7);
+    __pyx_t_3 = PyObject_Length(__pyx_t_7); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_v_self->width = __pyx_t_3;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":331
+ *         else:
+ *             # Get number of columns from first data row
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:             # <<<<<<<<<<<<<<
+ *                 self.raise_error("an error occurred while tokenizing the first line of data")
+ *             self.width = 0
+ */
+    __pyx_t_5 = ((tokenize(__pyx_v_self->tokenizer, -1, 1, 0) != 0) != 0);
+    if (__pyx_t_5) {
+
+      /* "astropy/io/ascii/cparser.pyx":332
+ *             # Get number of columns from first data row
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:
+ *                 self.raise_error("an error occurred while tokenizing the first line of data")             # <<<<<<<<<<<<<<
+ *             self.width = 0
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ */
+      __pyx_t_7 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->raise_error(__pyx_v_self, __pyx_kp_s_an_error_occurred_while_tokenizi_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L12;
+    }
+    __pyx_L12:;
+
+    /* "astropy/io/ascii/cparser.pyx":333
+ *             if tokenize(self.tokenizer, -1, 1, 0) != 0:
+ *                 self.raise_error("an error occurred while tokenizing the first line of data")
+ *             self.width = 0             # <<<<<<<<<<<<<<
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ *                 # zero byte -- field terminator
+ */
+    __pyx_v_self->width = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":334
+ *                 self.raise_error("an error occurred while tokenizing the first line of data")
+ *             self.width = 0
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string             # <<<<<<<<<<<<<<
+ *                 # zero byte -- field terminator
+ *                 if not self.tokenizer.output_cols[0][i]:
+ */
+    __pyx_t_7 = __Pyx_PyInt_From_int((__pyx_v_self->tokenizer->output_len[0])); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_7 = 0;
+    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_10, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    if (likely(PyList_CheckExact(__pyx_t_7)) || PyTuple_CheckExact(__pyx_t_7)) {
+      __pyx_t_10 = __pyx_t_7; __Pyx_INCREF(__pyx_t_10); __pyx_t_3 = 0;
+      __pyx_t_8 = NULL;
+    } else {
+      __pyx_t_3 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_8 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    for (;;) {
+      if (likely(!__pyx_t_8)) {
+        if (likely(PyList_CheckExact(__pyx_t_10))) {
+          if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_10)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_7 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_7 = PySequence_ITEM(__pyx_t_10, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_7 = PySequence_ITEM(__pyx_t_10, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_7 = __pyx_t_8(__pyx_t_10);
+        if (unlikely(!__pyx_t_7)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_7);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_7);
+      __pyx_t_7 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":336
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string
+ *                 # zero byte -- field terminator
+ *                 if not self.tokenizer.output_cols[0][i]:             # <<<<<<<<<<<<<<
+ *                     # ends valid field
+ *                     if i > 0 and self.tokenizer.output_cols[0][i - 1]:
+ */
+      __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_v_i); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = ((!(((__pyx_v_self->tokenizer->output_cols[0])[__pyx_t_9]) != 0)) != 0);
+      if (__pyx_t_5) {
+
+        /* "astropy/io/ascii/cparser.pyx":338
+ *                 if not self.tokenizer.output_cols[0][i]:
+ *                     # ends valid field
+ *                     if i > 0 and self.tokenizer.output_cols[0][i - 1]:             # <<<<<<<<<<<<<<
+ *                         self.width += 1
+ *                     else: # end of line
+ */
+        __pyx_t_7 = PyObject_RichCompare(__pyx_v_i, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        if (__pyx_t_1) {
+        } else {
+          __pyx_t_5 = __pyx_t_1;
+          goto __pyx_L17_bool_binop_done;
+        }
+        __pyx_t_7 = PyNumber_Subtract(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_1 = (((__pyx_v_self->tokenizer->output_cols[0])[__pyx_t_9]) != 0);
+        __pyx_t_5 = __pyx_t_1;
+        __pyx_L17_bool_binop_done:;
+        if (__pyx_t_5) {
+
+          /* "astropy/io/ascii/cparser.pyx":339
+ *                     # ends valid field
+ *                     if i > 0 and self.tokenizer.output_cols[0][i - 1]:
+ *                         self.width += 1             # <<<<<<<<<<<<<<
+ *                     else: # end of line
+ *                         break
+ */
+          __pyx_v_self->width = (__pyx_v_self->width + 1);
+          goto __pyx_L16;
+        }
+        /*else*/ {
+
+          /* "astropy/io/ascii/cparser.pyx":341
+ *                         self.width += 1
+ *                     else: # end of line
+ *                         break             # <<<<<<<<<<<<<<
+ *             if self.width == 0: # no data
+ *                 raise core.InconsistentTableError('No data lines found, C reader '
+ */
+          goto __pyx_L14_break;
+        }
+        __pyx_L16:;
+        goto __pyx_L15;
+      }
+      __pyx_L15:;
+
+      /* "astropy/io/ascii/cparser.pyx":334
+ *                 self.raise_error("an error occurred while tokenizing the first line of data")
+ *             self.width = 0
+ *             for i in range(self.tokenizer.output_len[0]): # header is in first col string             # <<<<<<<<<<<<<<
+ *                 # zero byte -- field terminator
+ *                 if not self.tokenizer.output_cols[0][i]:
+ */
+    }
+    __pyx_L14_break:;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":342
+ *                     else: # end of line
+ *                         break
+ *             if self.width == 0: # no data             # <<<<<<<<<<<<<<
+ *                 raise core.InconsistentTableError('No data lines found, C reader '
+ *                                             'cannot autogenerate column names')
+ */
+    __pyx_t_5 = ((__pyx_v_self->width == 0) != 0);
+    if (__pyx_t_5) {
+
+      /* "astropy/io/ascii/cparser.pyx":343
+ *                         break
+ *             if self.width == 0: # no data
+ *                 raise core.InconsistentTableError('No data lines found, C reader '             # <<<<<<<<<<<<<<
+ *                                             'cannot autogenerate column names')
+ *             # auto-generate names
+ */
+      __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_core); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_InconsistentTableError); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":346
+ *                                             'cannot autogenerate column names')
+ *             # auto-generate names
+ *             self.names = ['col{0}'.format(i + 1) for i in range(self.width)]             # <<<<<<<<<<<<<<
+ * 
+ *         # self.use_cols should only contain columns included in output
+ */
+    __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_self->width); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_7 = 0;
+    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_2, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (likely(PyList_CheckExact(__pyx_t_7)) || PyTuple_CheckExact(__pyx_t_7)) {
+      __pyx_t_2 = __pyx_t_7; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+      __pyx_t_8 = NULL;
+    } else {
+      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_8 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    for (;;) {
+      if (likely(!__pyx_t_8)) {
+        if (likely(PyList_CheckExact(__pyx_t_2))) {
+          if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_7 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_7 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_7 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_7 = __pyx_t_8(__pyx_t_2);
+        if (unlikely(!__pyx_t_7)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_7);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_7);
+      __pyx_t_7 = 0;
+      __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_col_0, __pyx_n_s_format); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __pyx_t_13 = PyNumber_Add(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_13);
+      __pyx_t_14 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_12))) {
+        __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_12);
+        if (likely(__pyx_t_14)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_12);
+          __Pyx_INCREF(__pyx_t_14);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_12, function);
+        }
+      }
+      if (!__pyx_t_14) {
+        __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __Pyx_GOTREF(__pyx_t_7);
+      } else {
+        __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_15);
+        PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_14); __Pyx_GIVEREF(__pyx_t_14); __pyx_t_14 = NULL;
+        PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_13 = 0;
+        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_15, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_10, (PyObject*)__pyx_t_7))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_GIVEREF(__pyx_t_10);
+    __Pyx_GOTREF(__pyx_v_self->names);
+    __Pyx_DECREF(__pyx_v_self->names);
+    __pyx_v_self->names = __pyx_t_10;
+    __pyx_t_10 = 0;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":349
+ * 
+ *         # self.use_cols should only contain columns included in output
+ *         self.use_cols = set(self.names)             # <<<<<<<<<<<<<<
+ *         if self.include_names is not None:
+ *             self.use_cols.intersection_update(self.include_names)
+ */
+  __pyx_t_10 = PySet_New(__pyx_v_self->names); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->use_cols);
+  __Pyx_DECREF(__pyx_v_self->use_cols);
+  __pyx_v_self->use_cols = ((PyObject*)__pyx_t_10);
+  __pyx_t_10 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":350
+ *         # self.use_cols should only contain columns included in output
+ *         self.use_cols = set(self.names)
+ *         if self.include_names is not None:             # <<<<<<<<<<<<<<
+ *             self.use_cols.intersection_update(self.include_names)
+ *         if self.exclude_names is not None:
+ */
+  __pyx_t_5 = (__pyx_v_self->include_names != Py_None);
+  __pyx_t_1 = (__pyx_t_5 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":351
+ *         self.use_cols = set(self.names)
+ *         if self.include_names is not None:
+ *             self.use_cols.intersection_update(self.include_names)             # <<<<<<<<<<<<<<
+ *         if self.exclude_names is not None:
+ *             self.use_cols.difference_update(self.exclude_names)
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->use_cols, __pyx_n_s_intersection_update); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (!__pyx_t_7) {
+      __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_self->include_names); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+    } else {
+      __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+      __Pyx_INCREF(__pyx_v_self->include_names);
+      PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_v_self->include_names);
+      __Pyx_GIVEREF(__pyx_v_self->include_names);
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_12, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    goto __pyx_L22;
+  }
+  __pyx_L22:;
+
+  /* "astropy/io/ascii/cparser.pyx":352
+ *         if self.include_names is not None:
+ *             self.use_cols.intersection_update(self.include_names)
+ *         if self.exclude_names is not None:             # <<<<<<<<<<<<<<
+ *             self.use_cols.difference_update(self.exclude_names)
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->exclude_names != Py_None);
+  __pyx_t_5 = (__pyx_t_1 != 0);
+  if (__pyx_t_5) {
+
+    /* "astropy/io/ascii/cparser.pyx":353
+ *             self.use_cols.intersection_update(self.include_names)
+ *         if self.exclude_names is not None:
+ *             self.use_cols.difference_update(self.exclude_names)             # <<<<<<<<<<<<<<
+ * 
+ *         self.width = len(self.names)
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->use_cols, __pyx_n_s_difference_update); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_12 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_12)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_12);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (!__pyx_t_12) {
+      __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_self->exclude_names); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+    } else {
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_12); __pyx_t_12 = NULL;
+      __Pyx_INCREF(__pyx_v_self->exclude_names);
+      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_self->exclude_names);
+      __Pyx_GIVEREF(__pyx_v_self->exclude_names);
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    goto __pyx_L23;
+  }
+  __pyx_L23:;
+
+  /* "astropy/io/ascii/cparser.pyx":355
+ *             self.use_cols.difference_update(self.exclude_names)
+ * 
+ *         self.width = len(self.names)             # <<<<<<<<<<<<<<
+ * 
+ *     def read(self, try_int, try_float, try_string):
+ */
+  __pyx_t_10 = __pyx_v_self->names;
+  __Pyx_INCREF(__pyx_t_10);
+  __pyx_t_3 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_v_self->width = __pyx_t_3;
+
+  /* "astropy/io/ascii/cparser.pyx":300
+ *         self.tokenizer.source_len = len(self.source_bytes)
+ * 
+ *     def read_header(self):             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source_pos = 0
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_XDECREF(__pyx_t_15);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.read_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_c);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":357
+ *         self.width = len(self.names)
+ * 
+ *     def read(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         if self.parallel:
+ *             return self._read_parallel(try_int, try_float, try_string)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_9read(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_9read(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_try_int = 0;
+  PyObject *__pyx_v_try_float = 0;
+  PyObject *__pyx_v_try_string = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_try_int,&__pyx_n_s_try_float,&__pyx_n_s_try_string,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_int)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_float)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_string)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_try_int = values[0];
+    __pyx_v_try_float = values[1];
+    __pyx_v_try_string = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("read", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_8read(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), __pyx_v_try_int, __pyx_v_try_float, __pyx_v_try_string);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_8read(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string) {
+  int __pyx_v_data_end;
+  int __pyx_v_num_rows;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  int __pyx_t_8;
+  long __pyx_t_9;
+  int __pyx_t_10;
+  PyObject *__pyx_t_11 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":358
+ * 
+ *     def read(self, try_int, try_float, try_string):
+ *         if self.parallel:             # <<<<<<<<<<<<<<
+ *             return self._read_parallel(try_int, try_float, try_string)
+ * 
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->parallel); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":359
+ *     def read(self, try_int, try_float, try_string):
+ *         if self.parallel:
+ *             return self._read_parallel(try_int, try_float, try_string)             # <<<<<<<<<<<<<<
+ * 
+ *         # Read in a single process
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_read_parallel); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = NULL;
+    __pyx_t_5 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+        __pyx_t_5 = 1;
+      }
+    }
+    __pyx_t_6 = PyTuple_New(3+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    if (__pyx_t_4) {
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    }
+    __Pyx_INCREF(__pyx_v_try_int);
+    PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_try_int);
+    __Pyx_GIVEREF(__pyx_v_try_int);
+    __Pyx_INCREF(__pyx_v_try_float);
+    PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_try_float);
+    __Pyx_GIVEREF(__pyx_v_try_float);
+    __Pyx_INCREF(__pyx_v_try_string);
+    PyTuple_SET_ITEM(__pyx_t_6, 2+__pyx_t_5, __pyx_v_try_string);
+    __Pyx_GIVEREF(__pyx_v_try_string);
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":362
+ * 
+ *         # Read in a single process
+ *         self.tokenizer.source_pos = 0             # <<<<<<<<<<<<<<
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+ *             self.raise_error("an error occurred while advancing to the first "
+ */
+  __pyx_v_self->tokenizer->source_pos = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":363
+ *         # Read in a single process
+ *         self.tokenizer.source_pos = 0
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:             # <<<<<<<<<<<<<<
+ *             self.raise_error("an error occurred while advancing to the first "
+ *                              "line of data")
+ */
+  __pyx_t_1 = ((skip_lines(__pyx_v_self->tokenizer, __pyx_v_self->data_start, 0) != 0) != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":364
+ *         self.tokenizer.source_pos = 0
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+ *             self.raise_error("an error occurred while advancing to the first "             # <<<<<<<<<<<<<<
+ *                              "line of data")
+ * 
+ */
+    __pyx_t_2 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->raise_error(__pyx_v_self, __pyx_kp_s_an_error_occurred_while_advancin_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "astropy/io/ascii/cparser.pyx":367
+ *                              "line of data")
+ * 
+ *         cdef int data_end = -1 # keep reading data until the end             # <<<<<<<<<<<<<<
+ *         if self.data_end is not None and self.data_end >= 0:
+ *             data_end = max(self.data_end - self.data_start, 0) # read nothing if data_end < 0
+ */
+  __pyx_v_data_end = -1;
+
+  /* "astropy/io/ascii/cparser.pyx":368
+ * 
+ *         cdef int data_end = -1 # keep reading data until the end
+ *         if self.data_end is not None and self.data_end >= 0:             # <<<<<<<<<<<<<<
+ *             data_end = max(self.data_end - self.data_start, 0) # read nothing if data_end < 0
+ * 
+ */
+  __pyx_t_7 = (__pyx_v_self->data_end != Py_None);
+  __pyx_t_8 = (__pyx_t_7 != 0);
+  if (__pyx_t_8) {
+  } else {
+    __pyx_t_1 = __pyx_t_8;
+    goto __pyx_L6_bool_binop_done;
+  }
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_self->data_end, __pyx_int_0, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __pyx_t_8;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":369
+ *         cdef int data_end = -1 # keep reading data until the end
+ *         if self.data_end is not None and self.data_end >= 0:
+ *             data_end = max(self.data_end - self.data_start, 0) # read nothing if data_end < 0             # <<<<<<<<<<<<<<
+ * 
+ *         if tokenize(self.tokenizer, data_end, 0, len(self.names)) != 0:
+ */
+    __pyx_t_9 = 0;
+    __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->data_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_self->data_end, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_t_9); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_6, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (__pyx_t_1) {
+      __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_2 = __pyx_t_4;
+      __pyx_t_4 = 0;
+    } else {
+      __Pyx_INCREF(__pyx_t_3);
+      __pyx_t_2 = __pyx_t_3;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_data_end = __pyx_t_10;
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "astropy/io/ascii/cparser.pyx":371
+ *             data_end = max(self.data_end - self.data_start, 0) # read nothing if data_end < 0
+ * 
+ *         if tokenize(self.tokenizer, data_end, 0, len(self.names)) != 0:             # <<<<<<<<<<<<<<
+ *             self.raise_error("an error occurred while parsing table data")
+ *         elif self.tokenizer.num_rows == 0: # no data
+ */
+  __pyx_t_2 = __pyx_v_self->names;
+  __Pyx_INCREF(__pyx_t_2);
+  __pyx_t_5 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = ((tokenize(__pyx_v_self->tokenizer, __pyx_v_data_end, 0, __pyx_t_5) != 0) != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":372
+ * 
+ *         if tokenize(self.tokenizer, data_end, 0, len(self.names)) != 0:
+ *             self.raise_error("an error occurred while parsing table data")             # <<<<<<<<<<<<<<
+ *         elif self.tokenizer.num_rows == 0: # no data
+ *             return ([np.array([], dtype=np.int_)] * self.width, [])
+ */
+    __pyx_t_2 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->raise_error(__pyx_v_self, __pyx_kp_s_an_error_occurred_while_parsing); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L8;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":373
+ *         if tokenize(self.tokenizer, data_end, 0, len(self.names)) != 0:
+ *             self.raise_error("an error occurred while parsing table data")
+ *         elif self.tokenizer.num_rows == 0: # no data             # <<<<<<<<<<<<<<
+ *             return ([np.array([], dtype=np.int_)] * self.width, [])
+ *         self._set_fill_values()
+ */
+  __pyx_t_1 = ((__pyx_v_self->tokenizer->num_rows == 0) != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":374
+ *             self.raise_error("an error occurred while parsing table data")
+ *         elif self.tokenizer.num_rows == 0: # no data
+ *             return ([np.array([], dtype=np.int_)] * self.width, [])             # <<<<<<<<<<<<<<
+ *         self._set_fill_values()
+ *         cdef int num_rows = self.tokenizer.num_rows
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_int); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_11) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->width<0) ? 0:__pyx_v_self->width)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    { Py_ssize_t __pyx_temp;
+      for (__pyx_temp=0; __pyx_temp < __pyx_v_self->width; __pyx_temp++) {
+        __Pyx_INCREF(__pyx_t_11);
+        PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_t_11);
+        __Pyx_GIVEREF(__pyx_t_11);
+      }
+    }
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_11);
+    __Pyx_GIVEREF(__pyx_t_11);
+    __pyx_t_2 = 0;
+    __pyx_t_11 = 0;
+    __pyx_r = __pyx_t_4;
+    __pyx_t_4 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L8:;
+
+  /* "astropy/io/ascii/cparser.pyx":375
+ *         elif self.tokenizer.num_rows == 0: # no data
+ *             return ([np.array([], dtype=np.int_)] * self.width, [])
+ *         self._set_fill_values()             # <<<<<<<<<<<<<<
+ *         cdef int num_rows = self.tokenizer.num_rows
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing
+ */
+  __pyx_t_4 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_set_fill_values(__pyx_v_self); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":376
+ *             return ([np.array([], dtype=np.int_)] * self.width, [])
+ *         self._set_fill_values()
+ *         cdef int num_rows = self.tokenizer.num_rows             # <<<<<<<<<<<<<<
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing
+ *             num_rows += self.data_end
+ */
+  __pyx_t_10 = __pyx_v_self->tokenizer->num_rows;
+  __pyx_v_num_rows = __pyx_t_10;
+
+  /* "astropy/io/ascii/cparser.pyx":377
+ *         self._set_fill_values()
+ *         cdef int num_rows = self.tokenizer.num_rows
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing             # <<<<<<<<<<<<<<
+ *             num_rows += self.data_end
+ *         return self._convert_data(self.tokenizer, try_int, try_float,
+ */
+  __pyx_t_8 = (__pyx_v_self->data_end != Py_None);
+  __pyx_t_7 = (__pyx_t_8 != 0);
+  if (__pyx_t_7) {
+  } else {
+    __pyx_t_1 = __pyx_t_7;
+    goto __pyx_L10_bool_binop_done;
+  }
+  __pyx_t_4 = PyObject_RichCompare(__pyx_v_self->data_end, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_1 = __pyx_t_7;
+  __pyx_L10_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":378
+ *         cdef int num_rows = self.tokenizer.num_rows
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing
+ *             num_rows += self.data_end             # <<<<<<<<<<<<<<
+ *         return self._convert_data(self.tokenizer, try_int, try_float,
+ *                                   try_string, num_rows)
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_num_rows); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_11 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_v_self->data_end); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __pyx_v_num_rows = __pyx_t_10;
+    goto __pyx_L9;
+  }
+  __pyx_L9:;
+
+  /* "astropy/io/ascii/cparser.pyx":379
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing
+ *             num_rows += self.data_end
+ *         return self._convert_data(self.tokenizer, try_int, try_float,             # <<<<<<<<<<<<<<
+ *                                   try_string, num_rows)
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+
+  /* "astropy/io/ascii/cparser.pyx":380
+ *             num_rows += self.data_end
+ *         return self._convert_data(self.tokenizer, try_int, try_float,
+ *                                   try_string, num_rows)             # <<<<<<<<<<<<<<
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):
+ */
+  __pyx_t_11 = __Pyx_PyInt_From_int(__pyx_v_num_rows); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+
+  /* "astropy/io/ascii/cparser.pyx":379
+ *         if self.data_end is not None and self.data_end < 0: # negative indexing
+ *             num_rows += self.data_end
+ *         return self._convert_data(self.tokenizer, try_int, try_float,             # <<<<<<<<<<<<<<
+ *                                   try_string, num_rows)
+ * 
+ */
+  __pyx_t_4 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_convert_data(__pyx_v_self, __pyx_v_self->tokenizer, __pyx_v_try_int, __pyx_v_try_float, __pyx_v_try_string, __pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":357
+ *         self.width = len(self.names)
+ * 
+ *     def read(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         if self.parallel:
+ *             return self._read_parallel(try_int, try_float, try_string)
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":382
+ *                                   try_string, num_rows)
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         cdef int source_len = len(self.source)
+ *         self.tokenizer.source_pos = 0
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_11_read_parallel(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_11_read_parallel(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_try_int = 0;
+  PyObject *__pyx_v_try_float = 0;
+  PyObject *__pyx_v_try_string = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_read_parallel (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_try_int,&__pyx_n_s_try_float,&__pyx_n_s_try_string,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_int)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_float)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_parallel", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_string)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_parallel", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_read_parallel") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_try_int = values[0];
+    __pyx_v_try_float = values[1];
+    __pyx_v_try_string = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_read_parallel", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._read_parallel", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_10_read_parallel(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), __pyx_v_try_int, __pyx_v_try_float, __pyx_v_try_string);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_2generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "astropy/io/ascii/cparser.pyx":396
+ * 
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in             # <<<<<<<<<<<<<<
+ *                          self.names), [])
+ * 
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_genexpr(PyObject *__pyx_self) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *__pyx_cur_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("genexpr", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *) __pyx_self;
+  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
+  {
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_2generator1, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_read_parallel_locals_genexpr); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_cur_scope);
+    __Pyx_RefNannyFinishContext();
+    return (PyObject *) gen;
+  }
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._read_parallel.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_2generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)__pyx_generator->closure);
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("None", 0);
+  switch (__pyx_generator->resume_label) {
+    case 0: goto __pyx_L3_first_run;
+    case 1: goto __pyx_L6_resume_from_yield;
+    default: /* CPython raises the right error here */
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __pyx_L3_first_run:;
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":397
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in
+ *                          self.names), [])             # <<<<<<<<<<<<<<
+ * 
+ *         cdef int chunksize = math.ceil((source_len - offset) / float(N))
+ */
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names)) {
+    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_3)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name);
+    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":396
+ * 
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in             # <<<<<<<<<<<<<<
+ *                          self.names), [])
+ * 
+ */
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_name);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    __pyx_t_8 = 0;
+    __pyx_r = __pyx_t_4;
+    __pyx_t_4 = 0;
+    __Pyx_XGIVEREF(__pyx_t_1);
+    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
+    __Pyx_XGIVEREF(__pyx_r);
+    __Pyx_RefNannyFinishContext();
+    /* return from generator, yielding value */
+    __pyx_generator->resume_label = 1;
+    return __pyx_r;
+    __pyx_L6_resume_from_yield:;
+    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+    __pyx_cur_scope->__pyx_t_0 = 0;
+    __Pyx_XGOTREF(__pyx_t_1);
+    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* function exit code */
+  PyErr_SetNone(PyExc_StopIteration);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_generator->resume_label = -1;
+  __Pyx_Generator_clear((PyObject*)__pyx_generator);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+}
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_5generator2(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "astropy/io/ascii/cparser.pyx":496
+ * 
+ *             if self.data_end < 0: # no data
+ *                 chunks = [dict((name, []) for name in self.names)]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 line_no = 0
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_3genexpr(PyObject *__pyx_self) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *__pyx_cur_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("genexpr", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *) __pyx_self;
+  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
+  {
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_5generator2, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_read_parallel_locals_genexpr); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_cur_scope);
+    __Pyx_RefNannyFinishContext();
+    return (PyObject *) gen;
+  }
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._read_parallel.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_5generator2(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)__pyx_generator->closure);
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("None", 0);
+  switch (__pyx_generator->resume_label) {
+    case 0: goto __pyx_L3_first_run;
+    case 1: goto __pyx_L6_resume_from_yield;
+    default: /* CPython raises the right error here */
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __pyx_L3_first_run:;
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names)) {
+    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->names); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_3)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name);
+    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_cur_scope->__pyx_v_name);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_4 = 0;
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    __Pyx_XGIVEREF(__pyx_t_1);
+    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
+    __Pyx_XGIVEREF(__pyx_r);
+    __Pyx_RefNannyFinishContext();
+    /* return from generator, yielding value */
+    __pyx_generator->resume_label = 1;
+    return __pyx_r;
+    __pyx_L6_resume_from_yield:;
+    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+    __pyx_cur_scope->__pyx_t_0 = 0;
+    __Pyx_XGOTREF(__pyx_t_1);
+    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* function exit code */
+  PyErr_SetNone(PyExc_StopIteration);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_generator->resume_label = -1;
+  __Pyx_Generator_clear((PyObject*)__pyx_generator);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+}
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_8generator3(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "astropy/io/ascii/cparser.pyx":512
+ *         for name in self.get_names():
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):             # <<<<<<<<<<<<<<
+ *                 ret[name] = ma.concatenate(col_chunks)
+ *             else:
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_6genexpr(PyObject *__pyx_self) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *__pyx_cur_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("genexpr", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *) __pyx_self;
+  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
+  {
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_8generator3, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_read_parallel_locals_genexpr); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_cur_scope);
+    __Pyx_RefNannyFinishContext();
+    return (PyObject *) gen;
+  }
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._read_parallel.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_8generator3(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)__pyx_generator->closure);
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("None", 0);
+  switch (__pyx_generator->resume_label) {
+    case 0: goto __pyx_L3_first_run;
+    case 1: goto __pyx_L6_resume_from_yield;
+    default: /* CPython raises the right error here */
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __pyx_L3_first_run:;
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_col_chunks)) { __Pyx_RaiseClosureNameError("col_chunks"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_col_chunks == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_col_chunks; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_col_chunk);
+    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_col_chunk, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_ma); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_masked_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_5 = PyObject_IsInstance(__pyx_cur_scope->__pyx_v_col_chunk, __pyx_t_4); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_r = __pyx_t_4;
+    __pyx_t_4 = 0;
+    __Pyx_XGIVEREF(__pyx_t_1);
+    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+    __Pyx_XGIVEREF(__pyx_r);
+    __Pyx_RefNannyFinishContext();
+    /* return from generator, yielding value */
+    __pyx_generator->resume_label = 1;
+    return __pyx_r;
+    __pyx_L6_resume_from_yield:;
+    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+    __pyx_cur_scope->__pyx_t_0 = 0;
+    __Pyx_XGOTREF(__pyx_t_1);
+    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* function exit code */
+  PyErr_SetNone(PyExc_StopIteration);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_generator->resume_label = -1;
+  __Pyx_Generator_clear((PyObject*)__pyx_generator);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+}
+
+/* "astropy/io/ascii/cparser.pyx":382
+ *                                   try_string, num_rows)
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         cdef int source_len = len(self.source)
+ *         self.tokenizer.source_pos = 0
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_10_read_parallel(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *__pyx_cur_scope;
+  int __pyx_v_source_len;
+  PyObject *__pyx_v_line_comments = 0;
+  int __pyx_v_N;
+  PyObject *__pyx_v_queue = NULL;
+  int __pyx_v_offset;
+  int __pyx_v_chunksize;
+  PyObject *__pyx_v_chunkindices = 0;
+  PyObject *__pyx_v_reconvert_queue = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_v_index = NULL;
+  PyObject *__pyx_v_processes = 0;
+  PyObject *__pyx_v_process = NULL;
+  PyObject *__pyx_v_chunks = 0;
+  PyObject *__pyx_v_failed_procs = 0;
+  PyObject *__pyx_v_queue_ret = NULL;
+  PyObject *__pyx_v_err = NULL;
+  PyObject *__pyx_v_proc = NULL;
+  PyObject *__pyx_v_comments = NULL;
+  PyObject *__pyx_v_data = NULL;
+  PyObject *__pyx_v_line_no = NULL;
+  PyObject *__pyx_v_seen_str = NULL;
+  PyObject *__pyx_v_seen_numeric = NULL;
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_v_chunk = NULL;
+  PyObject *__pyx_v_reconvert_cols = NULL;
+  PyObject *__pyx_v_reconverted = NULL;
+  PyObject *__pyx_v_col = NULL;
+  PyObject *__pyx_v_num_rows = NULL;
+  PyObject *__pyx_v_ret = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *(*__pyx_t_9)(PyObject *);
+  int __pyx_t_10;
+  int __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *(*__pyx_t_13)(PyObject *);
+  Py_ssize_t __pyx_t_14;
+  int __pyx_t_15;
+  Py_ssize_t __pyx_t_16;
+  PyObject *__pyx_t_17 = NULL;
+  PyObject *__pyx_t_18 = NULL;
+  PyObject *__pyx_t_19 = NULL;
+  PyObject *__pyx_t_20 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_read_parallel", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+  __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+  __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+
+  /* "astropy/io/ascii/cparser.pyx":383
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):
+ *         cdef int source_len = len(self.source)             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source_pos = 0
+ * 
+ */
+  __pyx_t_1 = __pyx_cur_scope->__pyx_v_self->source;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_source_len = __pyx_t_2;
+
+  /* "astropy/io/ascii/cparser.pyx":384
+ *     def _read_parallel(self, try_int, try_float, try_string):
+ *         cdef int source_len = len(self.source)
+ *         self.tokenizer.source_pos = 0             # <<<<<<<<<<<<<<
+ * 
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+ */
+  __pyx_cur_scope->__pyx_v_self->tokenizer->source_pos = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":386
+ *         self.tokenizer.source_pos = 0
+ * 
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:             # <<<<<<<<<<<<<<
+ *             self.raise_error("an error occurred while advancing to the first "
+ *                              "line of data")
+ */
+  __pyx_t_3 = ((skip_lines(__pyx_cur_scope->__pyx_v_self->tokenizer, __pyx_cur_scope->__pyx_v_self->data_start, 0) != 0) != 0);
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":387
+ * 
+ *         if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+ *             self.raise_error("an error occurred while advancing to the first "             # <<<<<<<<<<<<<<
+ *                              "line of data")
+ * 
+ */
+    __pyx_t_1 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->raise_error(__pyx_cur_scope->__pyx_v_self, __pyx_kp_s_an_error_occurred_while_advancin_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":390
+ *                              "line of data")
+ * 
+ *         cdef list line_comments = self._get_comments(self.tokenizer)             # <<<<<<<<<<<<<<
+ *         cdef int N = self.parallel
+ *         queue = multiprocessing.Queue()
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->_get_comments(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_self->tokenizer); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (!(likely(PyList_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_line_comments = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":391
+ * 
+ *         cdef list line_comments = self._get_comments(self.tokenizer)
+ *         cdef int N = self.parallel             # <<<<<<<<<<<<<<
+ *         queue = multiprocessing.Queue()
+ *         cdef int offset = self.tokenizer.source_pos
+ */
+  __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_cur_scope->__pyx_v_self->parallel); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_N = __pyx_t_4;
+
+  /* "astropy/io/ascii/cparser.pyx":392
+ *         cdef list line_comments = self._get_comments(self.tokenizer)
+ *         cdef int N = self.parallel
+ *         queue = multiprocessing.Queue()             # <<<<<<<<<<<<<<
+ *         cdef int offset = self.tokenizer.source_pos
+ * 
+ */
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_multiprocessing); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_Queue); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  if (__pyx_t_5) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_v_queue = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":393
+ *         cdef int N = self.parallel
+ *         queue = multiprocessing.Queue()
+ *         cdef int offset = self.tokenizer.source_pos             # <<<<<<<<<<<<<<
+ * 
+ *         if offset == source_len: # no data
+ */
+  __pyx_t_4 = __pyx_cur_scope->__pyx_v_self->tokenizer->source_pos;
+  __pyx_v_offset = __pyx_t_4;
+
+  /* "astropy/io/ascii/cparser.pyx":395
+ *         cdef int offset = self.tokenizer.source_pos
+ * 
+ *         if offset == source_len: # no data             # <<<<<<<<<<<<<<
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in
+ *                          self.names), [])
+ */
+  __pyx_t_3 = ((__pyx_v_offset == __pyx_v_source_len) != 0);
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":396
+ * 
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in             # <<<<<<<<<<<<<<
+ *                          self.names), [])
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_1 = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":397
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in
+ *                          self.names), [])             # <<<<<<<<<<<<<<
+ * 
+ *         cdef int chunksize = math.ceil((source_len - offset) / float(N))
+ */
+    __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+
+    /* "astropy/io/ascii/cparser.pyx":396
+ * 
+ *         if offset == source_len: # no data
+ *             return (dict((name, np.array([], dtype=np.int_)) for name in             # <<<<<<<<<<<<<<
+ *                          self.names), [])
+ * 
+ */
+    __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_1 = 0;
+    __pyx_t_6 = 0;
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":399
+ *                          self.names), [])
+ * 
+ *         cdef int chunksize = math.ceil((source_len - offset) / float(N))             # <<<<<<<<<<<<<<
+ *         cdef list chunkindices = [offset]
+ * 
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_math); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_ceil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_4 = (__pyx_v_source_len - __pyx_v_offset);
+  if (unlikely(((double)__pyx_v_N) == 0)) {
+    #ifdef WITH_THREAD
+    PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+    #endif
+    PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+    #ifdef WITH_THREAD
+    PyGILState_Release(__pyx_gilstate_save);
+    #endif
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_6 = PyFloat_FromDouble((__pyx_t_4 / ((double)__pyx_v_N))); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_1);
+    if (likely(__pyx_t_7)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_1, function);
+    }
+  }
+  if (!__pyx_t_7) {
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_GOTREF(__pyx_t_5);
+  } else {
+    __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_5); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_v_chunksize = __pyx_t_4;
+
+  /* "astropy/io/ascii/cparser.pyx":400
+ * 
+ *         cdef int chunksize = math.ceil((source_len - offset) / float(N))
+ *         cdef list chunkindices = [offset]             # <<<<<<<<<<<<<<
+ * 
+ *         # This queue is used to signal processes to reconvert if necessary
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_offset); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_v_chunkindices = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":403
+ * 
+ *         # This queue is used to signal processes to reconvert if necessary
+ *         reconvert_queue = multiprocessing.Queue()             # <<<<<<<<<<<<<<
+ * 
+ *         for i in range(1, N):
+ */
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_multiprocessing); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_Queue); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_8);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_8, function);
+    }
+  }
+  if (__pyx_t_5) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_v_reconvert_queue = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":405
+ *         reconvert_queue = multiprocessing.Queue()
+ * 
+ *         for i in range(1, N):             # <<<<<<<<<<<<<<
+ *             index = max(offset + chunksize * i, chunkindices[i - 1])
+ *             while index < source_len and self.source[index] != '\n':
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_INCREF(__pyx_int_1);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_int_1);
+  __Pyx_GIVEREF(__pyx_int_1);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+    __pyx_t_8 = __pyx_t_1; __Pyx_INCREF(__pyx_t_8); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_8))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_8)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_8, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_8)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_8, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_1 = __pyx_t_9(__pyx_t_8);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":406
+ * 
+ *         for i in range(1, N):
+ *             index = max(offset + chunksize * i, chunkindices[i - 1])             # <<<<<<<<<<<<<<
+ *             while index < source_len and self.source[index] != '\n':
+ *                 index += 1
+ */
+    __pyx_t_1 = PyNumber_Subtract(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = PyObject_GetItem(__pyx_v_chunkindices, __pyx_t_1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_chunksize); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = PyNumber_Multiply(__pyx_t_6, __pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_6, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_3) {
+      __Pyx_INCREF(__pyx_t_5);
+      __pyx_t_7 = __pyx_t_5;
+    } else {
+      __Pyx_INCREF(__pyx_t_6);
+      __pyx_t_7 = __pyx_t_6;
+    }
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = __pyx_t_7;
+    __Pyx_INCREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":407
+ *         for i in range(1, N):
+ *             index = max(offset + chunksize * i, chunkindices[i - 1])
+ *             while index < source_len and self.source[index] != '\n':             # <<<<<<<<<<<<<<
+ *                 index += 1
+ *             if index < source_len:
+ */
+    while (1) {
+      __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_source_len); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_7 = PyObject_RichCompare(__pyx_v_index, __pyx_t_5, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      if (__pyx_t_10) {
+      } else {
+        __pyx_t_3 = __pyx_t_10;
+        goto __pyx_L9_bool_binop_done;
+      }
+      __pyx_t_7 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->source, __pyx_v_index); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_10 = (__Pyx_PyString_Equals(__pyx_t_7, __pyx_kp_s__11, Py_NE)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_3 = __pyx_t_10;
+      __pyx_L9_bool_binop_done:;
+      if (!__pyx_t_3) break;
+
+      /* "astropy/io/ascii/cparser.pyx":408
+ *             index = max(offset + chunksize * i, chunkindices[i - 1])
+ *             while index < source_len and self.source[index] != '\n':
+ *                 index += 1             # <<<<<<<<<<<<<<
+ *             if index < source_len:
+ *                 chunkindices.append(index + 1)
+ */
+      __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_v_index, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_7);
+      __pyx_t_7 = 0;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":409
+ *             while index < source_len and self.source[index] != '\n':
+ *                 index += 1
+ *             if index < source_len:             # <<<<<<<<<<<<<<
+ *                 chunkindices.append(index + 1)
+ *             else:
+ */
+    __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_source_len); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_v_index, __pyx_t_7, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":410
+ *                 index += 1
+ *             if index < source_len:
+ *                 chunkindices.append(index + 1)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 N = i
+ */
+      __pyx_t_5 = PyNumber_Add(__pyx_v_index, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_chunkindices, __pyx_t_5); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L11;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":412
+ *                 chunkindices.append(index + 1)
+ *             else:
+ *                 N = i             # <<<<<<<<<<<<<<
+ *                 break
+ * 
+ */
+      __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_v_i); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_N = __pyx_t_4;
+
+      /* "astropy/io/ascii/cparser.pyx":413
+ *             else:
+ *                 N = i
+ *                 break             # <<<<<<<<<<<<<<
+ * 
+ *         self._set_fill_values()
+ */
+      goto __pyx_L6_break;
+    }
+    __pyx_L11:;
+
+    /* "astropy/io/ascii/cparser.pyx":405
+ *         reconvert_queue = multiprocessing.Queue()
+ * 
+ *         for i in range(1, N):             # <<<<<<<<<<<<<<
+ *             index = max(offset + chunksize * i, chunkindices[i - 1])
+ *             while index < source_len and self.source[index] != '\n':
+ */
+  }
+  __pyx_L6_break:;
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":415
+ *                 break
+ * 
+ *         self._set_fill_values()             # <<<<<<<<<<<<<<
+ *         chunkindices.append(source_len)
+ *         cdef list processes = []
+ */
+  __pyx_t_8 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->_set_fill_values(__pyx_cur_scope->__pyx_v_self); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":416
+ * 
+ *         self._set_fill_values()
+ *         chunkindices.append(source_len)             # <<<<<<<<<<<<<<
+ *         cdef list processes = []
+ * 
+ */
+  __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_source_len); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_chunkindices, __pyx_t_8); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":417
+ *         self._set_fill_values()
+ *         chunkindices.append(source_len)
+ *         cdef list processes = []             # <<<<<<<<<<<<<<
+ * 
+ *         for i in range(N):
+ */
+  __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_v_processes = ((PyObject*)__pyx_t_8);
+  __pyx_t_8 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":419
+ *         cdef list processes = []
+ * 
+ *         for i in range(N):             # <<<<<<<<<<<<<<
+ *             process = multiprocessing.Process(target=_read_chunk, args=(self,
+ *                 chunkindices[i], chunkindices[i + 1],
+ */
+  __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_5, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_8)) || PyTuple_CheckExact(__pyx_t_8)) {
+    __pyx_t_5 = __pyx_t_8; __Pyx_INCREF(__pyx_t_5); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_9 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_5))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_8 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_8 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_8 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_8 = __pyx_t_9(__pyx_t_5);
+      if (unlikely(!__pyx_t_8)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_8);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_8);
+    __pyx_t_8 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":420
+ * 
+ *         for i in range(N):
+ *             process = multiprocessing.Process(target=_read_chunk, args=(self,             # <<<<<<<<<<<<<<
+ *                 chunkindices[i], chunkindices[i + 1],
+ *                 try_int, try_float, try_string, queue, reconvert_queue, i))
+ */
+    __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_multiprocessing); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_Process); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_read_chunk); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_target, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":421
+ *         for i in range(N):
+ *             process = multiprocessing.Process(target=_read_chunk, args=(self,
+ *                 chunkindices[i], chunkindices[i + 1],             # <<<<<<<<<<<<<<
+ *                 try_int, try_float, try_string, queue, reconvert_queue, i))
+ *             processes.append(process)
+ */
+    __pyx_t_6 = PyObject_GetItem(__pyx_v_chunkindices, __pyx_v_i); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_1 = PyNumber_Add(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_12 = PyObject_GetItem(__pyx_v_chunkindices, __pyx_t_1); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_12);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":420
+ * 
+ *         for i in range(N):
+ *             process = multiprocessing.Process(target=_read_chunk, args=(self,             # <<<<<<<<<<<<<<
+ *                 chunkindices[i], chunkindices[i + 1],
+ *                 try_int, try_float, try_string, queue, reconvert_queue, i))
+ */
+    __pyx_t_1 = PyTuple_New(9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_cur_scope->__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_12);
+    __Pyx_GIVEREF(__pyx_t_12);
+    __Pyx_INCREF(__pyx_v_try_int);
+    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_try_int);
+    __Pyx_GIVEREF(__pyx_v_try_int);
+    __Pyx_INCREF(__pyx_v_try_float);
+    PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_try_float);
+    __Pyx_GIVEREF(__pyx_v_try_float);
+    __Pyx_INCREF(__pyx_v_try_string);
+    PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_v_try_string);
+    __Pyx_GIVEREF(__pyx_v_try_string);
+    __Pyx_INCREF(__pyx_v_queue);
+    PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_v_queue);
+    __Pyx_GIVEREF(__pyx_v_queue);
+    __Pyx_INCREF(__pyx_v_reconvert_queue);
+    PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_v_reconvert_queue);
+    __Pyx_GIVEREF(__pyx_v_reconvert_queue);
+    __Pyx_INCREF(__pyx_v_i);
+    PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_v_i);
+    __Pyx_GIVEREF(__pyx_v_i);
+    __pyx_t_6 = 0;
+    __pyx_t_12 = 0;
+    if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_args, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_empty_tuple, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_process, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":423
+ *                 chunkindices[i], chunkindices[i + 1],
+ *                 try_int, try_float, try_string, queue, reconvert_queue, i))
+ *             processes.append(process)             # <<<<<<<<<<<<<<
+ *             process.start()
+ * 
+ */
+    __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_processes, __pyx_v_process); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":424
+ *                 try_int, try_float, try_string, queue, reconvert_queue, i))
+ *             processes.append(process)
+ *             process.start()             # <<<<<<<<<<<<<<
+ * 
+ *         cdef list chunks = [None] * N
+ */
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_start); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_8, function);
+      }
+    }
+    if (__pyx_t_7) {
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    } else {
+      __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":419
+ *         cdef list processes = []
+ * 
+ *         for i in range(N):             # <<<<<<<<<<<<<<
+ *             process = multiprocessing.Process(target=_read_chunk, args=(self,
+ *                 chunkindices[i], chunkindices[i + 1],
+ */
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":426
+ *             process.start()
+ * 
+ *         cdef list chunks = [None] * N             # <<<<<<<<<<<<<<
+ *         cdef dict failed_procs = {}
+ * 
+ */
+  __pyx_t_5 = PyList_New(1 * ((__pyx_v_N<0) ? 0:__pyx_v_N)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  { Py_ssize_t __pyx_temp;
+    for (__pyx_temp=0; __pyx_temp < __pyx_v_N; __pyx_temp++) {
+      __Pyx_INCREF(Py_None);
+      PyList_SET_ITEM(__pyx_t_5, __pyx_temp, Py_None);
+      __Pyx_GIVEREF(Py_None);
+    }
+  }
+  __pyx_v_chunks = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":427
+ * 
+ *         cdef list chunks = [None] * N
+ *         cdef dict failed_procs = {}             # <<<<<<<<<<<<<<
+ * 
+ *         for i in range(N):
+ */
+  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_v_failed_procs = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":429
+ *         cdef dict failed_procs = {}
+ * 
+ *         for i in range(N):             # <<<<<<<<<<<<<<
+ *             queue_ret, err, proc = queue.get()
+ *             if isinstance(err, Exception):
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_1, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+    __pyx_t_1 = __pyx_t_5; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_9(__pyx_t_1);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":430
+ * 
+ *         for i in range(N):
+ *             queue_ret, err, proc = queue.get()             # <<<<<<<<<<<<<<
+ *             if isinstance(err, Exception):
+ *                 for process in processes:
+ */
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_get); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_8, function);
+      }
+    }
+    if (__pyx_t_7) {
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    } else {
+      __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
+      PyObject* sequence = __pyx_t_5;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 3)) {
+        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_8 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_12 = PyTuple_GET_ITEM(sequence, 2); 
+      } else {
+        __pyx_t_8 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_12 = PyList_GET_ITEM(sequence, 2); 
+      }
+      __Pyx_INCREF(__pyx_t_8);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_12);
+      #else
+      __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_12 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      #endif
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_6 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_13 = Py_TYPE(__pyx_t_6)->tp_iternext;
+      index = 0; __pyx_t_8 = __pyx_t_13(__pyx_t_6); if (unlikely(!__pyx_t_8)) goto __pyx_L16_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_8);
+      index = 1; __pyx_t_7 = __pyx_t_13(__pyx_t_6); if (unlikely(!__pyx_t_7)) goto __pyx_L16_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_7);
+      index = 2; __pyx_t_12 = __pyx_t_13(__pyx_t_6); if (unlikely(!__pyx_t_12)) goto __pyx_L16_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_12);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_6), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = NULL;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      goto __pyx_L17_unpacking_done;
+      __pyx_L16_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_13 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L17_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_queue_ret, __pyx_t_8);
+    __pyx_t_8 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_err, __pyx_t_7);
+    __pyx_t_7 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_proc, __pyx_t_12);
+    __pyx_t_12 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":431
+ *         for i in range(N):
+ *             queue_ret, err, proc = queue.get()
+ *             if isinstance(err, Exception):             # <<<<<<<<<<<<<<
+ *                 for process in processes:
+ *                     process.terminate()
+ */
+    __pyx_t_3 = PyObject_IsInstance(__pyx_v_err, __pyx_builtin_Exception); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = (__pyx_t_3 != 0);
+    if (__pyx_t_10) {
+
+      /* "astropy/io/ascii/cparser.pyx":432
+ *             queue_ret, err, proc = queue.get()
+ *             if isinstance(err, Exception):
+ *                 for process in processes:             # <<<<<<<<<<<<<<
+ *                     process.terminate()
+ *                 raise err
+ */
+      __pyx_t_5 = __pyx_v_processes; __Pyx_INCREF(__pyx_t_5); __pyx_t_14 = 0;
+      for (;;) {
+        if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_12 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_14); __Pyx_INCREF(__pyx_t_12); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_12 = PySequence_ITEM(__pyx_t_5, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+        __Pyx_XDECREF_SET(__pyx_v_process, __pyx_t_12);
+        __pyx_t_12 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":433
+ *             if isinstance(err, Exception):
+ *                 for process in processes:
+ *                     process.terminate()             # <<<<<<<<<<<<<<
+ *                 raise err
+ *             elif err is not None: # err is (error code, error line)
+ */
+        __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_terminate); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_8 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+          __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+          if (likely(__pyx_t_8)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+            __Pyx_INCREF(__pyx_t_8);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_7, function);
+          }
+        }
+        if (__pyx_t_8) {
+          __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        } else {
+          __pyx_t_12 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":432
+ *             queue_ret, err, proc = queue.get()
+ *             if isinstance(err, Exception):
+ *                 for process in processes:             # <<<<<<<<<<<<<<
+ *                     process.terminate()
+ *                 raise err
+ */
+      }
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":434
+ *                 for process in processes:
+ *                     process.terminate()
+ *                 raise err             # <<<<<<<<<<<<<<
+ *             elif err is not None: # err is (error code, error line)
+ *                 failed_procs[proc] = err
+ */
+      __Pyx_Raise(__pyx_v_err, 0, 0, 0);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":435
+ *                     process.terminate()
+ *                 raise err
+ *             elif err is not None: # err is (error code, error line)             # <<<<<<<<<<<<<<
+ *                 failed_procs[proc] = err
+ *             comments, data = queue_ret
+ */
+    __pyx_t_10 = (__pyx_v_err != Py_None);
+    __pyx_t_3 = (__pyx_t_10 != 0);
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":436
+ *                 raise err
+ *             elif err is not None: # err is (error code, error line)
+ *                 failed_procs[proc] = err             # <<<<<<<<<<<<<<
+ *             comments, data = queue_ret
+ *             line_comments.extend(comments)
+ */
+      if (unlikely(PyDict_SetItem(__pyx_v_failed_procs, __pyx_v_proc, __pyx_v_err) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L18;
+    }
+    __pyx_L18:;
+
+    /* "astropy/io/ascii/cparser.pyx":437
+ *             elif err is not None: # err is (error code, error line)
+ *                 failed_procs[proc] = err
+ *             comments, data = queue_ret             # <<<<<<<<<<<<<<
+ *             line_comments.extend(comments)
+ *             chunks[proc] = data
+ */
+    if ((likely(PyTuple_CheckExact(__pyx_v_queue_ret))) || (PyList_CheckExact(__pyx_v_queue_ret))) {
+      PyObject* sequence = __pyx_v_queue_ret;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_12 = PyTuple_GET_ITEM(sequence, 1); 
+      } else {
+        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_12 = PyList_GET_ITEM(sequence, 1); 
+      }
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_12);
+      #else
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_12 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      #endif
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_7 = PyObject_GetIter(__pyx_v_queue_ret); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_13 = Py_TYPE(__pyx_t_7)->tp_iternext;
+      index = 0; __pyx_t_5 = __pyx_t_13(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L21_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_5);
+      index = 1; __pyx_t_12 = __pyx_t_13(__pyx_t_7); if (unlikely(!__pyx_t_12)) goto __pyx_L21_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_12);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = NULL;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L22_unpacking_done;
+      __pyx_L21_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_13 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L22_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_comments, __pyx_t_5);
+    __pyx_t_5 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_data, __pyx_t_12);
+    __pyx_t_12 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":438
+ *                 failed_procs[proc] = err
+ *             comments, data = queue_ret
+ *             line_comments.extend(comments)             # <<<<<<<<<<<<<<
+ *             chunks[proc] = data
+ * 
+ */
+    if (unlikely(__pyx_v_line_comments == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "extend");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_11 = __Pyx_PyList_Extend(__pyx_v_line_comments, __pyx_v_comments); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":439
+ *             comments, data = queue_ret
+ *             line_comments.extend(comments)
+ *             chunks[proc] = data             # <<<<<<<<<<<<<<
+ * 
+ *         if failed_procs:
+ */
+    if (unlikely(PyObject_SetItem(__pyx_v_chunks, __pyx_v_proc, __pyx_v_data) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":429
+ *         cdef dict failed_procs = {}
+ * 
+ *         for i in range(N):             # <<<<<<<<<<<<<<
+ *             queue_ret, err, proc = queue.get()
+ *             if isinstance(err, Exception):
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":441
+ *             chunks[proc] = data
+ * 
+ *         if failed_procs:             # <<<<<<<<<<<<<<
+ *             # find the line number of the error
+ *             line_no = 0
+ */
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_failed_procs); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":443
+ *         if failed_procs:
+ *             # find the line number of the error
+ *             line_no = 0             # <<<<<<<<<<<<<<
+ *             for i in range(N):
+ *                 # ignore errors after data_end
+ */
+    __Pyx_INCREF(__pyx_int_0);
+    __pyx_v_line_no = __pyx_int_0;
+
+    /* "astropy/io/ascii/cparser.pyx":444
+ *             # find the line number of the error
+ *             line_no = 0
+ *             for i in range(N):             # <<<<<<<<<<<<<<
+ *                 # ignore errors after data_end
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:
+ */
+    __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+      __pyx_t_12 = __pyx_t_1; __Pyx_INCREF(__pyx_t_12); __pyx_t_2 = 0;
+      __pyx_t_9 = NULL;
+    } else {
+      __pyx_t_2 = -1; __pyx_t_12 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __pyx_t_9 = Py_TYPE(__pyx_t_12)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    for (;;) {
+      if (likely(!__pyx_t_9)) {
+        if (likely(PyList_CheckExact(__pyx_t_12))) {
+          if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_12)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_12)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_1 = __pyx_t_9(__pyx_t_12);
+        if (unlikely(!__pyx_t_1)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_1);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1);
+      __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":446
+ *             for i in range(N):
+ *                 # ignore errors after data_end
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:             # <<<<<<<<<<<<<<
+ *                     for process in processes:
+ *                         process.terminate()
+ */
+      __pyx_t_10 = (__Pyx_PyDict_Contains(__pyx_v_i, __pyx_v_failed_procs, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = (__pyx_t_10 != 0);
+      if (!__pyx_t_15) {
+        goto __pyx_L28_next_or;
+      } else {
+      }
+      __pyx_t_15 = (__pyx_cur_scope->__pyx_v_self->data_end == Py_None);
+      __pyx_t_10 = (__pyx_t_15 != 0);
+      if (!__pyx_t_10) {
+      } else {
+        __pyx_t_3 = __pyx_t_10;
+        goto __pyx_L27_bool_binop_done;
+      }
+      __pyx_L28_next_or:;
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_line_no, __pyx_cur_scope->__pyx_v_self->data_end, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_3 = __pyx_t_10;
+      __pyx_L27_bool_binop_done:;
+      if (__pyx_t_3) {
+
+        /* "astropy/io/ascii/cparser.pyx":447
+ *                 # ignore errors after data_end
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:
+ *                     for process in processes:             # <<<<<<<<<<<<<<
+ *                         process.terminate()
+ *                     raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,
+ */
+        __pyx_t_1 = __pyx_v_processes; __Pyx_INCREF(__pyx_t_1); __pyx_t_14 = 0;
+        for (;;) {
+          if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_1)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_14); __Pyx_INCREF(__pyx_t_5); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+          __Pyx_XDECREF_SET(__pyx_v_process, __pyx_t_5);
+          __pyx_t_5 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":448
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:
+ *                     for process in processes:
+ *                         process.terminate()             # <<<<<<<<<<<<<<
+ *                     raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,
+ *                                          "an error occurred while parsing table data")
+ */
+          __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_terminate); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_7);
+          __pyx_t_8 = NULL;
+          if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+            __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+            if (likely(__pyx_t_8)) {
+              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+              __Pyx_INCREF(__pyx_t_8);
+              __Pyx_INCREF(function);
+              __Pyx_DECREF_SET(__pyx_t_7, function);
+            }
+          }
+          if (__pyx_t_8) {
+            __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          } else {
+            __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          __Pyx_GOTREF(__pyx_t_5);
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":447
+ *                 # ignore errors after data_end
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:
+ *                     for process in processes:             # <<<<<<<<<<<<<<
+ *                         process.terminate()
+ *                     raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,
+ */
+        }
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":449
+ *                     for process in processes:
+ *                         process.terminate()
+ *                     raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,             # <<<<<<<<<<<<<<
+ *                                          "an error occurred while parsing table data")
+ *                 line_no += len(chunks[i][self.names[0]])
+ */
+        __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_failed_procs, __pyx_v_i); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_failed_procs, __pyx_v_i); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyNumber_Add(__pyx_t_7, __pyx_v_line_no); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->get_error(__pyx_cur_scope->__pyx_v_self, __pyx_t_5, __pyx_t_1, __pyx_kp_s_an_error_occurred_while_parsing); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "astropy/io/ascii/cparser.pyx":451
+ *                     raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,
+ *                                          "an error occurred while parsing table data")
+ *                 line_no += len(chunks[i][self.names[0]])             # <<<<<<<<<<<<<<
+ * 
+ *         seen_str = {}
+ */
+      __pyx_t_7 = PyObject_GetItem(__pyx_v_chunks, __pyx_v_i); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_self->names, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyObject_GetItem(__pyx_t_7, __pyx_t_1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_14 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_14); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_line_no, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_DECREF_SET(__pyx_v_line_no, __pyx_t_1);
+      __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":444
+ *             # find the line number of the error
+ *             line_no = 0
+ *             for i in range(N):             # <<<<<<<<<<<<<<
+ *                 # ignore errors after data_end
+ *                 if i in failed_procs and self.data_end is None or line_no < self.data_end:
+ */
+    }
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    goto __pyx_L23;
+  }
+  __pyx_L23:;
+
+  /* "astropy/io/ascii/cparser.pyx":453
+ *                 line_no += len(chunks[i][self.names[0]])
+ * 
+ *         seen_str = {}             # <<<<<<<<<<<<<<
+ *         seen_numeric = {}
+ *         for name in self.names:
+ */
+  __pyx_t_12 = PyDict_New(); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  __pyx_v_seen_str = ((PyObject*)__pyx_t_12);
+  __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":454
+ * 
+ *         seen_str = {}
+ *         seen_numeric = {}             # <<<<<<<<<<<<<<
+ *         for name in self.names:
+ *             seen_str[name] = False
+ */
+  __pyx_t_12 = PyDict_New(); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  __pyx_v_seen_numeric = ((PyObject*)__pyx_t_12);
+  __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":455
+ *         seen_str = {}
+ *         seen_numeric = {}
+ *         for name in self.names:             # <<<<<<<<<<<<<<
+ *             seen_str[name] = False
+ *             seen_numeric[name] = False
+ */
+  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) {
+    __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->names; __Pyx_INCREF(__pyx_t_12); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_12 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_self->names); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    __pyx_t_9 = Py_TYPE(__pyx_t_12)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_12))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_12)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_12)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_1 = __pyx_t_9(__pyx_t_12);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":456
+ *         seen_numeric = {}
+ *         for name in self.names:
+ *             seen_str[name] = False             # <<<<<<<<<<<<<<
+ *             seen_numeric[name] = False
+ * 
+ */
+    if (unlikely(PyDict_SetItem(__pyx_v_seen_str, __pyx_v_name, Py_False) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":457
+ *         for name in self.names:
+ *             seen_str[name] = False
+ *             seen_numeric[name] = False             # <<<<<<<<<<<<<<
+ * 
+ *         for chunk in chunks:
+ */
+    if (unlikely(PyDict_SetItem(__pyx_v_seen_numeric, __pyx_v_name, Py_False) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":455
+ *         seen_str = {}
+ *         seen_numeric = {}
+ *         for name in self.names:             # <<<<<<<<<<<<<<
+ *             seen_str[name] = False
+ *             seen_numeric[name] = False
+ */
+  }
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":459
+ *             seen_numeric[name] = False
+ * 
+ *         for chunk in chunks:             # <<<<<<<<<<<<<<
+ *             for name in chunk:
+ *                 if chunk[name].dtype.kind in ('S', 'U'):
+ */
+  __pyx_t_12 = __pyx_v_chunks; __Pyx_INCREF(__pyx_t_12); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_12)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_chunk, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":460
+ * 
+ *         for chunk in chunks:
+ *             for name in chunk:             # <<<<<<<<<<<<<<
+ *                 if chunk[name].dtype.kind in ('S', 'U'):
+ *                     # string values in column
+ */
+    if (likely(PyList_CheckExact(__pyx_v_chunk)) || PyTuple_CheckExact(__pyx_v_chunk)) {
+      __pyx_t_1 = __pyx_v_chunk; __Pyx_INCREF(__pyx_t_1); __pyx_t_14 = 0;
+      __pyx_t_9 = NULL;
+    } else {
+      __pyx_t_14 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_chunk); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_9)) {
+        if (likely(PyList_CheckExact(__pyx_t_1))) {
+          if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_1)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_14); __Pyx_INCREF(__pyx_t_5); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_14); __Pyx_INCREF(__pyx_t_5); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_5 = __pyx_t_9(__pyx_t_1);
+        if (unlikely(!__pyx_t_5)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_5);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_5);
+      __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":461
+ *         for chunk in chunks:
+ *             for name in chunk:
+ *                 if chunk[name].dtype.kind in ('S', 'U'):             # <<<<<<<<<<<<<<
+ *                     # string values in column
+ *                     seen_str[name] = True
+ */
+      __pyx_t_5 = PyObject_GetItem(__pyx_v_chunk, __pyx_v_name); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_kind); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_10 = (__Pyx_PyString_Equals(__pyx_t_5, __pyx_n_s_S, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!__pyx_t_10) {
+      } else {
+        __pyx_t_3 = __pyx_t_10;
+        goto __pyx_L39_bool_binop_done;
+      }
+      __pyx_t_10 = (__Pyx_PyString_Equals(__pyx_t_5, __pyx_n_s_U, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __pyx_t_10;
+      __pyx_L39_bool_binop_done:;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_10 = (__pyx_t_3 != 0);
+      if (__pyx_t_10) {
+
+        /* "astropy/io/ascii/cparser.pyx":463
+ *                 if chunk[name].dtype.kind in ('S', 'U'):
+ *                     # string values in column
+ *                     seen_str[name] = True             # <<<<<<<<<<<<<<
+ *                 elif len(chunk[name]) > 0: # ignore empty chunk columns
+ *                     seen_numeric[name] = True
+ */
+        if (unlikely(PyDict_SetItem(__pyx_v_seen_str, __pyx_v_name, Py_True) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L38;
+      }
+
+      /* "astropy/io/ascii/cparser.pyx":464
+ *                     # string values in column
+ *                     seen_str[name] = True
+ *                 elif len(chunk[name]) > 0: # ignore empty chunk columns             # <<<<<<<<<<<<<<
+ *                     seen_numeric[name] = True
+ * 
+ */
+      __pyx_t_5 = PyObject_GetItem(__pyx_v_chunk, __pyx_v_name); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_16 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_10 = ((__pyx_t_16 > 0) != 0);
+      if (__pyx_t_10) {
+
+        /* "astropy/io/ascii/cparser.pyx":465
+ *                     seen_str[name] = True
+ *                 elif len(chunk[name]) > 0: # ignore empty chunk columns
+ *                     seen_numeric[name] = True             # <<<<<<<<<<<<<<
+ * 
+ *         reconvert_cols = []
+ */
+        if (unlikely(PyDict_SetItem(__pyx_v_seen_numeric, __pyx_v_name, Py_True) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L38;
+      }
+      __pyx_L38:;
+
+      /* "astropy/io/ascii/cparser.pyx":460
+ * 
+ *         for chunk in chunks:
+ *             for name in chunk:             # <<<<<<<<<<<<<<
+ *                 if chunk[name].dtype.kind in ('S', 'U'):
+ *                     # string values in column
+ */
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":459
+ *             seen_numeric[name] = False
+ * 
+ *         for chunk in chunks:             # <<<<<<<<<<<<<<
+ *             for name in chunk:
+ *                 if chunk[name].dtype.kind in ('S', 'U'):
+ */
+  }
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":467
+ *                     seen_numeric[name] = True
+ * 
+ *         reconvert_cols = []             # <<<<<<<<<<<<<<
+ * 
+ *         for i, name in enumerate(self.names):
+ */
+  __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  __pyx_v_reconvert_cols = ((PyObject*)__pyx_t_12);
+  __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":469
+ *         reconvert_cols = []
+ * 
+ *         for i, name in enumerate(self.names):             # <<<<<<<<<<<<<<
+ *             if seen_str[name] and seen_numeric[name]:
+ *                 # Reconvert to str to avoid conversion issues, e.g.
+ */
+  __Pyx_INCREF(__pyx_int_0);
+  __pyx_t_12 = __pyx_int_0;
+  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) {
+    __pyx_t_1 = __pyx_cur_scope->__pyx_v_self->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_self->names); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_9(__pyx_t_1);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_5);
+    __pyx_t_5 = 0;
+    __Pyx_INCREF(__pyx_t_12);
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_12);
+    __pyx_t_5 = PyNumber_Add(__pyx_t_12, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_12);
+    __pyx_t_12 = __pyx_t_5;
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":470
+ * 
+ *         for i, name in enumerate(self.names):
+ *             if seen_str[name] and seen_numeric[name]:             # <<<<<<<<<<<<<<
+ *                 # Reconvert to str to avoid conversion issues, e.g.
+ *                 # 5 (int) -> 5.0 (float) -> 5.0 (string)
+ */
+    __pyx_t_5 = __Pyx_PyDict_GetItem(__pyx_v_seen_str, __pyx_v_name); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_3) {
+    } else {
+      __pyx_t_10 = __pyx_t_3;
+      goto __pyx_L44_bool_binop_done;
+    }
+    __pyx_t_5 = __Pyx_PyDict_GetItem(__pyx_v_seen_numeric, __pyx_v_name); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_10 = __pyx_t_3;
+    __pyx_L44_bool_binop_done:;
+    if (__pyx_t_10) {
+
+      /* "astropy/io/ascii/cparser.pyx":473
+ *                 # Reconvert to str to avoid conversion issues, e.g.
+ *                 # 5 (int) -> 5.0 (float) -> 5.0 (string)
+ *                 reconvert_cols.append(i)             # <<<<<<<<<<<<<<
+ * 
+ *         reconvert_queue.put(reconvert_cols)
+ */
+      __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_reconvert_cols, __pyx_v_i); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L43;
+    }
+    __pyx_L43:;
+
+    /* "astropy/io/ascii/cparser.pyx":469
+ *         reconvert_cols = []
+ * 
+ *         for i, name in enumerate(self.names):             # <<<<<<<<<<<<<<
+ *             if seen_str[name] and seen_numeric[name]:
+ *                 # Reconvert to str to avoid conversion issues, e.g.
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":475
+ *                 reconvert_cols.append(i)
+ * 
+ *         reconvert_queue.put(reconvert_cols)             # <<<<<<<<<<<<<<
+ *         for process in processes:
+ *             process.join() # wait for each process to finish
+ */
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_reconvert_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_1, function);
+    }
+  }
+  if (!__pyx_t_5) {
+    __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_reconvert_cols); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+  } else {
+    __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+    __Pyx_INCREF(__pyx_v_reconvert_cols);
+    PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_reconvert_cols);
+    __Pyx_GIVEREF(__pyx_v_reconvert_cols);
+    __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":476
+ * 
+ *         reconvert_queue.put(reconvert_cols)
+ *         for process in processes:             # <<<<<<<<<<<<<<
+ *             process.join() # wait for each process to finish
+ *         try:
+ */
+  __pyx_t_12 = __pyx_v_processes; __Pyx_INCREF(__pyx_t_12); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_12)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_12, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_1 = PySequence_ITEM(__pyx_t_12, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_process, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":477
+ *         reconvert_queue.put(reconvert_cols)
+ *         for process in processes:
+ *             process.join() # wait for each process to finish             # <<<<<<<<<<<<<<
+ *         try:
+ *             while True:
+ */
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_join); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_5 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_7);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_7, function);
+      }
+    }
+    if (__pyx_t_5) {
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":476
+ * 
+ *         reconvert_queue.put(reconvert_cols)
+ *         for process in processes:             # <<<<<<<<<<<<<<
+ *             process.join() # wait for each process to finish
+ *         try:
+ */
+  }
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":478
+ *         for process in processes:
+ *             process.join() # wait for each process to finish
+ *         try:             # <<<<<<<<<<<<<<
+ *             while True:
+ *                 reconverted, proc, col = queue.get(False)
+ */
+  {
+    __Pyx_ExceptionSave(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19);
+    __Pyx_XGOTREF(__pyx_t_17);
+    __Pyx_XGOTREF(__pyx_t_18);
+    __Pyx_XGOTREF(__pyx_t_19);
+    /*try:*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":479
+ *             process.join() # wait for each process to finish
+ *         try:
+ *             while True:             # <<<<<<<<<<<<<<
+ *                 reconverted, proc, col = queue.get(False)
+ *                 chunks[proc][self.names[col]] = reconverted
+ */
+      while (1) {
+
+        /* "astropy/io/ascii/cparser.pyx":480
+ *         try:
+ *             while True:
+ *                 reconverted, proc, col = queue.get(False)             # <<<<<<<<<<<<<<
+ *                 chunks[proc][self.names[col]] = reconverted
+ *         except Queue.Empty:
+ */
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_get); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+          PyObject* sequence = __pyx_t_1;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          Py_ssize_t size = Py_SIZE(sequence);
+          #else
+          Py_ssize_t size = PySequence_Size(sequence);
+          #endif
+          if (unlikely(size != 3)) {
+            if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+            else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          }
+          #if CYTHON_COMPILING_IN_CPYTHON
+          if (likely(PyTuple_CheckExact(sequence))) {
+            __pyx_t_12 = PyTuple_GET_ITEM(sequence, 0); 
+            __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+            __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); 
+          } else {
+            __pyx_t_12 = PyList_GET_ITEM(sequence, 0); 
+            __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+            __pyx_t_5 = PyList_GET_ITEM(sequence, 2); 
+          }
+          __Pyx_INCREF(__pyx_t_12);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_5);
+          #else
+          __pyx_t_12 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __Pyx_GOTREF(__pyx_t_7);
+          __pyx_t_5 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __Pyx_GOTREF(__pyx_t_5);
+          #endif
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        } else {
+          Py_ssize_t index = -1;
+          __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __pyx_t_13 = Py_TYPE(__pyx_t_8)->tp_iternext;
+          index = 0; __pyx_t_12 = __pyx_t_13(__pyx_t_8); if (unlikely(!__pyx_t_12)) goto __pyx_L58_unpacking_failed;
+          __Pyx_GOTREF(__pyx_t_12);
+          index = 1; __pyx_t_7 = __pyx_t_13(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L58_unpacking_failed;
+          __Pyx_GOTREF(__pyx_t_7);
+          index = 2; __pyx_t_5 = __pyx_t_13(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L58_unpacking_failed;
+          __Pyx_GOTREF(__pyx_t_5);
+          if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_8), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __pyx_t_13 = NULL;
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          goto __pyx_L59_unpacking_done;
+          __pyx_L58_unpacking_failed:;
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __pyx_t_13 = NULL;
+          if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+          __pyx_L59_unpacking_done:;
+        }
+        __Pyx_XDECREF_SET(__pyx_v_reconverted, __pyx_t_12);
+        __pyx_t_12 = 0;
+        __Pyx_XDECREF_SET(__pyx_v_proc, __pyx_t_7);
+        __pyx_t_7 = 0;
+        __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_5);
+        __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":481
+ *             while True:
+ *                 reconverted, proc, col = queue.get(False)
+ *                 chunks[proc][self.names[col]] = reconverted             # <<<<<<<<<<<<<<
+ *         except Queue.Empty:
+ *             pass
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_chunks, __pyx_v_proc); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L48_error;};
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_5 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->names, __pyx_v_col); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L48_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_t_5, __pyx_v_reconverted) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L48_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+    }
+    __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
+    __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
+    __Pyx_XDECREF(__pyx_t_19); __pyx_t_19 = 0;
+    goto __pyx_L55_try_end;
+    __pyx_L48_error:;
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":482
+ *                 reconverted, proc, col = queue.get(False)
+ *                 chunks[proc][self.names[col]] = reconverted
+ *         except Queue.Empty:             # <<<<<<<<<<<<<<
+ *             pass
+ * 
+ */
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_Queue); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L50_except_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_Empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L50_except_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_4 = PyErr_ExceptionMatches(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_4) {
+      PyErr_Restore(0,0,0);
+      goto __pyx_L49_exception_handled;
+    }
+    goto __pyx_L50_except_error;
+    __pyx_L50_except_error:;
+    __Pyx_XGIVEREF(__pyx_t_17);
+    __Pyx_XGIVEREF(__pyx_t_18);
+    __Pyx_XGIVEREF(__pyx_t_19);
+    __Pyx_ExceptionReset(__pyx_t_17, __pyx_t_18, __pyx_t_19);
+    goto __pyx_L1_error;
+    __pyx_L49_exception_handled:;
+    __Pyx_XGIVEREF(__pyx_t_17);
+    __Pyx_XGIVEREF(__pyx_t_18);
+    __Pyx_XGIVEREF(__pyx_t_19);
+    __Pyx_ExceptionReset(__pyx_t_17, __pyx_t_18, __pyx_t_19);
+    __pyx_L55_try_end:;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":485
+ *             pass
+ * 
+ *         if self.data_end is not None:             # <<<<<<<<<<<<<<
+ *             if self.data_end < 0:
+ *                 # e.g. if data_end = -1, cut the last row
+ */
+  __pyx_t_10 = (__pyx_cur_scope->__pyx_v_self->data_end != Py_None);
+  __pyx_t_3 = (__pyx_t_10 != 0);
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":486
+ * 
+ *         if self.data_end is not None:
+ *             if self.data_end < 0:             # <<<<<<<<<<<<<<
+ *                 # e.g. if data_end = -1, cut the last row
+ *                 num_rows = 0
+ */
+    __pyx_t_1 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_self->data_end, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":488
+ *             if self.data_end < 0:
+ *                 # e.g. if data_end = -1, cut the last row
+ *                 num_rows = 0             # <<<<<<<<<<<<<<
+ *                 for chunk in chunks:
+ *                     num_rows += len(chunk[self.names[0]])
+ */
+      __Pyx_INCREF(__pyx_int_0);
+      __pyx_v_num_rows = __pyx_int_0;
+
+      /* "astropy/io/ascii/cparser.pyx":489
+ *                 # e.g. if data_end = -1, cut the last row
+ *                 num_rows = 0
+ *                 for chunk in chunks:             # <<<<<<<<<<<<<<
+ *                     num_rows += len(chunk[self.names[0]])
+ *                 self.data_end += num_rows
+ */
+      __pyx_t_1 = __pyx_v_chunks; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+      for (;;) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+        __Pyx_XDECREF_SET(__pyx_v_chunk, __pyx_t_5);
+        __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":490
+ *                 num_rows = 0
+ *                 for chunk in chunks:
+ *                     num_rows += len(chunk[self.names[0]])             # <<<<<<<<<<<<<<
+ *                 self.data_end += num_rows
+ *             else:
+ */
+        __pyx_t_5 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_self->names, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_chunk, __pyx_t_5); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_14 = PyObject_Length(__pyx_t_7); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = PyInt_FromSsize_t(__pyx_t_14); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_num_rows, __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF_SET(__pyx_v_num_rows, __pyx_t_5);
+        __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":489
+ *                 # e.g. if data_end = -1, cut the last row
+ *                 num_rows = 0
+ *                 for chunk in chunks:             # <<<<<<<<<<<<<<
+ *                     num_rows += len(chunk[self.names[0]])
+ *                 self.data_end += num_rows
+ */
+      }
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":491
+ *                 for chunk in chunks:
+ *                     num_rows += len(chunk[self.names[0]])
+ *                 self.data_end += num_rows             # <<<<<<<<<<<<<<
+ *             else:
+ *                 self.data_end -= self.data_start # ignore header
+ */
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_self->data_end, __pyx_v_num_rows); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_self->data_end);
+      __Pyx_DECREF(__pyx_cur_scope->__pyx_v_self->data_end);
+      __pyx_cur_scope->__pyx_v_self->data_end = __pyx_t_1;
+      __pyx_t_1 = 0;
+      goto __pyx_L61;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":493
+ *                 self.data_end += num_rows
+ *             else:
+ *                 self.data_end -= self.data_start # ignore header             # <<<<<<<<<<<<<<
+ * 
+ *             if self.data_end < 0: # no data
+ */
+      __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_cur_scope->__pyx_v_self->data_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyNumber_InPlaceSubtract(__pyx_cur_scope->__pyx_v_self->data_end, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_GIVEREF(__pyx_t_5);
+      __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_self->data_end);
+      __Pyx_DECREF(__pyx_cur_scope->__pyx_v_self->data_end);
+      __pyx_cur_scope->__pyx_v_self->data_end = __pyx_t_5;
+      __pyx_t_5 = 0;
+    }
+    __pyx_L61:;
+
+    /* "astropy/io/ascii/cparser.pyx":495
+ *                 self.data_end -= self.data_start # ignore header
+ * 
+ *             if self.data_end < 0: # no data             # <<<<<<<<<<<<<<
+ *                 chunks = [dict((name, []) for name in self.names)]
+ *             else:
+ */
+    __pyx_t_5 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_self->data_end, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":496
+ * 
+ *             if self.data_end < 0: # no data
+ *                 chunks = [dict((name, []) for name in self.names)]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 line_no = 0
+ */
+      __pyx_t_5 = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_3genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_5 = 0;
+      __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_1, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_5 = 0;
+      __Pyx_DECREF_SET(__pyx_v_chunks, ((PyObject*)__pyx_t_1));
+      __pyx_t_1 = 0;
+      goto __pyx_L64;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":498
+ *                 chunks = [dict((name, []) for name in self.names)]
+ *             else:
+ *                 line_no = 0             # <<<<<<<<<<<<<<
+ *                 for i, chunk in enumerate(chunks):
+ *                     num_rows = len(chunk[self.names[0]])
+ */
+      __Pyx_INCREF(__pyx_int_0);
+      __Pyx_XDECREF_SET(__pyx_v_line_no, __pyx_int_0);
+
+      /* "astropy/io/ascii/cparser.pyx":499
+ *             else:
+ *                 line_no = 0
+ *                 for i, chunk in enumerate(chunks):             # <<<<<<<<<<<<<<
+ *                     num_rows = len(chunk[self.names[0]])
+ *                     if line_no + num_rows > self.data_end:
+ */
+      __Pyx_INCREF(__pyx_int_0);
+      __pyx_t_1 = __pyx_int_0;
+      __pyx_t_5 = __pyx_v_chunks; __Pyx_INCREF(__pyx_t_5); __pyx_t_2 = 0;
+      for (;;) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+        __Pyx_XDECREF_SET(__pyx_v_chunk, __pyx_t_7);
+        __pyx_t_7 = 0;
+        __Pyx_INCREF(__pyx_t_1);
+        __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1);
+        __pyx_t_7 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1);
+        __pyx_t_1 = __pyx_t_7;
+        __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":500
+ *                 line_no = 0
+ *                 for i, chunk in enumerate(chunks):
+ *                     num_rows = len(chunk[self.names[0]])             # <<<<<<<<<<<<<<
+ *                     if line_no + num_rows > self.data_end:
+ *                         for name in self.names:
+ */
+        __pyx_t_7 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_self->names, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_12 = PyObject_GetItem(__pyx_v_chunk, __pyx_t_7); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_14 = PyObject_Length(__pyx_t_12); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_t_12 = PyInt_FromSsize_t(__pyx_t_14); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_XDECREF_SET(__pyx_v_num_rows, __pyx_t_12);
+        __pyx_t_12 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":501
+ *                 for i, chunk in enumerate(chunks):
+ *                     num_rows = len(chunk[self.names[0]])
+ *                     if line_no + num_rows > self.data_end:             # <<<<<<<<<<<<<<
+ *                         for name in self.names:
+ *                             # truncate columns
+ */
+        __pyx_t_12 = PyNumber_Add(__pyx_v_line_no, __pyx_v_num_rows); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_7 = PyObject_RichCompare(__pyx_t_12, __pyx_cur_scope->__pyx_v_self->data_end, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        if (__pyx_t_3) {
+
+          /* "astropy/io/ascii/cparser.pyx":502
+ *                     num_rows = len(chunk[self.names[0]])
+ *                     if line_no + num_rows > self.data_end:
+ *                         for name in self.names:             # <<<<<<<<<<<<<<
+ *                             # truncate columns
+ *                             chunk[name] = chunk[name][:self.data_end - line_no]
+ */
+          if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_self->names)) {
+            __pyx_t_7 = __pyx_cur_scope->__pyx_v_self->names; __Pyx_INCREF(__pyx_t_7); __pyx_t_14 = 0;
+            __pyx_t_9 = NULL;
+          } else {
+            __pyx_t_14 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_self->names); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_7);
+            __pyx_t_9 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          for (;;) {
+            if (likely(!__pyx_t_9)) {
+              if (likely(PyList_CheckExact(__pyx_t_7))) {
+                if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_7)) break;
+                #if CYTHON_COMPILING_IN_CPYTHON
+                __pyx_t_12 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_14); __Pyx_INCREF(__pyx_t_12); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                #else
+                __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                #endif
+              } else {
+                if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
+                #if CYTHON_COMPILING_IN_CPYTHON
+                __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_14); __Pyx_INCREF(__pyx_t_12); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                #else
+                __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                #endif
+              }
+            } else {
+              __pyx_t_12 = __pyx_t_9(__pyx_t_7);
+              if (unlikely(!__pyx_t_12)) {
+                PyObject* exc_type = PyErr_Occurred();
+                if (exc_type) {
+                  if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+                  else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                }
+                break;
+              }
+              __Pyx_GOTREF(__pyx_t_12);
+            }
+            __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_12);
+            __pyx_t_12 = 0;
+
+            /* "astropy/io/ascii/cparser.pyx":504
+ *                         for name in self.names:
+ *                             # truncate columns
+ *                             chunk[name] = chunk[name][:self.data_end - line_no]             # <<<<<<<<<<<<<<
+ *                         del chunks[i + 1:]
+ *                         break
+ */
+            __pyx_t_12 = PyObject_GetItem(__pyx_v_chunk, __pyx_v_name); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+            __Pyx_GOTREF(__pyx_t_12);
+            __pyx_t_8 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_self->data_end, __pyx_v_line_no); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_8);
+            __pyx_t_6 = __Pyx_PyObject_GetSlice(__pyx_t_12, 0, 0, NULL, &__pyx_t_8, NULL, 0, 0, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_6);
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+            if (unlikely(PyObject_SetItem(__pyx_v_chunk, __pyx_v_name, __pyx_t_6) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+            /* "astropy/io/ascii/cparser.pyx":502
+ *                     num_rows = len(chunk[self.names[0]])
+ *                     if line_no + num_rows > self.data_end:
+ *                         for name in self.names:             # <<<<<<<<<<<<<<
+ *                             # truncate columns
+ *                             chunk[name] = chunk[name][:self.data_end - line_no]
+ */
+          }
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":505
+ *                             # truncate columns
+ *                             chunk[name] = chunk[name][:self.data_end - line_no]
+ *                         del chunks[i + 1:]             # <<<<<<<<<<<<<<
+ *                         break
+ *                     line_no += num_rows
+ */
+          __pyx_t_7 = PyNumber_Add(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_7);
+          __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+          if (__Pyx_PyObject_DelSlice(__pyx_v_chunks, __pyx_t_14, 0, NULL, NULL, NULL, 1, 0, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+          /* "astropy/io/ascii/cparser.pyx":506
+ *                             chunk[name] = chunk[name][:self.data_end - line_no]
+ *                         del chunks[i + 1:]
+ *                         break             # <<<<<<<<<<<<<<
+ *                     line_no += num_rows
+ * 
+ */
+          goto __pyx_L66_break;
+        }
+
+        /* "astropy/io/ascii/cparser.pyx":507
+ *                         del chunks[i + 1:]
+ *                         break
+ *                     line_no += num_rows             # <<<<<<<<<<<<<<
+ * 
+ *         ret = {}
+ */
+        __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_v_line_no, __pyx_v_num_rows); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF_SET(__pyx_v_line_no, __pyx_t_7);
+        __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":499
+ *             else:
+ *                 line_no = 0
+ *                 for i, chunk in enumerate(chunks):             # <<<<<<<<<<<<<<
+ *                     num_rows = len(chunk[self.names[0]])
+ *                     if line_no + num_rows > self.data_end:
+ */
+      }
+      __pyx_L66_break:;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    }
+    __pyx_L64:;
+    goto __pyx_L60;
+  }
+  __pyx_L60:;
+
+  /* "astropy/io/ascii/cparser.pyx":509
+ *                     line_no += num_rows
+ * 
+ *         ret = {}             # <<<<<<<<<<<<<<
+ *         for name in self.get_names():
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_ret = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":510
+ * 
+ *         ret = {}
+ *         for name in self.get_names():             # <<<<<<<<<<<<<<
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):
+ */
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s_get_names); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_7 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+    if (likely(__pyx_t_7)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_5, function);
+    }
+  }
+  if (__pyx_t_7) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+    __pyx_t_5 = __pyx_t_1; __Pyx_INCREF(__pyx_t_5); __pyx_t_2 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_9 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_5))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_1 = __pyx_t_9(__pyx_t_5);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":511
+ *         ret = {}
+ *         for name in self.get_names():
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]             # <<<<<<<<<<<<<<
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):
+ *                 ret[name] = ma.concatenate(col_chunks)
+ */
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_7 = __pyx_v_chunks; __Pyx_INCREF(__pyx_t_7); __pyx_t_14 = 0;
+    for (;;) {
+      if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_7)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_6 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_14); __Pyx_INCREF(__pyx_t_6); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_6 = PySequence_ITEM(__pyx_t_7, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+      __Pyx_XDECREF_SET(__pyx_v_chunk, __pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_chunk, __pyx_n_s_pop); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_12 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+        __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_8);
+        if (likely(__pyx_t_12)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+          __Pyx_INCREF(__pyx_t_12);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_8, function);
+        }
+      }
+      if (!__pyx_t_12) {
+        __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_name); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+      } else {
+        __pyx_t_20 = PyTuple_New(1+1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_20);
+        PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_12); __pyx_t_12 = NULL;
+        __Pyx_INCREF(__pyx_v_name);
+        PyTuple_SET_ITEM(__pyx_t_20, 0+1, __pyx_v_name);
+        __Pyx_GIVEREF(__pyx_v_name);
+        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_20, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_col_chunks);
+    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_col_chunks, ((PyObject*)__pyx_t_1));
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":512
+ *         for name in self.get_names():
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):             # <<<<<<<<<<<<<<
+ *                 ret[name] = ma.concatenate(col_chunks)
+ *             else:
+ */
+    __pyx_t_1 = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14_read_parallel_6genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_any, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":513
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):
+ *                 ret[name] = ma.concatenate(col_chunks)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 ret[name] = np.concatenate(col_chunks)
+ */
+      __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_ma); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_concatenate); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_7 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+        }
+      }
+      if (!__pyx_t_7) {
+        __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_cur_scope->__pyx_v_col_chunks); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+      } else {
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+        __Pyx_INCREF(__pyx_cur_scope->__pyx_v_col_chunks);
+        PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_cur_scope->__pyx_v_col_chunks);
+        __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_col_chunks);
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      if (unlikely(PyDict_SetItem(__pyx_v_ret, __pyx_v_name, __pyx_t_1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L74;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":515
+ *                 ret[name] = ma.concatenate(col_chunks)
+ *             else:
+ *                 ret[name] = np.concatenate(col_chunks)             # <<<<<<<<<<<<<<
+ * 
+ *         for process in processes:
+ */
+      __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_concatenate); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_6 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+        __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_8);
+        if (likely(__pyx_t_6)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+          __Pyx_INCREF(__pyx_t_6);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_8, function);
+        }
+      }
+      if (!__pyx_t_6) {
+        __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_cur_scope->__pyx_v_col_chunks); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+      } else {
+        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+        __Pyx_INCREF(__pyx_cur_scope->__pyx_v_col_chunks);
+        PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_cur_scope->__pyx_v_col_chunks);
+        __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_col_chunks);
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      if (unlikely(PyDict_SetItem(__pyx_v_ret, __pyx_v_name, __pyx_t_1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    }
+    __pyx_L74:;
+
+    /* "astropy/io/ascii/cparser.pyx":510
+ * 
+ *         ret = {}
+ *         for name in self.get_names():             # <<<<<<<<<<<<<<
+ *             col_chunks = [chunk.pop(name) for chunk in chunks]
+ *             if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):
+ */
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":517
+ *                 ret[name] = np.concatenate(col_chunks)
+ * 
+ *         for process in processes:             # <<<<<<<<<<<<<<
+ *             process.terminate()
+ * 
+ */
+  __pyx_t_5 = __pyx_v_processes; __Pyx_INCREF(__pyx_t_5); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_5)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_process, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":518
+ * 
+ *         for process in processes:
+ *             process.terminate()             # <<<<<<<<<<<<<<
+ * 
+ *         return ret, line_comments
+ */
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_terminate); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_8, function);
+      }
+    }
+    if (__pyx_t_7) {
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    } else {
+      __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":517
+ *                 ret[name] = np.concatenate(col_chunks)
+ * 
+ *         for process in processes:             # <<<<<<<<<<<<<<
+ *             process.terminate()
+ * 
+ */
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":520
+ *             process.terminate()
+ * 
+ *         return ret, line_comments             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _set_fill_values(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_ret);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_ret);
+  __Pyx_GIVEREF(__pyx_v_ret);
+  __Pyx_INCREF(__pyx_v_line_comments);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_line_comments);
+  __Pyx_GIVEREF(__pyx_v_line_comments);
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":382
+ *                                   try_string, num_rows)
+ * 
+ *     def _read_parallel(self, try_int, try_float, try_string):             # <<<<<<<<<<<<<<
+ *         cdef int source_len = len(self.source)
+ *         self.tokenizer.source_pos = 0
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_20);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._read_parallel", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_line_comments);
+  __Pyx_XDECREF(__pyx_v_queue);
+  __Pyx_XDECREF(__pyx_v_chunkindices);
+  __Pyx_XDECREF(__pyx_v_reconvert_queue);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_index);
+  __Pyx_XDECREF(__pyx_v_processes);
+  __Pyx_XDECREF(__pyx_v_process);
+  __Pyx_XDECREF(__pyx_v_chunks);
+  __Pyx_XDECREF(__pyx_v_failed_procs);
+  __Pyx_XDECREF(__pyx_v_queue_ret);
+  __Pyx_XDECREF(__pyx_v_err);
+  __Pyx_XDECREF(__pyx_v_proc);
+  __Pyx_XDECREF(__pyx_v_comments);
+  __Pyx_XDECREF(__pyx_v_data);
+  __Pyx_XDECREF(__pyx_v_line_no);
+  __Pyx_XDECREF(__pyx_v_seen_str);
+  __Pyx_XDECREF(__pyx_v_seen_numeric);
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XDECREF(__pyx_v_chunk);
+  __Pyx_XDECREF(__pyx_v_reconvert_cols);
+  __Pyx_XDECREF(__pyx_v_reconverted);
+  __Pyx_XDECREF(__pyx_v_col);
+  __Pyx_XDECREF(__pyx_v_num_rows);
+  __Pyx_XDECREF(__pyx_v_ret);
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":522
+ *         return ret, line_comments
+ * 
+ *     cdef _set_fill_values(self):             # <<<<<<<<<<<<<<
+ *         if self.fill_names is None:
+ *             self.fill_names = set(self.names)
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__set_fill_values(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *(*__pyx_t_7)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_set_fill_values", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":523
+ * 
+ *     cdef _set_fill_values(self):
+ *         if self.fill_names is None:             # <<<<<<<<<<<<<<
+ *             self.fill_names = set(self.names)
+ *             if self.fill_include_names is not None:
+ */
+  __pyx_t_1 = (__pyx_v_self->fill_names == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":524
+ *     cdef _set_fill_values(self):
+ *         if self.fill_names is None:
+ *             self.fill_names = set(self.names)             # <<<<<<<<<<<<<<
+ *             if self.fill_include_names is not None:
+ *                 self.fill_names.intersection_update(self.fill_include_names)
+ */
+    __pyx_t_3 = PySet_New(__pyx_v_self->names); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_GOTREF(__pyx_v_self->fill_names);
+    __Pyx_DECREF(__pyx_v_self->fill_names);
+    __pyx_v_self->fill_names = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":525
+ *         if self.fill_names is None:
+ *             self.fill_names = set(self.names)
+ *             if self.fill_include_names is not None:             # <<<<<<<<<<<<<<
+ *                 self.fill_names.intersection_update(self.fill_include_names)
+ *             if self.fill_exclude_names is not None:
+ */
+    __pyx_t_2 = (__pyx_v_self->fill_include_names != Py_None);
+    __pyx_t_1 = (__pyx_t_2 != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":526
+ *             self.fill_names = set(self.names)
+ *             if self.fill_include_names is not None:
+ *                 self.fill_names.intersection_update(self.fill_include_names)             # <<<<<<<<<<<<<<
+ *             if self.fill_exclude_names is not None:
+ *                 self.fill_names.difference_update(self.fill_exclude_names)
+ */
+      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->fill_names, __pyx_n_s_intersection_update); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+        __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+        if (likely(__pyx_t_5)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+          __Pyx_INCREF(__pyx_t_5);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_4, function);
+        }
+      }
+      if (!__pyx_t_5) {
+        __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->fill_include_names); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+      } else {
+        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+        __Pyx_INCREF(__pyx_v_self->fill_include_names);
+        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_self->fill_include_names);
+        __Pyx_GIVEREF(__pyx_v_self->fill_include_names);
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L4;
+    }
+    __pyx_L4:;
+
+    /* "astropy/io/ascii/cparser.pyx":527
+ *             if self.fill_include_names is not None:
+ *                 self.fill_names.intersection_update(self.fill_include_names)
+ *             if self.fill_exclude_names is not None:             # <<<<<<<<<<<<<<
+ *                 self.fill_names.difference_update(self.fill_exclude_names)
+ *         self.fill_values, self.fill_empty = get_fill_values(self.fill_values)
+ */
+    __pyx_t_1 = (__pyx_v_self->fill_exclude_names != Py_None);
+    __pyx_t_2 = (__pyx_t_1 != 0);
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":528
+ *                 self.fill_names.intersection_update(self.fill_include_names)
+ *             if self.fill_exclude_names is not None:
+ *                 self.fill_names.difference_update(self.fill_exclude_names)             # <<<<<<<<<<<<<<
+ *         self.fill_values, self.fill_empty = get_fill_values(self.fill_values)
+ * 
+ */
+      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->fill_names, __pyx_n_s_difference_update); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_6 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+        __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+        if (likely(__pyx_t_6)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+          __Pyx_INCREF(__pyx_t_6);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_4, function);
+        }
+      }
+      if (!__pyx_t_6) {
+        __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->fill_exclude_names); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+      } else {
+        __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+        __Pyx_INCREF(__pyx_v_self->fill_exclude_names);
+        PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_self->fill_exclude_names);
+        __Pyx_GIVEREF(__pyx_v_self->fill_exclude_names);
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":529
+ *             if self.fill_exclude_names is not None:
+ *                 self.fill_names.difference_update(self.fill_exclude_names)
+ *         self.fill_values, self.fill_empty = get_fill_values(self.fill_values)             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _get_comments(self, tokenizer_t *t):
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_get_fill_values); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_4, function);
+    }
+  }
+  if (!__pyx_t_5) {
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->fill_values); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+  } else {
+    __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+    __Pyx_INCREF(__pyx_v_self->fill_values);
+    PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_self->fill_values);
+    __Pyx_GIVEREF(__pyx_v_self->fill_values);
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
+    PyObject* sequence = __pyx_t_3;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_4 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_t_6);
+    #else
+    __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    #endif
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_7 = Py_TYPE(__pyx_t_5)->tp_iternext;
+    index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_4);
+    index = 1; __pyx_t_6 = __pyx_t_7(__pyx_t_5); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_6);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = NULL;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L7_unpacking_done;
+    __pyx_L6_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_7 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L7_unpacking_done:;
+  }
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_GOTREF(__pyx_v_self->fill_values);
+  __Pyx_DECREF(__pyx_v_self->fill_values);
+  __pyx_v_self->fill_values = __pyx_t_4;
+  __pyx_t_4 = 0;
+  __Pyx_GIVEREF(__pyx_t_6);
+  __Pyx_GOTREF(__pyx_v_self->fill_empty);
+  __Pyx_DECREF(__pyx_v_self->fill_empty);
+  __pyx_v_self->fill_empty = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":522
+ *         return ret, line_comments
+ * 
+ *     cdef _set_fill_values(self):             # <<<<<<<<<<<<<<
+ *         if self.fill_names is None:
+ *             self.fill_names = set(self.names)
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._set_fill_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":531
+ *         self.fill_values, self.fill_empty = get_fill_values(self.fill_values)
+ * 
+ *     cdef _get_comments(self, tokenizer_t *t):             # <<<<<<<<<<<<<<
+ *         line_comments = []
+ *         comment = ''
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__get_comments(CYTHON_UNUSED struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t) {
+  PyObject *__pyx_v_line_comments = NULL;
+  PyObject *__pyx_v_comment = NULL;
+  int __pyx_v_i;
+  char __pyx_v_c;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_comments", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":532
+ * 
+ *     cdef _get_comments(self, tokenizer_t *t):
+ *         line_comments = []             # <<<<<<<<<<<<<<
+ *         comment = ''
+ *         for i in range(t.comment_pos):
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_line_comments = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":533
+ *     cdef _get_comments(self, tokenizer_t *t):
+ *         line_comments = []
+ *         comment = ''             # <<<<<<<<<<<<<<
+ *         for i in range(t.comment_pos):
+ *             c = t.comment_lines[i] # next char in comment string
+ */
+  __Pyx_INCREF(__pyx_kp_s__3);
+  __pyx_v_comment = __pyx_kp_s__3;
+
+  /* "astropy/io/ascii/cparser.pyx":534
+ *         line_comments = []
+ *         comment = ''
+ *         for i in range(t.comment_pos):             # <<<<<<<<<<<<<<
+ *             c = t.comment_lines[i] # next char in comment string
+ *             if not c: # zero byte -- line terminator
+ */
+  __pyx_t_2 = __pyx_v_t->comment_pos;
+  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+    __pyx_v_i = __pyx_t_3;
+
+    /* "astropy/io/ascii/cparser.pyx":535
+ *         comment = ''
+ *         for i in range(t.comment_pos):
+ *             c = t.comment_lines[i] # next char in comment string             # <<<<<<<<<<<<<<
+ *             if not c: # zero byte -- line terminator
+ *                 # replace empty placeholder with ''
+ */
+    __pyx_v_c = (__pyx_v_t->comment_lines[__pyx_v_i]);
+
+    /* "astropy/io/ascii/cparser.pyx":536
+ *         for i in range(t.comment_pos):
+ *             c = t.comment_lines[i] # next char in comment string
+ *             if not c: # zero byte -- line terminator             # <<<<<<<<<<<<<<
+ *                 # replace empty placeholder with ''
+ *                 line_comments.append(comment.replace('\x01', '').strip())
+ */
+    __pyx_t_4 = ((!(__pyx_v_c != 0)) != 0);
+    if (__pyx_t_4) {
+
+      /* "astropy/io/ascii/cparser.pyx":538
+ *             if not c: # zero byte -- line terminator
+ *                 # replace empty placeholder with ''
+ *                 line_comments.append(comment.replace('\x01', '').strip())             # <<<<<<<<<<<<<<
+ *                 comment = ''
+ *             else:
+ */
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_comment, __pyx_n_s_replace); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_strip); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_6 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+        __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+        if (likely(__pyx_t_6)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+          __Pyx_INCREF(__pyx_t_6);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_5, function);
+        }
+      }
+      if (__pyx_t_6) {
+        __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      } else {
+        __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_line_comments, __pyx_t_1); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":539
+ *                 # replace empty placeholder with ''
+ *                 line_comments.append(comment.replace('\x01', '').strip())
+ *                 comment = ''             # <<<<<<<<<<<<<<
+ *             else:
+ *                 comment += chr(c)
+ */
+      __Pyx_INCREF(__pyx_kp_s__3);
+      __Pyx_DECREF_SET(__pyx_v_comment, __pyx_kp_s__3);
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":541
+ *                 comment = ''
+ *             else:
+ *                 comment += chr(c)             # <<<<<<<<<<<<<<
+ *         return line_comments
+ * 
+ */
+      __pyx_t_1 = __Pyx_PyInt_From_char(__pyx_v_c); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_comment, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF_SET(__pyx_v_comment, __pyx_t_5);
+      __pyx_t_5 = 0;
+    }
+    __pyx_L5:;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":542
+ *             else:
+ *                 comment += chr(c)
+ *         return line_comments             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _convert_data(self, tokenizer_t *t, try_int, try_float, try_string, num_rows):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_line_comments);
+  __pyx_r = __pyx_v_line_comments;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":531
+ *         self.fill_values, self.fill_empty = get_fill_values(self.fill_values)
+ * 
+ *     cdef _get_comments(self, tokenizer_t *t):             # <<<<<<<<<<<<<<
+ *         line_comments = []
+ *         comment = ''
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._get_comments", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_line_comments);
+  __Pyx_XDECREF(__pyx_v_comment);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":544
+ *         return line_comments
+ * 
+ *     cdef _convert_data(self, tokenizer_t *t, try_int, try_float, try_string, num_rows):             # <<<<<<<<<<<<<<
+ *         cols = {}
+ * 
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_data(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string, PyObject *__pyx_v_num_rows) {
+  PyObject *__pyx_v_cols = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *(*__pyx_t_4)(PyObject *);
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  int __pyx_t_12;
+  int __pyx_t_13;
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  PyObject *__pyx_t_16 = NULL;
+  PyObject *__pyx_t_17 = NULL;
+  PyObject *__pyx_t_18 = NULL;
+  PyObject *__pyx_t_19 = NULL;
+  PyObject *__pyx_t_20 = NULL;
+  PyObject *__pyx_t_21 = NULL;
+  PyObject *__pyx_t_22 = NULL;
+  PyObject *__pyx_t_23 = NULL;
+  PyObject *__pyx_t_24 = NULL;
+  PyObject *__pyx_t_25 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_convert_data", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":545
+ * 
+ *     cdef _convert_data(self, tokenizer_t *t, try_int, try_float, try_string, num_rows):
+ *         cols = {}             # <<<<<<<<<<<<<<
+ * 
+ *         for i, name in enumerate(self.names):
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_cols = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":547
+ *         cols = {}
+ * 
+ *         for i, name in enumerate(self.names):             # <<<<<<<<<<<<<<
+ *             if name not in self.use_cols:
+ *                 continue
+ */
+  __Pyx_INCREF(__pyx_int_0);
+  __pyx_t_1 = __pyx_int_0;
+  if (likely(PyList_CheckExact(__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_v_self->names)) {
+    __pyx_t_2 = __pyx_v_self->names; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+    __pyx_t_4 = NULL;
+  } else {
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_self->names); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_4)) {
+      if (likely(PyList_CheckExact(__pyx_t_2))) {
+        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_5);
+    __pyx_t_5 = 0;
+    __Pyx_INCREF(__pyx_t_1);
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1);
+    __pyx_t_5 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_1);
+    __pyx_t_1 = __pyx_t_5;
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":548
+ * 
+ *         for i, name in enumerate(self.names):
+ *             if name not in self.use_cols:             # <<<<<<<<<<<<<<
+ *                 continue
+ *             # Try int first, then float, then string
+ */
+    __pyx_t_6 = (__Pyx_PySequence_Contains(__pyx_v_name, __pyx_v_self->use_cols, Py_NE)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = (__pyx_t_6 != 0);
+    if (__pyx_t_7) {
+
+      /* "astropy/io/ascii/cparser.pyx":549
+ *         for i, name in enumerate(self.names):
+ *             if name not in self.use_cols:
+ *                 continue             # <<<<<<<<<<<<<<
+ *             # Try int first, then float, then string
+ *             try:
+ */
+      goto __pyx_L3_continue;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":551
+ *                 continue
+ *             # Try int first, then float, then string
+ *             try:             # <<<<<<<<<<<<<<
+ *                 if try_int and not try_int[name]:
+ *                     raise ValueError()
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10);
+      __Pyx_XGOTREF(__pyx_t_8);
+      __Pyx_XGOTREF(__pyx_t_9);
+      __Pyx_XGOTREF(__pyx_t_10);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":552
+ *             # Try int first, then float, then string
+ *             try:
+ *                 if try_int and not try_int[name]:             # <<<<<<<<<<<<<<
+ *                     raise ValueError()
+ *                 cols[name] = self._convert_int(t, i, num_rows)
+ */
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_try_int); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        if (__pyx_t_6) {
+        } else {
+          __pyx_t_7 = __pyx_t_6;
+          goto __pyx_L15_bool_binop_done;
+        }
+        __pyx_t_5 = PyObject_GetItem(__pyx_v_try_int, __pyx_v_name); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L6_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_11 = ((!__pyx_t_6) != 0);
+        __pyx_t_7 = __pyx_t_11;
+        __pyx_L15_bool_binop_done:;
+        if (__pyx_t_7) {
+
+          /* "astropy/io/ascii/cparser.pyx":553
+ *             try:
+ *                 if try_int and not try_int[name]:
+ *                     raise ValueError()             # <<<<<<<<<<<<<<
+ *                 cols[name] = self._convert_int(t, i, num_rows)
+ *             except ValueError:
+ */
+          __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(__pyx_t_5);
+          __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        }
+
+        /* "astropy/io/ascii/cparser.pyx":554
+ *                 if try_int and not try_int[name]:
+ *                     raise ValueError()
+ *                 cols[name] = self._convert_int(t, i, num_rows)             # <<<<<<<<<<<<<<
+ *             except ValueError:
+ *                 try:
+ */
+        __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_i); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_num_rows); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __pyx_t_5 = ((PyObject *)((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_convert_int(__pyx_v_self, __pyx_v_t, __pyx_t_12, __pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        if (unlikely(PyDict_SetItem(__pyx_v_cols, __pyx_v_name, __pyx_t_5) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L13_try_end;
+      __pyx_L6_error:;
+      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":555
+ *                     raise ValueError()
+ *                 cols[name] = self._convert_int(t, i, num_rows)
+ *             except ValueError:             # <<<<<<<<<<<<<<
+ *                 try:
+ *                     if try_float and not try_float[name]:
+ */
+      __pyx_t_13 = PyErr_ExceptionMatches(__pyx_builtin_ValueError);
+      if (__pyx_t_13) {
+        __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_14, &__pyx_t_15) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_GOTREF(__pyx_t_15);
+
+        /* "astropy/io/ascii/cparser.pyx":556
+ *                 cols[name] = self._convert_int(t, i, num_rows)
+ *             except ValueError:
+ *                 try:             # <<<<<<<<<<<<<<
+ *                     if try_float and not try_float[name]:
+ *                         raise ValueError()
+ */
+        {
+          __Pyx_ExceptionSave(&__pyx_t_16, &__pyx_t_17, &__pyx_t_18);
+          __Pyx_XGOTREF(__pyx_t_16);
+          __Pyx_XGOTREF(__pyx_t_17);
+          __Pyx_XGOTREF(__pyx_t_18);
+          /*try:*/ {
+
+            /* "astropy/io/ascii/cparser.pyx":557
+ *             except ValueError:
+ *                 try:
+ *                     if try_float and not try_float[name]:             # <<<<<<<<<<<<<<
+ *                         raise ValueError()
+ *                     cols[name] = self._convert_float(t, i, num_rows)
+ */
+            __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_try_float); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            if (__pyx_t_11) {
+            } else {
+              __pyx_t_7 = __pyx_t_11;
+              goto __pyx_L28_bool_binop_done;
+            }
+            __pyx_t_19 = PyObject_GetItem(__pyx_v_try_float, __pyx_v_name); if (unlikely(__pyx_t_19 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L19_error;};
+            __Pyx_GOTREF(__pyx_t_19);
+            __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_19); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+            __pyx_t_6 = ((!__pyx_t_11) != 0);
+            __pyx_t_7 = __pyx_t_6;
+            __pyx_L28_bool_binop_done:;
+            if (__pyx_t_7) {
+
+              /* "astropy/io/ascii/cparser.pyx":558
+ *                 try:
+ *                     if try_float and not try_float[name]:
+ *                         raise ValueError()             # <<<<<<<<<<<<<<
+ *                     cols[name] = self._convert_float(t, i, num_rows)
+ *                 except ValueError:
+ */
+              __pyx_t_19 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+              __Pyx_GOTREF(__pyx_t_19);
+              __Pyx_Raise(__pyx_t_19, 0, 0, 0);
+              __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            }
+
+            /* "astropy/io/ascii/cparser.pyx":559
+ *                     if try_float and not try_float[name]:
+ *                         raise ValueError()
+ *                     cols[name] = self._convert_float(t, i, num_rows)             # <<<<<<<<<<<<<<
+ *                 except ValueError:
+ *                     if try_string and not try_string[name]:
+ */
+            __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_i); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_num_rows); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            __pyx_t_19 = ((PyObject *)((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_convert_float(__pyx_v_self, __pyx_v_t, __pyx_t_13, __pyx_t_12)); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            __Pyx_GOTREF(__pyx_t_19);
+            if (unlikely(PyDict_SetItem(__pyx_v_cols, __pyx_v_name, __pyx_t_19) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L19_error;}
+            __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+          }
+          __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
+          __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
+          __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
+          goto __pyx_L26_try_end;
+          __pyx_L19_error:;
+          __Pyx_XDECREF(__pyx_t_19); __pyx_t_19 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":560
+ *                         raise ValueError()
+ *                     cols[name] = self._convert_float(t, i, num_rows)
+ *                 except ValueError:             # <<<<<<<<<<<<<<
+ *                     if try_string and not try_string[name]:
+ *                         raise ValueError('Column {0} failed to convert'.format(name))
+ */
+          __pyx_t_12 = PyErr_ExceptionMatches(__pyx_builtin_ValueError);
+          if (__pyx_t_12) {
+            __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+            if (__Pyx_GetException(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __Pyx_GOTREF(__pyx_t_19);
+            __Pyx_GOTREF(__pyx_t_20);
+            __Pyx_GOTREF(__pyx_t_21);
+
+            /* "astropy/io/ascii/cparser.pyx":561
+ *                     cols[name] = self._convert_float(t, i, num_rows)
+ *                 except ValueError:
+ *                     if try_string and not try_string[name]:             # <<<<<<<<<<<<<<
+ *                         raise ValueError('Column {0} failed to convert'.format(name))
+ *                     cols[name] = self._convert_str(t, i, num_rows)
+ */
+            __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_try_string); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            if (__pyx_t_6) {
+            } else {
+              __pyx_t_7 = __pyx_t_6;
+              goto __pyx_L33_bool_binop_done;
+            }
+            __pyx_t_22 = PyObject_GetItem(__pyx_v_try_string, __pyx_v_name); if (unlikely(__pyx_t_22 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;};
+            __Pyx_GOTREF(__pyx_t_22);
+            __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_22); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
+            __pyx_t_11 = ((!__pyx_t_6) != 0);
+            __pyx_t_7 = __pyx_t_11;
+            __pyx_L33_bool_binop_done:;
+            if (__pyx_t_7) {
+
+              /* "astropy/io/ascii/cparser.pyx":562
+ *                 except ValueError:
+ *                     if try_string and not try_string[name]:
+ *                         raise ValueError('Column {0} failed to convert'.format(name))             # <<<<<<<<<<<<<<
+ *                     cols[name] = self._convert_str(t, i, num_rows)
+ * 
+ */
+              __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Column_0_failed_to_convert, __pyx_n_s_format); if (unlikely(!__pyx_t_23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+              __Pyx_GOTREF(__pyx_t_23);
+              __pyx_t_24 = NULL;
+              if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_23))) {
+                __pyx_t_24 = PyMethod_GET_SELF(__pyx_t_23);
+                if (likely(__pyx_t_24)) {
+                  PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_23);
+                  __Pyx_INCREF(__pyx_t_24);
+                  __Pyx_INCREF(function);
+                  __Pyx_DECREF_SET(__pyx_t_23, function);
+                }
+              }
+              if (!__pyx_t_24) {
+                __pyx_t_22 = __Pyx_PyObject_CallOneArg(__pyx_t_23, __pyx_v_name); if (unlikely(!__pyx_t_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+                __Pyx_GOTREF(__pyx_t_22);
+              } else {
+                __pyx_t_25 = PyTuple_New(1+1); if (unlikely(!__pyx_t_25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+                __Pyx_GOTREF(__pyx_t_25);
+                PyTuple_SET_ITEM(__pyx_t_25, 0, __pyx_t_24); __Pyx_GIVEREF(__pyx_t_24); __pyx_t_24 = NULL;
+                __Pyx_INCREF(__pyx_v_name);
+                PyTuple_SET_ITEM(__pyx_t_25, 0+1, __pyx_v_name);
+                __Pyx_GIVEREF(__pyx_v_name);
+                __pyx_t_22 = __Pyx_PyObject_Call(__pyx_t_23, __pyx_t_25, NULL); if (unlikely(!__pyx_t_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+                __Pyx_GOTREF(__pyx_t_22);
+                __Pyx_DECREF(__pyx_t_25); __pyx_t_25 = 0;
+              }
+              __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
+              __pyx_t_23 = PyTuple_New(1); if (unlikely(!__pyx_t_23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+              __Pyx_GOTREF(__pyx_t_23);
+              PyTuple_SET_ITEM(__pyx_t_23, 0, __pyx_t_22);
+              __Pyx_GIVEREF(__pyx_t_22);
+              __pyx_t_22 = 0;
+              __pyx_t_22 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_23, NULL); if (unlikely(!__pyx_t_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+              __Pyx_GOTREF(__pyx_t_22);
+              __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
+              __Pyx_Raise(__pyx_t_22, 0, 0, 0);
+              __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            }
+
+            /* "astropy/io/ascii/cparser.pyx":563
+ *                     if try_string and not try_string[name]:
+ *                         raise ValueError('Column {0} failed to convert'.format(name))
+ *                     cols[name] = self._convert_str(t, i, num_rows)             # <<<<<<<<<<<<<<
+ * 
+ *         return cols, self._get_comments(t)
+ */
+            __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_i); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_num_rows); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __pyx_t_22 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_convert_str(__pyx_v_self, __pyx_v_t, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __Pyx_GOTREF(__pyx_t_22);
+            if (unlikely(PyDict_SetItem(__pyx_v_cols, __pyx_v_name, __pyx_t_22) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L21_except_error;}
+            __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
+            __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+            __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+            __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
+            goto __pyx_L20_exception_handled;
+          }
+          goto __pyx_L21_except_error;
+          __pyx_L21_except_error:;
+          __Pyx_XGIVEREF(__pyx_t_16);
+          __Pyx_XGIVEREF(__pyx_t_17);
+          __Pyx_XGIVEREF(__pyx_t_18);
+          __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18);
+          goto __pyx_L8_except_error;
+          __pyx_L20_exception_handled:;
+          __Pyx_XGIVEREF(__pyx_t_16);
+          __Pyx_XGIVEREF(__pyx_t_17);
+          __Pyx_XGIVEREF(__pyx_t_18);
+          __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18);
+          __pyx_L26_try_end:;
+        }
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+        goto __pyx_L7_exception_handled;
+      }
+      goto __pyx_L8_except_error;
+      __pyx_L8_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_9);
+      __Pyx_XGIVEREF(__pyx_t_10);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10);
+      goto __pyx_L1_error;
+      __pyx_L7_exception_handled:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_9);
+      __Pyx_XGIVEREF(__pyx_t_10);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10);
+      __pyx_L13_try_end:;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":547
+ *         cols = {}
+ * 
+ *         for i, name in enumerate(self.names):             # <<<<<<<<<<<<<<
+ *             if name not in self.use_cols:
+ *                 continue
+ */
+    __pyx_L3_continue:;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":565
+ *                     cols[name] = self._convert_str(t, i, num_rows)
+ * 
+ *         return cols, self._get_comments(t)             # <<<<<<<<<<<<<<
+ * 
+ *     cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self->__pyx_vtab)->_get_comments(__pyx_v_self, __pyx_v_t); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_cols);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_cols);
+  __Pyx_GIVEREF(__pyx_v_cols);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":544
+ *         return line_comments
+ * 
+ *     cdef _convert_data(self, tokenizer_t *t, try_int, try_float, try_string, num_rows):             # <<<<<<<<<<<<<<
+ *         cols = {}
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_XDECREF(__pyx_t_15);
+  __Pyx_XDECREF(__pyx_t_19);
+  __Pyx_XDECREF(__pyx_t_20);
+  __Pyx_XDECREF(__pyx_t_21);
+  __Pyx_XDECREF(__pyx_t_22);
+  __Pyx_XDECREF(__pyx_t_23);
+  __Pyx_XDECREF(__pyx_t_24);
+  __Pyx_XDECREF(__pyx_t_25);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_cols);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":567
+ *         return cols, self._get_comments(t)
+ * 
+ *     cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:
+ */
+
+static PyArrayObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_int(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows) {
+  int __pyx_v_num_rows;
+  PyArrayObject *__pyx_v_col = 0;
+  long __pyx_v_converted;
+  int __pyx_v_row;
+  long *__pyx_v_data;
+  char *__pyx_v_field;
+  char *__pyx_v_empty_field;
+  PyObject *__pyx_v_new_value = 0;
+  PyObject *__pyx_v_mask = NULL;
+  PyObject *__pyx_v_replace_info = NULL;
+  PyArrayObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  char *__pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_t_11;
+  Py_ssize_t __pyx_t_12;
+  int __pyx_t_13;
+  PyObject *__pyx_t_14 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_convert_int", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":568
+ * 
+ *     cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):
+ *         cdef int num_rows = t.num_rows             # <<<<<<<<<<<<<<
+ *         if nrows != -1:
+ *             num_rows = nrows
+ */
+  __pyx_t_1 = __pyx_v_t->num_rows;
+  __pyx_v_num_rows = __pyx_t_1;
+
+  /* "astropy/io/ascii/cparser.pyx":569
+ *     cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:             # <<<<<<<<<<<<<<
+ *             num_rows = nrows
+ *         # intialize ndarray
+ */
+  __pyx_t_2 = ((__pyx_v_nrows != -1) != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":570
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:
+ *             num_rows = nrows             # <<<<<<<<<<<<<<
+ *         # intialize ndarray
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.int_)
+ */
+    __pyx_v_num_rows = __pyx_v_nrows;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":572
+ *             num_rows = nrows
+ *         # intialize ndarray
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.int_)             # <<<<<<<<<<<<<<
+ *         cdef long converted
+ *         cdef int row = 0
+ */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_num_rows); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_int); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_col = ((PyArrayObject *)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":574
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.int_)
+ *         cdef long converted
+ *         cdef int row = 0             # <<<<<<<<<<<<<<
+ *         cdef long *data = <long *> col.data # pointer to raw data
+ *         cdef char *field
+ */
+  __pyx_v_row = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":575
+ *         cdef long converted
+ *         cdef int row = 0
+ *         cdef long *data = <long *> col.data # pointer to raw data             # <<<<<<<<<<<<<<
+ *         cdef char *field
+ *         cdef char *empty_field = t.buf # memory address of designated empty buffer
+ */
+  __pyx_v_data = ((long *)__pyx_v_col->data);
+
+  /* "astropy/io/ascii/cparser.pyx":577
+ *         cdef long *data = <long *> col.data # pointer to raw data
+ *         cdef char *field
+ *         cdef char *empty_field = t.buf # memory address of designated empty buffer             # <<<<<<<<<<<<<<
+ *         cdef bytes new_value
+ *         mask = set() # set of indices for masked values
+ */
+  __pyx_t_8 = __pyx_v_t->buf;
+  __pyx_v_empty_field = __pyx_t_8;
+
+  /* "astropy/io/ascii/cparser.pyx":579
+ *         cdef char *empty_field = t.buf # memory address of designated empty buffer
+ *         cdef bytes new_value
+ *         mask = set() # set of indices for masked values             # <<<<<<<<<<<<<<
+ *         start_iteration(t, i) # begin the iteration process in C
+ * 
+ */
+  __pyx_t_7 = PySet_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_v_mask = ((PyObject*)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":580
+ *         cdef bytes new_value
+ *         mask = set() # set of indices for masked values
+ *         start_iteration(t, i) # begin the iteration process in C             # <<<<<<<<<<<<<<
+ * 
+ *         for row in range(num_rows):
+ */
+  start_iteration(__pyx_v_t, __pyx_v_i);
+
+  /* "astropy/io/ascii/cparser.pyx":582
+ *         start_iteration(t, i) # begin the iteration process in C
+ * 
+ *         for row in range(num_rows):             # <<<<<<<<<<<<<<
+ *             # retrieve the next field as a C pointer
+ *             field = next_field(t, <int *>0)
+ */
+  __pyx_t_1 = __pyx_v_num_rows;
+  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_1; __pyx_t_9+=1) {
+    __pyx_v_row = __pyx_t_9;
+
+    /* "astropy/io/ascii/cparser.pyx":584
+ *         for row in range(num_rows):
+ *             # retrieve the next field as a C pointer
+ *             field = next_field(t, <int *>0)             # <<<<<<<<<<<<<<
+ *             replace_info = None
+ * 
+ */
+    __pyx_v_field = next_field(__pyx_v_t, ((int *)0));
+
+    /* "astropy/io/ascii/cparser.pyx":585
+ *             # retrieve the next field as a C pointer
+ *             field = next_field(t, <int *>0)
+ *             replace_info = None             # <<<<<<<<<<<<<<
+ * 
+ *             if field == empty_field and self.fill_empty:
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_XDECREF_SET(__pyx_v_replace_info, Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":587
+ *             replace_info = None
+ * 
+ *             if field == empty_field and self.fill_empty:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_empty
+ *             # hopefully this implicit char * -> byte conversion for fill values
+ */
+    __pyx_t_10 = ((__pyx_v_field == __pyx_v_empty_field) != 0);
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_empty); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_10;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":588
+ * 
+ *             if field == empty_field and self.fill_empty:
+ *                 replace_info = self.fill_empty             # <<<<<<<<<<<<<<
+ *             # hopefully this implicit char * -> byte conversion for fill values
+ *             # checking can be avoided in most cases, since self.fill_values will
+ */
+      __pyx_t_7 = __pyx_v_self->fill_empty;
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_7);
+      __pyx_t_7 = 0;
+      goto __pyx_L6;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":593
+ *             # be empty in the default case (self.fill_empty will do the work
+ *             # instead)
+ *             elif field != empty_field and self.fill_values and field in self.fill_values:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_values[field]
+ * 
+ */
+    __pyx_t_10 = ((__pyx_v_field != __pyx_v_empty_field) != 0);
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_values); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_field); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_10 = (__Pyx_PySequence_Contains(__pyx_t_7, __pyx_v_self->fill_values, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_11 = (__pyx_t_10 != 0);
+    __pyx_t_2 = __pyx_t_11;
+    __pyx_L9_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":594
+ *             # instead)
+ *             elif field != empty_field and self.fill_values and field in self.fill_values:
+ *                 replace_info = self.fill_values[field]             # <<<<<<<<<<<<<<
+ * 
+ *             if replace_info is not None:
+ */
+      __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_field); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_self->fill_values, __pyx_t_7); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "astropy/io/ascii/cparser.pyx":596
+ *                 replace_info = self.fill_values[field]
+ * 
+ *             if replace_info is not None:             # <<<<<<<<<<<<<<
+ *                 # Either this column applies to the field as specified in the
+ *                 # fill_values parameter, or no specific columns are specified
+ */
+    __pyx_t_2 = (__pyx_v_replace_info != Py_None);
+    __pyx_t_11 = (__pyx_t_2 != 0);
+    if (__pyx_t_11) {
+
+      /* "astropy/io/ascii/cparser.pyx":600
+ *                 # fill_values parameter, or no specific columns are specified
+ *                 # and this column should apply fill_values.
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+      __pyx_t_12 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((__pyx_t_12 > 1) != 0);
+      if (!__pyx_t_2) {
+        goto __pyx_L15_next_or;
+      } else {
+      }
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_v_replace_info, 1, 0, NULL, NULL, &__pyx_slice__21, 1, 0, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_3, __pyx_t_7, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_10 = (__pyx_t_2 != 0);
+      if (!__pyx_t_10) {
+      } else {
+        __pyx_t_11 = __pyx_t_10;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_L15_next_or:;
+
+      /* "astropy/io/ascii/cparser.pyx":601
+ *                 # and this column should apply fill_values.
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):             # <<<<<<<<<<<<<<
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ */
+      __pyx_t_12 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = ((__pyx_t_12 == 1) != 0);
+      if (__pyx_t_10) {
+      } else {
+        __pyx_t_11 = __pyx_t_10;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_10 = (__Pyx_PySequence_Contains(__pyx_t_7, __pyx_v_self->fill_names, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_2 = (__pyx_t_10 != 0);
+      __pyx_t_11 = __pyx_t_2;
+      __pyx_L14_bool_binop_done:;
+      if (__pyx_t_11) {
+
+        /* "astropy/io/ascii/cparser.pyx":602
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)             # <<<<<<<<<<<<<<
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ *                     # try converting the new value
+ */
+        __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_row); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_13 = PySet_Add(__pyx_v_mask, __pyx_t_7); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":603
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')             # <<<<<<<<<<<<<<
+ *                     # try converting the new value
+ *                     converted = str_to_long(t, new_value)
+ */
+        __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_replace_info, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_encode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        if (!(likely(PyBytes_CheckExact(__pyx_t_7))||((__pyx_t_7) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_7)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_XDECREF_SET(__pyx_v_new_value, ((PyObject*)__pyx_t_7));
+        __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":605
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ *                     # try converting the new value
+ *                     converted = str_to_long(t, new_value)             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     converted = str_to_long(t, field)
+ */
+        __pyx_t_8 = __Pyx_PyObject_AsString(__pyx_v_new_value); if (unlikely((!__pyx_t_8) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_v_converted = str_to_long(__pyx_v_t, __pyx_t_8);
+        goto __pyx_L13;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":607
+ *                     converted = str_to_long(t, new_value)
+ *                 else:
+ *                     converted = str_to_long(t, field)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # convert the field to long (widest integer type)
+ */
+        __pyx_v_converted = str_to_long(__pyx_v_t, __pyx_v_field);
+      }
+      __pyx_L13:;
+      goto __pyx_L12;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":610
+ *             else:
+ *                 # convert the field to long (widest integer type)
+ *                 converted = str_to_long(t, field)             # <<<<<<<<<<<<<<
+ * 
+ *             if t.code in (CONVERSION_ERROR, OVERFLOW_ERROR):
+ */
+      __pyx_v_converted = str_to_long(__pyx_v_t, __pyx_v_field);
+    }
+    __pyx_L12:;
+
+    /* "astropy/io/ascii/cparser.pyx":612
+ *                 converted = str_to_long(t, field)
+ * 
+ *             if t.code in (CONVERSION_ERROR, OVERFLOW_ERROR):             # <<<<<<<<<<<<<<
+ *                 # no dice
+ *                 t.code = NO_ERROR
+ */
+    switch (__pyx_v_t->code) {
+      case CONVERSION_ERROR:
+      case OVERFLOW_ERROR:
+
+      /* "astropy/io/ascii/cparser.pyx":614
+ *             if t.code in (CONVERSION_ERROR, OVERFLOW_ERROR):
+ *                 # no dice
+ *                 t.code = NO_ERROR             # <<<<<<<<<<<<<<
+ *                 raise ValueError()
+ * 
+ */
+      __pyx_v_t->code = NO_ERROR;
+
+      /* "astropy/io/ascii/cparser.pyx":615
+ *                 # no dice
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()             # <<<<<<<<<<<<<<
+ * 
+ *             data[row] = converted
+ */
+      __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+      default: break;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":617
+ *                 raise ValueError()
+ * 
+ *             data[row] = converted             # <<<<<<<<<<<<<<
+ *             row += 1
+ * 
+ */
+    (__pyx_v_data[__pyx_v_row]) = __pyx_v_converted;
+
+    /* "astropy/io/ascii/cparser.pyx":618
+ * 
+ *             data[row] = converted
+ *             row += 1             # <<<<<<<<<<<<<<
+ * 
+ *         if mask:
+ */
+    __pyx_v_row = (__pyx_v_row + 1);
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":620
+ *             row += 1
+ * 
+ *         if mask:             # <<<<<<<<<<<<<<
+ *             # convert to masked_array
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ */
+  __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_mask); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_11) {
+
+    /* "astropy/io/ascii/cparser.pyx":622
+ *         if mask:
+ *             # convert to masked_array
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_ma); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_masked_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_v_col));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_col));
+    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+
+    /* "astropy/io/ascii/cparser.pyx":623
+ *             # convert to masked_array
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ *                                               range(row)])             # <<<<<<<<<<<<<<
+ *         else:
+ *             return col
+ */
+    __pyx_t_1 = __pyx_v_row;
+    for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_1; __pyx_t_9+=1) {
+      __pyx_v_i = __pyx_t_9;
+
+      /* "astropy/io/ascii/cparser.pyx":622
+ *         if mask:
+ *             # convert to masked_array
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+      __pyx_t_14 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_14);
+      __pyx_t_11 = (__Pyx_PySequence_Contains(__pyx_t_14, __pyx_v_mask, Py_EQ)); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+      if ((__pyx_t_11 != 0)) {
+        __Pyx_INCREF(__pyx_int_1);
+        __pyx_t_6 = __pyx_int_1;
+      } else {
+        __Pyx_INCREF(__pyx_int_0);
+        __pyx_t_6 = __pyx_int_0;
+      }
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_mask, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_r = ((PyArrayObject *)__pyx_t_4);
+    __pyx_t_4 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":625
+ *                                               range(row)])
+ *         else:
+ *             return col             # <<<<<<<<<<<<<<
+ * 
+ *     cdef np.ndarray _convert_float(self, tokenizer_t *t, int i, int nrows):
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    __pyx_r = __pyx_v_col;
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":567
+ *         return cols, self._get_comments(t)
+ * 
+ *     cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_int", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_col);
+  __Pyx_XDECREF(__pyx_v_new_value);
+  __Pyx_XDECREF(__pyx_v_mask);
+  __Pyx_XDECREF(__pyx_v_replace_info);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":627
+ *             return col
+ * 
+ *     cdef np.ndarray _convert_float(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         # very similar to _convert_int()
+ *         cdef int num_rows = t.num_rows
+ */
+
+static PyArrayObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_float(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows) {
+  int __pyx_v_num_rows;
+  PyArrayObject *__pyx_v_col = 0;
+  double __pyx_v_converted;
+  int __pyx_v_row;
+  double *__pyx_v_data;
+  char *__pyx_v_field;
+  char *__pyx_v_empty_field;
+  PyObject *__pyx_v_new_value = 0;
+  CYTHON_UNUSED int __pyx_v_replacing;
+  PyObject *__pyx_v_mask = NULL;
+  PyObject *__pyx_v_replace_info = NULL;
+  PyArrayObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  char *__pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_t_11;
+  Py_ssize_t __pyx_t_12;
+  int __pyx_t_13;
+  PyObject *__pyx_t_14 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_convert_float", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":629
+ *     cdef np.ndarray _convert_float(self, tokenizer_t *t, int i, int nrows):
+ *         # very similar to _convert_int()
+ *         cdef int num_rows = t.num_rows             # <<<<<<<<<<<<<<
+ *         if nrows != -1:
+ *             num_rows = nrows
+ */
+  __pyx_t_1 = __pyx_v_t->num_rows;
+  __pyx_v_num_rows = __pyx_t_1;
+
+  /* "astropy/io/ascii/cparser.pyx":630
+ *         # very similar to _convert_int()
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:             # <<<<<<<<<<<<<<
+ *             num_rows = nrows
+ * 
+ */
+  __pyx_t_2 = ((__pyx_v_nrows != -1) != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":631
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:
+ *             num_rows = nrows             # <<<<<<<<<<<<<<
+ * 
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.float_)
+ */
+    __pyx_v_num_rows = __pyx_v_nrows;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":633
+ *             num_rows = nrows
+ * 
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.float_)             # <<<<<<<<<<<<<<
+ *         cdef double converted
+ *         cdef int row = 0
+ */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_num_rows); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_col = ((PyArrayObject *)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":635
+ *         cdef np.ndarray col = np.empty(num_rows, dtype=np.float_)
+ *         cdef double converted
+ *         cdef int row = 0             # <<<<<<<<<<<<<<
+ *         cdef double *data = <double *> col.data
+ *         cdef char *field
+ */
+  __pyx_v_row = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":636
+ *         cdef double converted
+ *         cdef int row = 0
+ *         cdef double *data = <double *> col.data             # <<<<<<<<<<<<<<
+ *         cdef char *field
+ *         cdef char *empty_field = t.buf
+ */
+  __pyx_v_data = ((double *)__pyx_v_col->data);
+
+  /* "astropy/io/ascii/cparser.pyx":638
+ *         cdef double *data = <double *> col.data
+ *         cdef char *field
+ *         cdef char *empty_field = t.buf             # <<<<<<<<<<<<<<
+ *         cdef bytes new_value
+ *         cdef int replacing
+ */
+  __pyx_t_8 = __pyx_v_t->buf;
+  __pyx_v_empty_field = __pyx_t_8;
+
+  /* "astropy/io/ascii/cparser.pyx":641
+ *         cdef bytes new_value
+ *         cdef int replacing
+ *         mask = set()             # <<<<<<<<<<<<<<
+ * 
+ *         start_iteration(t, i)
+ */
+  __pyx_t_7 = PySet_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_v_mask = ((PyObject*)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":643
+ *         mask = set()
+ * 
+ *         start_iteration(t, i)             # <<<<<<<<<<<<<<
+ *         for row in range(num_rows):
+ *             field = next_field(t, <int *>0)
+ */
+  start_iteration(__pyx_v_t, __pyx_v_i);
+
+  /* "astropy/io/ascii/cparser.pyx":644
+ * 
+ *         start_iteration(t, i)
+ *         for row in range(num_rows):             # <<<<<<<<<<<<<<
+ *             field = next_field(t, <int *>0)
+ *             replace_info = None
+ */
+  __pyx_t_1 = __pyx_v_num_rows;
+  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_1; __pyx_t_9+=1) {
+    __pyx_v_row = __pyx_t_9;
+
+    /* "astropy/io/ascii/cparser.pyx":645
+ *         start_iteration(t, i)
+ *         for row in range(num_rows):
+ *             field = next_field(t, <int *>0)             # <<<<<<<<<<<<<<
+ *             replace_info = None
+ *             replacing = False
+ */
+    __pyx_v_field = next_field(__pyx_v_t, ((int *)0));
+
+    /* "astropy/io/ascii/cparser.pyx":646
+ *         for row in range(num_rows):
+ *             field = next_field(t, <int *>0)
+ *             replace_info = None             # <<<<<<<<<<<<<<
+ *             replacing = False
+ * 
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_XDECREF_SET(__pyx_v_replace_info, Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":647
+ *             field = next_field(t, <int *>0)
+ *             replace_info = None
+ *             replacing = False             # <<<<<<<<<<<<<<
+ * 
+ *             if field == empty_field and self.fill_empty:
+ */
+    __pyx_v_replacing = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":649
+ *             replacing = False
+ * 
+ *             if field == empty_field and self.fill_empty:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_empty
+ * 
+ */
+    __pyx_t_10 = ((__pyx_v_field == __pyx_v_empty_field) != 0);
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_empty); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 649; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_10;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":650
+ * 
+ *             if field == empty_field and self.fill_empty:
+ *                 replace_info = self.fill_empty             # <<<<<<<<<<<<<<
+ * 
+ *             elif field != empty_field and self.fill_values and field in self.fill_values:
+ */
+      __pyx_t_7 = __pyx_v_self->fill_empty;
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_7);
+      __pyx_t_7 = 0;
+      goto __pyx_L6;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":652
+ *                 replace_info = self.fill_empty
+ * 
+ *             elif field != empty_field and self.fill_values and field in self.fill_values:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_values[field]
+ * 
+ */
+    __pyx_t_10 = ((__pyx_v_field != __pyx_v_empty_field) != 0);
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_values); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_10) {
+    } else {
+      __pyx_t_2 = __pyx_t_10;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_field); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_10 = (__Pyx_PySequence_Contains(__pyx_t_7, __pyx_v_self->fill_values, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_11 = (__pyx_t_10 != 0);
+    __pyx_t_2 = __pyx_t_11;
+    __pyx_L9_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":653
+ * 
+ *             elif field != empty_field and self.fill_values and field in self.fill_values:
+ *                 replace_info = self.fill_values[field]             # <<<<<<<<<<<<<<
+ * 
+ *             if replace_info is not None:
+ */
+      __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_field); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_self->fill_values, __pyx_t_7); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "astropy/io/ascii/cparser.pyx":655
+ *                 replace_info = self.fill_values[field]
+ * 
+ *             if replace_info is not None:             # <<<<<<<<<<<<<<
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ */
+    __pyx_t_2 = (__pyx_v_replace_info != Py_None);
+    __pyx_t_11 = (__pyx_t_2 != 0);
+    if (__pyx_t_11) {
+
+      /* "astropy/io/ascii/cparser.pyx":656
+ * 
+ *             if replace_info is not None:
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+      __pyx_t_12 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((__pyx_t_12 > 1) != 0);
+      if (!__pyx_t_2) {
+        goto __pyx_L15_next_or;
+      } else {
+      }
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_v_replace_info, 1, 0, NULL, NULL, &__pyx_slice__23, 1, 0, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_3, __pyx_t_7, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_10 = (__pyx_t_2 != 0);
+      if (!__pyx_t_10) {
+      } else {
+        __pyx_t_11 = __pyx_t_10;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_L15_next_or:;
+
+      /* "astropy/io/ascii/cparser.pyx":657
+ *             if replace_info is not None:
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):             # <<<<<<<<<<<<<<
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ */
+      __pyx_t_12 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = ((__pyx_t_12 == 1) != 0);
+      if (__pyx_t_10) {
+      } else {
+        __pyx_t_11 = __pyx_t_10;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_10 = (__Pyx_PySequence_Contains(__pyx_t_7, __pyx_v_self->fill_names, Py_EQ)); if (unlikely(__pyx_t_10 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_2 = (__pyx_t_10 != 0);
+      __pyx_t_11 = __pyx_t_2;
+      __pyx_L14_bool_binop_done:;
+      if (__pyx_t_11) {
+
+        /* "astropy/io/ascii/cparser.pyx":658
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)             # <<<<<<<<<<<<<<
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ *                     replacing = True
+ */
+        __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_row); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_13 = PySet_Add(__pyx_v_mask, __pyx_t_7); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":659
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')             # <<<<<<<<<<<<<<
+ *                     replacing = True
+ *                     converted = str_to_double(t, new_value)
+ */
+        __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_replace_info, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_encode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        if (!(likely(PyBytes_CheckExact(__pyx_t_7))||((__pyx_t_7) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_7)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_XDECREF_SET(__pyx_v_new_value, ((PyObject*)__pyx_t_7));
+        __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":660
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ *                     replacing = True             # <<<<<<<<<<<<<<
+ *                     converted = str_to_double(t, new_value)
+ *                 else:
+ */
+        __pyx_v_replacing = 1;
+
+        /* "astropy/io/ascii/cparser.pyx":661
+ *                     new_value = str(replace_info[0]).encode('ascii')
+ *                     replacing = True
+ *                     converted = str_to_double(t, new_value)             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     converted = str_to_double(t, field)
+ */
+        __pyx_t_8 = __Pyx_PyObject_AsString(__pyx_v_new_value); if (unlikely((!__pyx_t_8) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_v_converted = str_to_double(__pyx_v_t, __pyx_t_8);
+        goto __pyx_L13;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":663
+ *                     converted = str_to_double(t, new_value)
+ *                 else:
+ *                     converted = str_to_double(t, field)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 converted = str_to_double(t, field)
+ */
+        __pyx_v_converted = str_to_double(__pyx_v_t, __pyx_v_field);
+      }
+      __pyx_L13:;
+      goto __pyx_L12;
+    }
+    /*else*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":665
+ *                     converted = str_to_double(t, field)
+ *             else:
+ *                 converted = str_to_double(t, field)             # <<<<<<<<<<<<<<
+ * 
+ *             if t.code == CONVERSION_ERROR:
+ */
+      __pyx_v_converted = str_to_double(__pyx_v_t, __pyx_v_field);
+    }
+    __pyx_L12:;
+
+    /* "astropy/io/ascii/cparser.pyx":670
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()
+ *             elif t.code == OVERFLOW_ERROR:             # <<<<<<<<<<<<<<
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()
+ */
+    switch (__pyx_v_t->code) {
+
+      /* "astropy/io/ascii/cparser.pyx":667
+ *                 converted = str_to_double(t, field)
+ * 
+ *             if t.code == CONVERSION_ERROR:             # <<<<<<<<<<<<<<
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()
+ */
+      case CONVERSION_ERROR:
+
+      /* "astropy/io/ascii/cparser.pyx":668
+ * 
+ *             if t.code == CONVERSION_ERROR:
+ *                 t.code = NO_ERROR             # <<<<<<<<<<<<<<
+ *                 raise ValueError()
+ *             elif t.code == OVERFLOW_ERROR:
+ */
+      __pyx_v_t->code = NO_ERROR;
+
+      /* "astropy/io/ascii/cparser.pyx":669
+ *             if t.code == CONVERSION_ERROR:
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()             # <<<<<<<<<<<<<<
+ *             elif t.code == OVERFLOW_ERROR:
+ *                 t.code = NO_ERROR
+ */
+      __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 669; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 669; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+
+      /* "astropy/io/ascii/cparser.pyx":670
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()
+ *             elif t.code == OVERFLOW_ERROR:             # <<<<<<<<<<<<<<
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()
+ */
+      case OVERFLOW_ERROR:
+
+      /* "astropy/io/ascii/cparser.pyx":671
+ *                 raise ValueError()
+ *             elif t.code == OVERFLOW_ERROR:
+ *                 t.code = NO_ERROR             # <<<<<<<<<<<<<<
+ *                 raise ValueError()
+ *             else:
+ */
+      __pyx_v_t->code = NO_ERROR;
+
+      /* "astropy/io/ascii/cparser.pyx":672
+ *             elif t.code == OVERFLOW_ERROR:
+ *                 t.code = NO_ERROR
+ *                 raise ValueError()             # <<<<<<<<<<<<<<
+ *             else:
+ *                 data[row] = converted
+ */
+      __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+      default:
+
+      /* "astropy/io/ascii/cparser.pyx":674
+ *                 raise ValueError()
+ *             else:
+ *                 data[row] = converted             # <<<<<<<<<<<<<<
+ *             row += 1
+ * 
+ */
+      (__pyx_v_data[__pyx_v_row]) = __pyx_v_converted;
+      break;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":675
+ *             else:
+ *                 data[row] = converted
+ *             row += 1             # <<<<<<<<<<<<<<
+ * 
+ *         if mask:
+ */
+    __pyx_v_row = (__pyx_v_row + 1);
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":677
+ *             row += 1
+ * 
+ *         if mask:             # <<<<<<<<<<<<<<
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ *                                               range(row)])
+ */
+  __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_mask); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 677; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_11) {
+
+    /* "astropy/io/ascii/cparser.pyx":678
+ * 
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_ma); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_masked_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_v_col));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_col));
+    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+
+    /* "astropy/io/ascii/cparser.pyx":679
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ *                                               range(row)])             # <<<<<<<<<<<<<<
+ *         else:
+ *             return col
+ */
+    __pyx_t_1 = __pyx_v_row;
+    for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_1; __pyx_t_9+=1) {
+      __pyx_v_i = __pyx_t_9;
+
+      /* "astropy/io/ascii/cparser.pyx":678
+ * 
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+      __pyx_t_14 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_14);
+      __pyx_t_11 = (__Pyx_PySequence_Contains(__pyx_t_14, __pyx_v_mask, Py_EQ)); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+      if ((__pyx_t_11 != 0)) {
+        __Pyx_INCREF(__pyx_int_1);
+        __pyx_t_6 = __pyx_int_1;
+      } else {
+        __Pyx_INCREF(__pyx_int_0);
+        __pyx_t_6 = __pyx_int_0;
+      }
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_mask, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_r = ((PyArrayObject *)__pyx_t_4);
+    __pyx_t_4 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":681
+ *                                               range(row)])
+ *         else:
+ *             return col             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _convert_str(self, tokenizer_t *t, int i, int nrows):
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    __pyx_r = __pyx_v_col;
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":627
+ *             return col
+ * 
+ *     cdef np.ndarray _convert_float(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         # very similar to _convert_int()
+ *         cdef int num_rows = t.num_rows
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_float", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_col);
+  __Pyx_XDECREF(__pyx_v_new_value);
+  __Pyx_XDECREF(__pyx_v_mask);
+  __Pyx_XDECREF(__pyx_v_replace_info);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":683
+ *             return col
+ * 
+ *     cdef _convert_str(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         # similar to _convert_int, but no actual conversion
+ *         cdef int num_rows = t.num_rows
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_str(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, tokenizer_t *__pyx_v_t, int __pyx_v_i, int __pyx_v_nrows) {
+  int __pyx_v_num_rows;
+  int __pyx_v_row;
+  PyObject *__pyx_v_field = 0;
+  int __pyx_v_field_len;
+  int __pyx_v_max_len;
+  PyObject *__pyx_v_fields_list = 0;
+  PyObject *__pyx_v_mask = NULL;
+  PyObject *__pyx_v_replace_info = NULL;
+  PyObject *__pyx_v_el = NULL;
+  PyArrayObject *__pyx_v_col = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  int __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_convert_str", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":685
+ *     cdef _convert_str(self, tokenizer_t *t, int i, int nrows):
+ *         # similar to _convert_int, but no actual conversion
+ *         cdef int num_rows = t.num_rows             # <<<<<<<<<<<<<<
+ *         if nrows != -1:
+ *             num_rows = nrows
+ */
+  __pyx_t_1 = __pyx_v_t->num_rows;
+  __pyx_v_num_rows = __pyx_t_1;
+
+  /* "astropy/io/ascii/cparser.pyx":686
+ *         # similar to _convert_int, but no actual conversion
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:             # <<<<<<<<<<<<<<
+ *             num_rows = nrows
+ * 
+ */
+  __pyx_t_2 = ((__pyx_v_nrows != -1) != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":687
+ *         cdef int num_rows = t.num_rows
+ *         if nrows != -1:
+ *             num_rows = nrows             # <<<<<<<<<<<<<<
+ * 
+ *         cdef int row = 0
+ */
+    __pyx_v_num_rows = __pyx_v_nrows;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":689
+ *             num_rows = nrows
+ * 
+ *         cdef int row = 0             # <<<<<<<<<<<<<<
+ *         cdef bytes field
+ *         cdef int field_len
+ */
+  __pyx_v_row = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":692
+ *         cdef bytes field
+ *         cdef int field_len
+ *         cdef int max_len = 0             # <<<<<<<<<<<<<<
+ *         cdef list fields_list = []
+ *         mask = set()
+ */
+  __pyx_v_max_len = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":693
+ *         cdef int field_len
+ *         cdef int max_len = 0
+ *         cdef list fields_list = []             # <<<<<<<<<<<<<<
+ *         mask = set()
+ * 
+ */
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_fields_list = ((PyObject*)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":694
+ *         cdef int max_len = 0
+ *         cdef list fields_list = []
+ *         mask = set()             # <<<<<<<<<<<<<<
+ * 
+ *         start_iteration(t, i)
+ */
+  __pyx_t_3 = PySet_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_mask = ((PyObject*)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":696
+ *         mask = set()
+ * 
+ *         start_iteration(t, i)             # <<<<<<<<<<<<<<
+ *         for row in range(num_rows):
+ *             field = next_field(t, &field_len)
+ */
+  start_iteration(__pyx_v_t, __pyx_v_i);
+
+  /* "astropy/io/ascii/cparser.pyx":697
+ * 
+ *         start_iteration(t, i)
+ *         for row in range(num_rows):             # <<<<<<<<<<<<<<
+ *             field = next_field(t, &field_len)
+ *             replace_info = None
+ */
+  __pyx_t_1 = __pyx_v_num_rows;
+  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_1; __pyx_t_4+=1) {
+    __pyx_v_row = __pyx_t_4;
+
+    /* "astropy/io/ascii/cparser.pyx":698
+ *         start_iteration(t, i)
+ *         for row in range(num_rows):
+ *             field = next_field(t, &field_len)             # <<<<<<<<<<<<<<
+ *             replace_info = None
+ * 
+ */
+    __pyx_t_3 = __Pyx_PyBytes_FromString(next_field(__pyx_v_t, (&__pyx_v_field_len))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_XDECREF_SET(__pyx_v_field, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":699
+ *         for row in range(num_rows):
+ *             field = next_field(t, &field_len)
+ *             replace_info = None             # <<<<<<<<<<<<<<
+ * 
+ *             if field_len == 0 and self.fill_empty:
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_XDECREF_SET(__pyx_v_replace_info, Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":701
+ *             replace_info = None
+ * 
+ *             if field_len == 0 and self.fill_empty:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_empty
+ * 
+ */
+    __pyx_t_5 = ((__pyx_v_field_len == 0) != 0);
+    if (__pyx_t_5) {
+    } else {
+      __pyx_t_2 = __pyx_t_5;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_empty); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_5;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":702
+ * 
+ *             if field_len == 0 and self.fill_empty:
+ *                 replace_info = self.fill_empty             # <<<<<<<<<<<<<<
+ * 
+ *             elif field_len > 0 and self.fill_values and field in self.fill_values:
+ */
+      __pyx_t_3 = __pyx_v_self->fill_empty;
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L6;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":704
+ *                 replace_info = self.fill_empty
+ * 
+ *             elif field_len > 0 and self.fill_values and field in self.fill_values:             # <<<<<<<<<<<<<<
+ *                 replace_info = self.fill_values[field]
+ * 
+ */
+    __pyx_t_5 = ((__pyx_v_field_len > 0) != 0);
+    if (__pyx_t_5) {
+    } else {
+      __pyx_t_2 = __pyx_t_5;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_self->fill_values); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 704; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_5) {
+    } else {
+      __pyx_t_2 = __pyx_t_5;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_v_field, __pyx_v_self->fill_values, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 704; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = (__pyx_t_5 != 0);
+    __pyx_t_2 = __pyx_t_6;
+    __pyx_L9_bool_binop_done:;
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":705
+ * 
+ *             elif field_len > 0 and self.fill_values and field in self.fill_values:
+ *                 replace_info = self.fill_values[field]             # <<<<<<<<<<<<<<
+ * 
+ *             if replace_info is not None:
+ */
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_self->fill_values, __pyx_v_field); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF_SET(__pyx_v_replace_info, __pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "astropy/io/ascii/cparser.pyx":707
+ *                 replace_info = self.fill_values[field]
+ * 
+ *             if replace_info is not None:             # <<<<<<<<<<<<<<
+ *                 el = replace_info[0].encode('ascii')
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ */
+    __pyx_t_2 = (__pyx_v_replace_info != Py_None);
+    __pyx_t_6 = (__pyx_t_2 != 0);
+    if (__pyx_t_6) {
+
+      /* "astropy/io/ascii/cparser.pyx":708
+ * 
+ *             if replace_info is not None:
+ *                 el = replace_info[0].encode('ascii')             # <<<<<<<<<<<<<<
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ */
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_replace_info, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_encode); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_XDECREF_SET(__pyx_v_el, __pyx_t_3);
+      __pyx_t_3 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":709
+ *             if replace_info is not None:
+ *                 el = replace_info[0].encode('ascii')
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+      __pyx_t_8 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((__pyx_t_8 > 1) != 0);
+      if (!__pyx_t_2) {
+        goto __pyx_L15_next_or;
+      } else {
+      }
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_v_replace_info, 1, 0, NULL, NULL, &__pyx_slice__26, 1, 0, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_3, __pyx_t_7, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_5 = (__pyx_t_2 != 0);
+      if (!__pyx_t_5) {
+      } else {
+        __pyx_t_6 = __pyx_t_5;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_L15_next_or:;
+
+      /* "astropy/io/ascii/cparser.pyx":710
+ *                 el = replace_info[0].encode('ascii')
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):             # <<<<<<<<<<<<<<
+ *                     mask.add(row)
+ *                     field = el
+ */
+      __pyx_t_8 = PyObject_Length(__pyx_v_replace_info); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = ((__pyx_t_8 == 1) != 0);
+      if (__pyx_t_5) {
+      } else {
+        __pyx_t_6 = __pyx_t_5;
+        goto __pyx_L14_bool_binop_done;
+      }
+      __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_self->names, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_t_7, __pyx_v_self->fill_names, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_2 = (__pyx_t_5 != 0);
+      __pyx_t_6 = __pyx_t_2;
+      __pyx_L14_bool_binop_done:;
+      if (__pyx_t_6) {
+
+        /* "astropy/io/ascii/cparser.pyx":711
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)             # <<<<<<<<<<<<<<
+ *                     field = el
+ * 
+ */
+        __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_row); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_9 = PySet_Add(__pyx_v_mask, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":712
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ *                     field = el             # <<<<<<<<<<<<<<
+ * 
+ *             fields_list.append(field)
+ */
+        if (!(likely(PyBytes_CheckExact(__pyx_v_el))||((__pyx_v_el) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_el)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __pyx_v_el;
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_DECREF_SET(__pyx_v_field, ((PyObject*)__pyx_t_7));
+        __pyx_t_7 = 0;
+        goto __pyx_L13;
+      }
+      __pyx_L13:;
+      goto __pyx_L12;
+    }
+    __pyx_L12:;
+
+    /* "astropy/io/ascii/cparser.pyx":714
+ *                     field = el
+ * 
+ *             fields_list.append(field)             # <<<<<<<<<<<<<<
+ *             if field_len > max_len:
+ *                 max_len = field_len
+ */
+    __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_fields_list, __pyx_v_field); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "astropy/io/ascii/cparser.pyx":715
+ * 
+ *             fields_list.append(field)
+ *             if field_len > max_len:             # <<<<<<<<<<<<<<
+ *                 max_len = field_len
+ *             row += 1
+ */
+    __pyx_t_6 = ((__pyx_v_field_len > __pyx_v_max_len) != 0);
+    if (__pyx_t_6) {
+
+      /* "astropy/io/ascii/cparser.pyx":716
+ *             fields_list.append(field)
+ *             if field_len > max_len:
+ *                 max_len = field_len             # <<<<<<<<<<<<<<
+ *             row += 1
+ * 
+ */
+      __pyx_v_max_len = __pyx_v_field_len;
+      goto __pyx_L18;
+    }
+    __pyx_L18:;
+
+    /* "astropy/io/ascii/cparser.pyx":717
+ *             if field_len > max_len:
+ *                 max_len = field_len
+ *             row += 1             # <<<<<<<<<<<<<<
+ * 
+ *         cdef np.ndarray col = np.array(fields_list, dtype=(np.str, max_len))
+ */
+    __pyx_v_row = (__pyx_v_row + 1);
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":719
+ *             row += 1
+ * 
+ *         cdef np.ndarray col = np.array(fields_list, dtype=(np.str, max_len))             # <<<<<<<<<<<<<<
+ * 
+ *         if mask:
+ */
+  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_INCREF(__pyx_v_fields_list);
+  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_fields_list);
+  __Pyx_GIVEREF(__pyx_v_fields_list);
+  __pyx_t_10 = PyDict_New(); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_str); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_11 = __Pyx_PyInt_From_int(__pyx_v_max_len); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
+  PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_12);
+  __Pyx_GIVEREF(__pyx_t_12);
+  PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_11);
+  __Pyx_GIVEREF(__pyx_t_11);
+  __pyx_t_12 = 0;
+  __pyx_t_11 = 0;
+  if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_dtype, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, __pyx_t_10); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_col = ((PyArrayObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":721
+ *         cdef np.ndarray col = np.array(fields_list, dtype=(np.str, max_len))
+ * 
+ *         if mask:             # <<<<<<<<<<<<<<
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ *                                               range(row)])
+ */
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_mask); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_6) {
+
+    /* "astropy/io/ascii/cparser.pyx":722
+ * 
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_13 = __Pyx_GetModuleGlobalName(__pyx_n_s_ma); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_masked_array); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_col));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_col));
+    __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+
+    /* "astropy/io/ascii/cparser.pyx":723
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+ *                                               range(row)])             # <<<<<<<<<<<<<<
+ *         else:
+ *             return col
+ */
+    __pyx_t_1 = __pyx_v_row;
+    for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_1; __pyx_t_4+=1) {
+      __pyx_v_i = __pyx_t_4;
+
+      /* "astropy/io/ascii/cparser.pyx":722
+ * 
+ *         if mask:
+ *             return ma.masked_array(col, mask=[1 if i in mask else 0 for i in             # <<<<<<<<<<<<<<
+ *                                               range(row)])
+ *         else:
+ */
+      __pyx_t_12 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __pyx_t_6 = (__Pyx_PySequence_Contains(__pyx_t_12, __pyx_v_mask, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      if ((__pyx_t_6 != 0)) {
+        __Pyx_INCREF(__pyx_int_1);
+        __pyx_t_11 = __pyx_int_1;
+      } else {
+        __Pyx_INCREF(__pyx_int_0);
+        __pyx_t_11 = __pyx_int_0;
+      }
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_11))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    }
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_mask, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_13, __pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_r = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":725
+ *                                               range(row)])
+ *         else:
+ *             return col             # <<<<<<<<<<<<<<
+ * 
+ *     def get_names(self):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_col));
+    __pyx_r = ((PyObject *)__pyx_v_col);
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":683
+ *             return col
+ * 
+ *     cdef _convert_str(self, tokenizer_t *t, int i, int nrows):             # <<<<<<<<<<<<<<
+ *         # similar to _convert_int, but no actual conversion
+ *         cdef int num_rows = t.num_rows
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser._convert_str", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_field);
+  __Pyx_XDECREF(__pyx_v_fields_list);
+  __Pyx_XDECREF(__pyx_v_mask);
+  __Pyx_XDECREF(__pyx_v_replace_info);
+  __Pyx_XDECREF(__pyx_v_el);
+  __Pyx_XDECREF((PyObject *)__pyx_v_col);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":727
+ *             return col
+ * 
+ *     def get_names(self):             # <<<<<<<<<<<<<<
+ *         # ignore excluded columns
+ *         return [name for name in self.names if name in self.use_cols]
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_13get_names(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_13get_names(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_names (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12get_names(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12get_names(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *(*__pyx_t_4)(PyObject *);
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_names", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":729
+ *     def get_names(self):
+ *         # ignore excluded columns
+ *         return [name for name in self.names if name in self.use_cols]             # <<<<<<<<<<<<<<
+ * 
+ *     def set_names(self, names):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (likely(PyList_CheckExact(__pyx_v_self->names)) || PyTuple_CheckExact(__pyx_v_self->names)) {
+    __pyx_t_2 = __pyx_v_self->names; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+    __pyx_t_4 = NULL;
+  } else {
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_self->names); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_4)) {
+      if (likely(PyList_CheckExact(__pyx_t_2))) {
+        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_5);
+    __pyx_t_5 = 0;
+    __pyx_t_6 = (__Pyx_PySequence_Contains(__pyx_v_name, __pyx_v_self->use_cols, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = (__pyx_t_6 != 0);
+    if (__pyx_t_7) {
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_v_name))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":727
+ *             return col
+ * 
+ *     def get_names(self):             # <<<<<<<<<<<<<<
+ *         # ignore excluded columns
+ *         return [name for name in self.names if name in self.use_cols]
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.get_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":731
+ *         return [name for name in self.names if name in self.use_cols]
+ * 
+ *     def set_names(self, names):             # <<<<<<<<<<<<<<
+ *         self.names = names
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_15set_names(PyObject *__pyx_v_self, PyObject *__pyx_v_names); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_15set_names(PyObject *__pyx_v_self, PyObject *__pyx_v_names) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_names (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14set_names(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), ((PyObject *)__pyx_v_names));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_14set_names(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_names) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_names", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":732
+ * 
+ *     def set_names(self, names):
+ *         self.names = names             # <<<<<<<<<<<<<<
+ * 
+ *     def __reduce__(self):
+ */
+  __Pyx_INCREF(__pyx_v_names);
+  __Pyx_GIVEREF(__pyx_v_names);
+  __Pyx_GOTREF(__pyx_v_self->names);
+  __Pyx_DECREF(__pyx_v_self->names);
+  __pyx_v_self->names = __pyx_v_names;
+
+  /* "astropy/io/ascii/cparser.pyx":731
+ *         return [name for name in self.names if name in self.use_cols]
+ * 
+ *     def set_names(self, names):             # <<<<<<<<<<<<<<
+ *         self.names = names
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":734
+ *         self.names = names
+ * 
+ *     def __reduce__(self):             # <<<<<<<<<<<<<<
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_17__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_17__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__reduce__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_16__reduce__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_16__reduce__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_v_source_ptr = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__reduce__", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":735
+ * 
+ *     def __reduce__(self):
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''             # <<<<<<<<<<<<<<
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,
+ */
+  if ((__pyx_v_self->source_ptr != 0)) {
+    __pyx_t_2 = __Pyx_PyBytes_FromString(__pyx_v_self->source_ptr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_t_2 = 0;
+  } else {
+    __Pyx_INCREF(__pyx_kp_b__3);
+    __pyx_t_1 = __pyx_kp_b__3;
+  }
+  __pyx_v_source_ptr = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":736
+ *     def __reduce__(self):
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,             # <<<<<<<<<<<<<<
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,
+ *                                 self.tokenizer.strip_whitespace_fields,
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_copy_cparser); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+
+  /* "astropy/io/ascii/cparser.pyx":737
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,             # <<<<<<<<<<<<<<
+ *                                 self.tokenizer.strip_whitespace_fields,
+ *                                 dict(delimiter=chr(self.tokenizer.delimiter),
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->tokenizer->strip_whitespace_lines); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 737; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+
+  /* "astropy/io/ascii/cparser.pyx":738
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,
+ *                                 self.tokenizer.strip_whitespace_fields,             # <<<<<<<<<<<<<<
+ *                                 dict(delimiter=chr(self.tokenizer.delimiter),
+ *                                 comment=chr(self.tokenizer.comment),
+ */
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_self->tokenizer->strip_whitespace_fields); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+
+  /* "astropy/io/ascii/cparser.pyx":739
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,
+ *                                 self.tokenizer.strip_whitespace_fields,
+ *                                 dict(delimiter=chr(self.tokenizer.delimiter),             # <<<<<<<<<<<<<<
+ *                                 comment=chr(self.tokenizer.comment),
+ *                                 quotechar=chr(self.tokenizer.quotechar),
+ */
+  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyInt_From_char(__pyx_v_self->tokenizer->delimiter); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_delimiter, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":740
+ *                                 self.tokenizer.strip_whitespace_fields,
+ *                                 dict(delimiter=chr(self.tokenizer.delimiter),
+ *                                 comment=chr(self.tokenizer.comment),             # <<<<<<<<<<<<<<
+ *                                 quotechar=chr(self.tokenizer.quotechar),
+ *                                 header_start=self.header_start,
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_char(__pyx_v_self->tokenizer->comment); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_comment, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":741
+ *                                 dict(delimiter=chr(self.tokenizer.delimiter),
+ *                                 comment=chr(self.tokenizer.comment),
+ *                                 quotechar=chr(self.tokenizer.quotechar),             # <<<<<<<<<<<<<<
+ *                                 header_start=self.header_start,
+ *                                 data_start=self.data_start,
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_char(__pyx_v_self->tokenizer->quotechar); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_quotechar, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":742
+ *                                 comment=chr(self.tokenizer.comment),
+ *                                 quotechar=chr(self.tokenizer.quotechar),
+ *                                 header_start=self.header_start,             # <<<<<<<<<<<<<<
+ *                                 data_start=self.data_start,
+ *                                 data_end=self.data_end,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_header_start, __pyx_v_self->header_start) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":743
+ *                                 quotechar=chr(self.tokenizer.quotechar),
+ *                                 header_start=self.header_start,
+ *                                 data_start=self.data_start,             # <<<<<<<<<<<<<<
+ *                                 data_end=self.data_end,
+ *                                 names=self.names,
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_self->data_start); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_data_start, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":744
+ *                                 header_start=self.header_start,
+ *                                 data_start=self.data_start,
+ *                                 data_end=self.data_end,             # <<<<<<<<<<<<<<
+ *                                 names=self.names,
+ *                                 include_names=self.include_names,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_data_end, __pyx_v_self->data_end) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":745
+ *                                 data_start=self.data_start,
+ *                                 data_end=self.data_end,
+ *                                 names=self.names,             # <<<<<<<<<<<<<<
+ *                                 include_names=self.include_names,
+ *                                 exclude_names=self.exclude_names,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_names, __pyx_v_self->names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":746
+ *                                 data_end=self.data_end,
+ *                                 names=self.names,
+ *                                 include_names=self.include_names,             # <<<<<<<<<<<<<<
+ *                                 exclude_names=self.exclude_names,
+ *                                 fill_values=None,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_include_names, __pyx_v_self->include_names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":747
+ *                                 names=self.names,
+ *                                 include_names=self.include_names,
+ *                                 exclude_names=self.exclude_names,             # <<<<<<<<<<<<<<
+ *                                 fill_values=None,
+ *                                 fill_include_names=self.fill_include_names,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_exclude_names, __pyx_v_self->exclude_names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":748
+ *                                 include_names=self.include_names,
+ *                                 exclude_names=self.exclude_names,
+ *                                 fill_values=None,             # <<<<<<<<<<<<<<
+ *                                 fill_include_names=self.fill_include_names,
+ *                                 fill_exclude_names=self.fill_exclude_names,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_fill_values, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":749
+ *                                 exclude_names=self.exclude_names,
+ *                                 fill_values=None,
+ *                                 fill_include_names=self.fill_include_names,             # <<<<<<<<<<<<<<
+ *                                 fill_exclude_names=self.fill_exclude_names,
+ *                                 fill_extra_cols=self.tokenizer.fill_extra_cols,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_fill_include_names, __pyx_v_self->fill_include_names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":750
+ *                                 fill_values=None,
+ *                                 fill_include_names=self.fill_include_names,
+ *                                 fill_exclude_names=self.fill_exclude_names,             # <<<<<<<<<<<<<<
+ *                                 fill_extra_cols=self.tokenizer.fill_extra_cols,
+ *                                 use_fast_converter=self.tokenizer.use_fast_converter,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_fill_exclude_names, __pyx_v_self->fill_exclude_names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":751
+ *                                 fill_include_names=self.fill_include_names,
+ *                                 fill_exclude_names=self.fill_exclude_names,
+ *                                 fill_extra_cols=self.tokenizer.fill_extra_cols,             # <<<<<<<<<<<<<<
+ *                                 use_fast_converter=self.tokenizer.use_fast_converter,
+ *                                 parallel=False)))
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_self->tokenizer->fill_extra_cols); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_fill_extra_cols, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":752
+ *                                 fill_exclude_names=self.fill_exclude_names,
+ *                                 fill_extra_cols=self.tokenizer.fill_extra_cols,
+ *                                 use_fast_converter=self.tokenizer.use_fast_converter,             # <<<<<<<<<<<<<<
+ *                                 parallel=False)))
+ * 
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_self->tokenizer->use_fast_converter); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_use_fast_converter, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":753
+ *                                 fill_extra_cols=self.tokenizer.fill_extra_cols,
+ *                                 use_fast_converter=self.tokenizer.use_fast_converter,
+ *                                 parallel=False)))             # <<<<<<<<<<<<<<
+ * 
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,
+ */
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_parallel, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":736
+ *     def __reduce__(self):
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,             # <<<<<<<<<<<<<<
+ *                                 self.fill_values, self.tokenizer.strip_whitespace_lines,
+ *                                 self.tokenizer.strip_whitespace_fields,
+ */
+  __pyx_t_5 = PyTuple_New(8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_source_ptr);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_source_ptr);
+  __Pyx_GIVEREF(__pyx_v_source_ptr);
+  __Pyx_INCREF(__pyx_v_self->source_bytes);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_self->source_bytes);
+  __Pyx_GIVEREF(__pyx_v_self->source_bytes);
+  __Pyx_INCREF(__pyx_v_self->use_cols);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_self->use_cols);
+  __Pyx_GIVEREF(__pyx_v_self->use_cols);
+  __Pyx_INCREF(__pyx_v_self->fill_names);
+  PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_self->fill_names);
+  __Pyx_GIVEREF(__pyx_v_self->fill_names);
+  __Pyx_INCREF(__pyx_v_self->fill_values);
+  PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_v_self->fill_values);
+  __Pyx_GIVEREF(__pyx_v_self->fill_values);
+  PyTuple_SET_ITEM(__pyx_t_5, 5, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_5, 6, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_5, 7, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_1 = 0;
+  __pyx_t_5 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":734
+ *         self.names = names
+ * 
+ *     def __reduce__(self):             # <<<<<<<<<<<<<<
+ *         cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+ *         return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_source_ptr);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":187
+ * 
+ *     cdef public:
+ *         int width             # <<<<<<<<<<<<<<
+ *         object source
+ *         object header_start
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width___get__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->width); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.width.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width_2__set__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_5width_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->width = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.CParser.width.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":188
+ *     cdef public:
+ *         int width
+ *         object source             # <<<<<<<<<<<<<<
+ *         object header_start
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source___get__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->source);
+  __pyx_r = __pyx_v_self->source;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_2__set__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->source);
+  __Pyx_DECREF(__pyx_v_self->source);
+  __pyx_v_self->source = __pyx_v_value;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_4__del__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_6source_4__del__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->source);
+  __Pyx_DECREF(__pyx_v_self->source);
+  __pyx_v_self->source = Py_None;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":189
+ *         int width
+ *         object source
+ *         object header_start             # <<<<<<<<<<<<<<
+ * 
+ *     def __cinit__(self, source, strip_line_whitespace, strip_line_fields,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start___get__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start___get__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->header_start);
+  __pyx_r = __pyx_v_self->header_start;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_2__set__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_2__set__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->header_start);
+  __Pyx_DECREF(__pyx_v_self->header_start);
+  __pyx_v_self->header_start = __pyx_v_value;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_4__del__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_7CParser_12header_start_4__del__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->header_start);
+  __Pyx_DECREF(__pyx_v_self->header_start);
+  __pyx_v_self->header_start = Py_None;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":755
+ *                                 parallel=False)))
+ * 
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,             # <<<<<<<<<<<<<<
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_1_copy_cparser(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_1_copy_cparser = {"_copy_cparser", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_1_copy_cparser, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_1_copy_cparser(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_src_ptr = 0;
+  PyObject *__pyx_v_source_bytes = 0;
+  PyObject *__pyx_v_use_cols = 0;
+  PyObject *__pyx_v_fill_names = 0;
+  PyObject *__pyx_v_fill_values = 0;
+  PyObject *__pyx_v_strip_whitespace_lines = 0;
+  PyObject *__pyx_v_strip_whitespace_fields = 0;
+  PyObject *__pyx_v_kwargs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_copy_cparser (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_src_ptr,&__pyx_n_s_source_bytes,&__pyx_n_s_use_cols,&__pyx_n_s_fill_names,&__pyx_n_s_fill_values,&__pyx_n_s_strip_whitespace_lines,&__pyx_n_s_strip_whitespace_fields,&__pyx_n_s_kwargs,0};
+    PyObject* values[8] = {0,0,0,0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_src_ptr)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_source_bytes)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_use_cols)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_names)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_values)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strip_whitespace_lines)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strip_whitespace_fields)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  7:
+        if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kwargs)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_copy_cparser") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+      values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+    }
+    __pyx_v_src_ptr = ((PyObject*)values[0]);
+    __pyx_v_source_bytes = ((PyObject*)values[1]);
+    __pyx_v_use_cols = values[2];
+    __pyx_v_fill_names = values[3];
+    __pyx_v_fill_values = values[4];
+    __pyx_v_strip_whitespace_lines = values[5];
+    __pyx_v_strip_whitespace_fields = values[6];
+    __pyx_v_kwargs = values[7];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_copy_cparser", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser._copy_cparser", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_src_ptr), (&PyBytes_Type), 1, "src_ptr", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_source_bytes), (&PyBytes_Type), 1, "source_bytes", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser__copy_cparser(__pyx_self, __pyx_v_src_ptr, __pyx_v_source_bytes, __pyx_v_use_cols, __pyx_v_fill_names, __pyx_v_fill_values, __pyx_v_strip_whitespace_lines, __pyx_v_strip_whitespace_fields, __pyx_v_kwargs);
+
+  /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser__copy_cparser(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_src_ptr, PyObject *__pyx_v_source_bytes, PyObject *__pyx_v_use_cols, PyObject *__pyx_v_fill_names, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_strip_whitespace_lines, PyObject *__pyx_v_strip_whitespace_fields, PyObject *__pyx_v_kwargs) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_parser = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  char *__pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_copy_cparser", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":757
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)             # <<<<<<<<<<<<<<
+ *     parser.use_cols = use_cols
+ *     parser.fill_names = fill_names
+ */
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_INCREF(__pyx_v_strip_whitespace_lines);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_strip_whitespace_lines);
+  __Pyx_GIVEREF(__pyx_v_strip_whitespace_lines);
+  __Pyx_INCREF(__pyx_v_strip_whitespace_fields);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_strip_whitespace_fields);
+  __Pyx_GIVEREF(__pyx_v_strip_whitespace_fields);
+  if (unlikely(__pyx_v_kwargs == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "argument after ** must be a mapping, not NoneType");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  if (likely(PyDict_Check(__pyx_v_kwargs))) {
+    __pyx_t_2 = __pyx_v_kwargs;
+    __Pyx_INCREF(__pyx_t_2);
+  } else {
+    __pyx_t_2 = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, __pyx_v_kwargs, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+  }
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_7astropy_2io_5ascii_7cparser_CParser)), __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_parser = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":758
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ *     parser.use_cols = use_cols             # <<<<<<<<<<<<<<
+ *     parser.fill_names = fill_names
+ *     parser.fill_values = fill_values
+ */
+  if (!(likely(PySet_CheckExact(__pyx_v_use_cols))||((__pyx_v_use_cols) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "set", Py_TYPE(__pyx_v_use_cols)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __pyx_v_use_cols;
+  __Pyx_INCREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_parser->use_cols);
+  __Pyx_DECREF(__pyx_v_parser->use_cols);
+  __pyx_v_parser->use_cols = ((PyObject*)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":759
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ *     parser.use_cols = use_cols
+ *     parser.fill_names = fill_names             # <<<<<<<<<<<<<<
+ *     parser.fill_values = fill_values
+ * 
+ */
+  __Pyx_INCREF(__pyx_v_fill_names);
+  __Pyx_GIVEREF(__pyx_v_fill_names);
+  __Pyx_GOTREF(__pyx_v_parser->fill_names);
+  __Pyx_DECREF(__pyx_v_parser->fill_names);
+  __pyx_v_parser->fill_names = __pyx_v_fill_names;
+
+  /* "astropy/io/ascii/cparser.pyx":760
+ *     parser.use_cols = use_cols
+ *     parser.fill_names = fill_names
+ *     parser.fill_values = fill_values             # <<<<<<<<<<<<<<
+ * 
+ *     if src_ptr:
+ */
+  __Pyx_INCREF(__pyx_v_fill_values);
+  __Pyx_GIVEREF(__pyx_v_fill_values);
+  __Pyx_GOTREF(__pyx_v_parser->fill_values);
+  __Pyx_DECREF(__pyx_v_parser->fill_values);
+  __pyx_v_parser->fill_values = __pyx_v_fill_values;
+
+  /* "astropy/io/ascii/cparser.pyx":762
+ *     parser.fill_values = fill_values
+ * 
+ *     if src_ptr:             # <<<<<<<<<<<<<<
+ *         parser.tokenizer.source = src_ptr
+ *     else:
+ */
+  __pyx_t_4 = (__pyx_v_src_ptr != Py_None) && (PyBytes_GET_SIZE(__pyx_v_src_ptr) != 0);
+  if (__pyx_t_4) {
+
+    /* "astropy/io/ascii/cparser.pyx":763
+ * 
+ *     if src_ptr:
+ *         parser.tokenizer.source = src_ptr             # <<<<<<<<<<<<<<
+ *     else:
+ *         parser.tokenizer.source = source_bytes
+ */
+    __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_src_ptr); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 763; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_parser->tokenizer->source = __pyx_t_5;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":765
+ *         parser.tokenizer.source = src_ptr
+ *     else:
+ *         parser.tokenizer.source = source_bytes             # <<<<<<<<<<<<<<
+ *     return parser
+ * 
+ */
+    __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_source_bytes); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_parser->tokenizer->source = __pyx_t_5;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":766
+ *     else:
+ *         parser.tokenizer.source = source_bytes
+ *     return parser             # <<<<<<<<<<<<<<
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_parser));
+  __pyx_r = ((PyObject *)__pyx_v_parser);
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":755
+ *                                 parallel=False)))
+ * 
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,             # <<<<<<<<<<<<<<
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser._copy_cparser", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_parser);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_3_read_chunk(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_3_read_chunk = {"_read_chunk", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_3_read_chunk, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_3_read_chunk(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self = 0;
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_end = 0;
+  PyObject *__pyx_v_try_int = 0;
+  PyObject *__pyx_v_try_float = 0;
+  PyObject *__pyx_v_try_string = 0;
+  PyObject *__pyx_v_queue = 0;
+  PyObject *__pyx_v_reconvert_queue = 0;
+  PyObject *__pyx_v_i = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_read_chunk (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_try_int,&__pyx_n_s_try_float,&__pyx_n_s_try_string,&__pyx_n_s_queue,&__pyx_n_s_reconvert_queue,&__pyx_n_s_i,0};
+    PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_int)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_float)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_try_string)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_queue)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  7:
+        if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_reconvert_queue)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  8:
+        if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_read_chunk") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+      values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+      values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+    }
+    __pyx_v_self = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)values[0]);
+    __pyx_v_start = values[1];
+    __pyx_v_end = values[2];
+    __pyx_v_try_int = values[3];
+    __pyx_v_try_float = values[4];
+    __pyx_v_try_string = values[5];
+    __pyx_v_queue = values[6];
+    __pyx_v_reconvert_queue = values[7];
+    __pyx_v_i = values[8];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_read_chunk", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser._read_chunk", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_self), __pyx_ptype_7astropy_2io_5ascii_7cparser_CParser, 1, "self", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_2_read_chunk(__pyx_self, __pyx_v_self, __pyx_v_start, __pyx_v_end, __pyx_v_try_int, __pyx_v_try_float, __pyx_v_try_string, __pyx_v_queue, __pyx_v_reconvert_queue, __pyx_v_i);
+
+  /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_11_read_chunk_2generator4(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "astropy/io/ascii/cparser.pyx":781
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())             # <<<<<<<<<<<<<<
+ *         line_comments = self._get_comments(chunk_tokenizer)
+ *     else:
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_11_read_chunk_genexpr(PyObject *__pyx_self) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *__pyx_cur_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("genexpr", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *) __pyx_self;
+  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
+  {
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_7astropy_2io_5ascii_7cparser_11_read_chunk_2generator4, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_read_chunk_locals_genexpr); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_cur_scope);
+    __Pyx_RefNannyFinishContext();
+    return (PyObject *) gen;
+  }
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser._read_chunk.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_gb_7astropy_2io_5ascii_7cparser_11_read_chunk_2generator4(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)__pyx_generator->closure);
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *(*__pyx_t_5)(PyObject *);
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("None", 0);
+  switch (__pyx_generator->resume_label) {
+    case 0: goto __pyx_L3_first_run;
+    case 1: goto __pyx_L6_resume_from_yield;
+    default: /* CPython raises the right error here */
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __pyx_L3_first_run:;
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self), __pyx_n_s_get_names); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+    __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_4 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_5)) {
+      if (likely(PyList_CheckExact(__pyx_t_2))) {
+        if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_1 = __pyx_t_5(__pyx_t_2);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name);
+    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = NULL;
+    __pyx_t_9 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_6, function);
+        __pyx_t_9 = 1;
+      }
+    }
+    __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    if (__pyx_t_7) {
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    __pyx_t_3 = 0;
+    __pyx_t_8 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_cur_scope->__pyx_v_name);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_name);
+    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_r = __pyx_t_6;
+    __pyx_t_6 = 0;
+    __Pyx_XGIVEREF(__pyx_t_2);
+    __pyx_cur_scope->__pyx_t_0 = __pyx_t_2;
+    __pyx_cur_scope->__pyx_t_1 = __pyx_t_4;
+    __pyx_cur_scope->__pyx_t_2 = __pyx_t_5;
+    __Pyx_XGIVEREF(__pyx_r);
+    __Pyx_RefNannyFinishContext();
+    /* return from generator, yielding value */
+    __pyx_generator->resume_label = 1;
+    return __pyx_r;
+    __pyx_L6_resume_from_yield:;
+    __pyx_t_2 = __pyx_cur_scope->__pyx_t_0;
+    __pyx_cur_scope->__pyx_t_0 = 0;
+    __Pyx_XGOTREF(__pyx_t_2);
+    __pyx_t_4 = __pyx_cur_scope->__pyx_t_1;
+    __pyx_t_5 = __pyx_cur_scope->__pyx_t_2;
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* function exit code */
+  PyErr_SetNone(PyExc_StopIteration);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_generator->resume_label = -1;
+  __Pyx_Generator_clear((PyObject*)__pyx_generator);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+}
+
+/* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_2_read_chunk(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end, PyObject *__pyx_v_try_int, PyObject *__pyx_v_try_float, PyObject *__pyx_v_try_string, PyObject *__pyx_v_queue, PyObject *__pyx_v_reconvert_queue, PyObject *__pyx_v_i) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *__pyx_cur_scope;
+  tokenizer_t *__pyx_v_chunk_tokenizer;
+  PyObject *__pyx_v_data = NULL;
+  PyObject *__pyx_v_err = NULL;
+  PyObject *__pyx_v_line_comments = NULL;
+  PyObject *__pyx_v_e = NULL;
+  PyObject *__pyx_v_reconvert_cols = NULL;
+  PyObject *__pyx_v_col = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  tokenizer_t *__pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *(*__pyx_t_12)(PyObject *);
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  PyObject *__pyx_t_16 = NULL;
+  PyObject *(*__pyx_t_17)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_read_chunk", 0);
+  __pyx_cur_scope = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(__pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+  __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+  __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+
+  /* "astropy/io/ascii/cparser.pyx":770
+ * def _read_chunk(CParser self, start, end, try_int,
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer             # <<<<<<<<<<<<<<
+ *     chunk_tokenizer.source_len = end
+ *     chunk_tokenizer.source_pos = start
+ */
+  __pyx_t_1 = __pyx_cur_scope->__pyx_v_self->tokenizer;
+  __pyx_v_chunk_tokenizer = __pyx_t_1;
+
+  /* "astropy/io/ascii/cparser.pyx":771
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ *     chunk_tokenizer.source_len = end             # <<<<<<<<<<<<<<
+ *     chunk_tokenizer.source_pos = start
+ *     reset_comments(chunk_tokenizer)
+ */
+  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_end); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_chunk_tokenizer->source_len = __pyx_t_2;
+
+  /* "astropy/io/ascii/cparser.pyx":772
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ *     chunk_tokenizer.source_len = end
+ *     chunk_tokenizer.source_pos = start             # <<<<<<<<<<<<<<
+ *     reset_comments(chunk_tokenizer)
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_chunk_tokenizer->source_pos = __pyx_t_2;
+
+  /* "astropy/io/ascii/cparser.pyx":773
+ *     chunk_tokenizer.source_len = end
+ *     chunk_tokenizer.source_pos = start
+ *     reset_comments(chunk_tokenizer)             # <<<<<<<<<<<<<<
+ * 
+ *     data = None
+ */
+  reset_comments(__pyx_v_chunk_tokenizer);
+
+  /* "astropy/io/ascii/cparser.pyx":775
+ *     reset_comments(chunk_tokenizer)
+ * 
+ *     data = None             # <<<<<<<<<<<<<<
+ *     err = None
+ * 
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_data = Py_None;
+
+  /* "astropy/io/ascii/cparser.pyx":776
+ * 
+ *     data = None
+ *     err = None             # <<<<<<<<<<<<<<
+ * 
+ *     if tokenize(chunk_tokenizer, -1, 0, len(self.names)) != 0:
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_err = Py_None;
+
+  /* "astropy/io/ascii/cparser.pyx":778
+ *     err = None
+ * 
+ *     if tokenize(chunk_tokenizer, -1, 0, len(self.names)) != 0:             # <<<<<<<<<<<<<<
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ */
+  __pyx_t_3 = __pyx_cur_scope->__pyx_v_self->names;
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = ((tokenize(__pyx_v_chunk_tokenizer, -1, 0, __pyx_t_4) != 0) != 0);
+  if (__pyx_t_5) {
+
+    /* "astropy/io/ascii/cparser.pyx":779
+ * 
+ *     if tokenize(chunk_tokenizer, -1, 0, len(self.names)) != 0:
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)             # <<<<<<<<<<<<<<
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())
+ */
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_chunk_tokenizer->code); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_chunk_tokenizer->num_rows); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_3 = 0;
+    __pyx_t_6 = 0;
+    __Pyx_DECREF_SET(__pyx_v_err, __pyx_t_7);
+    __pyx_t_7 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":780
+ *     if tokenize(chunk_tokenizer, -1, 0, len(self.names)) != 0:
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+ *     if chunk_tokenizer.num_rows == 0: # no data             # <<<<<<<<<<<<<<
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())
+ *         line_comments = self._get_comments(chunk_tokenizer)
+ */
+  __pyx_t_5 = ((__pyx_v_chunk_tokenizer->num_rows == 0) != 0);
+  if (__pyx_t_5) {
+
+    /* "astropy/io/ascii/cparser.pyx":781
+ *         err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())             # <<<<<<<<<<<<<<
+ *         line_comments = self._get_comments(chunk_tokenizer)
+ *     else:
+ */
+    __pyx_t_7 = __pyx_pf_7astropy_2io_5ascii_7cparser_11_read_chunk_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_7 = 0;
+    __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_6, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_7);
+    __pyx_t_7 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":782
+ *     if chunk_tokenizer.num_rows == 0: # no data
+ *         data = dict((name, np.array([], np.int_)) for name in self.get_names())
+ *         line_comments = self._get_comments(chunk_tokenizer)             # <<<<<<<<<<<<<<
+ *     else:
+ *         try:
+ */
+    __pyx_t_7 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->_get_comments(__pyx_cur_scope->__pyx_v_self, __pyx_v_chunk_tokenizer); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_v_line_comments = __pyx_t_7;
+    __pyx_t_7 = 0;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":784
+ *         line_comments = self._get_comments(chunk_tokenizer)
+ *     else:
+ *         try:             # <<<<<<<<<<<<<<
+ *             data, line_comments = self._convert_data(chunk_tokenizer,
+ *                                       try_int, try_float, try_string, -1)
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10);
+      __Pyx_XGOTREF(__pyx_t_8);
+      __Pyx_XGOTREF(__pyx_t_9);
+      __Pyx_XGOTREF(__pyx_t_10);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":785
+ *     else:
+ *         try:
+ *             data, line_comments = self._convert_data(chunk_tokenizer,             # <<<<<<<<<<<<<<
+ *                                       try_int, try_float, try_string, -1)
+ *         except Exception as e:
+ */
+        __pyx_t_7 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->_convert_data(__pyx_cur_scope->__pyx_v_self, __pyx_v_chunk_tokenizer, __pyx_v_try_int, __pyx_v_try_float, __pyx_v_try_string, __pyx_int_neg_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) {
+          PyObject* sequence = __pyx_t_7;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          Py_ssize_t size = Py_SIZE(sequence);
+          #else
+          Py_ssize_t size = PySequence_Size(sequence);
+          #endif
+          if (unlikely(size != 2)) {
+            if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+            else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          }
+          #if CYTHON_COMPILING_IN_CPYTHON
+          if (likely(PyTuple_CheckExact(sequence))) {
+            __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); 
+            __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); 
+          } else {
+            __pyx_t_6 = PyList_GET_ITEM(sequence, 0); 
+            __pyx_t_3 = PyList_GET_ITEM(sequence, 1); 
+          }
+          __Pyx_INCREF(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_3);
+          #else
+          __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          __Pyx_GOTREF(__pyx_t_3);
+          #endif
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        } else {
+          Py_ssize_t index = -1;
+          __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+          __pyx_t_12 = Py_TYPE(__pyx_t_11)->tp_iternext;
+          index = 0; __pyx_t_6 = __pyx_t_12(__pyx_t_11); if (unlikely(!__pyx_t_6)) goto __pyx_L13_unpacking_failed;
+          __Pyx_GOTREF(__pyx_t_6);
+          index = 1; __pyx_t_3 = __pyx_t_12(__pyx_t_11); if (unlikely(!__pyx_t_3)) goto __pyx_L13_unpacking_failed;
+          __Pyx_GOTREF(__pyx_t_3);
+          if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_11), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          __pyx_t_12 = NULL;
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          goto __pyx_L14_unpacking_done;
+          __pyx_L13_unpacking_failed:;
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __pyx_t_12 = NULL;
+          if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+          __pyx_L14_unpacking_done:;
+        }
+        __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_6);
+        __pyx_t_6 = 0;
+        __pyx_v_line_comments = __pyx_t_3;
+        __pyx_t_3 = 0;
+      }
+      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L12_try_end;
+      __pyx_L5_error:;
+      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":787
+ *             data, line_comments = self._convert_data(chunk_tokenizer,
+ *                                       try_int, try_float, try_string, -1)
+ *         except Exception as e:             # <<<<<<<<<<<<<<
+ *             delete_tokenizer(chunk_tokenizer)
+ *             queue.put((None, e, i))
+ */
+      __pyx_t_2 = PyErr_ExceptionMatches(__pyx_builtin_Exception);
+      if (__pyx_t_2) {
+        __Pyx_AddTraceback("astropy.io.ascii.cparser._read_chunk", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_3, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_3);
+        __pyx_v_e = __pyx_t_3;
+
+        /* "astropy/io/ascii/cparser.pyx":788
+ *                                       try_int, try_float, try_string, -1)
+ *         except Exception as e:
+ *             delete_tokenizer(chunk_tokenizer)             # <<<<<<<<<<<<<<
+ *             queue.put((None, e, i))
+ *             return
+ */
+        delete_tokenizer(__pyx_v_chunk_tokenizer);
+
+        /* "astropy/io/ascii/cparser.pyx":789
+ *         except Exception as e:
+ *             delete_tokenizer(chunk_tokenizer)
+ *             queue.put((None, e, i))             # <<<<<<<<<<<<<<
+ *             return
+ * 
+ */
+        __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(3); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_INCREF(Py_None);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, Py_None);
+        __Pyx_GIVEREF(Py_None);
+        __Pyx_INCREF(__pyx_v_e);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_v_e);
+        __Pyx_GIVEREF(__pyx_v_e);
+        __Pyx_INCREF(__pyx_v_i);
+        PyTuple_SET_ITEM(__pyx_t_14, 2, __pyx_v_i);
+        __Pyx_GIVEREF(__pyx_v_i);
+        __pyx_t_15 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_13))) {
+          __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_13);
+          if (likely(__pyx_t_15)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13);
+            __Pyx_INCREF(__pyx_t_15);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_13, function);
+          }
+        }
+        if (!__pyx_t_15) {
+          __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_14); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+          __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+          __Pyx_GOTREF(__pyx_t_11);
+        } else {
+          __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+          __Pyx_GOTREF(__pyx_t_16);
+          PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_15); __Pyx_GIVEREF(__pyx_t_15); __pyx_t_15 = NULL;
+          PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_14);
+          __Pyx_GIVEREF(__pyx_t_14);
+          __pyx_t_14 = 0;
+          __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+        }
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":790
+ *             delete_tokenizer(chunk_tokenizer)
+ *             queue.put((None, e, i))
+ *             return             # <<<<<<<<<<<<<<
+ * 
+ *     try:
+ */
+        __Pyx_XDECREF(__pyx_r);
+        __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        goto __pyx_L8_except_return;
+      }
+      goto __pyx_L7_except_error;
+      __pyx_L7_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_9);
+      __Pyx_XGIVEREF(__pyx_t_10);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10);
+      goto __pyx_L1_error;
+      __pyx_L8_except_return:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_9);
+      __Pyx_XGIVEREF(__pyx_t_10);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10);
+      goto __pyx_L0;
+      __pyx_L12_try_end:;
+    }
+  }
+  __pyx_L4:;
+
+  /* "astropy/io/ascii/cparser.pyx":792
+ *             return
+ * 
+ *     try:             # <<<<<<<<<<<<<<
+ *         queue.put(((line_comments, data), err, i))
+ *     except Queue.Full as e:
+ */
+  {
+    __Pyx_ExceptionSave(&__pyx_t_10, &__pyx_t_9, &__pyx_t_8);
+    __Pyx_XGOTREF(__pyx_t_10);
+    __Pyx_XGOTREF(__pyx_t_9);
+    __Pyx_XGOTREF(__pyx_t_8);
+    /*try:*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":793
+ * 
+ *     try:
+ *         queue.put(((line_comments, data), err, i))             # <<<<<<<<<<<<<<
+ *     except Queue.Full as e:
+ *         # hopefully this shouldn't happen
+ */
+      __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_v_line_comments);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_line_comments);
+      __Pyx_GIVEREF(__pyx_v_line_comments);
+      __Pyx_INCREF(__pyx_v_data);
+      PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_data);
+      __Pyx_GIVEREF(__pyx_v_data);
+      __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+      __Pyx_GIVEREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_v_err);
+      PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_err);
+      __Pyx_GIVEREF(__pyx_v_err);
+      __Pyx_INCREF(__pyx_v_i);
+      PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_v_i);
+      __Pyx_GIVEREF(__pyx_v_i);
+      __pyx_t_7 = 0;
+      __pyx_t_7 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+        }
+      }
+      if (!__pyx_t_7) {
+        __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_11); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __Pyx_GOTREF(__pyx_t_6);
+      } else {
+        __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+        PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_t_11);
+        __Pyx_GIVEREF(__pyx_t_11);
+        __pyx_t_11 = 0;
+        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_13, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+    goto __pyx_L24_try_end;
+    __pyx_L17_error:;
+    __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+    __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+    __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":794
+ *     try:
+ *         queue.put(((line_comments, data), err, i))
+ *     except Queue.Full as e:             # <<<<<<<<<<<<<<
+ *         # hopefully this shouldn't happen
+ *         delete_tokenizer(chunk_tokenizer)
+ */
+    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_Queue); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_Full); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_2 = PyErr_ExceptionMatches(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (__pyx_t_2) {
+      __Pyx_AddTraceback("astropy.io.ascii.cparser._read_chunk", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_6, &__pyx_t_13) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_GOTREF(__pyx_t_13);
+      __Pyx_INCREF(__pyx_t_6);
+      __pyx_v_e = __pyx_t_6;
+
+      /* "astropy/io/ascii/cparser.pyx":796
+ *     except Queue.Full as e:
+ *         # hopefully this shouldn't happen
+ *         delete_tokenizer(chunk_tokenizer)             # <<<<<<<<<<<<<<
+ *         queue.pop()
+ *         queue.put((None, e, i))
+ */
+      delete_tokenizer(__pyx_v_chunk_tokenizer);
+
+      /* "astropy/io/ascii/cparser.pyx":797
+ *         # hopefully this shouldn't happen
+ *         delete_tokenizer(chunk_tokenizer)
+ *         queue.pop()             # <<<<<<<<<<<<<<
+ *         queue.put((None, e, i))
+ *     reconvert_cols = reconvert_queue.get()
+ */
+      __pyx_t_11 = __Pyx_PyObject_Pop(__pyx_v_queue); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":798
+ *         delete_tokenizer(chunk_tokenizer)
+ *         queue.pop()
+ *         queue.put((None, e, i))             # <<<<<<<<<<<<<<
+ *     reconvert_cols = reconvert_queue.get()
+ *     for col in reconvert_cols:
+ */
+      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_16 = PyTuple_New(3); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+      __Pyx_GOTREF(__pyx_t_16);
+      __Pyx_INCREF(Py_None);
+      PyTuple_SET_ITEM(__pyx_t_16, 0, Py_None);
+      __Pyx_GIVEREF(Py_None);
+      __Pyx_INCREF(__pyx_v_e);
+      PyTuple_SET_ITEM(__pyx_t_16, 1, __pyx_v_e);
+      __Pyx_GIVEREF(__pyx_v_e);
+      __Pyx_INCREF(__pyx_v_i);
+      PyTuple_SET_ITEM(__pyx_t_16, 2, __pyx_v_i);
+      __Pyx_GIVEREF(__pyx_v_i);
+      __pyx_t_14 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+        __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_7);
+        if (likely(__pyx_t_14)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_14);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_7, function);
+        }
+      }
+      if (!__pyx_t_14) {
+        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_16); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+        __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+        __Pyx_GOTREF(__pyx_t_11);
+      } else {
+        __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+        __Pyx_GOTREF(__pyx_t_15);
+        PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_14); __Pyx_GIVEREF(__pyx_t_14); __pyx_t_14 = NULL;
+        PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_16);
+        __Pyx_GIVEREF(__pyx_t_16);
+        __pyx_t_16 = 0;
+        __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_15, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+      goto __pyx_L18_exception_handled;
+    }
+    goto __pyx_L19_except_error;
+    __pyx_L19_except_error:;
+    __Pyx_XGIVEREF(__pyx_t_10);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_XGIVEREF(__pyx_t_8);
+    __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_9, __pyx_t_8);
+    goto __pyx_L1_error;
+    __pyx_L18_exception_handled:;
+    __Pyx_XGIVEREF(__pyx_t_10);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_XGIVEREF(__pyx_t_8);
+    __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_9, __pyx_t_8);
+    __pyx_L24_try_end:;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":799
+ *         queue.pop()
+ *         queue.put((None, e, i))
+ *     reconvert_cols = reconvert_queue.get()             # <<<<<<<<<<<<<<
+ *     for col in reconvert_cols:
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+ */
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_reconvert_queue, __pyx_n_s_get); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  if (__pyx_t_3) {
+    __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  } else {
+    __pyx_t_13 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_13);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_v_reconvert_cols = __pyx_t_13;
+  __pyx_t_13 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":800
+ *         queue.put((None, e, i))
+ *     reconvert_cols = reconvert_queue.get()
+ *     for col in reconvert_cols:             # <<<<<<<<<<<<<<
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+ *     delete_tokenizer(chunk_tokenizer)
+ */
+  if (likely(PyList_CheckExact(__pyx_v_reconvert_cols)) || PyTuple_CheckExact(__pyx_v_reconvert_cols)) {
+    __pyx_t_13 = __pyx_v_reconvert_cols; __Pyx_INCREF(__pyx_t_13); __pyx_t_4 = 0;
+    __pyx_t_17 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_13 = PyObject_GetIter(__pyx_v_reconvert_cols); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_17 = Py_TYPE(__pyx_t_13)->tp_iternext; if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_17)) {
+      if (likely(PyList_CheckExact(__pyx_t_13))) {
+        if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_13)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_13, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_13)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_13, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_13, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_6 = __pyx_t_17(__pyx_t_13);
+      if (unlikely(!__pyx_t_6)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_6);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_6);
+    __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":801
+ *     reconvert_cols = reconvert_queue.get()
+ *     for col in reconvert_cols:
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))             # <<<<<<<<<<<<<<
+ *     delete_tokenizer(chunk_tokenizer)
+ *     reconvert_queue.put(reconvert_cols) # return to the queue for other processes
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_col); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->_convert_str(__pyx_cur_scope->__pyx_v_self, __pyx_v_chunk_tokenizer, __pyx_t_2, -1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_11);
+    __Pyx_GIVEREF(__pyx_t_11);
+    __Pyx_INCREF(__pyx_v_i);
+    PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_i);
+    __Pyx_GIVEREF(__pyx_v_i);
+    __Pyx_INCREF(__pyx_v_col);
+    PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_v_col);
+    __Pyx_GIVEREF(__pyx_v_col);
+    __pyx_t_11 = 0;
+    __pyx_t_11 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_11)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_11);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_11) {
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_GOTREF(__pyx_t_6);
+    } else {
+      __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_15);
+      PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
+      PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_7);
+      __Pyx_GIVEREF(__pyx_t_7);
+      __pyx_t_7 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_15, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":800
+ *         queue.put((None, e, i))
+ *     reconvert_cols = reconvert_queue.get()
+ *     for col in reconvert_cols:             # <<<<<<<<<<<<<<
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+ *     delete_tokenizer(chunk_tokenizer)
+ */
+  }
+  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":802
+ *     for col in reconvert_cols:
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+ *     delete_tokenizer(chunk_tokenizer)             # <<<<<<<<<<<<<<
+ *     reconvert_queue.put(reconvert_cols) # return to the queue for other processes
+ * 
+ */
+  delete_tokenizer(__pyx_v_chunk_tokenizer);
+
+  /* "astropy/io/ascii/cparser.pyx":803
+ *         queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+ *     delete_tokenizer(chunk_tokenizer)
+ *     reconvert_queue.put(reconvert_cols) # return to the queue for other processes             # <<<<<<<<<<<<<<
+ * 
+ * cdef class FastWriter:
+ */
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_reconvert_queue, __pyx_n_s_put); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_reconvert_cols); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+  } else {
+    __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_15);
+    PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_reconvert_cols);
+    PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_v_reconvert_cols);
+    __Pyx_GIVEREF(__pyx_v_reconvert_cols);
+    __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_15, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_XDECREF(__pyx_t_15);
+  __Pyx_XDECREF(__pyx_t_16);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser._read_chunk", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_data);
+  __Pyx_XDECREF(__pyx_v_err);
+  __Pyx_XDECREF(__pyx_v_line_comments);
+  __Pyx_XDECREF(__pyx_v_e);
+  __Pyx_XDECREF(__pyx_v_reconvert_cols);
+  __Pyx_XDECREF(__pyx_v_col);
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":826
+ *         object comment
+ * 
+ *     def __cinit__(self, table,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment='# ',
+ */
+
+/* Python wrapper */
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_table = 0;
+  PyObject *__pyx_v_delimiter = 0;
+  PyObject *__pyx_v_comment = 0;
+  PyObject *__pyx_v_quotechar = 0;
+  PyObject *__pyx_v_formats = 0;
+  PyObject *__pyx_v_strip_whitespace = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_names = 0;
+  PyObject *__pyx_v_include_names = 0;
+  PyObject *__pyx_v_exclude_names = 0;
+  PyObject *__pyx_v_fill_values = 0;
+  PyObject *__pyx_v_fill_include_names = 0;
+  PyObject *__pyx_v_fill_exclude_names = 0;
+  PyObject *__pyx_v_fast_writer = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_table,&__pyx_n_s_delimiter,&__pyx_n_s_comment,&__pyx_n_s_quotechar,&__pyx_n_s_formats,&__pyx_n_s_strip_whitespace,&__pyx_n_s_names,&__pyx_n_s_include_names,&__pyx_n_s_exclude_names,&__pyx_n_s_fill_values,&__pyx_n_s_fill_include_names,&__pyx_n_s_fill_exclude_names,&__pyx_n_s_fast_writer,0};
+    PyObject* values[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
+    values[1] = ((PyObject *)__pyx_kp_s_);
+    values[2] = ((PyObject *)__pyx_kp_s__27);
+    values[3] = ((PyObject *)__pyx_kp_s__2);
+
+    /* "astropy/io/ascii/cparser.pyx":830
+ *                   comment='# ',
+ *                   quotechar='"',
+ *                   formats=None,             # <<<<<<<<<<<<<<
+ *                   strip_whitespace=True,
+ *                   names=None, # ignore, already used in _get_writer
+ */
+    values[4] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":831
+ *                   quotechar='"',
+ *                   formats=None,
+ *                   strip_whitespace=True,             # <<<<<<<<<<<<<<
+ *                   names=None, # ignore, already used in _get_writer
+ *                   include_names=None,
+ */
+    values[5] = ((PyObject *)Py_True);
+
+    /* "astropy/io/ascii/cparser.pyx":832
+ *                   formats=None,
+ *                   strip_whitespace=True,
+ *                   names=None, # ignore, already used in _get_writer             # <<<<<<<<<<<<<<
+ *                   include_names=None,
+ *                   exclude_names=None,
+ */
+    values[6] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":833
+ *                   strip_whitespace=True,
+ *                   names=None, # ignore, already used in _get_writer
+ *                   include_names=None,             # <<<<<<<<<<<<<<
+ *                   exclude_names=None,
+ *                   fill_values=[],
+ */
+    values[7] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":834
+ *                   names=None, # ignore, already used in _get_writer
+ *                   include_names=None,
+ *                   exclude_names=None,             # <<<<<<<<<<<<<<
+ *                   fill_values=[],
+ *                   fill_include_names=None,
+ */
+    values[8] = ((PyObject *)Py_None);
+    values[9] = __pyx_k__28;
+
+    /* "astropy/io/ascii/cparser.pyx":836
+ *                   exclude_names=None,
+ *                   fill_values=[],
+ *                   fill_include_names=None,             # <<<<<<<<<<<<<<
+ *                   fill_exclude_names=None,
+ *                   fast_writer=True):
+ */
+    values[10] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":837
+ *                   fill_values=[],
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,             # <<<<<<<<<<<<<<
+ *                   fast_writer=True):
+ * 
+ */
+    values[11] = ((PyObject *)Py_None);
+
+    /* "astropy/io/ascii/cparser.pyx":838
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,
+ *                   fast_writer=True):             # <<<<<<<<<<<<<<
+ * 
+ *         if fast_writer is True:
+ */
+    values[12] = ((PyObject *)Py_True);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
+        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
+        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
+        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_table)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_delimiter);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_comment);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_quotechar);
+          if (value) { values[3] = value; kw_args--; }
+        }
+        case  4:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_formats);
+          if (value) { values[4] = value; kw_args--; }
+        }
+        case  5:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strip_whitespace);
+          if (value) { values[5] = value; kw_args--; }
+        }
+        case  6:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_names);
+          if (value) { values[6] = value; kw_args--; }
+        }
+        case  7:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_include_names);
+          if (value) { values[7] = value; kw_args--; }
+        }
+        case  8:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_exclude_names);
+          if (value) { values[8] = value; kw_args--; }
+        }
+        case  9:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_values);
+          if (value) { values[9] = value; kw_args--; }
+        }
+        case 10:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_include_names);
+          if (value) { values[10] = value; kw_args--; }
+        }
+        case 11:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_exclude_names);
+          if (value) { values[11] = value; kw_args--; }
+        }
+        case 12:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fast_writer);
+          if (value) { values[12] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
+        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
+        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
+        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_table = values[0];
+    __pyx_v_delimiter = values[1];
+    __pyx_v_comment = values[2];
+    __pyx_v_quotechar = values[3];
+    __pyx_v_formats = values[4];
+    __pyx_v_strip_whitespace = values[5];
+    __pyx_v_names = values[6];
+    __pyx_v_include_names = values[7];
+    __pyx_v_exclude_names = values[8];
+    __pyx_v_fill_values = values[9];
+    __pyx_v_fill_include_names = values[10];
+    __pyx_v_fill_exclude_names = values[11];
+    __pyx_v_fast_writer = values[12];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 13, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter___cinit__(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)__pyx_v_self), __pyx_v_table, __pyx_v_delimiter, __pyx_v_comment, __pyx_v_quotechar, __pyx_v_formats, __pyx_v_strip_whitespace, __pyx_v_names, __pyx_v_include_names, __pyx_v_exclude_names, __pyx_v_fill_values, __pyx_v_fill_include_names, __pyx_v_fill_exclude_names, __pyx_v_fast_writer);
+
+  /* "astropy/io/ascii/cparser.pyx":826
+ *         object comment
+ * 
+ *     def __cinit__(self, table,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment='# ',
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter___cinit__(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_table, PyObject *__pyx_v_delimiter, PyObject *__pyx_v_comment, PyObject *__pyx_v_quotechar, PyObject *__pyx_v_formats, PyObject *__pyx_v_strip_whitespace, CYTHON_UNUSED PyObject *__pyx_v_names, PyObject *__pyx_v_include_names, PyObject *__pyx_v_exclude_names, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_fill_include_names, P [...]
+  PyObject *__pyx_v_use_names = NULL;
+  PyObject *__pyx_v_key = NULL;
+  PyObject *__pyx_v_val = NULL;
+  PyObject *__pyx_v_fill_names = NULL;
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_v_col = NULL;
+  PyObject *__pyx_v_x = NULL;
+  PyObject *__pyx_v_i = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  PyObject *(*__pyx_t_9)(PyObject *);
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  double __pyx_t_15;
+  int __pyx_t_16;
+  PyObject *__pyx_t_17 = NULL;
+  Py_ssize_t __pyx_t_18;
+  PyObject *__pyx_t_19 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+  __Pyx_INCREF(__pyx_v_fill_values);
+  __Pyx_INCREF(__pyx_v_fast_writer);
+
+  /* "astropy/io/ascii/cparser.pyx":840
+ *                   fast_writer=True):
+ * 
+ *         if fast_writer is True:             # <<<<<<<<<<<<<<
+ *             fast_writer = {}
+ *         # fast_writer might contain custom writing options
+ */
+  __pyx_t_1 = (__pyx_v_fast_writer == Py_True);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":841
+ * 
+ *         if fast_writer is True:
+ *             fast_writer = {}             # <<<<<<<<<<<<<<
+ *         # fast_writer might contain custom writing options
+ * 
+ */
+    __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF_SET(__pyx_v_fast_writer, __pyx_t_3);
+    __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":844
+ *         # fast_writer might contain custom writing options
+ * 
+ *         self.table = table             # <<<<<<<<<<<<<<
+ *         self.comment = comment
+ *         self.strip_whitespace = strip_whitespace
+ */
+  __Pyx_INCREF(__pyx_v_table);
+  __Pyx_GIVEREF(__pyx_v_table);
+  __Pyx_GOTREF(__pyx_v_self->table);
+  __Pyx_DECREF(__pyx_v_self->table);
+  __pyx_v_self->table = __pyx_v_table;
+
+  /* "astropy/io/ascii/cparser.pyx":845
+ * 
+ *         self.table = table
+ *         self.comment = comment             # <<<<<<<<<<<<<<
+ *         self.strip_whitespace = strip_whitespace
+ *         use_names = set(table.colnames)
+ */
+  __Pyx_INCREF(__pyx_v_comment);
+  __Pyx_GIVEREF(__pyx_v_comment);
+  __Pyx_GOTREF(__pyx_v_self->comment);
+  __Pyx_DECREF(__pyx_v_self->comment);
+  __pyx_v_self->comment = __pyx_v_comment;
+
+  /* "astropy/io/ascii/cparser.pyx":846
+ *         self.table = table
+ *         self.comment = comment
+ *         self.strip_whitespace = strip_whitespace             # <<<<<<<<<<<<<<
+ *         use_names = set(table.colnames)
+ * 
+ */
+  __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_v_strip_whitespace); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->strip_whitespace = __pyx_t_4;
+
+  /* "astropy/io/ascii/cparser.pyx":847
+ *         self.comment = comment
+ *         self.strip_whitespace = strip_whitespace
+ *         use_names = set(table.colnames)             # <<<<<<<<<<<<<<
+ * 
+ *         # Apply include_names before exclude_names
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_table, __pyx_n_s_colnames); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PySet_New(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_use_names = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":850
+ * 
+ *         # Apply include_names before exclude_names
+ *         if include_names is not None:             # <<<<<<<<<<<<<<
+ *             use_names.intersection_update(include_names)
+ *         if exclude_names is not None:
+ */
+  __pyx_t_2 = (__pyx_v_include_names != Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":851
+ *         # Apply include_names before exclude_names
+ *         if include_names is not None:
+ *             use_names.intersection_update(include_names)             # <<<<<<<<<<<<<<
+ *         if exclude_names is not None:
+ *             use_names.difference_update(exclude_names)
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_use_names, __pyx_n_s_intersection_update); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_include_names); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+    } else {
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      __Pyx_INCREF(__pyx_v_include_names);
+      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_include_names);
+      __Pyx_GIVEREF(__pyx_v_include_names);
+      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "astropy/io/ascii/cparser.pyx":852
+ *         if include_names is not None:
+ *             use_names.intersection_update(include_names)
+ *         if exclude_names is not None:             # <<<<<<<<<<<<<<
+ *             use_names.difference_update(exclude_names)
+ *         # preserve column ordering via list
+ */
+  __pyx_t_1 = (__pyx_v_exclude_names != Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":853
+ *             use_names.intersection_update(include_names)
+ *         if exclude_names is not None:
+ *             use_names.difference_update(exclude_names)             # <<<<<<<<<<<<<<
+ *         # preserve column ordering via list
+ *         self.use_names = [x for x in table.colnames if x in use_names]
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_use_names, __pyx_n_s_difference_update); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_7) {
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_exclude_names); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+    } else {
+      __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+      __Pyx_INCREF(__pyx_v_exclude_names);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_exclude_names);
+      __Pyx_GIVEREF(__pyx_v_exclude_names);
+      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "astropy/io/ascii/cparser.pyx":855
+ *             use_names.difference_update(exclude_names)
+ *         # preserve column ordering via list
+ *         self.use_names = [x for x in table.colnames if x in use_names]             # <<<<<<<<<<<<<<
+ * 
+ *         fill_values = get_fill_values(fill_values, False)
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_table, __pyx_n_s_colnames); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+    __pyx_t_6 = __pyx_t_3; __Pyx_INCREF(__pyx_t_6); __pyx_t_8 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_8 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_9 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_6))) {
+        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_6)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_3 = __pyx_t_9(__pyx_t_6);
+      if (unlikely(!__pyx_t_3)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_3);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_x, __pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_v_x, __pyx_v_use_names, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = (__pyx_t_2 != 0);
+    if (__pyx_t_1) {
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_v_x))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+  }
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->use_names);
+  __Pyx_DECREF(__pyx_v_self->use_names);
+  __pyx_v_self->use_names = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":857
+ *         self.use_names = [x for x in table.colnames if x in use_names]
+ * 
+ *         fill_values = get_fill_values(fill_values, False)             # <<<<<<<<<<<<<<
+ *         self.fill_values = fill_values.copy()
+ * 
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_get_fill_values); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = NULL;
+  __pyx_t_8 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+      __pyx_t_8 = 1;
+    }
+  }
+  __pyx_t_7 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  if (__pyx_t_3) {
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+  }
+  __Pyx_INCREF(__pyx_v_fill_values);
+  PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_8, __pyx_v_fill_values);
+  __Pyx_GIVEREF(__pyx_v_fill_values);
+  __Pyx_INCREF(Py_False);
+  PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_8, Py_False);
+  __Pyx_GIVEREF(Py_False);
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF_SET(__pyx_v_fill_values, __pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":858
+ * 
+ *         fill_values = get_fill_values(fill_values, False)
+ *         self.fill_values = fill_values.copy()             # <<<<<<<<<<<<<<
+ * 
+ *         # Add int/float versions of each fill value (if applicable)
+ */
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_fill_values, __pyx_n_s_copy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_7)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  if (__pyx_t_7) {
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  } else {
+    __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (!(likely(PyDict_CheckExact(__pyx_t_5))||((__pyx_t_5) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "dict", Py_TYPE(__pyx_t_5)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->fill_values);
+  __Pyx_DECREF(__pyx_v_self->fill_values);
+  __pyx_v_self->fill_values = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":864
+ *         # to call unicode() on every value, which is a major
+ *         # performance hit.
+ *         for key, val in six.iteritems(fill_values):             # <<<<<<<<<<<<<<
+ *             try:
+ *                 self.fill_values[int(key)] = val
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_iteritems); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_7, function);
+    }
+  }
+  if (!__pyx_t_6) {
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_fill_values); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+  } else {
+    __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+    __Pyx_INCREF(__pyx_v_fill_values);
+    PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_fill_values);
+    __Pyx_GIVEREF(__pyx_v_fill_values);
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+    __pyx_t_7 = __pyx_t_5; __Pyx_INCREF(__pyx_t_7); __pyx_t_8 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_8 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_9 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_7))) {
+        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_7)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_7, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_7, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_9(__pyx_t_7);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
+      PyObject* sequence = __pyx_t_5;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+      } else {
+        __pyx_t_3 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+      }
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      #endif
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
+      index = 0; __pyx_t_3 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_3)) goto __pyx_L11_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_3);
+      index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_6);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = NULL;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L12_unpacking_done;
+      __pyx_L11_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_t_11 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L12_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_3);
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_val, __pyx_t_6);
+    __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":865
+ *         # performance hit.
+ *         for key, val in six.iteritems(fill_values):
+ *             try:             # <<<<<<<<<<<<<<
+ *                 self.fill_values[int(key)] = val
+ *                 self.fill_values[float(key)] = val
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14);
+      __Pyx_XGOTREF(__pyx_t_12);
+      __Pyx_XGOTREF(__pyx_t_13);
+      __Pyx_XGOTREF(__pyx_t_14);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":866
+ *         for key, val in six.iteritems(fill_values):
+ *             try:
+ *                 self.fill_values[int(key)] = val             # <<<<<<<<<<<<<<
+ *                 self.fill_values[float(key)] = val
+ *             except (ValueError, np.ma.MaskError):
+ */
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        }
+        __pyx_t_5 = PyNumber_Int(__pyx_v_key); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        if (unlikely(PyDict_SetItem(__pyx_v_self->fill_values, __pyx_t_5, __pyx_v_val) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":867
+ *             try:
+ *                 self.fill_values[int(key)] = val
+ *                 self.fill_values[float(key)] = val             # <<<<<<<<<<<<<<
+ *             except (ValueError, np.ma.MaskError):
+ *                 pass
+ */
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        }
+        __pyx_t_15 = __Pyx_PyObject_AsDouble(__pyx_v_key); if (unlikely(__pyx_t_15 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        __pyx_t_5 = PyFloat_FromDouble(__pyx_t_15); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        if (unlikely(PyDict_SetItem(__pyx_v_self->fill_values, __pyx_t_5, __pyx_v_val) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+      __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+      __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+      goto __pyx_L20_try_end;
+      __pyx_L13_error:;
+      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":868
+ *                 self.fill_values[int(key)] = val
+ *                 self.fill_values[float(key)] = val
+ *             except (ValueError, np.ma.MaskError):             # <<<<<<<<<<<<<<
+ *                 pass
+ * 
+ */
+      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 868; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ma); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 868; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_MaskError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 868; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_4 = PyErr_ExceptionMatches(__pyx_builtin_ValueError) || PyErr_ExceptionMatches(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_4) {
+        PyErr_Restore(0,0,0);
+        goto __pyx_L14_exception_handled;
+      }
+      goto __pyx_L15_except_error;
+      __pyx_L15_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_12);
+      __Pyx_XGIVEREF(__pyx_t_13);
+      __Pyx_XGIVEREF(__pyx_t_14);
+      __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14);
+      goto __pyx_L1_error;
+      __pyx_L14_exception_handled:;
+      __Pyx_XGIVEREF(__pyx_t_12);
+      __Pyx_XGIVEREF(__pyx_t_13);
+      __Pyx_XGIVEREF(__pyx_t_14);
+      __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14);
+      __pyx_L20_try_end:;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":864
+ *         # to call unicode() on every value, which is a major
+ *         # performance hit.
+ *         for key, val in six.iteritems(fill_values):             # <<<<<<<<<<<<<<
+ *             try:
+ *                 self.fill_values[int(key)] = val
+ */
+  }
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":871
+ *                 pass
+ * 
+ *         fill_names = set(self.use_names)             # <<<<<<<<<<<<<<
+ *         # Apply fill_include_names before fill_exclude_names
+ *         if fill_include_names is not None:
+ */
+  __pyx_t_7 = PySet_New(__pyx_v_self->use_names); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_v_fill_names = ((PyObject*)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":873
+ *         fill_names = set(self.use_names)
+ *         # Apply fill_include_names before fill_exclude_names
+ *         if fill_include_names is not None:             # <<<<<<<<<<<<<<
+ *             fill_names.intersection_update(fill_include_names)
+ *         if fill_exclude_names is not None:
+ */
+  __pyx_t_1 = (__pyx_v_fill_include_names != Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":874
+ *         # Apply fill_include_names before fill_exclude_names
+ *         if fill_include_names is not None:
+ *             fill_names.intersection_update(fill_include_names)             # <<<<<<<<<<<<<<
+ *         if fill_exclude_names is not None:
+ *             fill_names.difference_update(fill_exclude_names)
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_fill_names, __pyx_n_s_intersection_update); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fill_include_names); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+    } else {
+      __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      __Pyx_INCREF(__pyx_v_fill_include_names);
+      PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_fill_include_names);
+      __Pyx_GIVEREF(__pyx_v_fill_include_names);
+      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    goto __pyx_L21;
+  }
+  __pyx_L21:;
+
+  /* "astropy/io/ascii/cparser.pyx":875
+ *         if fill_include_names is not None:
+ *             fill_names.intersection_update(fill_include_names)
+ *         if fill_exclude_names is not None:             # <<<<<<<<<<<<<<
+ *             fill_names.difference_update(fill_exclude_names)
+ *         # Preserve column ordering
+ */
+  __pyx_t_2 = (__pyx_v_fill_exclude_names != Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":876
+ *             fill_names.intersection_update(fill_include_names)
+ *         if fill_exclude_names is not None:
+ *             fill_names.difference_update(fill_exclude_names)             # <<<<<<<<<<<<<<
+ *         # Preserve column ordering
+ *         self.fill_cols = set([i for i, name in enumerate(self.use_names) if
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_fill_names, __pyx_n_s_difference_update); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_3)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_3);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_3) {
+      __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fill_exclude_names); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+    } else {
+      __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+      __Pyx_INCREF(__pyx_v_fill_exclude_names);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_fill_exclude_names);
+      __Pyx_GIVEREF(__pyx_v_fill_exclude_names);
+      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    goto __pyx_L22;
+  }
+  __pyx_L22:;
+
+  /* "astropy/io/ascii/cparser.pyx":878
+ *             fill_names.difference_update(fill_exclude_names)
+ *         # Preserve column ordering
+ *         self.fill_cols = set([i for i, name in enumerate(self.use_names) if             # <<<<<<<<<<<<<<
+ *                               name in fill_names])
+ * 
+ */
+  __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_INCREF(__pyx_int_0);
+  __pyx_t_5 = __pyx_int_0;
+  __pyx_t_6 = __pyx_v_self->use_names; __Pyx_INCREF(__pyx_t_6); __pyx_t_8 = 0;
+  for (;;) {
+    if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_6)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_3);
+    __pyx_t_3 = 0;
+    __Pyx_INCREF(__pyx_t_5);
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_5);
+    __pyx_t_3 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_5);
+    __pyx_t_5 = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":879
+ *         # Preserve column ordering
+ *         self.fill_cols = set([i for i, name in enumerate(self.use_names) if
+ *                               name in fill_names])             # <<<<<<<<<<<<<<
+ * 
+ *         # formats in user-specified dict should override
+ */
+    __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_name, __pyx_v_fill_names, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = (__pyx_t_1 != 0);
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":878
+ *             fill_names.difference_update(fill_exclude_names)
+ *         # Preserve column ordering
+ *         self.fill_cols = set([i for i, name in enumerate(self.use_names) if             # <<<<<<<<<<<<<<
+ *                               name in fill_names])
+ * 
+ */
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_7, (PyObject*)__pyx_v_i))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L25;
+    }
+    __pyx_L25:;
+  }
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PySet_New(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->fill_cols);
+  __Pyx_DECREF(__pyx_v_self->fill_cols);
+  __pyx_v_self->fill_cols = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":883
+ *         # formats in user-specified dict should override
+ *         # existing column formats
+ *         if formats is not None:             # <<<<<<<<<<<<<<
+ *             for name in self.use_names:
+ *                 if name in formats:
+ */
+  __pyx_t_2 = (__pyx_v_formats != Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":884
+ *         # existing column formats
+ *         if formats is not None:
+ *             for name in self.use_names:             # <<<<<<<<<<<<<<
+ *                 if name in formats:
+ *                     self.table[name].format = formats[name]
+ */
+    if (unlikely(__pyx_v_self->use_names == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_5 = __pyx_v_self->use_names; __Pyx_INCREF(__pyx_t_5); __pyx_t_8 = 0;
+    for (;;) {
+      if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_5)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_8); __Pyx_INCREF(__pyx_t_7); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_5, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+      __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_7);
+      __pyx_t_7 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":885
+ *         if formats is not None:
+ *             for name in self.use_names:
+ *                 if name in formats:             # <<<<<<<<<<<<<<
+ *                     self.table[name].format = formats[name]
+ * 
+ */
+      __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_name, __pyx_v_formats, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = (__pyx_t_1 != 0);
+      if (__pyx_t_2) {
+
+        /* "astropy/io/ascii/cparser.pyx":886
+ *             for name in self.use_names:
+ *                 if name in formats:
+ *                     self.table[name].format = formats[name]             # <<<<<<<<<<<<<<
+ * 
+ *         self.col_iters = []
+ */
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_formats, __pyx_v_name); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_6 = PyObject_GetItem(__pyx_v_self->table, __pyx_v_name); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        if (__Pyx_PyObject_SetAttrStr(__pyx_t_6, __pyx_n_s_format, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        goto __pyx_L29;
+      }
+      __pyx_L29:;
+
+      /* "astropy/io/ascii/cparser.pyx":884
+ *         # existing column formats
+ *         if formats is not None:
+ *             for name in self.use_names:             # <<<<<<<<<<<<<<
+ *                 if name in formats:
+ *                     self.table[name].format = formats[name]
+ */
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L26;
+  }
+  __pyx_L26:;
+
+  /* "astropy/io/ascii/cparser.pyx":888
+ *                     self.table[name].format = formats[name]
+ * 
+ *         self.col_iters = []             # <<<<<<<<<<<<<<
+ *         self.formats = []
+ *         self.format_funcs = []
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->col_iters);
+  __Pyx_DECREF(__pyx_v_self->col_iters);
+  __pyx_v_self->col_iters = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":889
+ * 
+ *         self.col_iters = []
+ *         self.formats = []             # <<<<<<<<<<<<<<
+ *         self.format_funcs = []
+ *         self.line_comments = table.meta.get('comments', [])
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->formats);
+  __Pyx_DECREF(__pyx_v_self->formats);
+  __pyx_v_self->formats = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":890
+ *         self.col_iters = []
+ *         self.formats = []
+ *         self.format_funcs = []             # <<<<<<<<<<<<<<
+ *         self.line_comments = table.meta.get('comments', [])
+ * 
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->format_funcs);
+  __Pyx_DECREF(__pyx_v_self->format_funcs);
+  __pyx_v_self->format_funcs = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":891
+ *         self.formats = []
+ *         self.format_funcs = []
+ *         self.line_comments = table.meta.get('comments', [])             # <<<<<<<<<<<<<<
+ * 
+ *         for col in six.itervalues(table.columns):
+ */
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_table, __pyx_n_s_meta); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_get); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = NULL;
+  __pyx_t_8 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_7);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_7, function);
+      __pyx_t_8 = 1;
+    }
+  }
+  __pyx_t_10 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  if (__pyx_t_3) {
+    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+  }
+  __Pyx_INCREF(__pyx_n_s_comments);
+  PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_8, __pyx_n_s_comments);
+  __Pyx_GIVEREF(__pyx_n_s_comments);
+  PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_8, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_6 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (!(likely(PyList_CheckExact(__pyx_t_5))||((__pyx_t_5) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_5)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->line_comments);
+  __Pyx_DECREF(__pyx_v_self->line_comments);
+  __pyx_v_self->line_comments = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":893
+ *         self.line_comments = table.meta.get('comments', [])
+ * 
+ *         for col in six.itervalues(table.columns):             # <<<<<<<<<<<<<<
+ *             if col.name in self.use_names: # iterate over included columns
+ *                 if col.format is None:
+ */
+  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_itervalues); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_table, __pyx_n_s_columns); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_10);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_10, function);
+    }
+  }
+  if (!__pyx_t_6) {
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_GOTREF(__pyx_t_5);
+  } else {
+    __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_7 = 0;
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+    __pyx_t_10 = __pyx_t_5; __Pyx_INCREF(__pyx_t_10); __pyx_t_8 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_8 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_9 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_10))) {
+        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_10, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_10, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_9(__pyx_t_10);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":894
+ * 
+ *         for col in six.itervalues(table.columns):
+ *             if col.name in self.use_names: # iterate over included columns             # <<<<<<<<<<<<<<
+ *                 if col.format is None:
+ *                     self.format_funcs.append(None)
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_col, __pyx_n_s_name); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_5, __pyx_v_self->use_names, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_1 = (__pyx_t_2 != 0);
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":895
+ *         for col in six.itervalues(table.columns):
+ *             if col.name in self.use_names: # iterate over included columns
+ *                 if col.format is None:             # <<<<<<<<<<<<<<
+ *                     self.format_funcs.append(None)
+ *                 else:
+ */
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_col, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = (__pyx_t_5 == Py_None);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_2 = (__pyx_t_1 != 0);
+      if (__pyx_t_2) {
+
+        /* "astropy/io/ascii/cparser.pyx":896
+ *             if col.name in self.use_names: # iterate over included columns
+ *                 if col.format is None:
+ *                     self.format_funcs.append(None)             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     self.format_funcs.append(pprint._format_funcs.get(col.format,
+ */
+        if (unlikely(__pyx_v_self->format_funcs == Py_None)) {
+          PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_self->format_funcs, Py_None); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L33;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":898
+ *                     self.format_funcs.append(None)
+ *                 else:
+ *                     self.format_funcs.append(pprint._format_funcs.get(col.format,             # <<<<<<<<<<<<<<
+ *                                                             auto_format_func))
+ *                 # col is a numpy.ndarray, so we convert it to
+ */
+        if (unlikely(__pyx_v_self->format_funcs == Py_None)) {
+          PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_pprint); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_format_funcs); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_col, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+
+        /* "astropy/io/ascii/cparser.pyx":899
+ *                 else:
+ *                     self.format_funcs.append(pprint._format_funcs.get(col.format,
+ *                                                             auto_format_func))             # <<<<<<<<<<<<<<
+ *                 # col is a numpy.ndarray, so we convert it to
+ *                 # an ordinary list because csv.writer will call
+ */
+        __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_auto_format_func); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_17 = NULL;
+        __pyx_t_18 = 0;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+          __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_3);
+          if (likely(__pyx_t_17)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+            __Pyx_INCREF(__pyx_t_17);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_3, function);
+            __pyx_t_18 = 1;
+          }
+        }
+        __pyx_t_19 = PyTuple_New(2+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_19);
+        if (__pyx_t_17) {
+          PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+        }
+        PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __pyx_t_7 = 0;
+        __pyx_t_6 = 0;
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_19, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":898
+ *                     self.format_funcs.append(None)
+ *                 else:
+ *                     self.format_funcs.append(pprint._format_funcs.get(col.format,             # <<<<<<<<<<<<<<
+ *                                                             auto_format_func))
+ *                 # col is a numpy.ndarray, so we convert it to
+ */
+        __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_self->format_funcs, __pyx_t_5); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      }
+      __pyx_L33:;
+
+      /* "astropy/io/ascii/cparser.pyx":904
+ *                 # np.array_str() on each numpy value, which is
+ *                 # very inefficient
+ *                 self.col_iters.append(iter(col.tolist()))             # <<<<<<<<<<<<<<
+ *                 self.formats.append(col.format)
+ * 
+ */
+      if (unlikely(__pyx_v_self->col_iters == Py_None)) {
+        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_col, __pyx_n_s_tolist); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_19 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+        __pyx_t_19 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_19)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_19);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+        }
+      }
+      if (__pyx_t_19) {
+        __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_19); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+      } else {
+        __pyx_t_5 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_self->col_iters, __pyx_t_3); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":905
+ *                 # very inefficient
+ *                 self.col_iters.append(iter(col.tolist()))
+ *                 self.formats.append(col.format)             # <<<<<<<<<<<<<<
+ * 
+ *         self.quotechar = None if quotechar is None else str(quotechar)
+ */
+      if (unlikely(__pyx_v_self->formats == Py_None)) {
+        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_col, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_self->formats, __pyx_t_3); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L32;
+    }
+    __pyx_L32:;
+
+    /* "astropy/io/ascii/cparser.pyx":893
+ *         self.line_comments = table.meta.get('comments', [])
+ * 
+ *         for col in six.itervalues(table.columns):             # <<<<<<<<<<<<<<
+ *             if col.name in self.use_names: # iterate over included columns
+ *                 if col.format is None:
+ */
+  }
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":907
+ *                 self.formats.append(col.format)
+ * 
+ *         self.quotechar = None if quotechar is None else str(quotechar)             # <<<<<<<<<<<<<<
+ *         self.delimiter = ' ' if delimiter is None else str(delimiter)
+ *         # 'S' for string types, 'N' for numeric types
+ */
+  __pyx_t_2 = (__pyx_v_quotechar == Py_None);
+  if ((__pyx_t_2 != 0)) {
+    __Pyx_INCREF(Py_None);
+    __pyx_t_10 = Py_None;
+  } else {
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_quotechar);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_quotechar);
+    __Pyx_GIVEREF(__pyx_v_quotechar);
+    __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (!(likely(PyString_CheckExact(__pyx_t_5))||((__pyx_t_5) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_5)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __pyx_t_5;
+    __pyx_t_5 = 0;
+  }
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->quotechar);
+  __Pyx_DECREF(__pyx_v_self->quotechar);
+  __pyx_v_self->quotechar = ((PyObject*)__pyx_t_10);
+  __pyx_t_10 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":908
+ * 
+ *         self.quotechar = None if quotechar is None else str(quotechar)
+ *         self.delimiter = ' ' if delimiter is None else str(delimiter)             # <<<<<<<<<<<<<<
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'
+ */
+  __pyx_t_2 = (__pyx_v_delimiter == Py_None);
+  if ((__pyx_t_2 != 0)) {
+    __Pyx_INCREF(__pyx_kp_s__29);
+    __pyx_t_10 = __pyx_kp_s__29;
+  } else {
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_v_delimiter);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_delimiter);
+    __Pyx_GIVEREF(__pyx_v_delimiter);
+    __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (!(likely(PyString_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __pyx_t_3;
+    __pyx_t_3 = 0;
+  }
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->delimiter);
+  __Pyx_DECREF(__pyx_v_self->delimiter);
+  __pyx_v_self->delimiter = ((PyObject*)__pyx_t_10);
+  __pyx_t_10 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":910
+ *         self.delimiter = ' ' if delimiter is None else str(delimiter)
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'             # <<<<<<<<<<<<<<
+ *                       for name in self.use_names]
+ * 
+ */
+  __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+
+  /* "astropy/io/ascii/cparser.pyx":911
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'
+ *                       for name in self.use_names]             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _write_comments(self, output):
+ */
+  if (unlikely(__pyx_v_self->use_names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_3 = __pyx_v_self->use_names; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
+  for (;;) {
+    if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":910
+ *         self.delimiter = ' ' if delimiter is None else str(delimiter)
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'             # <<<<<<<<<<<<<<
+ *                       for name in self.use_names]
+ * 
+ */
+    __pyx_t_19 = PyObject_GetItem(__pyx_v_self->table, __pyx_v_name); if (unlikely(__pyx_t_19 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_19);
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_19, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+    __pyx_t_19 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_kind); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_19);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_1 = (__Pyx_PyString_Equals(__pyx_t_19, __pyx_n_s_S, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_1) {
+    } else {
+      __pyx_t_2 = __pyx_t_1;
+      goto __pyx_L36_bool_binop_done;
+    }
+    __pyx_t_1 = (__Pyx_PyString_Equals(__pyx_t_19, __pyx_n_s_U, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_1;
+    __pyx_L36_bool_binop_done:;
+    __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+    if ((__pyx_t_2 != 0)) {
+      __Pyx_INCREF(__pyx_n_s_S);
+      __pyx_t_5 = __pyx_n_s_S;
+    } else {
+      __Pyx_INCREF(__pyx_n_s_N);
+      __pyx_t_5 = __pyx_n_s_N;
+    }
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_10, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":911
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'
+ *                       for name in self.use_names]             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _write_comments(self, output):
+ */
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":910
+ *         self.delimiter = ' ' if delimiter is None else str(delimiter)
+ *         # 'S' for string types, 'N' for numeric types
+ *         self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'             # <<<<<<<<<<<<<<
+ *                       for name in self.use_names]
+ * 
+ */
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->types);
+  __Pyx_DECREF(__pyx_v_self->types);
+  __pyx_v_self->types = ((PyObject*)__pyx_t_10);
+  __pyx_t_10 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":826
+ *         object comment
+ * 
+ *     def __cinit__(self, table,             # <<<<<<<<<<<<<<
+ *                   delimiter=',',
+ *                   comment='# ',
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_17);
+  __Pyx_XDECREF(__pyx_t_19);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_use_names);
+  __Pyx_XDECREF(__pyx_v_key);
+  __Pyx_XDECREF(__pyx_v_val);
+  __Pyx_XDECREF(__pyx_v_fill_names);
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XDECREF(__pyx_v_col);
+  __Pyx_XDECREF(__pyx_v_x);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_fill_values);
+  __Pyx_XDECREF(__pyx_v_fast_writer);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":913
+ *                       for name in self.use_names]
+ * 
+ *     cdef _write_comments(self, output):             # <<<<<<<<<<<<<<
+ *         if self.comment is not False:
+ *             for comment_line in self.line_comments:
+ */
+
+static PyObject *__pyx_f_7astropy_2io_5ascii_7cparser_10FastWriter__write_comments(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output) {
+  PyObject *__pyx_v_comment_line = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_write_comments", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":914
+ * 
+ *     cdef _write_comments(self, output):
+ *         if self.comment is not False:             # <<<<<<<<<<<<<<
+ *             for comment_line in self.line_comments:
+ *                 output.write(self.comment + comment_line + '\n')
+ */
+  __pyx_t_1 = (__pyx_v_self->comment != Py_False);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":915
+ *     cdef _write_comments(self, output):
+ *         if self.comment is not False:
+ *             for comment_line in self.line_comments:             # <<<<<<<<<<<<<<
+ *                 output.write(self.comment + comment_line + '\n')
+ * 
+ */
+    if (unlikely(__pyx_v_self->line_comments == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __pyx_v_self->line_comments; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
+    for (;;) {
+      if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_5); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+      __Pyx_XDECREF_SET(__pyx_v_comment_line, __pyx_t_5);
+      __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":916
+ *         if self.comment is not False:
+ *             for comment_line in self.line_comments:
+ *                 output.write(self.comment + comment_line + '\n')             # <<<<<<<<<<<<<<
+ * 
+ *     def _write_header(self, output, writer, header_output, output_types):
+ */
+      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_output, __pyx_n_s_write); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_7 = PyNumber_Add(__pyx_v_self->comment, __pyx_v_comment_line); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_8 = PyNumber_Add(__pyx_t_7, __pyx_kp_s__11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_7 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+        }
+      }
+      if (!__pyx_t_7) {
+        __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_GOTREF(__pyx_t_5);
+      } else {
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+        PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_8);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_t_8 = 0;
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":915
+ *     cdef _write_comments(self, output):
+ *         if self.comment is not False:
+ *             for comment_line in self.line_comments:             # <<<<<<<<<<<<<<
+ *                 output.write(self.comment + comment_line + '\n')
+ * 
+ */
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":913
+ *                       for name in self.use_names]
+ * 
+ *     cdef _write_comments(self, output):             # <<<<<<<<<<<<<<
+ *         if self.comment is not False:
+ *             for comment_line in self.line_comments:
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter._write_comments", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_comment_line);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":918
+ *                 output.write(self.comment + comment_line + '\n')
+ * 
+ *     def _write_header(self, output, writer, header_output, output_types):             # <<<<<<<<<<<<<<
+ *         if header_output is not None and header_output == 'comment':
+ *             output.write(self.comment)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_3_write_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_3_write_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_output = 0;
+  PyObject *__pyx_v_writer = 0;
+  PyObject *__pyx_v_header_output = 0;
+  PyObject *__pyx_v_output_types = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_write_header (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_output,&__pyx_n_s_writer,&__pyx_n_s_header_output,&__pyx_n_s_output_types,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_writer)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_write_header", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_header_output)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_write_header", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_types)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_write_header", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_write_header") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_output = values[0];
+    __pyx_v_writer = values[1];
+    __pyx_v_header_output = values[2];
+    __pyx_v_output_types = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_write_header", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter._write_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_2_write_header(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)__pyx_v_self), __pyx_v_output, __pyx_v_writer, __pyx_v_header_output, __pyx_v_output_types);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_2_write_header(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output, PyObject *__pyx_v_writer, PyObject *__pyx_v_header_output, PyObject *__pyx_v_output_types) {
+  PyObject *__pyx_v_x = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_write_header", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":919
+ * 
+ *     def _write_header(self, output, writer, header_output, output_types):
+ *         if header_output is not None and header_output == 'comment':             # <<<<<<<<<<<<<<
+ *             output.write(self.comment)
+ *             writer.writerow([x.strip() for x in self.use_names] if
+ */
+  __pyx_t_2 = (__pyx_v_header_output != Py_None);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
+  } else {
+    __pyx_t_1 = __pyx_t_3;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_header_output, __pyx_n_s_comment, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_t_3;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":920
+ *     def _write_header(self, output, writer, header_output, output_types):
+ *         if header_output is not None and header_output == 'comment':
+ *             output.write(self.comment)             # <<<<<<<<<<<<<<
+ *             writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_output, __pyx_n_s_write); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_self->comment); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+    } else {
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      __Pyx_INCREF(__pyx_v_self->comment);
+      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_self->comment);
+      __Pyx_GIVEREF(__pyx_v_self->comment);
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":921
+ *         if header_output is not None and header_output == 'comment':
+ *             output.write(self.comment)
+ *             writer.writerow([x.strip() for x in self.use_names] if             # <<<<<<<<<<<<<<
+ *                             self.strip_whitespace else self.use_names)
+ *             self._write_comments(output)
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_writer, __pyx_n_s_writerow); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+
+    /* "astropy/io/ascii/cparser.pyx":922
+ *             output.write(self.comment)
+ *             writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)             # <<<<<<<<<<<<<<
+ *             self._write_comments(output)
+ *         else:
+ */
+    if ((__pyx_v_self->strip_whitespace != 0)) {
+
+      /* "astropy/io/ascii/cparser.pyx":921
+ *         if header_output is not None and header_output == 'comment':
+ *             output.write(self.comment)
+ *             writer.writerow([x.strip() for x in self.use_names] if             # <<<<<<<<<<<<<<
+ *                             self.strip_whitespace else self.use_names)
+ *             self._write_comments(output)
+ */
+      __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      if (unlikely(__pyx_v_self->use_names == Py_None)) {
+        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_8 = __pyx_v_self->use_names; __Pyx_INCREF(__pyx_t_8); __pyx_t_9 = 0;
+      for (;;) {
+        if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_8)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_10 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_10); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_10 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+        __Pyx_XDECREF_SET(__pyx_v_x, __pyx_t_10);
+        __pyx_t_10 = 0;
+        __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_strip); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_12 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_11))) {
+          __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_11);
+          if (likely(__pyx_t_12)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+            __Pyx_INCREF(__pyx_t_12);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_11, function);
+          }
+        }
+        if (__pyx_t_12) {
+          __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_12); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        } else {
+          __pyx_t_10 = __Pyx_PyObject_CallNoArg(__pyx_t_11); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __Pyx_GOTREF(__pyx_t_10);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_10))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_7 = __pyx_t_6;
+      __pyx_t_6 = 0;
+    } else {
+
+      /* "astropy/io/ascii/cparser.pyx":922
+ *             output.write(self.comment)
+ *             writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)             # <<<<<<<<<<<<<<
+ *             self._write_comments(output)
+ *         else:
+ */
+      __Pyx_INCREF(__pyx_v_self->use_names);
+      __pyx_t_7 = __pyx_v_self->use_names;
+    }
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_GOTREF(__pyx_t_4);
+    } else {
+      __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_7);
+      __Pyx_GIVEREF(__pyx_t_7);
+      __pyx_t_7 = 0;
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":923
+ *             writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)
+ *             self._write_comments(output)             # <<<<<<<<<<<<<<
+ *         else:
+ *             self._write_comments(output)
+ */
+    __pyx_t_4 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter *)__pyx_v_self->__pyx_vtab)->_write_comments(__pyx_v_self, __pyx_v_output); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":925
+ *             self._write_comments(output)
+ *         else:
+ *             self._write_comments(output)             # <<<<<<<<<<<<<<
+ *             if header_output is not None:
+ *                 writer.writerow([x.strip() for x in self.use_names] if
+ */
+    __pyx_t_4 = ((struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter *)__pyx_v_self->__pyx_vtab)->_write_comments(__pyx_v_self, __pyx_v_output); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":926
+ *         else:
+ *             self._write_comments(output)
+ *             if header_output is not None:             # <<<<<<<<<<<<<<
+ *                 writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)
+ */
+    __pyx_t_1 = (__pyx_v_header_output != Py_None);
+    __pyx_t_3 = (__pyx_t_1 != 0);
+    if (__pyx_t_3) {
+
+      /* "astropy/io/ascii/cparser.pyx":927
+ *             self._write_comments(output)
+ *             if header_output is not None:
+ *                 writer.writerow([x.strip() for x in self.use_names] if             # <<<<<<<<<<<<<<
+ *                             self.strip_whitespace else self.use_names)
+ *         if output_types:
+ */
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_writer, __pyx_n_s_writerow); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+
+      /* "astropy/io/ascii/cparser.pyx":928
+ *             if header_output is not None:
+ *                 writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)             # <<<<<<<<<<<<<<
+ *         if output_types:
+ *             writer.writerow(self.types)
+ */
+      if ((__pyx_v_self->strip_whitespace != 0)) {
+
+        /* "astropy/io/ascii/cparser.pyx":927
+ *             self._write_comments(output)
+ *             if header_output is not None:
+ *                 writer.writerow([x.strip() for x in self.use_names] if             # <<<<<<<<<<<<<<
+ *                             self.strip_whitespace else self.use_names)
+ *         if output_types:
+ */
+        __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        if (unlikely(__pyx_v_self->use_names == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_6 = __pyx_v_self->use_names; __Pyx_INCREF(__pyx_t_6); __pyx_t_9 = 0;
+        for (;;) {
+          if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_6)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_10 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_9); __Pyx_INCREF(__pyx_t_10); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_10 = PySequence_ITEM(__pyx_t_6, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+          __Pyx_XDECREF_SET(__pyx_v_x, __pyx_t_10);
+          __pyx_t_10 = 0;
+          __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_strip); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __pyx_t_12 = NULL;
+          if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_11))) {
+            __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_11);
+            if (likely(__pyx_t_12)) {
+              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+              __Pyx_INCREF(__pyx_t_12);
+              __Pyx_INCREF(function);
+              __Pyx_DECREF_SET(__pyx_t_11, function);
+            }
+          }
+          if (__pyx_t_12) {
+            __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_12); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          } else {
+            __pyx_t_10 = __Pyx_PyObject_CallNoArg(__pyx_t_11); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          __Pyx_GOTREF(__pyx_t_10);
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          if (unlikely(__Pyx_ListComp_Append(__pyx_t_7, (PyObject*)__pyx_t_10))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+        }
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_8 = __pyx_t_7;
+        __pyx_t_7 = 0;
+      } else {
+
+        /* "astropy/io/ascii/cparser.pyx":928
+ *             if header_output is not None:
+ *                 writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)             # <<<<<<<<<<<<<<
+ *         if output_types:
+ *             writer.writerow(self.types)
+ */
+        __Pyx_INCREF(__pyx_v_self->use_names);
+        __pyx_t_8 = __pyx_v_self->use_names;
+      }
+      __pyx_t_7 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_5, function);
+        }
+      }
+      if (!__pyx_t_7) {
+        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_GOTREF(__pyx_t_4);
+      } else {
+        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_8);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_t_8 = 0;
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":929
+ *                 writer.writerow([x.strip() for x in self.use_names] if
+ *                             self.strip_whitespace else self.use_names)
+ *         if output_types:             # <<<<<<<<<<<<<<
+ *             writer.writerow(self.types)
+ * 
+ */
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_output_types); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_3) {
+
+    /* "astropy/io/ascii/cparser.pyx":930
+ *                             self.strip_whitespace else self.use_names)
+ *         if output_types:
+ *             writer.writerow(self.types)             # <<<<<<<<<<<<<<
+ * 
+ *     def write(self, output, header_output, output_types):
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_writer, __pyx_n_s_writerow); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_self->types); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+    } else {
+      __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      __Pyx_INCREF(__pyx_v_self->types);
+      PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_self->types);
+      __Pyx_GIVEREF(__pyx_v_self->types);
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L11;
+  }
+  __pyx_L11:;
+
+  /* "astropy/io/ascii/cparser.pyx":918
+ *                 output.write(self.comment + comment_line + '\n')
+ * 
+ *     def _write_header(self, output, writer, header_output, output_types):             # <<<<<<<<<<<<<<
+ *         if header_output is not None and header_output == 'comment':
+ *             output.write(self.comment)
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter._write_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_x);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":932
+ *             writer.writerow(self.types)
+ * 
+ *     def write(self, output, header_output, output_types):             # <<<<<<<<<<<<<<
+ *         opened_file = False
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_5write(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_5write(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_output = 0;
+  PyObject *__pyx_v_header_output = 0;
+  PyObject *__pyx_v_output_types = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("write (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_output,&__pyx_n_s_header_output,&__pyx_n_s_output_types,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_header_output)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("write", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_types)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("write", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "write") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_output = values[0];
+    __pyx_v_header_output = values[1];
+    __pyx_v_output_types = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("write", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_4write(((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)__pyx_v_self), __pyx_v_output, __pyx_v_header_output, __pyx_v_output_types);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_10FastWriter_4write(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *__pyx_v_self, PyObject *__pyx_v_output, PyObject *__pyx_v_header_output, PyObject *__pyx_v_output_types) {
+  int __pyx_v_opened_file;
+  PyObject *__pyx_v_writer = NULL;
+  int __pyx_v_N;
+  int __pyx_v_num_cols;
+  int __pyx_v_num_rows;
+  PyObject *__pyx_v_string_rows = 0;
+  PyObject *__pyx_v_rows = 0;
+  PyObject *__pyx_v_i = NULL;
+  int __pyx_v_j;
+  PyObject *__pyx_v_orig_field = NULL;
+  PyObject *__pyx_v_str_val = NULL;
+  PyObject *__pyx_v_field = NULL;
+  PyObject *__pyx_v_new_val = NULL;
+  PyObject *__pyx_v_type = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  PyObject *(*__pyx_t_9)(PyObject *);
+  int __pyx_t_10;
+  int __pyx_t_11;
+  Py_ssize_t __pyx_t_12;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_t_14;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("write", 0);
+  __Pyx_INCREF(__pyx_v_output);
+
+  /* "astropy/io/ascii/cparser.pyx":933
+ * 
+ *     def write(self, output, header_output, output_types):
+ *         opened_file = False             # <<<<<<<<<<<<<<
+ * 
+ *         if not hasattr(output, 'write'): # output is a filename
+ */
+  __pyx_v_opened_file = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":935
+ *         opened_file = False
+ * 
+ *         if not hasattr(output, 'write'): # output is a filename             # <<<<<<<<<<<<<<
+ *             output = open(output, 'w')
+ *             opened_file = True # remember to close file afterwards
+ */
+  __pyx_t_1 = PyObject_HasAttr(__pyx_v_output, __pyx_n_s_write); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+  if (__pyx_t_2) {
+
+    /* "astropy/io/ascii/cparser.pyx":936
+ * 
+ *         if not hasattr(output, 'write'): # output is a filename
+ *             output = open(output, 'w')             # <<<<<<<<<<<<<<
+ *             opened_file = True # remember to close file afterwards
+ *         writer = csv.writer(output,
+ */
+    __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_output);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_output);
+    __Pyx_GIVEREF(__pyx_v_output);
+    __Pyx_INCREF(__pyx_n_s_w);
+    PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_w);
+    __Pyx_GIVEREF(__pyx_n_s_w);
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF_SET(__pyx_v_output, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":937
+ *         if not hasattr(output, 'write'): # output is a filename
+ *             output = open(output, 'w')
+ *             opened_file = True # remember to close file afterwards             # <<<<<<<<<<<<<<
+ *         writer = csv.writer(output,
+ *                             delimiter=self.delimiter,
+ */
+    __pyx_v_opened_file = 1;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":938
+ *             output = open(output, 'w')
+ *             opened_file = True # remember to close file afterwards
+ *         writer = csv.writer(output,             # <<<<<<<<<<<<<<
+ *                             delimiter=self.delimiter,
+ *                             doublequote=True,
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_csv); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_writer); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_output);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_output);
+  __Pyx_GIVEREF(__pyx_v_output);
+  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+
+  /* "astropy/io/ascii/cparser.pyx":939
+ *             opened_file = True # remember to close file afterwards
+ *         writer = csv.writer(output,
+ *                             delimiter=self.delimiter,             # <<<<<<<<<<<<<<
+ *                             doublequote=True,
+ *                             escapechar=None,
+ */
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_delimiter, __pyx_v_self->delimiter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":940
+ *         writer = csv.writer(output,
+ *                             delimiter=self.delimiter,
+ *                             doublequote=True,             # <<<<<<<<<<<<<<
+ *                             escapechar=None,
+ *                             quotechar=self.quotechar,
+ */
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_doublequote, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":941
+ *                             delimiter=self.delimiter,
+ *                             doublequote=True,
+ *                             escapechar=None,             # <<<<<<<<<<<<<<
+ *                             quotechar=self.quotechar,
+ *                             quoting=csv.QUOTE_MINIMAL,
+ */
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_escapechar, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":942
+ *                             doublequote=True,
+ *                             escapechar=None,
+ *                             quotechar=self.quotechar,             # <<<<<<<<<<<<<<
+ *                             quoting=csv.QUOTE_MINIMAL,
+ *                             lineterminator=os.linesep)
+ */
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_quotechar, __pyx_v_self->quotechar) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":943
+ *                             escapechar=None,
+ *                             quotechar=self.quotechar,
+ *                             quoting=csv.QUOTE_MINIMAL,             # <<<<<<<<<<<<<<
+ *                             lineterminator=os.linesep)
+ *         self._write_header(output, writer, header_output, output_types)
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_csv); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_QUOTE_MINIMAL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_quoting, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":944
+ *                             quotechar=self.quotechar,
+ *                             quoting=csv.QUOTE_MINIMAL,
+ *                             lineterminator=os.linesep)             # <<<<<<<<<<<<<<
+ *         self._write_header(output, writer, header_output, output_types)
+ * 
+ */
+  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_os); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_linesep); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_lineterminator, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":938
+ *             output = open(output, 'w')
+ *             opened_file = True # remember to close file afterwards
+ *         writer = csv.writer(output,             # <<<<<<<<<<<<<<
+ *                             delimiter=self.delimiter,
+ *                             doublequote=True,
+ */
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_v_writer = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":945
+ *                             quoting=csv.QUOTE_MINIMAL,
+ *                             lineterminator=os.linesep)
+ *         self._write_header(output, writer, header_output, output_types)             # <<<<<<<<<<<<<<
+ * 
+ *         # Split rows into N-sized chunks, since we don't want to
+ */
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_header); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_4 = NULL;
+  __pyx_t_8 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_5, function);
+      __pyx_t_8 = 1;
+    }
+  }
+  __pyx_t_3 = PyTuple_New(4+__pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (__pyx_t_4) {
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+  }
+  __Pyx_INCREF(__pyx_v_output);
+  PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_8, __pyx_v_output);
+  __Pyx_GIVEREF(__pyx_v_output);
+  __Pyx_INCREF(__pyx_v_writer);
+  PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_8, __pyx_v_writer);
+  __Pyx_GIVEREF(__pyx_v_writer);
+  __Pyx_INCREF(__pyx_v_header_output);
+  PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_8, __pyx_v_header_output);
+  __Pyx_GIVEREF(__pyx_v_header_output);
+  __Pyx_INCREF(__pyx_v_output_types);
+  PyTuple_SET_ITEM(__pyx_t_3, 3+__pyx_t_8, __pyx_v_output_types);
+  __Pyx_GIVEREF(__pyx_v_output_types);
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":951
+ *         # or fail to take advantage of the speed boost of writerows()
+ *         # over writerow().
+ *         cdef int N = 100             # <<<<<<<<<<<<<<
+ *         cdef int num_cols = len(self.use_names)
+ *         cdef int num_rows = len(self.table)
+ */
+  __pyx_v_N = 100;
+
+  /* "astropy/io/ascii/cparser.pyx":952
+ *         # over writerow().
+ *         cdef int N = 100
+ *         cdef int num_cols = len(self.use_names)             # <<<<<<<<<<<<<<
+ *         cdef int num_rows = len(self.table)
+ *         # cache string columns beforehand
+ */
+  __pyx_t_6 = __pyx_v_self->use_names;
+  __Pyx_INCREF(__pyx_t_6);
+  if (unlikely(__pyx_t_6 == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_8 = PyList_GET_SIZE(__pyx_t_6); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_v_num_cols = __pyx_t_8;
+
+  /* "astropy/io/ascii/cparser.pyx":953
+ *         cdef int N = 100
+ *         cdef int num_cols = len(self.use_names)
+ *         cdef int num_rows = len(self.table)             # <<<<<<<<<<<<<<
+ *         # cache string columns beforehand
+ *         cdef set string_rows = set([i for i, type in enumerate(self.types) if
+ */
+  __pyx_t_6 = __pyx_v_self->table;
+  __Pyx_INCREF(__pyx_t_6);
+  __pyx_t_8 = PyObject_Length(__pyx_t_6); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_v_num_rows = __pyx_t_8;
+
+  /* "astropy/io/ascii/cparser.pyx":955
+ *         cdef int num_rows = len(self.table)
+ *         # cache string columns beforehand
+ *         cdef set string_rows = set([i for i, type in enumerate(self.types) if             # <<<<<<<<<<<<<<
+ *                                     type == 'S'])
+ *         cdef list rows = [[None] * num_cols for i in range(N)]
+ */
+  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_INCREF(__pyx_int_0);
+  __pyx_t_5 = __pyx_int_0;
+  __pyx_t_3 = __pyx_v_self->types; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
+  for (;;) {
+    if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_4); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_type, __pyx_t_4);
+    __pyx_t_4 = 0;
+    __Pyx_INCREF(__pyx_t_5);
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_5);
+    __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5);
+    __pyx_t_5 = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":956
+ *         # cache string columns beforehand
+ *         cdef set string_rows = set([i for i, type in enumerate(self.types) if
+ *                                     type == 'S'])             # <<<<<<<<<<<<<<
+ *         cdef list rows = [[None] * num_cols for i in range(N)]
+ * 
+ */
+    __pyx_t_2 = (__Pyx_PyString_Equals(__pyx_v_type, __pyx_n_s_S, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_2) {
+
+      /* "astropy/io/ascii/cparser.pyx":955
+ *         cdef int num_rows = len(self.table)
+ *         # cache string columns beforehand
+ *         cdef set string_rows = set([i for i, type in enumerate(self.types) if             # <<<<<<<<<<<<<<
+ *                                     type == 'S'])
+ *         cdef list rows = [[None] * num_cols for i in range(N)]
+ */
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_v_i))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PySet_New(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_v_string_rows = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":957
+ *         cdef set string_rows = set([i for i, type in enumerate(self.types) if
+ *                                     type == 'S'])
+ *         cdef list rows = [[None] * num_cols for i in range(N)]             # <<<<<<<<<<<<<<
+ * 
+ *         for i in range(num_rows):
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_6 = 0;
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_6)) || PyTuple_CheckExact(__pyx_t_6)) {
+    __pyx_t_3 = __pyx_t_6; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_8 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_3))) {
+        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_6 = __pyx_t_9(__pyx_t_3);
+      if (unlikely(!__pyx_t_6)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_6);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_6 = PyList_New(1 * ((__pyx_v_num_cols<0) ? 0:__pyx_v_num_cols)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    { Py_ssize_t __pyx_temp;
+      for (__pyx_temp=0; __pyx_temp < __pyx_v_num_cols; __pyx_temp++) {
+        __Pyx_INCREF(Py_None);
+        PyList_SET_ITEM(__pyx_t_6, __pyx_temp, Py_None);
+        __Pyx_GIVEREF(Py_None);
+      }
+    }
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_rows = ((PyObject*)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":959
+ *         cdef list rows = [[None] * num_cols for i in range(N)]
+ * 
+ *         for i in range(num_rows):             # <<<<<<<<<<<<<<
+ *             for j in range(num_cols):
+ *                 orig_field = next(self.col_iters[j]) # get field
+ */
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_num_rows); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+    __pyx_t_3 = __pyx_t_5; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_8 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_3))) {
+        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_9(__pyx_t_3);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":960
+ * 
+ *         for i in range(num_rows):
+ *             for j in range(num_cols):             # <<<<<<<<<<<<<<
+ *                 orig_field = next(self.col_iters[j]) # get field
+ *                 # str_val monitors whether we should check if the field
+ */
+    __pyx_t_10 = __pyx_v_num_cols;
+    for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {
+      __pyx_v_j = __pyx_t_11;
+
+      /* "astropy/io/ascii/cparser.pyx":961
+ *         for i in range(num_rows):
+ *             for j in range(num_cols):
+ *                 orig_field = next(self.col_iters[j]) # get field             # <<<<<<<<<<<<<<
+ *                 # str_val monitors whether we should check if the field
+ *                 # should be stripped
+ */
+      if (unlikely(__pyx_v_self->col_iters == Py_None)) {
+        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_self->col_iters, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyIter_Next(__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_XDECREF_SET(__pyx_v_orig_field, __pyx_t_6);
+      __pyx_t_6 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":964
+ *                 # str_val monitors whether we should check if the field
+ *                 # should be stripped
+ *                 str_val = True             # <<<<<<<<<<<<<<
+ * 
+ *                 if orig_field is None: # tolist() converts ma.masked to None
+ */
+      __Pyx_INCREF(Py_True);
+      __Pyx_XDECREF_SET(__pyx_v_str_val, Py_True);
+
+      /* "astropy/io/ascii/cparser.pyx":966
+ *                 str_val = True
+ * 
+ *                 if orig_field is None: # tolist() converts ma.masked to None             # <<<<<<<<<<<<<<
+ *                     field = core.masked
+ *                     rows[i % N][j] = '--'
+ */
+      __pyx_t_2 = (__pyx_v_orig_field == Py_None);
+      __pyx_t_1 = (__pyx_t_2 != 0);
+      if (__pyx_t_1) {
+
+        /* "astropy/io/ascii/cparser.pyx":967
+ * 
+ *                 if orig_field is None: # tolist() converts ma.masked to None
+ *                     field = core.masked             # <<<<<<<<<<<<<<
+ *                     rows[i % N][j] = '--'
+ * 
+ */
+        __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_core); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_masked); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_XDECREF_SET(__pyx_v_field, __pyx_t_5);
+        __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":968
+ *                 if orig_field is None: # tolist() converts ma.masked to None
+ *                     field = core.masked
+ *                     rows[i % N][j] = '--'             # <<<<<<<<<<<<<<
+ * 
+ *                 elif self.format_funcs[j] is not None:
+ */
+        __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_6 = PyNumber_Remainder(__pyx_v_i, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = PyObject_GetItem(__pyx_v_rows, __pyx_t_6); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        if (unlikely(__Pyx_SetItemInt(__pyx_t_5, __pyx_v_j, __pyx_kp_s__30, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        goto __pyx_L13;
+      }
+
+      /* "astropy/io/ascii/cparser.pyx":970
+ *                     rows[i % N][j] = '--'
+ * 
+ *                 elif self.format_funcs[j] is not None:             # <<<<<<<<<<<<<<
+ *                     field = self.format_funcs[j](self.formats[j], orig_field)
+ *                     rows[i % N][j] = field
+ */
+      if (unlikely(__pyx_v_self->format_funcs == Py_None)) {
+        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_5 = __Pyx_GetItemInt_List(__pyx_v_self->format_funcs, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = (__pyx_t_5 != Py_None);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_2 = (__pyx_t_1 != 0);
+      if (__pyx_t_2) {
+
+        /* "astropy/io/ascii/cparser.pyx":971
+ * 
+ *                 elif self.format_funcs[j] is not None:
+ *                     field = self.format_funcs[j](self.formats[j], orig_field)             # <<<<<<<<<<<<<<
+ *                     rows[i % N][j] = field
+ * 
+ */
+        if (unlikely(__pyx_v_self->format_funcs == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_6 = __Pyx_GetItemInt_List(__pyx_v_self->format_funcs, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        if (unlikely(__pyx_v_self->formats == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_4 = __Pyx_GetItemInt_List(__pyx_v_self->formats, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_4);
+        __pyx_t_7 = NULL;
+        __pyx_t_12 = 0;
+        if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+          __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+          if (likely(__pyx_t_7)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+            __Pyx_INCREF(__pyx_t_7);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_6, function);
+            __pyx_t_12 = 1;
+          }
+        }
+        __pyx_t_13 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        if (__pyx_t_7) {
+          PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+        }
+        PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_4);
+        __Pyx_GIVEREF(__pyx_t_4);
+        __Pyx_INCREF(__pyx_v_orig_field);
+        PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_v_orig_field);
+        __Pyx_GIVEREF(__pyx_v_orig_field);
+        __pyx_t_4 = 0;
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_13, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_XDECREF_SET(__pyx_v_field, __pyx_t_5);
+        __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":972
+ *                 elif self.format_funcs[j] is not None:
+ *                     field = self.format_funcs[j](self.formats[j], orig_field)
+ *                     rows[i % N][j] = field             # <<<<<<<<<<<<<<
+ * 
+ *                 else:
+ */
+        __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_6 = PyNumber_Remainder(__pyx_v_i, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = PyObject_GetItem(__pyx_v_rows, __pyx_t_6); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        if (unlikely(__Pyx_SetItemInt(__pyx_t_5, __pyx_v_j, __pyx_v_field, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        goto __pyx_L13;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":975
+ * 
+ *                 else:
+ *                     field = orig_field             # <<<<<<<<<<<<<<
+ *                     rows[i % N][j] = field
+ *                     str_val = j in string_rows
+ */
+        __Pyx_INCREF(__pyx_v_orig_field);
+        __Pyx_XDECREF_SET(__pyx_v_field, __pyx_v_orig_field);
+
+        /* "astropy/io/ascii/cparser.pyx":976
+ *                 else:
+ *                     field = orig_field
+ *                     rows[i % N][j] = field             # <<<<<<<<<<<<<<
+ *                     str_val = j in string_rows
+ * 
+ */
+        __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_6 = PyNumber_Remainder(__pyx_v_i, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = PyObject_GetItem(__pyx_v_rows, __pyx_t_6); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        if (unlikely(__Pyx_SetItemInt(__pyx_t_5, __pyx_v_j, __pyx_v_field, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":977
+ *                     field = orig_field
+ *                     rows[i % N][j] = field
+ *                     str_val = j in string_rows             # <<<<<<<<<<<<<<
+ * 
+ *                 if field in self.fill_values:
+ */
+        __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_j); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_5, __pyx_v_string_rows, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF_SET(__pyx_v_str_val, __pyx_t_5);
+        __pyx_t_5 = 0;
+      }
+      __pyx_L13:;
+
+      /* "astropy/io/ascii/cparser.pyx":979
+ *                     str_val = j in string_rows
+ * 
+ *                 if field in self.fill_values:             # <<<<<<<<<<<<<<
+ *                     new_val = self.fill_values[field][0]
+ *                     # Either this column applies to the field as specified in
+ */
+      if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_2 = (__Pyx_PyDict_Contains(__pyx_v_field, __pyx_v_self->fill_values, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = (__pyx_t_2 != 0);
+      if (__pyx_t_1) {
+
+        /* "astropy/io/ascii/cparser.pyx":980
+ * 
+ *                 if field in self.fill_values:
+ *                     new_val = self.fill_values[field][0]             # <<<<<<<<<<<<<<
+ *                     # Either this column applies to the field as specified in
+ *                     # the fill_values parameter, or no specific columns are
+ */
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_5 = __Pyx_PyDict_GetItem(__pyx_v_self->fill_values, __pyx_v_field); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __Pyx_XDECREF_SET(__pyx_v_new_val, __pyx_t_6);
+        __pyx_t_6 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":984
+ *                     # the fill_values parameter, or no specific columns are
+ *                     # specified and this column should apply fill_values.
+ *                     if (len(self.fill_values[field]) > 1 and self.use_names[j] in self.fill_values[field][1:]) \             # <<<<<<<<<<<<<<
+ *                        or (len(self.fill_values[field]) == 1 and j in self.fill_cols):
+ *                         str_val = True
+ */
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_6 = __Pyx_PyDict_GetItem(__pyx_v_self->fill_values, __pyx_v_field); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_12 = PyObject_Length(__pyx_t_6); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_2 = ((__pyx_t_12 > 1) != 0);
+        if (!__pyx_t_2) {
+          goto __pyx_L17_next_or;
+        } else {
+        }
+        if (unlikely(__pyx_v_self->use_names == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_6 = __Pyx_GetItemInt_List(__pyx_v_self->use_names, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_5 = __Pyx_PyDict_GetItem(__pyx_v_self->fill_values, __pyx_v_field); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = __Pyx_PyObject_GetSlice(__pyx_t_5, 1, 0, NULL, NULL, &__pyx_slice__31, 1, 0, 1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_6, __pyx_t_13, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = (__pyx_t_2 != 0);
+        if (!__pyx_t_14) {
+        } else {
+          __pyx_t_1 = __pyx_t_14;
+          goto __pyx_L16_bool_binop_done;
+        }
+        __pyx_L17_next_or:;
+
+        /* "astropy/io/ascii/cparser.pyx":985
+ *                     # specified and this column should apply fill_values.
+ *                     if (len(self.fill_values[field]) > 1 and self.use_names[j] in self.fill_values[field][1:]) \
+ *                        or (len(self.fill_values[field]) == 1 and j in self.fill_cols):             # <<<<<<<<<<<<<<
+ *                         str_val = True
+ *                         rows[i % N][j] = new_val
+ */
+        if (unlikely(__pyx_v_self->fill_values == Py_None)) {
+          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __pyx_t_13 = __Pyx_PyDict_GetItem(__pyx_v_self->fill_values, __pyx_v_field); if (unlikely(__pyx_t_13 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_12 = PyObject_Length(__pyx_t_13); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = ((__pyx_t_12 == 1) != 0);
+        if (__pyx_t_14) {
+        } else {
+          __pyx_t_1 = __pyx_t_14;
+          goto __pyx_L16_bool_binop_done;
+        }
+        __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_j); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = (__Pyx_PySequence_Contains(__pyx_t_13, __pyx_v_self->fill_cols, Py_EQ)); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_2 = (__pyx_t_14 != 0);
+        __pyx_t_1 = __pyx_t_2;
+        __pyx_L16_bool_binop_done:;
+        if (__pyx_t_1) {
+
+          /* "astropy/io/ascii/cparser.pyx":986
+ *                     if (len(self.fill_values[field]) > 1 and self.use_names[j] in self.fill_values[field][1:]) \
+ *                        or (len(self.fill_values[field]) == 1 and j in self.fill_cols):
+ *                         str_val = True             # <<<<<<<<<<<<<<
+ *                         rows[i % N][j] = new_val
+ *                         if self.strip_whitespace: # new_val should be a string
+ */
+          __Pyx_INCREF(Py_True);
+          __Pyx_DECREF_SET(__pyx_v_str_val, Py_True);
+
+          /* "astropy/io/ascii/cparser.pyx":987
+ *                        or (len(self.fill_values[field]) == 1 and j in self.fill_cols):
+ *                         str_val = True
+ *                         rows[i % N][j] = new_val             # <<<<<<<<<<<<<<
+ *                         if self.strip_whitespace: # new_val should be a string
+ *                             rows[i % N][j] = rows[i % N][j].strip()
+ */
+          __pyx_t_13 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __pyx_t_6 = PyNumber_Remainder(__pyx_v_i, __pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+          __pyx_t_13 = PyObject_GetItem(__pyx_v_rows, __pyx_t_6); if (unlikely(__pyx_t_13 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 987; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          if (unlikely(__Pyx_SetItemInt(__pyx_t_13, __pyx_v_j, __pyx_v_new_val, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":988
+ *                         str_val = True
+ *                         rows[i % N][j] = new_val
+ *                         if self.strip_whitespace: # new_val should be a string             # <<<<<<<<<<<<<<
+ *                             rows[i % N][j] = rows[i % N][j].strip()
+ * 
+ */
+          __pyx_t_1 = (__pyx_v_self->strip_whitespace != 0);
+          if (__pyx_t_1) {
+
+            /* "astropy/io/ascii/cparser.pyx":989
+ *                         rows[i % N][j] = new_val
+ *                         if self.strip_whitespace: # new_val should be a string
+ *                             rows[i % N][j] = rows[i % N][j].strip()             # <<<<<<<<<<<<<<
+ * 
+ *                 if str_val and self.strip_whitespace:
+ */
+            __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_6);
+            __pyx_t_5 = PyNumber_Remainder(__pyx_v_i, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+            __pyx_t_6 = PyObject_GetItem(__pyx_v_rows, __pyx_t_5); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+            __Pyx_GOTREF(__pyx_t_6);
+            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+            __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_6);
+            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            __pyx_t_5 = NULL;
+            if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+              __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+              if (likely(__pyx_t_5)) {
+                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+                __Pyx_INCREF(__pyx_t_5);
+                __Pyx_INCREF(function);
+                __Pyx_DECREF_SET(__pyx_t_6, function);
+              }
+            }
+            if (__pyx_t_5) {
+              __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            } else {
+              __pyx_t_13 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            }
+            __Pyx_GOTREF(__pyx_t_13);
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+            __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_6);
+            __pyx_t_5 = PyNumber_Remainder(__pyx_v_i, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+            __pyx_t_6 = PyObject_GetItem(__pyx_v_rows, __pyx_t_5); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+            __Pyx_GOTREF(__pyx_t_6);
+            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            if (unlikely(__Pyx_SetItemInt(__pyx_t_6, __pyx_v_j, __pyx_t_13, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+            __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+            goto __pyx_L20;
+          }
+          __pyx_L20:;
+          goto __pyx_L15;
+        }
+        __pyx_L15:;
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "astropy/io/ascii/cparser.pyx":991
+ *                             rows[i % N][j] = rows[i % N][j].strip()
+ * 
+ *                 if str_val and self.strip_whitespace:             # <<<<<<<<<<<<<<
+ *                     rows[i % N][j] = rows[i % N][j].strip()
+ * 
+ */
+      __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_str_val); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__pyx_t_2) {
+      } else {
+        __pyx_t_1 = __pyx_t_2;
+        goto __pyx_L22_bool_binop_done;
+      }
+      __pyx_t_2 = (__pyx_v_self->strip_whitespace != 0);
+      __pyx_t_1 = __pyx_t_2;
+      __pyx_L22_bool_binop_done:;
+      if (__pyx_t_1) {
+
+        /* "astropy/io/ascii/cparser.pyx":992
+ * 
+ *                 if str_val and self.strip_whitespace:
+ *                     rows[i % N][j] = rows[i % N][j].strip()             # <<<<<<<<<<<<<<
+ * 
+ *             if i >= N - 1 and i % N == N - 1: # rows is now full
+ */
+        __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_5 = PyNumber_Remainder(__pyx_v_i, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_6 = PyObject_GetItem(__pyx_v_rows, __pyx_t_5); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_5 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+          if (likely(__pyx_t_5)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+            __Pyx_INCREF(__pyx_t_5);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_6, function);
+          }
+        }
+        if (__pyx_t_5) {
+          __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        } else {
+          __pyx_t_13 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_5 = PyNumber_Remainder(__pyx_v_i, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_6 = PyObject_GetItem(__pyx_v_rows, __pyx_t_5); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        if (unlikely(__Pyx_SetItemInt(__pyx_t_6, __pyx_v_j, __pyx_t_13, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        goto __pyx_L21;
+      }
+      __pyx_L21:;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":994
+ *                     rows[i % N][j] = rows[i % N][j].strip()
+ * 
+ *             if i >= N - 1 and i % N == N - 1: # rows is now full             # <<<<<<<<<<<<<<
+ *                 writer.writerows(rows)
+ * 
+ */
+    __pyx_t_13 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_6 = PyObject_RichCompare(__pyx_v_i, __pyx_t_13, Py_GE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L25_bool_binop_done;
+    }
+    __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_13 = PyNumber_Remainder(__pyx_v_i, __pyx_t_6); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_13, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L25_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":995
+ * 
+ *             if i >= N - 1 and i % N == N - 1: # rows is now full
+ *                 writer.writerows(rows)             # <<<<<<<<<<<<<<
+ * 
+ *         # Write leftover rows not included in previous chunks
+ */
+      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_writer, __pyx_n_s_writerows); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_13 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_13)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_13);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+        }
+      }
+      if (!__pyx_t_13) {
+        __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_rows); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+      } else {
+        __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_13); __Pyx_GIVEREF(__pyx_t_13); __pyx_t_13 = NULL;
+        __Pyx_INCREF(__pyx_v_rows);
+        PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_rows);
+        __Pyx_GIVEREF(__pyx_v_rows);
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L24;
+    }
+    __pyx_L24:;
+
+    /* "astropy/io/ascii/cparser.pyx":959
+ *         cdef list rows = [[None] * num_cols for i in range(N)]
+ * 
+ *         for i in range(num_rows):             # <<<<<<<<<<<<<<
+ *             for j in range(num_cols):
+ *                 orig_field = next(self.col_iters[j]) # get field
+ */
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":998
+ * 
+ *         # Write leftover rows not included in previous chunks
+ *         if i % N != N - 1:             # <<<<<<<<<<<<<<
+ *             writer.writerows(rows[:i % N + 1])
+ * 
+ */
+  if (unlikely(!__pyx_v_i)) { __Pyx_RaiseUnboundLocalError("i"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyNumber_Remainder(__pyx_v_i, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_t_3, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":999
+ *         # Write leftover rows not included in previous chunks
+ *         if i % N != N - 1:
+ *             writer.writerows(rows[:i % N + 1])             # <<<<<<<<<<<<<<
+ * 
+ *         if opened_file:
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_writer, __pyx_n_s_writerows); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (unlikely(!__pyx_v_i)) { __Pyx_RaiseUnboundLocalError("i"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = PyNumber_Remainder(__pyx_v_i, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = __Pyx_PyList_GetSlice(__pyx_v_rows, 0, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_4) {
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_GOTREF(__pyx_t_6);
+    } else {
+      __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_13);
+      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+      PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_5 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_13, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    goto __pyx_L27;
+  }
+  __pyx_L27:;
+
+  /* "astropy/io/ascii/cparser.pyx":1001
+ *             writer.writerows(rows[:i % N + 1])
+ * 
+ *         if opened_file:             # <<<<<<<<<<<<<<
+ *             output.close()
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_opened_file != 0);
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":1002
+ * 
+ *         if opened_file:
+ *             output.close()             # <<<<<<<<<<<<<<
+ * 
+ * def get_fill_values(fill_values, read=True):
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_output, __pyx_n_s_close); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_13 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_13)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_13);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (__pyx_t_13) {
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    } else {
+      __pyx_t_6 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    goto __pyx_L28;
+  }
+  __pyx_L28:;
+
+  /* "astropy/io/ascii/cparser.pyx":932
+ *             writer.writerow(self.types)
+ * 
+ *     def write(self, output, header_output, output_types):             # <<<<<<<<<<<<<<
+ *         opened_file = False
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.FastWriter.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_writer);
+  __Pyx_XDECREF(__pyx_v_string_rows);
+  __Pyx_XDECREF(__pyx_v_rows);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_orig_field);
+  __Pyx_XDECREF(__pyx_v_str_val);
+  __Pyx_XDECREF(__pyx_v_field);
+  __Pyx_XDECREF(__pyx_v_new_val);
+  __Pyx_XDECREF(__pyx_v_type);
+  __Pyx_XDECREF(__pyx_v_output);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1004
+ *             output.close()
+ * 
+ * def get_fill_values(fill_values, read=True):             # <<<<<<<<<<<<<<
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+ *         # e.g. fill_values=('999', '0')
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_5get_fill_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_5get_fill_values = {"get_fill_values", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_5get_fill_values, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_5get_fill_values(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_fill_values = 0;
+  PyObject *__pyx_v_read = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_fill_values (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_fill_values,&__pyx_n_s_read,0};
+    PyObject* values[2] = {0,0};
+    values[1] = ((PyObject *)Py_True);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_values)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_read);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_fill_values") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_fill_values = values[0];
+    __pyx_v_read = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get_fill_values", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.get_fill_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_4get_fill_values(__pyx_self, __pyx_v_fill_values, __pyx_v_read);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_4get_fill_values(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_fill_values, PyObject *__pyx_v_read) {
+  PyObject *__pyx_v_fill_empty = NULL;
+  PyObject *__pyx_v_el = NULL;
+  PyObject *__pyx_v_l = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  Py_ssize_t __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *(*__pyx_t_8)(PyObject *);
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_t_14;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_fill_values", 0);
+  __Pyx_INCREF(__pyx_v_fill_values);
+
+  /* "astropy/io/ascii/cparser.pyx":1005
+ * 
+ * def get_fill_values(fill_values, read=True):
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):             # <<<<<<<<<<<<<<
+ *         # e.g. fill_values=('999', '0')
+ *         fill_values = [fill_values]
+ */
+  __pyx_t_2 = PyObject_Length(__pyx_v_fill_values); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = ((__pyx_t_2 > 0) != 0);
+  if (__pyx_t_3) {
+  } else {
+    __pyx_t_1 = __pyx_t_3;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_fill_values, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_string_types); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = PyObject_IsInstance(__pyx_t_4, __pyx_t_6); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_7 = (__pyx_t_3 != 0);
+  __pyx_t_1 = __pyx_t_7;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":1007
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+ *         # e.g. fill_values=('999', '0')
+ *         fill_values = [fill_values]             # <<<<<<<<<<<<<<
+ *     else:
+ *         fill_values = fill_values
+ */
+    __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_INCREF(__pyx_v_fill_values);
+    PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_fill_values);
+    __Pyx_GIVEREF(__pyx_v_fill_values);
+    __Pyx_DECREF_SET(__pyx_v_fill_values, __pyx_t_6);
+    __pyx_t_6 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":1009
+ *         fill_values = [fill_values]
+ *     else:
+ *         fill_values = fill_values             # <<<<<<<<<<<<<<
+ * 
+ *     # look for an empty replacement to cache for speedy conversion
+ */
+    __Pyx_INCREF(__pyx_v_fill_values);
+    __Pyx_DECREF_SET(__pyx_v_fill_values, __pyx_v_fill_values);
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":1012
+ * 
+ *     # look for an empty replacement to cache for speedy conversion
+ *     fill_empty = None             # <<<<<<<<<<<<<<
+ *     for el in fill_values:
+ *         if el[0] == '':
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_fill_empty = Py_None;
+
+  /* "astropy/io/ascii/cparser.pyx":1013
+ *     # look for an empty replacement to cache for speedy conversion
+ *     fill_empty = None
+ *     for el in fill_values:             # <<<<<<<<<<<<<<
+ *         if el[0] == '':
+ *             fill_empty = el[1:]
+ */
+  if (likely(PyList_CheckExact(__pyx_v_fill_values)) || PyTuple_CheckExact(__pyx_v_fill_values)) {
+    __pyx_t_6 = __pyx_v_fill_values; __Pyx_INCREF(__pyx_t_6); __pyx_t_2 = 0;
+    __pyx_t_8 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_v_fill_values); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_8 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_8)) {
+      if (likely(PyList_CheckExact(__pyx_t_6))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_6)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_6, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_6, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_4 = __pyx_t_8(__pyx_t_6);
+      if (unlikely(!__pyx_t_4)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_el, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":1014
+ *     fill_empty = None
+ *     for el in fill_values:
+ *         if el[0] == '':             # <<<<<<<<<<<<<<
+ *             fill_empty = el[1:]
+ *             break
+ */
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_el, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_1 = (__Pyx_PyString_Equals(__pyx_t_4, __pyx_kp_s__3, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (__pyx_t_1) {
+
+      /* "astropy/io/ascii/cparser.pyx":1015
+ *     for el in fill_values:
+ *         if el[0] == '':
+ *             fill_empty = el[1:]             # <<<<<<<<<<<<<<
+ *             break
+ * 
+ */
+      __pyx_t_4 = __Pyx_PyObject_GetSlice(__pyx_v_el, 1, 0, NULL, NULL, &__pyx_slice__32, 1, 0, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF_SET(__pyx_v_fill_empty, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":1016
+ *         if el[0] == '':
+ *             fill_empty = el[1:]
+ *             break             # <<<<<<<<<<<<<<
+ * 
+ *     try:
+ */
+      goto __pyx_L7_break;
+    }
+
+    /* "astropy/io/ascii/cparser.pyx":1013
+ *     # look for an empty replacement to cache for speedy conversion
+ *     fill_empty = None
+ *     for el in fill_values:             # <<<<<<<<<<<<<<
+ *         if el[0] == '':
+ *             fill_empty = el[1:]
+ */
+  }
+  __pyx_L7_break:;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":1018
+ *             break
+ * 
+ *     try:             # <<<<<<<<<<<<<<
+ *         # Create a dict with the values to be replaced as keys
+ *         if read:
+ */
+  {
+    __Pyx_ExceptionSave(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+    __Pyx_XGOTREF(__pyx_t_9);
+    __Pyx_XGOTREF(__pyx_t_10);
+    __Pyx_XGOTREF(__pyx_t_11);
+    /*try:*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":1020
+ *     try:
+ *         # Create a dict with the values to be replaced as keys
+ *         if read:             # <<<<<<<<<<<<<<
+ *             fill_values = dict([(l[0].encode('ascii'), l[1:]) for
+ *                                 l in fill_values if l[0] != ''])
+ */
+      __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_read); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+      if (__pyx_t_1) {
+
+        /* "astropy/io/ascii/cparser.pyx":1021
+ *         # Create a dict with the values to be replaced as keys
+ *         if read:
+ *             fill_values = dict([(l[0].encode('ascii'), l[1:]) for             # <<<<<<<<<<<<<<
+ *                                 l in fill_values if l[0] != ''])
+ *         else:
+ */
+        __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+
+        /* "astropy/io/ascii/cparser.pyx":1022
+ *         if read:
+ *             fill_values = dict([(l[0].encode('ascii'), l[1:]) for
+ *                                 l in fill_values if l[0] != ''])             # <<<<<<<<<<<<<<
+ *         else:
+ *             # don't worry about encoding for writing
+ */
+        if (likely(PyList_CheckExact(__pyx_v_fill_values)) || PyTuple_CheckExact(__pyx_v_fill_values)) {
+          __pyx_t_4 = __pyx_v_fill_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_2 = 0;
+          __pyx_t_8 = NULL;
+        } else {
+          __pyx_t_2 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_fill_values); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          __pyx_t_8 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        }
+        for (;;) {
+          if (likely(!__pyx_t_8)) {
+            if (likely(PyList_CheckExact(__pyx_t_4))) {
+              if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_4)) break;
+              #if CYTHON_COMPILING_IN_CPYTHON
+              __pyx_t_5 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #else
+              __pyx_t_5 = PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #endif
+            } else {
+              if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+              #if CYTHON_COMPILING_IN_CPYTHON
+              __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #else
+              __pyx_t_5 = PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #endif
+            }
+          } else {
+            __pyx_t_5 = __pyx_t_8(__pyx_t_4);
+            if (unlikely(!__pyx_t_5)) {
+              PyObject* exc_type = PyErr_Occurred();
+              if (exc_type) {
+                if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+                else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              }
+              break;
+            }
+            __Pyx_GOTREF(__pyx_t_5);
+          }
+          __Pyx_XDECREF_SET(__pyx_v_l, __pyx_t_5);
+          __pyx_t_5 = 0;
+          __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_l, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;};
+          __Pyx_GOTREF(__pyx_t_5);
+          __pyx_t_1 = (__Pyx_PyString_Equals(__pyx_t_5, __pyx_kp_s__3, Py_NE)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+          if (__pyx_t_1) {
+
+            /* "astropy/io/ascii/cparser.pyx":1021
+ *         # Create a dict with the values to be replaced as keys
+ *         if read:
+ *             fill_values = dict([(l[0].encode('ascii'), l[1:]) for             # <<<<<<<<<<<<<<
+ *                                 l in fill_values if l[0] != ''])
+ *         else:
+ */
+            __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_l, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;};
+            __Pyx_GOTREF(__pyx_t_5);
+            __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+            __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+            __Pyx_GOTREF(__pyx_t_5);
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __pyx_t_12 = __Pyx_PyObject_GetSlice(__pyx_v_l, 1, 0, NULL, NULL, &__pyx_slice__34, 1, 0, 1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+            __Pyx_GOTREF(__pyx_t_13);
+            PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_5);
+            __Pyx_GIVEREF(__pyx_t_5);
+            PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_12);
+            __Pyx_GIVEREF(__pyx_t_12);
+            __pyx_t_5 = 0;
+            __pyx_t_12 = 0;
+            if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_13))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+            __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+            goto __pyx_L20;
+          }
+          __pyx_L20:;
+        }
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __pyx_t_6 = 0;
+        __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_DECREF_SET(__pyx_v_fill_values, __pyx_t_6);
+        __pyx_t_6 = 0;
+        goto __pyx_L17;
+      }
+      /*else*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":1025
+ *         else:
+ *             # don't worry about encoding for writing
+ *             fill_values = dict([(l[0], l[1:]) for l in fill_values])             # <<<<<<<<<<<<<<
+ * 
+ *     except IndexError:
+ */
+        __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        if (likely(PyList_CheckExact(__pyx_v_fill_values)) || PyTuple_CheckExact(__pyx_v_fill_values)) {
+          __pyx_t_4 = __pyx_v_fill_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_2 = 0;
+          __pyx_t_8 = NULL;
+        } else {
+          __pyx_t_2 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_fill_values); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          __pyx_t_8 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        }
+        for (;;) {
+          if (likely(!__pyx_t_8)) {
+            if (likely(PyList_CheckExact(__pyx_t_4))) {
+              if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_4)) break;
+              #if CYTHON_COMPILING_IN_CPYTHON
+              __pyx_t_13 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_13); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #else
+              __pyx_t_13 = PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #endif
+            } else {
+              if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+              #if CYTHON_COMPILING_IN_CPYTHON
+              __pyx_t_13 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_13); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #else
+              __pyx_t_13 = PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              #endif
+            }
+          } else {
+            __pyx_t_13 = __pyx_t_8(__pyx_t_4);
+            if (unlikely(!__pyx_t_13)) {
+              PyObject* exc_type = PyErr_Occurred();
+              if (exc_type) {
+                if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+                else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+              }
+              break;
+            }
+            __Pyx_GOTREF(__pyx_t_13);
+          }
+          __Pyx_XDECREF_SET(__pyx_v_l, __pyx_t_13);
+          __pyx_t_13 = 0;
+          __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_l, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_13 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;};
+          __Pyx_GOTREF(__pyx_t_13);
+          __pyx_t_12 = __Pyx_PyObject_GetSlice(__pyx_v_l, 1, 0, NULL, NULL, &__pyx_slice__35, 1, 0, 1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_GOTREF(__pyx_t_5);
+          PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
+          __Pyx_GIVEREF(__pyx_t_13);
+          PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_12);
+          __Pyx_GIVEREF(__pyx_t_12);
+          __pyx_t_13 = 0;
+          __pyx_t_12 = 0;
+          if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        }
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __pyx_t_6 = 0;
+        __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L9_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_DECREF_SET(__pyx_v_fill_values, __pyx_t_6);
+        __pyx_t_6 = 0;
+      }
+      __pyx_L17:;
+    }
+    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+    goto __pyx_L16_try_end;
+    __pyx_L9_error:;
+    __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":1027
+ *             fill_values = dict([(l[0], l[1:]) for l in fill_values])
+ * 
+ *     except IndexError:             # <<<<<<<<<<<<<<
+ *         raise ValueError("Format of fill_values must be "
+ *                          "(<bad>, <fill>, <optional col1>, ...)")
+ */
+    __pyx_t_14 = PyErr_ExceptionMatches(__pyx_builtin_IndexError);
+    if (__pyx_t_14) {
+      __Pyx_AddTraceback("astropy.io.ascii.cparser.get_fill_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_4, &__pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L11_except_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_GOTREF(__pyx_t_5);
+
+      /* "astropy/io/ascii/cparser.pyx":1028
+ * 
+ *     except IndexError:
+ *         raise ValueError("Format of fill_values must be "             # <<<<<<<<<<<<<<
+ *                          "(<bad>, <fill>, <optional col1>, ...)")
+ *     if read:
+ */
+      __pyx_t_12 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L11_except_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __Pyx_Raise(__pyx_t_12, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L11_except_error;}
+    }
+    goto __pyx_L11_except_error;
+    __pyx_L11_except_error:;
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_XGIVEREF(__pyx_t_10);
+    __Pyx_XGIVEREF(__pyx_t_11);
+    __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+    goto __pyx_L1_error;
+    __pyx_L16_try_end:;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":1030
+ *         raise ValueError("Format of fill_values must be "
+ *                          "(<bad>, <fill>, <optional col1>, ...)")
+ *     if read:             # <<<<<<<<<<<<<<
+ *         return (fill_values, fill_empty)
+ *     else:
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_read); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+
+    /* "astropy/io/ascii/cparser.pyx":1031
+ *                          "(<bad>, <fill>, <optional col1>, ...)")
+ *     if read:
+ *         return (fill_values, fill_empty)             # <<<<<<<<<<<<<<
+ *     else:
+ *         return fill_values # cache for empty values doesn't matter for writing
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_v_fill_values);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_fill_values);
+    __Pyx_GIVEREF(__pyx_v_fill_values);
+    __Pyx_INCREF(__pyx_v_fill_empty);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_fill_empty);
+    __Pyx_GIVEREF(__pyx_v_fill_empty);
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":1033
+ *         return (fill_values, fill_empty)
+ *     else:
+ *         return fill_values # cache for empty values doesn't matter for writing             # <<<<<<<<<<<<<<
+ * 
+ * def auto_format_func(format_, val):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_v_fill_values);
+    __pyx_r = __pyx_v_fill_values;
+    goto __pyx_L0;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":1004
+ *             output.close()
+ * 
+ * def get_fill_values(fill_values, read=True):             # <<<<<<<<<<<<<<
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+ *         # e.g. fill_values=('999', '0')
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.get_fill_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_fill_empty);
+  __Pyx_XDECREF(__pyx_v_el);
+  __Pyx_XDECREF(__pyx_v_l);
+  __Pyx_XDECREF(__pyx_v_fill_values);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1035
+ *         return fill_values # cache for empty values doesn't matter for writing
+ * 
+ * def auto_format_func(format_, val):             # <<<<<<<<<<<<<<
+ *     """
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7auto_format_func(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7astropy_2io_5ascii_7cparser_6auto_format_func[] = "\n    Mimics pprint._auto_format_func for non-numpy values.\n    ";
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_7auto_format_func = {"auto_format_func", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7auto_format_func, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_2io_5ascii_7cparser_6auto_format_func};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_7auto_format_func(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_format_ = 0;
+  PyObject *__pyx_v_val = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("auto_format_func (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_format_2,&__pyx_n_s_val,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format_2)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_val)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("auto_format_func", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "auto_format_func") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_format_ = values[0];
+    __pyx_v_val = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("auto_format_func", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_7astropy_2io_5ascii_7cparser_6auto_format_func(__pyx_self, __pyx_v_format_, __pyx_v_val);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1040
+ *     """
+ *     if six.callable(format_):
+ *         format_func = lambda format_, val: format_(val)             # <<<<<<<<<<<<<<
+ *         try:
+ *             out = format_func(format_, val)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_lambda3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_lambda3 = {"lambda3", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_lambda3, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_lambda3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_format_ = 0;
+  PyObject *__pyx_v_val = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda3 (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_format_2,&__pyx_n_s_val,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format_2)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_val)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("lambda3", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda3") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_format_ = values[0];
+    __pyx_v_val = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("lambda3", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_lambda_funcdef_lambda3(__pyx_self, __pyx_v_format_, __pyx_v_val);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda3", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_format_);
+  __pyx_t_2 = __pyx_v_format_; __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_val);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_val);
+    __Pyx_GIVEREF(__pyx_v_val);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1057
+ *             if out == format_:
+ *                 raise ValueError
+ *             format_func = lambda format_, val: format_.format(val)             # <<<<<<<<<<<<<<
+ *         except:  # Not sure what exceptions might be raised
+ *             try:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_1lambda4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_1lambda4 = {"lambda4", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_1lambda4, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_1lambda4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_format_ = 0;
+  PyObject *__pyx_v_val = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda4 (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_format_2,&__pyx_n_s_val,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format_2)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_val)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("lambda4", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda4") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_format_ = values[0];
+    __pyx_v_val = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("lambda4", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_lambda_funcdef_lambda4(__pyx_self, __pyx_v_format_, __pyx_v_val);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_lambda4(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda4", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_format_, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_val);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_val);
+    __Pyx_GIVEREF(__pyx_v_val);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1063
+ *                 if out == format_:
+ *                     raise ValueError
+ *                 format_func = lambda format_, val: format_ % val             # <<<<<<<<<<<<<<
+ *             except:
+ *                 raise ValueError('Unable to parse format string {0}'
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_2lambda5(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_2lambda5 = {"lambda5", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_2lambda5, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_7astropy_2io_5ascii_7cparser_16auto_format_func_2lambda5(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_format_ = 0;
+  PyObject *__pyx_v_val = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda5 (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_format_2,&__pyx_n_s_val,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format_2)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_val)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("lambda5", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda5") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_format_ = values[0];
+    __pyx_v_val = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("lambda5", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_lambda_funcdef_lambda5(__pyx_self, __pyx_v_format_, __pyx_v_val);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_lambda5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda5", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyNumber_Remainder(__pyx_v_format_, __pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func.lambda5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "astropy/io/ascii/cparser.pyx":1035
+ *         return fill_values # cache for empty values doesn't matter for writing
+ * 
+ * def auto_format_func(format_, val):             # <<<<<<<<<<<<<<
+ *     """
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ */
+
+static PyObject *__pyx_pf_7astropy_2io_5ascii_7cparser_6auto_format_func(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_format_, PyObject *__pyx_v_val) {
+  PyObject *__pyx_v_format_func = NULL;
+  PyObject *__pyx_v_out = NULL;
+  PyObject *__pyx_v_err = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_t_9;
+  Py_ssize_t __pyx_t_10;
+  int __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  PyObject *__pyx_t_16 = NULL;
+  PyObject *__pyx_t_17 = NULL;
+  PyObject *__pyx_t_18 = NULL;
+  PyObject *__pyx_t_19 = NULL;
+  PyObject *__pyx_t_20 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("auto_format_func", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":1039
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ *     """
+ *     if six.callable(format_):             # <<<<<<<<<<<<<<
+ *         format_func = lambda format_, val: format_(val)
+ *         try:
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_callable); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (!__pyx_t_2) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_format_); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+    __Pyx_INCREF(__pyx_v_format_);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_format_);
+    __Pyx_GIVEREF(__pyx_v_format_);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_5) {
+
+    /* "astropy/io/ascii/cparser.pyx":1040
+ *     """
+ *     if six.callable(format_):
+ *         format_func = lambda format_, val: format_(val)             # <<<<<<<<<<<<<<
+ *         try:
+ *             out = format_func(format_, val)
+ */
+    __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_lambda3, 0, __pyx_n_s_auto_format_func_locals_lambda, NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_d, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_v_format_func = __pyx_t_1;
+    __pyx_t_1 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":1041
+ *     if six.callable(format_):
+ *         format_func = lambda format_, val: format_(val)
+ *         try:             # <<<<<<<<<<<<<<
+ *             out = format_func(format_, val)
+ *             if not isinstance(out, six.string_types):
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+      __Pyx_XGOTREF(__pyx_t_6);
+      __Pyx_XGOTREF(__pyx_t_7);
+      __Pyx_XGOTREF(__pyx_t_8);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":1042
+ *         format_func = lambda format_, val: format_(val)
+ *         try:
+ *             out = format_func(format_, val)             # <<<<<<<<<<<<<<
+ *             if not isinstance(out, six.string_types):
+ *                 raise ValueError('Format function for value {0} returned {1} instead of string type'
+ */
+        __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_v_format_);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_format_);
+        __Pyx_GIVEREF(__pyx_v_format_);
+        __Pyx_INCREF(__pyx_v_val);
+        PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_val);
+        __Pyx_GIVEREF(__pyx_v_val);
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_v_format_func, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_v_out = __pyx_t_3;
+        __pyx_t_3 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":1043
+ *         try:
+ *             out = format_func(format_, val)
+ *             if not isinstance(out, six.string_types):             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Format function for value {0} returned {1} instead of string type'
+ *                                  .format(val, type(val)))
+ */
+        __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_six); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_string_types); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_5 = PyObject_IsInstance(__pyx_v_out, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_9 = ((!(__pyx_t_5 != 0)) != 0);
+        if (__pyx_t_9) {
+
+          /* "astropy/io/ascii/cparser.pyx":1045
+ *             if not isinstance(out, six.string_types):
+ *                 raise ValueError('Format function for value {0} returned {1} instead of string type'
+ *                                  .format(val, type(val)))             # <<<<<<<<<<<<<<
+ *         except Exception as err:
+ *             raise ValueError('Format function for value {0} failed: {1}'
+ */
+          __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Format_function_for_value_0_retu, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+          __Pyx_GOTREF(__pyx_t_3);
+          __pyx_t_4 = NULL;
+          __pyx_t_10 = 0;
+          if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+            __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+            if (likely(__pyx_t_4)) {
+              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+              __Pyx_INCREF(__pyx_t_4);
+              __Pyx_INCREF(function);
+              __Pyx_DECREF_SET(__pyx_t_3, function);
+              __pyx_t_10 = 1;
+            }
+          }
+          __pyx_t_2 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          if (__pyx_t_4) {
+            PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+          }
+          __Pyx_INCREF(__pyx_v_val);
+          PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_10, __pyx_v_val);
+          __Pyx_GIVEREF(__pyx_v_val);
+          __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_val)));
+          PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_10, ((PyObject *)Py_TYPE(__pyx_v_val)));
+          __Pyx_GIVEREF(((PyObject *)Py_TYPE(__pyx_v_val)));
+          __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":1044
+ *             out = format_func(format_, val)
+ *             if not isinstance(out, six.string_types):
+ *                 raise ValueError('Format function for value {0} returned {1} instead of string type'             # <<<<<<<<<<<<<<
+ *                                  .format(val, type(val)))
+ *         except Exception as err:
+ */
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+          __Pyx_GOTREF(__pyx_t_3);
+          PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+          __Pyx_GIVEREF(__pyx_t_1);
+          __pyx_t_1 = 0;
+          __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+          __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        }
+      }
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+      goto __pyx_L11_try_end;
+      __pyx_L4_error:;
+      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":1046
+ *                 raise ValueError('Format function for value {0} returned {1} instead of string type'
+ *                                  .format(val, type(val)))
+ *         except Exception as err:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Format function for value {0} failed: {1}'
+ *                              .format(val, err))
+ */
+      __pyx_t_11 = PyErr_ExceptionMatches(__pyx_builtin_Exception);
+      if (__pyx_t_11) {
+        __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_3, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_3);
+        __pyx_v_err = __pyx_t_3;
+
+        /* "astropy/io/ascii/cparser.pyx":1048
+ *         except Exception as err:
+ *             raise ValueError('Format function for value {0} failed: {1}'
+ *                              .format(val, err))             # <<<<<<<<<<<<<<
+ *     else:
+ *         try:
+ */
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Format_function_for_value_0_fail, __pyx_n_s_format); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_13 = NULL;
+        __pyx_t_10 = 0;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_12))) {
+          __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_12);
+          if (likely(__pyx_t_13)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_12);
+            __Pyx_INCREF(__pyx_t_13);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_12, function);
+            __pyx_t_10 = 1;
+          }
+        }
+        __pyx_t_14 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        if (__pyx_t_13) {
+          PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13); __Pyx_GIVEREF(__pyx_t_13); __pyx_t_13 = NULL;
+        }
+        __Pyx_INCREF(__pyx_v_val);
+        PyTuple_SET_ITEM(__pyx_t_14, 0+__pyx_t_10, __pyx_v_val);
+        __Pyx_GIVEREF(__pyx_v_val);
+        __Pyx_INCREF(__pyx_v_err);
+        PyTuple_SET_ITEM(__pyx_t_14, 1+__pyx_t_10, __pyx_v_err);
+        __Pyx_GIVEREF(__pyx_v_err);
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_14, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":1047
+ *                                  .format(val, type(val)))
+ *         except Exception as err:
+ *             raise ValueError('Format function for value {0} failed: {1}'             # <<<<<<<<<<<<<<
+ *                              .format(val, err))
+ *     else:
+ */
+        __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4);
+        __Pyx_GIVEREF(__pyx_t_4);
+        __pyx_t_4 = 0;
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_12, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+      }
+      goto __pyx_L6_except_error;
+      __pyx_L6_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_6);
+      __Pyx_XGIVEREF(__pyx_t_7);
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+      goto __pyx_L1_error;
+      __pyx_L11_try_end:;
+    }
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "astropy/io/ascii/cparser.pyx":1050
+ *                              .format(val, err))
+ *     else:
+ *         try:             # <<<<<<<<<<<<<<
+ *             # Convert val to Python object with tolist().  See
+ *             # https://github.com/astropy/astropy/issues/148#issuecomment-3930809
+ */
+    {
+      __Pyx_ExceptionSave(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6);
+      __Pyx_XGOTREF(__pyx_t_8);
+      __Pyx_XGOTREF(__pyx_t_7);
+      __Pyx_XGOTREF(__pyx_t_6);
+      /*try:*/ {
+
+        /* "astropy/io/ascii/cparser.pyx":1053
+ *             # Convert val to Python object with tolist().  See
+ *             # https://github.com/astropy/astropy/issues/148#issuecomment-3930809
+ *             out = format_.format(val)             # <<<<<<<<<<<<<<
+ *             # Require that the format statement actually did something
+ *             if out == format_:
+ */
+        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_format_, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+          __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
+          if (likely(__pyx_t_1)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+            __Pyx_INCREF(__pyx_t_1);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_3, function);
+          }
+        }
+        if (!__pyx_t_1) {
+          __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_val); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+        } else {
+          __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+          __Pyx_INCREF(__pyx_v_val);
+          PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_val);
+          __Pyx_GIVEREF(__pyx_v_val);
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        }
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_v_out = __pyx_t_2;
+        __pyx_t_2 = 0;
+
+        /* "astropy/io/ascii/cparser.pyx":1055
+ *             out = format_.format(val)
+ *             # Require that the format statement actually did something
+ *             if out == format_:             # <<<<<<<<<<<<<<
+ *                 raise ValueError
+ *             format_func = lambda format_, val: format_.format(val)
+ */
+        __pyx_t_2 = PyObject_RichCompare(__pyx_v_out, __pyx_v_format_, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+        __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        if (__pyx_t_9) {
+
+          /* "astropy/io/ascii/cparser.pyx":1056
+ *             # Require that the format statement actually did something
+ *             if out == format_:
+ *                 raise ValueError             # <<<<<<<<<<<<<<
+ *             format_func = lambda format_, val: format_.format(val)
+ *         except:  # Not sure what exceptions might be raised
+ */
+          __Pyx_Raise(__pyx_builtin_ValueError, 0, 0, 0);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1056; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+        }
+
+        /* "astropy/io/ascii/cparser.pyx":1057
+ *             if out == format_:
+ *                 raise ValueError
+ *             format_func = lambda format_, val: format_.format(val)             # <<<<<<<<<<<<<<
+ *         except:  # Not sure what exceptions might be raised
+ *             try:
+ */
+        __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_1lambda4, 0, __pyx_n_s_auto_format_func_locals_lambda, NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_d, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_v_format_func = __pyx_t_2;
+        __pyx_t_2 = 0;
+      }
+      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      goto __pyx_L22_try_end;
+      __pyx_L15_error:;
+      __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+      __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+      __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+      /* "astropy/io/ascii/cparser.pyx":1058
+ *                 raise ValueError
+ *             format_func = lambda format_, val: format_.format(val)
+ *         except:  # Not sure what exceptions might be raised             # <<<<<<<<<<<<<<
+ *             try:
+ *                 out = format_ % val
+ */
+      /*except:*/ {
+        __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1058; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_GOTREF(__pyx_t_4);
+
+        /* "astropy/io/ascii/cparser.pyx":1059
+ *             format_func = lambda format_, val: format_.format(val)
+ *         except:  # Not sure what exceptions might be raised
+ *             try:             # <<<<<<<<<<<<<<
+ *                 out = format_ % val
+ *                 if out == format_:
+ */
+        {
+          __Pyx_ExceptionSave(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17);
+          __Pyx_XGOTREF(__pyx_t_15);
+          __Pyx_XGOTREF(__pyx_t_16);
+          __Pyx_XGOTREF(__pyx_t_17);
+          /*try:*/ {
+
+            /* "astropy/io/ascii/cparser.pyx":1060
+ *         except:  # Not sure what exceptions might be raised
+ *             try:
+ *                 out = format_ % val             # <<<<<<<<<<<<<<
+ *                 if out == format_:
+ *                     raise ValueError
+ */
+            __pyx_t_1 = PyNumber_Remainder(__pyx_v_format_, __pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_XDECREF_SET(__pyx_v_out, __pyx_t_1);
+            __pyx_t_1 = 0;
+
+            /* "astropy/io/ascii/cparser.pyx":1061
+ *             try:
+ *                 out = format_ % val
+ *                 if out == format_:             # <<<<<<<<<<<<<<
+ *                     raise ValueError
+ *                 format_func = lambda format_, val: format_ % val
+ */
+            __pyx_t_1 = PyObject_RichCompare(__pyx_v_out, __pyx_v_format_, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+            __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            if (__pyx_t_9) {
+
+              /* "astropy/io/ascii/cparser.pyx":1062
+ *                 out = format_ % val
+ *                 if out == format_:
+ *                     raise ValueError             # <<<<<<<<<<<<<<
+ *                 format_func = lambda format_, val: format_ % val
+ *             except:
+ */
+              __Pyx_Raise(__pyx_builtin_ValueError, 0, 0, 0);
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+            }
+
+            /* "astropy/io/ascii/cparser.pyx":1063
+ *                 if out == format_:
+ *                     raise ValueError
+ *                 format_func = lambda format_, val: format_ % val             # <<<<<<<<<<<<<<
+ *             except:
+ *                 raise ValueError('Unable to parse format string {0}'
+ */
+            __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_16auto_format_func_2lambda5, 0, __pyx_n_s_auto_format_func_locals_lambda, NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_d, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_XDECREF_SET(__pyx_v_format_func, __pyx_t_1);
+            __pyx_t_1 = 0;
+          }
+          __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+          __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
+          __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
+          goto __pyx_L33_try_end;
+          __pyx_L26_error:;
+          __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+          __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+          __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+          __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+          /* "astropy/io/ascii/cparser.pyx":1064
+ *                     raise ValueError
+ *                 format_func = lambda format_, val: format_ % val
+ *             except:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Unable to parse format string {0}'
+ *                                  .format(format_))
+ */
+          /*except:*/ {
+            __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func", __pyx_clineno, __pyx_lineno, __pyx_filename);
+            if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_12, &__pyx_t_14) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1064; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_GOTREF(__pyx_t_14);
+
+            /* "astropy/io/ascii/cparser.pyx":1066
+ *             except:
+ *                 raise ValueError('Unable to parse format string {0}'
+ *                                  .format(format_))             # <<<<<<<<<<<<<<
+ *     pprint._format_funcs[format_] = format_func
+ *     return out
+ */
+            __pyx_t_18 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unable_to_parse_format_string_0, __pyx_n_s_format); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1066; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+            __Pyx_GOTREF(__pyx_t_18);
+            __pyx_t_19 = NULL;
+            if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_18))) {
+              __pyx_t_19 = PyMethod_GET_SELF(__pyx_t_18);
+              if (likely(__pyx_t_19)) {
+                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_18);
+                __Pyx_INCREF(__pyx_t_19);
+                __Pyx_INCREF(function);
+                __Pyx_DECREF_SET(__pyx_t_18, function);
+              }
+            }
+            if (!__pyx_t_19) {
+              __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_18, __pyx_v_format_); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1066; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+              __Pyx_GOTREF(__pyx_t_13);
+            } else {
+              __pyx_t_20 = PyTuple_New(1+1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1066; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+              __Pyx_GOTREF(__pyx_t_20);
+              PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_19); __Pyx_GIVEREF(__pyx_t_19); __pyx_t_19 = NULL;
+              __Pyx_INCREF(__pyx_v_format_);
+              PyTuple_SET_ITEM(__pyx_t_20, 0+1, __pyx_v_format_);
+              __Pyx_GIVEREF(__pyx_v_format_);
+              __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_18, __pyx_t_20, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1066; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+              __Pyx_GOTREF(__pyx_t_13);
+              __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+            }
+            __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+
+            /* "astropy/io/ascii/cparser.pyx":1065
+ *                 format_func = lambda format_, val: format_ % val
+ *             except:
+ *                 raise ValueError('Unable to parse format string {0}'             # <<<<<<<<<<<<<<
+ *                                  .format(format_))
+ *     pprint._format_funcs[format_] = format_func
+ */
+            __pyx_t_18 = PyTuple_New(1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1065; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+            __Pyx_GOTREF(__pyx_t_18);
+            PyTuple_SET_ITEM(__pyx_t_18, 0, __pyx_t_13);
+            __Pyx_GIVEREF(__pyx_t_13);
+            __pyx_t_13 = 0;
+            __pyx_t_13 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_18, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1065; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+            __Pyx_GOTREF(__pyx_t_13);
+            __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+            __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+            __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1065; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+          }
+          __pyx_L28_except_error:;
+          __Pyx_XGIVEREF(__pyx_t_15);
+          __Pyx_XGIVEREF(__pyx_t_16);
+          __Pyx_XGIVEREF(__pyx_t_17);
+          __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17);
+          goto __pyx_L17_except_error;
+          __pyx_L33_try_end:;
+        }
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        goto __pyx_L16_exception_handled;
+      }
+      __pyx_L17_except_error:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_7);
+      __Pyx_XGIVEREF(__pyx_t_6);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_7, __pyx_t_6);
+      goto __pyx_L1_error;
+      __pyx_L16_exception_handled:;
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_7);
+      __Pyx_XGIVEREF(__pyx_t_6);
+      __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_7, __pyx_t_6);
+      __pyx_L22_try_end:;
+    }
+  }
+  __pyx_L3:;
+
+  /* "astropy/io/ascii/cparser.pyx":1067
+ *                 raise ValueError('Unable to parse format string {0}'
+ *                                  .format(format_))
+ *     pprint._format_funcs[format_] = format_func             # <<<<<<<<<<<<<<
+ *     return out
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_pprint); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_format_funcs); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (unlikely(PyObject_SetItem(__pyx_t_3, __pyx_v_format_, __pyx_v_format_func) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":1068
+ *                                  .format(format_))
+ *     pprint._format_funcs[format_] = format_func
+ *     return out             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_out);
+  __pyx_r = __pyx_v_out;
+  goto __pyx_L0;
+
+  /* "astropy/io/ascii/cparser.pyx":1035
+ *         return fill_values # cache for empty values doesn't matter for writing
+ * 
+ * def auto_format_func(format_, val):             # <<<<<<<<<<<<<<
+ *     """
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_XDECREF(__pyx_t_18);
+  __Pyx_XDECREF(__pyx_t_19);
+  __Pyx_XDECREF(__pyx_t_20);
+  __Pyx_AddTraceback("astropy.io.ascii.cparser.auto_format_func", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_format_func);
+  __Pyx_XDECREF(__pyx_v_out);
+  __Pyx_XDECREF(__pyx_v_err);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L14;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__39, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_FileString(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)o);
+  p->fhandle = Py_None; Py_INCREF(Py_None);
+  p->mmap = Py_None; Py_INCREF(Py_None);
+  p->buf.obj = NULL;
+  if (unlikely(__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_1__cinit__(o, a, k) < 0)) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_FileString(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_3__dealloc__(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_CLEAR(p->fhandle);
+  Py_CLEAR(p->mmap);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_FileString(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)o;
+  if (p->fhandle) {
+    e = (*v)(p->fhandle, a); if (e) return e;
+  }
+  if (p->mmap) {
+    e = (*v)(p->mmap, a); if (e) return e;
+  }
+  if (p->buf.obj) {
+    e = (*v)(p->buf.obj, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser_FileString(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)o;
+  tmp = ((PyObject*)p->fhandle);
+  p->fhandle = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->mmap);
+  p->mmap = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  Py_CLEAR(p->buf.obj);
+  return 0;
+}
+static PyObject *__pyx_sq_item_7astropy_2io_5ascii_7cparser_FileString(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyMethodDef __pyx_methods_7astropy_2io_5ascii_7cparser_FileString[] = {
+  {"splitlines", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_9splitlines, METH_NOARGS, __pyx_doc_7astropy_2io_5ascii_7cparser_10FileString_8splitlines},
+  {0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_FileString = {
+  __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_5__len__, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_7astropy_2io_5ascii_7cparser_FileString, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_FileString = {
+  __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_5__len__, /*mp_length*/
+  __pyx_pw_7astropy_2io_5ascii_7cparser_10FileString_7__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser_FileString = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.FileString", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_FileString, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  &__pyx_tp_as_sequence_FileString, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_FileString, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A wrapper class for a memory-mapped file pointer.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_FileString, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser_FileString, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_7astropy_2io_5ascii_7cparser_FileString, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser_FileString, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_CParser __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_CParser(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)o);
+  p->__pyx_vtab = __pyx_vtabptr_7astropy_2io_5ascii_7cparser_CParser;
+  p->names = Py_None; Py_INCREF(Py_None);
+  p->data_end = Py_None; Py_INCREF(Py_None);
+  p->include_names = Py_None; Py_INCREF(Py_None);
+  p->exclude_names = Py_None; Py_INCREF(Py_None);
+  p->fill_values = Py_None; Py_INCREF(Py_None);
+  p->fill_empty = Py_None; Py_INCREF(Py_None);
+  p->fill_include_names = Py_None; Py_INCREF(Py_None);
+  p->fill_exclude_names = Py_None; Py_INCREF(Py_None);
+  p->fill_names = Py_None; Py_INCREF(Py_None);
+  p->source_bytes = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->parallel = Py_None; Py_INCREF(Py_None);
+  p->use_cols = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->source = Py_None; Py_INCREF(Py_None);
+  p->header_start = Py_None; Py_INCREF(Py_None);
+  if (unlikely(__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_1__cinit__(o, a, k) < 0)) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_CParser(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_3__dealloc__(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_CLEAR(p->names);
+  Py_CLEAR(p->data_end);
+  Py_CLEAR(p->include_names);
+  Py_CLEAR(p->exclude_names);
+  Py_CLEAR(p->fill_values);
+  Py_CLEAR(p->fill_empty);
+  Py_CLEAR(p->fill_include_names);
+  Py_CLEAR(p->fill_exclude_names);
+  Py_CLEAR(p->fill_names);
+  Py_CLEAR(p->source_bytes);
+  Py_CLEAR(p->parallel);
+  Py_CLEAR(p->use_cols);
+  Py_CLEAR(p->source);
+  Py_CLEAR(p->header_start);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_CParser(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)o;
+  if (p->names) {
+    e = (*v)(p->names, a); if (e) return e;
+  }
+  if (p->data_end) {
+    e = (*v)(p->data_end, a); if (e) return e;
+  }
+  if (p->include_names) {
+    e = (*v)(p->include_names, a); if (e) return e;
+  }
+  if (p->exclude_names) {
+    e = (*v)(p->exclude_names, a); if (e) return e;
+  }
+  if (p->fill_values) {
+    e = (*v)(p->fill_values, a); if (e) return e;
+  }
+  if (p->fill_empty) {
+    e = (*v)(p->fill_empty, a); if (e) return e;
+  }
+  if (p->fill_include_names) {
+    e = (*v)(p->fill_include_names, a); if (e) return e;
+  }
+  if (p->fill_exclude_names) {
+    e = (*v)(p->fill_exclude_names, a); if (e) return e;
+  }
+  if (p->fill_names) {
+    e = (*v)(p->fill_names, a); if (e) return e;
+  }
+  if (p->parallel) {
+    e = (*v)(p->parallel, a); if (e) return e;
+  }
+  if (p->use_cols) {
+    e = (*v)(p->use_cols, a); if (e) return e;
+  }
+  if (p->source) {
+    e = (*v)(p->source, a); if (e) return e;
+  }
+  if (p->header_start) {
+    e = (*v)(p->header_start, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser_CParser(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)o;
+  tmp = ((PyObject*)p->names);
+  p->names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->data_end);
+  p->data_end = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->include_names);
+  p->include_names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->exclude_names);
+  p->exclude_names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_values);
+  p->fill_values = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_empty);
+  p->fill_empty = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_include_names);
+  p->fill_include_names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_exclude_names);
+  p->fill_exclude_names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_names);
+  p->fill_names = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->parallel);
+  p->parallel = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->use_cols);
+  p->use_cols = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->source);
+  p->source = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->header_start);
+  p->header_start = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_width(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_1__get__(o);
+}
+
+static int __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_width(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5width_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_source(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_1__get__(o);
+}
+
+static int __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_source(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_6source_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_header_start(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_1__get__(o);
+}
+
+static int __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_header_start(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_12header_start_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_7astropy_2io_5ascii_7cparser_CParser[] = {
+  {"setup_tokenizer", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_5setup_tokenizer, METH_O, 0},
+  {"read_header", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_7read_header, METH_NOARGS, 0},
+  {"read", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_9read, METH_VARARGS|METH_KEYWORDS, 0},
+  {"_read_parallel", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_11_read_parallel, METH_VARARGS|METH_KEYWORDS, 0},
+  {"get_names", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_13get_names, METH_NOARGS, 0},
+  {"set_names", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_15set_names, METH_O, 0},
+  {"__reduce__", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_7CParser_17__reduce__, METH_NOARGS, 0},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_7astropy_2io_5ascii_7cparser_CParser[] = {
+  {(char *)"width", __pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_width, __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_width, 0, 0},
+  {(char *)"source", __pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_source, __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_source, 0, 0},
+  {(char *)"header_start", __pyx_getprop_7astropy_2io_5ascii_7cparser_7CParser_header_start, __pyx_setprop_7astropy_2io_5ascii_7cparser_7CParser_header_start, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser_CParser = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.CParser", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_CParser, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A fast Cython parser class which uses underlying C code\n    for tokenization.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_CParser, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser_CParser, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_7astropy_2io_5ascii_7cparser_CParser, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_7astropy_2io_5ascii_7cparser_CParser, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser_CParser, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_7astropy_2io_5ascii_7cparser_FastWriter __pyx_vtable_7astropy_2io_5ascii_7cparser_FastWriter;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser_FastWriter(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)o);
+  p->__pyx_vtab = __pyx_vtabptr_7astropy_2io_5ascii_7cparser_FastWriter;
+  p->table = Py_None; Py_INCREF(Py_None);
+  p->use_names = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->fill_values = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->fill_cols = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->col_iters = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->formats = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->format_funcs = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->types = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->line_comments = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->quotechar = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->delimiter = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  p->comment = Py_None; Py_INCREF(Py_None);
+  if (unlikely(__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_1__cinit__(o, a, k) < 0)) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_FastWriter(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->table);
+  Py_CLEAR(p->use_names);
+  Py_CLEAR(p->fill_values);
+  Py_CLEAR(p->fill_cols);
+  Py_CLEAR(p->col_iters);
+  Py_CLEAR(p->formats);
+  Py_CLEAR(p->format_funcs);
+  Py_CLEAR(p->types);
+  Py_CLEAR(p->line_comments);
+  Py_CLEAR(p->quotechar);
+  Py_CLEAR(p->delimiter);
+  Py_CLEAR(p->comment);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_FastWriter(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)o;
+  if (p->table) {
+    e = (*v)(p->table, a); if (e) return e;
+  }
+  if (p->use_names) {
+    e = (*v)(p->use_names, a); if (e) return e;
+  }
+  if (p->fill_values) {
+    e = (*v)(p->fill_values, a); if (e) return e;
+  }
+  if (p->fill_cols) {
+    e = (*v)(p->fill_cols, a); if (e) return e;
+  }
+  if (p->col_iters) {
+    e = (*v)(p->col_iters, a); if (e) return e;
+  }
+  if (p->formats) {
+    e = (*v)(p->formats, a); if (e) return e;
+  }
+  if (p->format_funcs) {
+    e = (*v)(p->format_funcs, a); if (e) return e;
+  }
+  if (p->types) {
+    e = (*v)(p->types, a); if (e) return e;
+  }
+  if (p->line_comments) {
+    e = (*v)(p->line_comments, a); if (e) return e;
+  }
+  if (p->comment) {
+    e = (*v)(p->comment, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser_FastWriter(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *)o;
+  tmp = ((PyObject*)p->table);
+  p->table = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->use_names);
+  p->use_names = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_values);
+  p->fill_values = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->fill_cols);
+  p->fill_cols = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->col_iters);
+  p->col_iters = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->formats);
+  p->formats = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->format_funcs);
+  p->format_funcs = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->types);
+  p->types = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->line_comments);
+  p->line_comments = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->comment);
+  p->comment = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_7astropy_2io_5ascii_7cparser_FastWriter[] = {
+  {"_write_header", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_3_write_header, METH_VARARGS|METH_KEYWORDS, 0},
+  {"write", (PyCFunction)__pyx_pw_7astropy_2io_5ascii_7cparser_10FastWriter_5write, METH_VARARGS|METH_KEYWORDS, 0},
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser_FastWriter = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.FastWriter", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser_FastWriter, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A fast Cython writing class for writing tables\n    as ASCII data.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser_FastWriter, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser_FastWriter, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_7astropy_2io_5ascii_7cparser_FastWriter, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser_FastWriter, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_v_self);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)o;
+  if (p->__pyx_v_self) {
+    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines *)o;
+  tmp = ((PyObject*)p->__pyx_v_self);
+  p->__pyx_v_self = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_FileString *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct__splitlines", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_v_col_chunks);
+  Py_CLEAR(p->__pyx_v_self);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)o;
+  if (p->__pyx_v_col_chunks) {
+    e = (*v)(p->__pyx_v_col_chunks, a); if (e) return e;
+  }
+  if (p->__pyx_v_self) {
+    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)o;
+  tmp = ((PyObject*)p->__pyx_v_col_chunks);
+  p->__pyx_v_col_chunks = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_self);
+  p->__pyx_v_self = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_1__read_parallel", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_name);
+  Py_CLEAR(p->__pyx_t_0);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
+  }
+  if (p->__pyx_v_name) {
+    e = (*v)(p->__pyx_v_name, a); if (e) return e;
+  }
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr *)o;
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_name);
+  p->__pyx_v_name = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_2_genexpr", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_name);
+  Py_CLEAR(p->__pyx_t_0);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
+  }
+  if (p->__pyx_v_name) {
+    e = (*v)(p->__pyx_v_name, a); if (e) return e;
+  }
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr *)o;
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_name);
+  p->__pyx_v_name = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_3_genexpr", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_col_chunk);
+  Py_CLEAR(p->__pyx_t_0);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
+  }
+  if (p->__pyx_v_col_chunk) {
+    e = (*v)(p->__pyx_v_col_chunk, a); if (e) return e;
+  }
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr *)o;
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_col_chunk);
+  p->__pyx_v_col_chunk = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_4_genexpr", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_v_self);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)o;
+  if (p->__pyx_v_self) {
+    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)o;
+  tmp = ((PyObject*)p->__pyx_v_self);
+  p->__pyx_v_self = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_5__read_chunk", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr[8];
+static int __pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr = 0;
+
+static PyObject *__pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr)))) {
+    o = (PyObject*)__pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr[--__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr];
+    memset(o, 0, sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr));
+    (void) PyObject_INIT(o, t);
+    PyObject_GC_Track(o);
+  } else {
+    o = (*t->tp_alloc)(t, 0);
+    if (unlikely(!o)) return 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(PyObject *o) {
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_name);
+  Py_CLEAR(p->__pyx_t_0);
+  if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr)))) {
+    __pyx_freelist_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr[__pyx_freecount_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr++] = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)o);
+  } else {
+    (*Py_TYPE(o)->tp_free)(o);
+  }
+}
+
+static int __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
+  }
+  if (p->__pyx_v_name) {
+    e = (*v)(p->__pyx_v_name, a); if (e) return e;
+  }
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr *)o;
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_name);
+  p->__pyx_v_name = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyTypeObject __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "astropy.io.ascii.cparser.__pyx_scope_struct_6_genexpr", /*tp_name*/
+  sizeof(struct __pyx_obj_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "cparser",
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0},
+  {&__pyx_kp_s_0, __pyx_k_0, sizeof(__pyx_k_0), 0, 0, 1, 0},
+  {&__pyx_kp_s_0_1, __pyx_k_0_1, sizeof(__pyx_k_0_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_An_instance_of_this_class_is_th, __pyx_k_An_instance_of_this_class_is_th, sizeof(__pyx_k_An_instance_of_this_class_is_th), 0, 0, 1, 0},
+  {&__pyx_n_s_CParserError, __pyx_k_CParserError, sizeof(__pyx_k_CParserError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Column_0_failed_to_convert, __pyx_k_Column_0_failed_to_convert, sizeof(__pyx_k_Column_0_failed_to_convert), 0, 0, 1, 0},
+  {&__pyx_n_s_ERR_CODES, __pyx_k_ERR_CODES, sizeof(__pyx_k_ERR_CODES), 0, 0, 1, 1},
+  {&__pyx_n_s_Empty, __pyx_k_Empty, sizeof(__pyx_k_Empty), 0, 0, 1, 1},
+  {&__pyx_n_s_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 0, 0, 1, 1},
+  {&__pyx_n_s_FastOptionsError, __pyx_k_FastOptionsError, sizeof(__pyx_k_FastOptionsError), 0, 0, 1, 1},
+  {&__pyx_n_s_FileString_splitlines, __pyx_k_FileString_splitlines, sizeof(__pyx_k_FileString_splitlines), 0, 0, 1, 1},
+  {&__pyx_kp_s_File_0_could_not_be_opened, __pyx_k_File_0_could_not_be_opened, sizeof(__pyx_k_File_0_could_not_be_opened), 0, 0, 1, 0},
+  {&__pyx_kp_s_Format_function_for_value_0_fail, __pyx_k_Format_function_for_value_0_fail, sizeof(__pyx_k_Format_function_for_value_0_fail), 0, 0, 1, 0},
+  {&__pyx_kp_s_Format_function_for_value_0_retu, __pyx_k_Format_function_for_value_0_retu, sizeof(__pyx_k_Format_function_for_value_0_retu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Format_of_fill_values_must_be_ba, __pyx_k_Format_of_fill_values_must_be_ba, sizeof(__pyx_k_Format_of_fill_values_must_be_ba), 0, 0, 1, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_Full, __pyx_k_Full, sizeof(__pyx_k_Full), 0, 0, 1, 1},
+  {&__pyx_n_s_IOError, __pyx_k_IOError, sizeof(__pyx_k_IOError), 0, 0, 1, 1},
+  {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1},
+  {&__pyx_n_s_InconsistentTableError, __pyx_k_InconsistentTableError, sizeof(__pyx_k_InconsistentTableError), 0, 0, 1, 1},
+  {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Input_table_must_be_a_file_like, __pyx_k_Input_table_must_be_a_file_like, sizeof(__pyx_k_Input_table_must_be_a_file_like), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_parameter_in_fast_reader, __pyx_k_Invalid_parameter_in_fast_reader, sizeof(__pyx_k_Invalid_parameter_in_fast_reader), 0, 0, 1, 0},
+  {&__pyx_n_s_MaskError, __pyx_k_MaskError, sizeof(__pyx_k_MaskError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Multiprocessing_is_not_yet_suppo, __pyx_k_Multiprocessing_is_not_yet_suppo, sizeof(__pyx_k_Multiprocessing_is_not_yet_suppo), 0, 0, 1, 0},
+  {&__pyx_n_s_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 0, 1, 1},
+  {&__pyx_kp_s_No_data_lines_found_C_reader_can, __pyx_k_No_data_lines_found_C_reader_can, sizeof(__pyx_k_No_data_lines_found_C_reader_can), 0, 0, 1, 0},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_NotImplementedError, __pyx_k_NotImplementedError, sizeof(__pyx_k_NotImplementedError), 0, 0, 1, 1},
+  {&__pyx_n_s_PROT_READ, __pyx_k_PROT_READ, sizeof(__pyx_k_PROT_READ), 0, 0, 1, 1},
+  {&__pyx_n_s_PY2, __pyx_k_PY2, sizeof(__pyx_k_PY2), 0, 0, 1, 1},
+  {&__pyx_n_s_ParameterError, __pyx_k_ParameterError, sizeof(__pyx_k_ParameterError), 0, 0, 1, 1},
+  {&__pyx_n_s_Process, __pyx_k_Process, sizeof(__pyx_k_Process), 0, 0, 1, 1},
+  {&__pyx_n_s_QUOTE_MINIMAL, __pyx_k_QUOTE_MINIMAL, sizeof(__pyx_k_QUOTE_MINIMAL), 0, 0, 1, 1},
+  {&__pyx_n_s_Queue, __pyx_k_Queue, sizeof(__pyx_k_Queue), 0, 0, 1, 1},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 0, 1, 1},
+  {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+  {&__pyx_n_s_U, __pyx_k_U, sizeof(__pyx_k_U), 0, 0, 1, 1},
+  {&__pyx_kp_s_Unable_to_parse_format_string_0, __pyx_k_Unable_to_parse_format_string_0, sizeof(__pyx_k_Unable_to_parse_format_string_0), 0, 0, 1, 0},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_kp_s__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 0, 1, 0},
+  {&__pyx_kp_s__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 0, 1, 0},
+  {&__pyx_kp_s__12, __pyx_k__12, sizeof(__pyx_k__12), 0, 0, 1, 0},
+  {&__pyx_kp_s__16, __pyx_k__16, sizeof(__pyx_k__16), 0, 0, 1, 0},
+  {&__pyx_kp_s__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 0, 1, 0},
+  {&__pyx_kp_s__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 0, 1, 0},
+  {&__pyx_kp_s__29, __pyx_k__29, sizeof(__pyx_k__29), 0, 0, 1, 0},
+  {&__pyx_kp_b__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 0, 0},
+  {&__pyx_kp_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 0},
+  {&__pyx_kp_s__30, __pyx_k__30, sizeof(__pyx_k__30), 0, 0, 1, 0},
+  {&__pyx_kp_s_an_error_occurred_while_advancin, __pyx_k_an_error_occurred_while_advancin, sizeof(__pyx_k_an_error_occurred_while_advancin), 0, 0, 1, 0},
+  {&__pyx_kp_s_an_error_occurred_while_advancin_2, __pyx_k_an_error_occurred_while_advancin_2, sizeof(__pyx_k_an_error_occurred_while_advancin_2), 0, 0, 1, 0},
+  {&__pyx_kp_s_an_error_occurred_while_parsing, __pyx_k_an_error_occurred_while_parsing, sizeof(__pyx_k_an_error_occurred_while_parsing), 0, 0, 1, 0},
+  {&__pyx_kp_s_an_error_occurred_while_tokenizi, __pyx_k_an_error_occurred_while_tokenizi, sizeof(__pyx_k_an_error_occurred_while_tokenizi), 0, 0, 1, 0},
+  {&__pyx_kp_s_an_error_occurred_while_tokenizi_2, __pyx_k_an_error_occurred_while_tokenizi_2, sizeof(__pyx_k_an_error_occurred_while_tokenizi_2), 0, 0, 1, 0},
+  {&__pyx_n_s_any, __pyx_k_any, sizeof(__pyx_k_any), 0, 0, 1, 1},
+  {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
+  {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+  {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+  {&__pyx_n_s_ascii, __pyx_k_ascii, sizeof(__pyx_k_ascii), 0, 0, 1, 1},
+  {&__pyx_n_s_astropy_io_ascii_cparser, __pyx_k_astropy_io_ascii_cparser, sizeof(__pyx_k_astropy_io_ascii_cparser), 0, 0, 1, 1},
+  {&__pyx_n_s_auto_format_func, __pyx_k_auto_format_func, sizeof(__pyx_k_auto_format_func), 0, 0, 1, 1},
+  {&__pyx_n_s_auto_format_func_locals_lambda, __pyx_k_auto_format_func_locals_lambda, sizeof(__pyx_k_auto_format_func_locals_lambda), 0, 0, 1, 1},
+  {&__pyx_n_s_callable, __pyx_k_callable, sizeof(__pyx_k_callable), 0, 0, 1, 1},
+  {&__pyx_n_s_ceil, __pyx_k_ceil, sizeof(__pyx_k_ceil), 0, 0, 1, 1},
+  {&__pyx_n_s_chr, __pyx_k_chr, sizeof(__pyx_k_chr), 0, 0, 1, 1},
+  {&__pyx_n_s_chunk_tokenizer, __pyx_k_chunk_tokenizer, sizeof(__pyx_k_chunk_tokenizer), 0, 0, 1, 1},
+  {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1},
+  {&__pyx_n_s_col, __pyx_k_col, sizeof(__pyx_k_col), 0, 0, 1, 1},
+  {&__pyx_kp_s_col_0, __pyx_k_col_0, sizeof(__pyx_k_col_0), 0, 0, 1, 0},
+  {&__pyx_n_s_colnames, __pyx_k_colnames, sizeof(__pyx_k_colnames), 0, 0, 1, 1},
+  {&__pyx_n_s_columns, __pyx_k_columns, sizeof(__pyx_k_columns), 0, 0, 1, 1},
+  {&__pyx_n_s_comment, __pyx_k_comment, sizeof(__pyx_k_comment), 0, 0, 1, 1},
+  {&__pyx_n_s_comments, __pyx_k_comments, sizeof(__pyx_k_comments), 0, 0, 1, 1},
+  {&__pyx_n_s_concatenate, __pyx_k_concatenate, sizeof(__pyx_k_concatenate), 0, 0, 1, 1},
+  {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
+  {&__pyx_n_s_copy_cparser, __pyx_k_copy_cparser, sizeof(__pyx_k_copy_cparser), 0, 0, 1, 1},
+  {&__pyx_n_s_core, __pyx_k_core, sizeof(__pyx_k_core), 0, 0, 1, 1},
+  {&__pyx_n_s_cpu_count, __pyx_k_cpu_count, sizeof(__pyx_k_cpu_count), 0, 0, 1, 1},
+  {&__pyx_n_s_csv, __pyx_k_csv, sizeof(__pyx_k_csv), 0, 0, 1, 1},
+  {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+  {&__pyx_n_s_data_end, __pyx_k_data_end, sizeof(__pyx_k_data_end), 0, 0, 1, 1},
+  {&__pyx_n_s_data_start, __pyx_k_data_start, sizeof(__pyx_k_data_start), 0, 0, 1, 1},
+  {&__pyx_n_s_delimiter, __pyx_k_delimiter, sizeof(__pyx_k_delimiter), 0, 0, 1, 1},
+  {&__pyx_n_s_difference_update, __pyx_k_difference_update, sizeof(__pyx_k_difference_update), 0, 0, 1, 1},
+  {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
+  {&__pyx_n_s_doublequote, __pyx_k_doublequote, sizeof(__pyx_k_doublequote), 0, 0, 1, 1},
+  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_e, __pyx_k_e, sizeof(__pyx_k_e), 0, 0, 1, 1},
+  {&__pyx_n_s_el, __pyx_k_el, sizeof(__pyx_k_el), 0, 0, 1, 1},
+  {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+  {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1},
+  {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1},
+  {&__pyx_n_s_enter, __pyx_k_enter, sizeof(__pyx_k_enter), 0, 0, 1, 1},
+  {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+  {&__pyx_n_s_err, __pyx_k_err, sizeof(__pyx_k_err), 0, 0, 1, 1},
+  {&__pyx_n_s_escapechar, __pyx_k_escapechar, sizeof(__pyx_k_escapechar), 0, 0, 1, 1},
+  {&__pyx_n_s_exclude_names, __pyx_k_exclude_names, sizeof(__pyx_k_exclude_names), 0, 0, 1, 1},
+  {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1},
+  {&__pyx_n_s_extern, __pyx_k_extern, sizeof(__pyx_k_extern), 0, 0, 1, 1},
+  {&__pyx_n_s_fast_reader, __pyx_k_fast_reader, sizeof(__pyx_k_fast_reader), 0, 0, 1, 1},
+  {&__pyx_kp_s_fast_reader_cannot_be_False_for, __pyx_k_fast_reader_cannot_be_False_for, sizeof(__pyx_k_fast_reader_cannot_be_False_for), 0, 0, 1, 0},
+  {&__pyx_n_s_fast_writer, __pyx_k_fast_writer, sizeof(__pyx_k_fast_writer), 0, 0, 1, 1},
+  {&__pyx_n_s_fileno, __pyx_k_fileno, sizeof(__pyx_k_fileno), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_empty, __pyx_k_fill_empty, sizeof(__pyx_k_fill_empty), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_exclude_names, __pyx_k_fill_exclude_names, sizeof(__pyx_k_fill_exclude_names), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_extra_cols, __pyx_k_fill_extra_cols, sizeof(__pyx_k_fill_extra_cols), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_include_names, __pyx_k_fill_include_names, sizeof(__pyx_k_fill_include_names), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_names, __pyx_k_fill_names, sizeof(__pyx_k_fill_names), 0, 0, 1, 1},
+  {&__pyx_n_s_fill_values, __pyx_k_fill_values, sizeof(__pyx_k_fill_values), 0, 0, 1, 1},
+  {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1},
+  {&__pyx_n_s_fname, __pyx_k_fname, sizeof(__pyx_k_fname), 0, 0, 1, 1},
+  {&__pyx_n_s_force, __pyx_k_force, sizeof(__pyx_k_force), 0, 0, 1, 1},
+  {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+  {&__pyx_n_s_format_2, __pyx_k_format_2, sizeof(__pyx_k_format_2), 0, 0, 1, 1},
+  {&__pyx_n_s_format_func, __pyx_k_format_func, sizeof(__pyx_k_format_func), 0, 0, 1, 1},
+  {&__pyx_n_s_format_funcs, __pyx_k_format_funcs, sizeof(__pyx_k_format_funcs), 0, 0, 1, 1},
+  {&__pyx_n_s_formats, __pyx_k_formats, sizeof(__pyx_k_formats), 0, 0, 1, 1},
+  {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1},
+  {&__pyx_n_s_get, __pyx_k_get, sizeof(__pyx_k_get), 0, 0, 1, 1},
+  {&__pyx_n_s_get_fill_values, __pyx_k_get_fill_values, sizeof(__pyx_k_get_fill_values), 0, 0, 1, 1},
+  {&__pyx_n_s_get_names, __pyx_k_get_names, sizeof(__pyx_k_get_names), 0, 0, 1, 1},
+  {&__pyx_n_s_get_readable_fileobj, __pyx_k_get_readable_fileobj, sizeof(__pyx_k_get_readable_fileobj), 0, 0, 1, 1},
+  {&__pyx_n_s_header_output, __pyx_k_header_output, sizeof(__pyx_k_header_output), 0, 0, 1, 1},
+  {&__pyx_n_s_header_start, __pyx_k_header_start, sizeof(__pyx_k_header_start), 0, 0, 1, 1},
+  {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_include_names, __pyx_k_include_names, sizeof(__pyx_k_include_names), 0, 0, 1, 1},
+  {&__pyx_n_s_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 0, 1, 1},
+  {&__pyx_n_s_intersection_update, __pyx_k_intersection_update, sizeof(__pyx_k_intersection_update), 0, 0, 1, 1},
+  {&__pyx_kp_s_invalid_line_supplied, __pyx_k_invalid_line_supplied, sizeof(__pyx_k_invalid_line_supplied), 0, 0, 1, 0},
+  {&__pyx_n_s_iteritems, __pyx_k_iteritems, sizeof(__pyx_k_iteritems), 0, 0, 1, 1},
+  {&__pyx_n_s_itervalues, __pyx_k_itervalues, sizeof(__pyx_k_itervalues), 0, 0, 1, 1},
+  {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1},
+  {&__pyx_n_s_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 0, 1, 1},
+  {&__pyx_n_s_kwargs, __pyx_k_kwargs, sizeof(__pyx_k_kwargs), 0, 0, 1, 1},
+  {&__pyx_n_s_l, __pyx_k_l, sizeof(__pyx_k_l), 0, 0, 1, 1},
+  {&__pyx_n_s_lambda, __pyx_k_lambda, sizeof(__pyx_k_lambda), 0, 0, 1, 1},
+  {&__pyx_n_s_line_comments, __pyx_k_line_comments, sizeof(__pyx_k_line_comments), 0, 0, 1, 1},
+  {&__pyx_n_s_linesep, __pyx_k_linesep, sizeof(__pyx_k_linesep), 0, 0, 1, 1},
+  {&__pyx_n_s_lineterminator, __pyx_k_lineterminator, sizeof(__pyx_k_lineterminator), 0, 0, 1, 1},
+  {&__pyx_n_s_ma, __pyx_k_ma, sizeof(__pyx_k_ma), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_n_s_mask, __pyx_k_mask, sizeof(__pyx_k_mask), 0, 0, 1, 1},
+  {&__pyx_n_s_masked, __pyx_k_masked, sizeof(__pyx_k_masked), 0, 0, 1, 1},
+  {&__pyx_n_s_masked_array, __pyx_k_masked_array, sizeof(__pyx_k_masked_array), 0, 0, 1, 1},
+  {&__pyx_n_s_math, __pyx_k_math, sizeof(__pyx_k_math), 0, 0, 1, 1},
+  {&__pyx_n_s_meta, __pyx_k_meta, sizeof(__pyx_k_meta), 0, 0, 1, 1},
+  {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1},
+  {&__pyx_n_s_mmap, __pyx_k_mmap, sizeof(__pyx_k_mmap), 0, 0, 1, 1},
+  {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1},
+  {&__pyx_n_s_multiprocessing, __pyx_k_multiprocessing, sizeof(__pyx_k_multiprocessing), 0, 0, 1, 1},
+  {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+  {&__pyx_n_s_names, __pyx_k_names, sizeof(__pyx_k_names), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_kp_s_no_error, __pyx_k_no_error, sizeof(__pyx_k_no_error), 0, 0, 1, 0},
+  {&__pyx_kp_s_not_enough_columns_found_in_line, __pyx_k_not_enough_columns_found_in_line, sizeof(__pyx_k_not_enough_columns_found_in_line), 0, 0, 1, 0},
+  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+  {&__pyx_n_s_nt, __pyx_k_nt, sizeof(__pyx_k_nt), 0, 0, 1, 1},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
+  {&__pyx_n_s_ord, __pyx_k_ord, sizeof(__pyx_k_ord), 0, 0, 1, 1},
+  {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
+  {&__pyx_n_s_out, __pyx_k_out, sizeof(__pyx_k_out), 0, 0, 1, 1},
+  {&__pyx_n_s_output, __pyx_k_output, sizeof(__pyx_k_output), 0, 0, 1, 1},
+  {&__pyx_n_s_output_types, __pyx_k_output_types, sizeof(__pyx_k_output_types), 0, 0, 1, 1},
+  {&__pyx_kp_s_overflow_error, __pyx_k_overflow_error, sizeof(__pyx_k_overflow_error), 0, 0, 1, 0},
+  {&__pyx_n_s_parallel, __pyx_k_parallel, sizeof(__pyx_k_parallel), 0, 0, 1, 1},
+  {&__pyx_n_s_parser, __pyx_k_parser, sizeof(__pyx_k_parser), 0, 0, 1, 1},
+  {&__pyx_n_s_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 0, 0, 1, 1},
+  {&__pyx_n_s_pprint, __pyx_k_pprint, sizeof(__pyx_k_pprint), 0, 0, 1, 1},
+  {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
+  {&__pyx_n_s_prot, __pyx_k_prot, sizeof(__pyx_k_prot), 0, 0, 1, 1},
+  {&__pyx_n_s_put, __pyx_k_put, sizeof(__pyx_k_put), 0, 0, 1, 1},
+  {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+  {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
+  {&__pyx_n_s_queue, __pyx_k_queue, sizeof(__pyx_k_queue), 0, 0, 1, 1},
+  {&__pyx_n_s_quotechar, __pyx_k_quotechar, sizeof(__pyx_k_quotechar), 0, 0, 1, 1},
+  {&__pyx_n_s_quoting, __pyx_k_quoting, sizeof(__pyx_k_quoting), 0, 0, 1, 1},
+  {&__pyx_n_s_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_read, __pyx_k_read, sizeof(__pyx_k_read), 0, 0, 1, 1},
+  {&__pyx_n_s_read_chunk, __pyx_k_read_chunk, sizeof(__pyx_k_read_chunk), 0, 0, 1, 1},
+  {&__pyx_n_s_read_chunk_locals_genexpr, __pyx_k_read_chunk_locals_genexpr, sizeof(__pyx_k_read_chunk_locals_genexpr), 0, 0, 1, 1},
+  {&__pyx_n_s_read_parallel, __pyx_k_read_parallel, sizeof(__pyx_k_read_parallel), 0, 0, 1, 1},
+  {&__pyx_n_s_read_parallel_locals_genexpr, __pyx_k_read_parallel_locals_genexpr, sizeof(__pyx_k_read_parallel_locals_genexpr), 0, 0, 1, 1},
+  {&__pyx_n_s_reconvert_cols, __pyx_k_reconvert_cols, sizeof(__pyx_k_reconvert_cols), 0, 0, 1, 1},
+  {&__pyx_n_s_reconvert_queue, __pyx_k_reconvert_queue, sizeof(__pyx_k_reconvert_queue), 0, 0, 1, 1},
+  {&__pyx_n_s_replace, __pyx_k_replace, sizeof(__pyx_k_replace), 0, 0, 1, 1},
+  {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1},
+  {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1},
+  {&__pyx_n_s_setup_tokenizer, __pyx_k_setup_tokenizer, sizeof(__pyx_k_setup_tokenizer), 0, 0, 1, 1},
+  {&__pyx_n_s_six, __pyx_k_six, sizeof(__pyx_k_six), 0, 0, 1, 1},
+  {&__pyx_n_s_source, __pyx_k_source, sizeof(__pyx_k_source), 0, 0, 1, 1},
+  {&__pyx_n_s_source_bytes, __pyx_k_source_bytes, sizeof(__pyx_k_source_bytes), 0, 0, 1, 1},
+  {&__pyx_n_s_splitlines, __pyx_k_splitlines, sizeof(__pyx_k_splitlines), 0, 0, 1, 1},
+  {&__pyx_n_s_src_ptr, __pyx_k_src_ptr, sizeof(__pyx_k_src_ptr), 0, 0, 1, 1},
+  {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+  {&__pyx_n_s_str, __pyx_k_str, sizeof(__pyx_k_str), 0, 0, 1, 1},
+  {&__pyx_n_s_string_types, __pyx_k_string_types, sizeof(__pyx_k_string_types), 0, 0, 1, 1},
+  {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+  {&__pyx_n_s_strip_line_fields, __pyx_k_strip_line_fields, sizeof(__pyx_k_strip_line_fields), 0, 0, 1, 1},
+  {&__pyx_n_s_strip_line_whitespace, __pyx_k_strip_line_whitespace, sizeof(__pyx_k_strip_line_whitespace), 0, 0, 1, 1},
+  {&__pyx_n_s_strip_whitespace, __pyx_k_strip_whitespace, sizeof(__pyx_k_strip_whitespace), 0, 0, 1, 1},
+  {&__pyx_n_s_strip_whitespace_fields, __pyx_k_strip_whitespace_fields, sizeof(__pyx_k_strip_whitespace_fields), 0, 0, 1, 1},
+  {&__pyx_n_s_strip_whitespace_lines, __pyx_k_strip_whitespace_lines, sizeof(__pyx_k_strip_whitespace_lines), 0, 0, 1, 1},
+  {&__pyx_n_s_table, __pyx_k_table, sizeof(__pyx_k_table), 0, 0, 1, 1},
+  {&__pyx_n_s_target, __pyx_k_target, sizeof(__pyx_k_target), 0, 0, 1, 1},
+  {&__pyx_n_s_terminate, __pyx_k_terminate, sizeof(__pyx_k_terminate), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1},
+  {&__pyx_n_s_tolist, __pyx_k_tolist, sizeof(__pyx_k_tolist), 0, 0, 1, 1},
+  {&__pyx_kp_s_too_many_columns_found_in_line_0, __pyx_k_too_many_columns_found_in_line_0, sizeof(__pyx_k_too_many_columns_found_in_line_0), 0, 0, 1, 0},
+  {&__pyx_n_s_try_float, __pyx_k_try_float, sizeof(__pyx_k_try_float), 0, 0, 1, 1},
+  {&__pyx_n_s_try_int, __pyx_k_try_int, sizeof(__pyx_k_try_int), 0, 0, 1, 1},
+  {&__pyx_n_s_try_string, __pyx_k_try_string, sizeof(__pyx_k_try_string), 0, 0, 1, 1},
+  {&__pyx_kp_s_type_conversion_error, __pyx_k_type_conversion_error, sizeof(__pyx_k_type_conversion_error), 0, 0, 1, 0},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_kp_s_unknown_error, __pyx_k_unknown_error, sizeof(__pyx_k_unknown_error), 0, 0, 1, 0},
+  {&__pyx_n_s_use_cols, __pyx_k_use_cols, sizeof(__pyx_k_use_cols), 0, 0, 1, 1},
+  {&__pyx_n_s_use_fast_converter, __pyx_k_use_fast_converter, sizeof(__pyx_k_use_fast_converter), 0, 0, 1, 1},
+  {&__pyx_n_s_utils_data, __pyx_k_utils_data, sizeof(__pyx_k_utils_data), 0, 0, 1, 1},
+  {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1},
+  {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},
+  {&__pyx_n_s_write, __pyx_k_write, sizeof(__pyx_k_write), 0, 0, 1, 1},
+  {&__pyx_n_s_write_header, __pyx_k_write_header, sizeof(__pyx_k_write_header), 0, 0, 1, 1},
+  {&__pyx_n_s_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 0, 1, 1},
+  {&__pyx_n_s_writerow, __pyx_k_writerow, sizeof(__pyx_k_writerow), 0, 0, 1, 1},
+  {&__pyx_n_s_writerows, __pyx_k_writerows, sizeof(__pyx_k_writerows), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ord = __Pyx_GetBuiltinName(__pyx_n_s_ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_chr = __Pyx_GetBuiltinName(__pyx_n_s_chr); if (!__pyx_builtin_chr) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_any = __Pyx_GetBuiltinName(__pyx_n_s_any); if (!__pyx_builtin_any) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "astropy/io/ascii/cparser.pyx":201
+ *                   include_names=None,
+ *                   exclude_names=None,
+ *                   fill_values=('', '0'),             # <<<<<<<<<<<<<<
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,
+ */
+  __pyx_tuple__4 = PyTuple_Pack(2, __pyx_kp_s__3, __pyx_kp_s_0); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "astropy/io/ascii/cparser.pyx":211
+ *             fast_reader = {}
+ *         elif fast_reader is False: # shouldn't happen
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")             # <<<<<<<<<<<<<<
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)
+ */
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_fast_reader_cannot_be_False_for); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
+
+  /* "astropy/io/ascii/cparser.pyx":213
+ *             raise core.ParameterError("fast_reader cannot be False for fast readers")
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)             # <<<<<<<<<<<<<<
+ *         parallel = fast_reader.pop('parallel', False)
+ *         if fast_reader:
+ */
+  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_n_s_use_fast_converter, Py_False); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "astropy/io/ascii/cparser.pyx":214
+ *         # parallel and use_fast_reader are False by default
+ *         use_fast_converter = fast_reader.pop('use_fast_converter', False)
+ *         parallel = fast_reader.pop('parallel', False)             # <<<<<<<<<<<<<<
+ *         if fast_reader:
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ */
+  __pyx_tuple__7 = PyTuple_Pack(2, __pyx_n_s_parallel, Py_False); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
+
+  /* "astropy/io/ascii/cparser.pyx":216
+ *         parallel = fast_reader.pop('parallel', False)
+ *         if fast_reader:
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")             # <<<<<<<<<<<<<<
+ *         if parallel and os.name == 'nt':
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")
+ */
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Invalid_parameter_in_fast_reader); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
+
+  /* "astropy/io/ascii/cparser.pyx":218
+ *             raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+ *         if parallel and os.name == 'nt':
+ *             raise NotImplementedError("Multiprocessing is not yet supported on Windows")             # <<<<<<<<<<<<<<
+ * 
+ *         if comment is None:
+ */
+  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Multiprocessing_is_not_yet_suppo); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+
+  /* "astropy/io/ascii/cparser.pyx":279
+ *             # Otherwise, source is the actual data so we leave it be
+ *         elif hasattr(source, 'read'): # file-like object
+ *             with get_readable_fileobj(source) as file_obj:             # <<<<<<<<<<<<<<
+ *                 source = file_obj.read()
+ *         elif isinstance(source, FileString):
+ */
+  __pyx_tuple__13 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__13);
+  __Pyx_GIVEREF(__pyx_tuple__13);
+
+  /* "astropy/io/ascii/cparser.pyx":290
+ *                 source = '\n'.join(source) # iterable sequence of lines
+ *             except TypeError:
+ *                 raise TypeError('Input "table" must be a file-like object, a '             # <<<<<<<<<<<<<<
+ *                                 'string (filename or data), or an iterable')
+ *         # Create a reference to the Python object so its char * pointer remains valid
+ */
+  __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Input_table_must_be_a_file_like); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__14);
+  __Pyx_GIVEREF(__pyx_tuple__14);
+
+  /* "astropy/io/ascii/cparser.pyx":296
+ * 
+ *         # encode in ASCII for char * handling
+ *         self.source_bytes = self.source.encode('ascii')             # <<<<<<<<<<<<<<
+ *         self.tokenizer.source = self.source_bytes
+ *         self.tokenizer.source_len = len(self.source_bytes)
+ */
+  __pyx_tuple__15 = PyTuple_Pack(1, __pyx_n_s_ascii); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__15);
+  __Pyx_GIVEREF(__pyx_tuple__15);
+
+  /* "astropy/io/ascii/cparser.pyx":321
+ *                     if name:
+ *                         # replace empty placeholder with ''
+ *                         self.names.append(name.replace('\x01', ''))             # <<<<<<<<<<<<<<
+ *                         name = ''
+ *                     else:
+ */
+  __pyx_tuple__17 = PyTuple_Pack(2, __pyx_kp_s__16, __pyx_kp_s__3); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__17);
+  __Pyx_GIVEREF(__pyx_tuple__17);
+
+  /* "astropy/io/ascii/cparser.pyx":343
+ *                         break
+ *             if self.width == 0: # no data
+ *                 raise core.InconsistentTableError('No data lines found, C reader '             # <<<<<<<<<<<<<<
+ *                                             'cannot autogenerate column names')
+ *             # auto-generate names
+ */
+  __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_No_data_lines_found_C_reader_can); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__18);
+  __Pyx_GIVEREF(__pyx_tuple__18);
+
+  /* "astropy/io/ascii/cparser.pyx":480
+ *         try:
+ *             while True:
+ *                 reconverted, proc, col = queue.get(False)             # <<<<<<<<<<<<<<
+ *                 chunks[proc][self.names[col]] = reconverted
+ *         except Queue.Empty:
+ */
+  __pyx_tuple__19 = PyTuple_Pack(1, Py_False); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__19);
+  __Pyx_GIVEREF(__pyx_tuple__19);
+
+  /* "astropy/io/ascii/cparser.pyx":538
+ *             if not c: # zero byte -- line terminator
+ *                 # replace empty placeholder with ''
+ *                 line_comments.append(comment.replace('\x01', '').strip())             # <<<<<<<<<<<<<<
+ *                 comment = ''
+ *             else:
+ */
+  __pyx_tuple__20 = PyTuple_Pack(2, __pyx_kp_s__16, __pyx_kp_s__3); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__20);
+  __Pyx_GIVEREF(__pyx_tuple__20);
+
+  /* "astropy/io/ascii/cparser.pyx":600
+ *                 # fill_values parameter, or no specific columns are specified
+ *                 # and this column should apply fill_values.
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+  __pyx_slice__21 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__21);
+  __Pyx_GIVEREF(__pyx_slice__21);
+
+  /* "astropy/io/ascii/cparser.pyx":603
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')             # <<<<<<<<<<<<<<
+ *                     # try converting the new value
+ *                     converted = str_to_long(t, new_value)
+ */
+  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_n_s_ascii); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__22);
+  __Pyx_GIVEREF(__pyx_tuple__22);
+
+  /* "astropy/io/ascii/cparser.pyx":656
+ * 
+ *             if replace_info is not None:
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+  __pyx_slice__23 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__23);
+  __Pyx_GIVEREF(__pyx_slice__23);
+
+  /* "astropy/io/ascii/cparser.pyx":659
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ *                     new_value = str(replace_info[0]).encode('ascii')             # <<<<<<<<<<<<<<
+ *                     replacing = True
+ *                     converted = str_to_double(t, new_value)
+ */
+  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_n_s_ascii); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__24);
+  __Pyx_GIVEREF(__pyx_tuple__24);
+
+  /* "astropy/io/ascii/cparser.pyx":708
+ * 
+ *             if replace_info is not None:
+ *                 el = replace_info[0].encode('ascii')             # <<<<<<<<<<<<<<
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ */
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_n_s_ascii); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
+
+  /* "astropy/io/ascii/cparser.pyx":709
+ *             if replace_info is not None:
+ *                 el = replace_info[0].encode('ascii')
+ *                 if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \             # <<<<<<<<<<<<<<
+ *                    or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+ *                     mask.add(row)
+ */
+  __pyx_slice__26 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__26);
+  __Pyx_GIVEREF(__pyx_slice__26);
+
+  /* "astropy/io/ascii/cparser.pyx":984
+ *                     # the fill_values parameter, or no specific columns are
+ *                     # specified and this column should apply fill_values.
+ *                     if (len(self.fill_values[field]) > 1 and self.use_names[j] in self.fill_values[field][1:]) \             # <<<<<<<<<<<<<<
+ *                        or (len(self.fill_values[field]) == 1 and j in self.fill_cols):
+ *                         str_val = True
+ */
+  __pyx_slice__31 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__31);
+  __Pyx_GIVEREF(__pyx_slice__31);
+
+  /* "astropy/io/ascii/cparser.pyx":1015
+ *     for el in fill_values:
+ *         if el[0] == '':
+ *             fill_empty = el[1:]             # <<<<<<<<<<<<<<
+ *             break
+ * 
+ */
+  __pyx_slice__32 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__32);
+  __Pyx_GIVEREF(__pyx_slice__32);
+
+  /* "astropy/io/ascii/cparser.pyx":1021
+ *         # Create a dict with the values to be replaced as keys
+ *         if read:
+ *             fill_values = dict([(l[0].encode('ascii'), l[1:]) for             # <<<<<<<<<<<<<<
+ *                                 l in fill_values if l[0] != ''])
+ *         else:
+ */
+  __pyx_tuple__33 = PyTuple_Pack(1, __pyx_n_s_ascii); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__33);
+  __Pyx_GIVEREF(__pyx_tuple__33);
+  __pyx_slice__34 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__34);
+  __Pyx_GIVEREF(__pyx_slice__34);
+
+  /* "astropy/io/ascii/cparser.pyx":1025
+ *         else:
+ *             # don't worry about encoding for writing
+ *             fill_values = dict([(l[0], l[1:]) for l in fill_values])             # <<<<<<<<<<<<<<
+ * 
+ *     except IndexError:
+ */
+  __pyx_slice__35 = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__35);
+  __Pyx_GIVEREF(__pyx_slice__35);
+
+  /* "astropy/io/ascii/cparser.pyx":1028
+ * 
+ *     except IndexError:
+ *         raise ValueError("Format of fill_values must be "             # <<<<<<<<<<<<<<
+ *                          "(<bad>, <fill>, <optional col1>, ...)")
+ *     if read:
+ */
+  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_s_Format_of_fill_values_must_be_ba); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__36);
+  __Pyx_GIVEREF(__pyx_tuple__36);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__37);
+  __Pyx_GIVEREF(__pyx_tuple__37);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__38 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__38)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__38);
+  __Pyx_GIVEREF(__pyx_tuple__38);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__39 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__39);
+  __Pyx_GIVEREF(__pyx_tuple__39);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__40);
+  __Pyx_GIVEREF(__pyx_tuple__40);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__41 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__41);
+  __Pyx_GIVEREF(__pyx_tuple__41);
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__42);
+  __Pyx_GIVEREF(__pyx_tuple__42);
+
+  /* "astropy/io/ascii/cparser.pyx":755
+ *                                 parallel=False)))
+ * 
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,             # <<<<<<<<<<<<<<
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ */
+  __pyx_tuple__43 = PyTuple_Pack(9, __pyx_n_s_src_ptr, __pyx_n_s_source_bytes, __pyx_n_s_use_cols, __pyx_n_s_fill_names, __pyx_n_s_fill_values, __pyx_n_s_strip_whitespace_lines, __pyx_n_s_strip_whitespace_fields, __pyx_n_s_kwargs, __pyx_n_s_parser); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__43);
+  __Pyx_GIVEREF(__pyx_tuple__43);
+  __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(8, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_copy_cparser, 755, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+  __pyx_tuple__45 = PyTuple_Pack(18, __pyx_n_s_self, __pyx_n_s_start, __pyx_n_s_end, __pyx_n_s_try_int, __pyx_n_s_try_float, __pyx_n_s_try_string, __pyx_n_s_queue, __pyx_n_s_reconvert_queue, __pyx_n_s_i, __pyx_n_s_chunk_tokenizer, __pyx_n_s_data, __pyx_n_s_err, __pyx_n_s_line_comments, __pyx_n_s_e, __pyx_n_s_reconvert_cols, __pyx_n_s_col, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto [...]
+  __Pyx_GOTREF(__pyx_tuple__45);
+  __Pyx_GIVEREF(__pyx_tuple__45);
+  __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(9, 0, 18, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_read_chunk, 768, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":1004
+ *             output.close()
+ * 
+ * def get_fill_values(fill_values, read=True):             # <<<<<<<<<<<<<<
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+ *         # e.g. fill_values=('999', '0')
+ */
+  __pyx_tuple__47 = PyTuple_Pack(5, __pyx_n_s_fill_values, __pyx_n_s_read, __pyx_n_s_fill_empty, __pyx_n_s_el, __pyx_n_s_l); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__47);
+  __Pyx_GIVEREF(__pyx_tuple__47);
+  __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_get_fill_values, 1004, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "astropy/io/ascii/cparser.pyx":1035
+ *         return fill_values # cache for empty values doesn't matter for writing
+ * 
+ * def auto_format_func(format_, val):             # <<<<<<<<<<<<<<
+ *     """
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ */
+  __pyx_tuple__49 = PyTuple_Pack(5, __pyx_n_s_format_2, __pyx_n_s_val, __pyx_n_s_format_func, __pyx_n_s_out, __pyx_n_s_err); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__49);
+  __Pyx_GIVEREF(__pyx_tuple__49);
+  __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_auto_format_func, 1035, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initcparser(void); /*proto*/
+PyMODINIT_FUNC initcparser(void)
+#else
+PyMODINIT_FUNC PyInit_cparser(void); /*proto*/
+PyMODINIT_FUNC PyInit_cparser(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cparser(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("cparser", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_astropy__io__ascii__cparser) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "astropy.io.ascii.cparser")) {
+      if (unlikely(PyDict_SetItemString(modules, "astropy.io.ascii.cparser", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser_FileString) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser_FileString.tp_print = 0;
+  if (PyObject_SetAttrString(__pyx_m, "FileString", (PyObject *)&__pyx_type_7astropy_2io_5ascii_7cparser_FileString) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7astropy_2io_5ascii_7cparser_FileString = &__pyx_type_7astropy_2io_5ascii_7cparser_FileString;
+  __pyx_vtabptr_7astropy_2io_5ascii_7cparser_CParser = &__pyx_vtable_7astropy_2io_5ascii_7cparser_CParser;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser.get_error = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *, PyObject *, PyObject *))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_get_error;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser.raise_error = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_raise_error;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser.setup_tokenizer = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, PyObject *, int __pyx_skip_dispatch))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser_setup_tokenizer;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._set_fill_values = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__set_fill_values;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._get_comments = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__get_comments;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._convert_data = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, PyObject *, PyObject *, PyObject *, PyObject *))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_data;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._convert_int = (PyArrayObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_int;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._convert_float = (PyArrayObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_float;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_CParser._convert_str = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_CParser *, tokenizer_t *, int, int))__pyx_f_7astropy_2io_5ascii_7cparser_7CParser__convert_str;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser_CParser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser_CParser.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_7astropy_2io_5ascii_7cparser_CParser.tp_dict, __pyx_vtabptr_7astropy_2io_5ascii_7cparser_CParser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "CParser", (PyObject *)&__pyx_type_7astropy_2io_5ascii_7cparser_CParser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7astropy_2io_5ascii_7cparser_CParser = &__pyx_type_7astropy_2io_5ascii_7cparser_CParser;
+  __pyx_vtabptr_7astropy_2io_5ascii_7cparser_FastWriter = &__pyx_vtable_7astropy_2io_5ascii_7cparser_FastWriter;
+  __pyx_vtable_7astropy_2io_5ascii_7cparser_FastWriter._write_comments = (PyObject *(*)(struct __pyx_obj_7astropy_2io_5ascii_7cparser_FastWriter *, PyObject *))__pyx_f_7astropy_2io_5ascii_7cparser_10FastWriter__write_comments;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser_FastWriter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser_FastWriter.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_7astropy_2io_5ascii_7cparser_FastWriter.tp_dict, __pyx_vtabptr_7astropy_2io_5ascii_7cparser_FastWriter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "FastWriter", (PyObject *)&__pyx_type_7astropy_2io_5ascii_7cparser_FastWriter) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7astropy_2io_5ascii_7cparser_FastWriter = &__pyx_type_7astropy_2io_5ascii_7cparser_FastWriter;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct__splitlines;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_1__read_parallel;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_2_genexpr;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_3_genexpr;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_4_genexpr;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_5__read_chunk;
+  if (PyType_Ready(&__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr.tp_print = 0;
+  __pyx_ptype_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr = &__pyx_type_7astropy_2io_5ascii_7cparser___pyx_scope_struct_6_genexpr;
+  /*--- Type import code ---*/
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "astropy/io/ascii/cparser.pyx":3
+ * # Licensed under a 3-clause BSD style license - see LICENSE.rst
+ * 
+ * import csv             # <<<<<<<<<<<<<<
+ * import os
+ * import math
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_csv, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_csv, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":4
+ * 
+ * import csv
+ * import os             # <<<<<<<<<<<<<<
+ * import math
+ * import multiprocessing
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":5
+ * import csv
+ * import os
+ * import math             # <<<<<<<<<<<<<<
+ * import multiprocessing
+ * import mmap
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_math, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_math, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":6
+ * import os
+ * import math
+ * import multiprocessing             # <<<<<<<<<<<<<<
+ * import mmap
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_multiprocessing, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_multiprocessing, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":7
+ * import math
+ * import multiprocessing
+ * import mmap             # <<<<<<<<<<<<<<
+ * 
+ * import numpy as np
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_mmap, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_mmap, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":9
+ * import mmap
+ * 
+ * import numpy as np             # <<<<<<<<<<<<<<
+ * cimport numpy as np
+ * from numpy import ma
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":11
+ * import numpy as np
+ * cimport numpy as np
+ * from numpy import ma             # <<<<<<<<<<<<<<
+ * from libc cimport stdio
+ * from cpython.buffer cimport PyBUF_SIMPLE
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_ma);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_ma);
+  __Pyx_GIVEREF(__pyx_n_s_ma);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_ma); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ma, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":17
+ * from cpython.buffer cimport PyObject_GetBuffer, PyBuffer_Release
+ * 
+ * from ...utils.data import get_readable_fileobj             # <<<<<<<<<<<<<<
+ * from ...table import pprint
+ * from ...extern import six
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_get_readable_fileobj);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_get_readable_fileobj);
+  __Pyx_GIVEREF(__pyx_n_s_get_readable_fileobj);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_utils_data, __pyx_t_2, 3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_get_readable_fileobj); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_readable_fileobj, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":18
+ * 
+ * from ...utils.data import get_readable_fileobj
+ * from ...table import pprint             # <<<<<<<<<<<<<<
+ * from ...extern import six
+ * from . import core
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_pprint);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_pprint);
+  __Pyx_GIVEREF(__pyx_n_s_pprint);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_table, __pyx_t_1, 3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_pprint); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pprint, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":19
+ * from ...utils.data import get_readable_fileobj
+ * from ...table import pprint
+ * from ...extern import six             # <<<<<<<<<<<<<<
+ * from . import core
+ * 
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_six);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_six);
+  __Pyx_GIVEREF(__pyx_n_s_six);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_extern, __pyx_t_2, 3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_six); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_six, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":20
+ * from ...table import pprint
+ * from ...extern import six
+ * from . import core             # <<<<<<<<<<<<<<
+ * 
+ * try:
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_core);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_core);
+  __Pyx_GIVEREF(__pyx_n_s_core);
+  __pyx_t_2 = __Pyx_Import(__pyx_kp_s__3, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_core); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_core, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":22
+ * from . import core
+ * 
+ * try:             # <<<<<<<<<<<<<<
+ *     import Queue
+ * except ImportError: # in python 3, the module is named queue
+ */
+  {
+    __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+    __Pyx_XGOTREF(__pyx_t_3);
+    __Pyx_XGOTREF(__pyx_t_4);
+    __Pyx_XGOTREF(__pyx_t_5);
+    /*try:*/ {
+
+      /* "astropy/io/ascii/cparser.pyx":23
+ * 
+ * try:
+ *     import Queue             # <<<<<<<<<<<<<<
+ * except ImportError: # in python 3, the module is named queue
+ *     import queue as Queue
+ */
+      __pyx_t_2 = __Pyx_Import(__pyx_n_s_Queue, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L2_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      if (PyDict_SetItem(__pyx_d, __pyx_n_s_Queue, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L2_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    }
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L9_try_end;
+    __pyx_L2_error:;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "astropy/io/ascii/cparser.pyx":24
+ * try:
+ *     import Queue
+ * except ImportError: # in python 3, the module is named queue             # <<<<<<<<<<<<<<
+ *     import queue as Queue
+ * 
+ */
+    __pyx_t_6 = PyErr_ExceptionMatches(__pyx_builtin_ImportError);
+    if (__pyx_t_6) {
+      __Pyx_AddTraceback("astropy.io.ascii.cparser", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_1, &__pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L4_except_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_t_7);
+
+      /* "astropy/io/ascii/cparser.pyx":25
+ *     import Queue
+ * except ImportError: # in python 3, the module is named queue
+ *     import queue as Queue             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "src/tokenizer.h":
+ */
+      __pyx_t_8 = __Pyx_Import(__pyx_n_s_queue, 0, -1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L4_except_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      if (PyDict_SetItem(__pyx_d, __pyx_n_s_Queue, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L4_except_error;}
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L3_exception_handled;
+    }
+    goto __pyx_L4_except_error;
+    __pyx_L4_except_error:;
+    __Pyx_XGIVEREF(__pyx_t_3);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_XGIVEREF(__pyx_t_5);
+    __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+    goto __pyx_L1_error;
+    __pyx_L3_exception_handled:;
+    __Pyx_XGIVEREF(__pyx_t_3);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_XGIVEREF(__pyx_t_5);
+    __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+    __pyx_L9_try_end:;
+  }
+
+  /* "astropy/io/ascii/cparser.pyx":98
+ *     int PyObject_AsReadBuffer(object obj, const void **buffer, Py_ssize_t *buffer_len)
+ * 
+ * class CParserError(Exception):             # <<<<<<<<<<<<<<
+ *     """
+ *     An instance of this class is thrown when an error occurs
+ */
+  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_INCREF(__pyx_builtin_Exception);
+  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_builtin_Exception);
+  __Pyx_GIVEREF(__pyx_builtin_Exception);
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_7, __pyx_n_s_CParserError, __pyx_n_s_CParserError, (PyObject *) NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_kp_s_An_instance_of_this_class_is_th); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_CParserError, __pyx_t_7, __pyx_t_2, NULL, 0, 1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CParserError, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":107
+ *     "no error",
+ *     "invalid line supplied",
+ *     lambda line: "too many columns found in line {0} of data".format(line),             # <<<<<<<<<<<<<<
+ *     lambda line: "not enough columns found in line {0} of data".format(line),
+ *     "type conversion error",
+ */
+  __pyx_t_7 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_8lambda1, 0, __pyx_n_s_lambda, NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_d, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+
+  /* "astropy/io/ascii/cparser.pyx":108
+ *     "invalid line supplied",
+ *     lambda line: "too many columns found in line {0} of data".format(line),
+ *     lambda line: "not enough columns found in line {0} of data".format(line),             # <<<<<<<<<<<<<<
+ *     "type conversion error",
+ *     "overflow error"
+ */
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_9lambda2, 0, __pyx_n_s_lambda, NULL, __pyx_n_s_astropy_io_ascii_cparser, __pyx_d, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+
+  /* "astropy/io/ascii/cparser.pyx":104
+ *     """
+ * 
+ * ERR_CODES = dict(enumerate([             # <<<<<<<<<<<<<<
+ *     "no error",
+ *     "invalid line supplied",
+ */
+  __pyx_t_2 = PyList_New(6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_kp_s_no_error);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_kp_s_no_error);
+  __Pyx_GIVEREF(__pyx_kp_s_no_error);
+  __Pyx_INCREF(__pyx_kp_s_invalid_line_supplied);
+  PyList_SET_ITEM(__pyx_t_2, 1, __pyx_kp_s_invalid_line_supplied);
+  __Pyx_GIVEREF(__pyx_kp_s_invalid_line_supplied);
+  PyList_SET_ITEM(__pyx_t_2, 2, __pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyList_SET_ITEM(__pyx_t_2, 3, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_kp_s_type_conversion_error);
+  PyList_SET_ITEM(__pyx_t_2, 4, __pyx_kp_s_type_conversion_error);
+  __Pyx_GIVEREF(__pyx_kp_s_type_conversion_error);
+  __Pyx_INCREF(__pyx_kp_s_overflow_error);
+  PyList_SET_ITEM(__pyx_t_2, 5, __pyx_kp_s_overflow_error);
+  __Pyx_GIVEREF(__pyx_kp_s_overflow_error);
+  __pyx_t_7 = 0;
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_enumerate, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERR_CODES, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":755
+ *                                 parallel=False)))
+ * 
+ * def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,             # <<<<<<<<<<<<<<
+ *                   strip_whitespace_lines, strip_whitespace_fields, kwargs):
+ *     parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_1_copy_cparser, NULL, __pyx_n_s_astropy_io_ascii_cparser); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_copy_cparser, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":768
+ *     return parser
+ * 
+ * def _read_chunk(CParser self, start, end, try_int,             # <<<<<<<<<<<<<<
+ *                 try_float, try_string, queue, reconvert_queue, i):
+ *     cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_3_read_chunk, NULL, __pyx_n_s_astropy_io_ascii_cparser); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_read_chunk, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":835
+ *                   include_names=None,
+ *                   exclude_names=None,
+ *                   fill_values=[],             # <<<<<<<<<<<<<<
+ *                   fill_include_names=None,
+ *                   fill_exclude_names=None,
+ */
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_k__28 = __pyx_t_2;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":1004
+ *             output.close()
+ * 
+ * def get_fill_values(fill_values, read=True):             # <<<<<<<<<<<<<<
+ *     if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+ *         # e.g. fill_values=('999', '0')
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_5get_fill_values, NULL, __pyx_n_s_astropy_io_ascii_cparser); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_fill_values, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":1035
+ *         return fill_values # cache for empty values doesn't matter for writing
+ * 
+ * def auto_format_func(format_, val):             # <<<<<<<<<<<<<<
+ *     """
+ *     Mimics pprint._auto_format_func for non-numpy values.
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_2io_5ascii_7cparser_7auto_format_func, NULL, __pyx_n_s_astropy_io_ascii_cparser); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_auto_format_func, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "astropy/io/ascii/cparser.pyx":1
+ * # Licensed under a 3-clause BSD style license - see LICENSE.rst             # <<<<<<<<<<<<<<
+ * 
+ * import csv
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init astropy.io.ascii.cparser", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init astropy.io.ascii.cparser");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+    PyObject *self, *result;
+    PyCFunction cfunc;
+    cfunc = PyCFunction_GET_FUNCTION(func);
+    self = PyCFunction_GET_SELF(func);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = cfunc(self, arg);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject *result;
+    PyObject *args = PyTuple_New(1);
+    if (unlikely(!args)) return NULL;
+    Py_INCREF(arg);
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = __Pyx_PyObject_Call(func, args, NULL);
+    Py_DECREF(args);
+    return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+            return __Pyx_PyObject_CallMethO(func, arg);
+        }
+    }
+    return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject* args = PyTuple_Pack(1, arg);
+    return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%.200s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%.200s() got an unexpected keyword argument '%.200s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                if (PyObject_IsSubclass(instance_class, type)) {
+                    type = instance_class;
+                } else {
+                    instance_class = NULL;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+#endif
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (likely(result)) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+            return __Pyx_PyObject_CallMethO(func, NULL);
+        }
+    }
+    return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+                                  CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+                                  int full_traceback) {
+    PyObject *old_exc, *old_val, *old_tb;
+    PyObject *ctx;
+    __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+    if (full_traceback) {
+        Py_XINCREF(old_exc);
+        Py_XINCREF(old_val);
+        Py_XINCREF(old_tb);
+        __Pyx_ErrRestore(old_exc, old_val, old_tb);
+        PyErr_PrintEx(1);
+    }
+    #if PY_MAJOR_VERSION < 3
+    ctx = PyString_FromString(name);
+    #else
+    ctx = PyUnicode_FromString(name);
+    #endif
+    __Pyx_ErrRestore(old_exc, old_val, old_tb);
+    if (!ctx) {
+        PyErr_WriteUnraisable(Py_None);
+    } else {
+        PyErr_WriteUnraisable(ctx);
+        Py_DECREF(ctx);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+         const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+         const char* encoding, const char* errors,
+         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+    Py_ssize_t length;
+    if (unlikely((start < 0) | (stop < 0))) {
+        length = strlen(cstring);
+        if (start < 0) {
+            start += length;
+            if (start < 0)
+                start = 0;
+        }
+        if (stop < 0)
+            stop += length;
+    }
+    length = stop - start;
+    if (unlikely(length <= 0))
+        return PyUnicode_FromUnicode(NULL, 0);
+    cstring += start;
+    if (decode_func) {
+        return decode_func(cstring, length, errors);
+    } else {
+        return PyUnicode_Decode(cstring, length, encoding, errors);
+    }
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+    return PyObject_RichCompareBool(s1, s2, equals);
+#else
+    if (s1 == s2) {
+        return (equals == Py_EQ);
+    } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+        const char *ps1, *ps2;
+        Py_ssize_t length = PyBytes_GET_SIZE(s1);
+        if (length != PyBytes_GET_SIZE(s2))
+            return (equals == Py_NE);
+        ps1 = PyBytes_AS_STRING(s1);
+        ps2 = PyBytes_AS_STRING(s2);
+        if (ps1[0] != ps2[0]) {
+            return (equals == Py_NE);
+        } else if (length == 1) {
+            return (equals == Py_EQ);
+        } else {
+            int result = memcmp(ps1, ps2, (size_t)length);
+            return (equals == Py_EQ) ? (result == 0) : (result != 0);
+        }
+    } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+        return (equals == Py_NE);
+    } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+        return (equals == Py_NE);
+    } else {
+        int result;
+        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+        if (!py_result)
+            return -1;
+        result = __Pyx_PyObject_IsTrue(py_result);
+        Py_DECREF(py_result);
+        return result;
+    }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+    return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+    PyObject* owned_ref = NULL;
+#endif
+    int s1_is_unicode, s2_is_unicode;
+    if (s1 == s2) {
+        goto return_eq;
+    }
+    s1_is_unicode = PyUnicode_CheckExact(s1);
+    s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+    if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+        owned_ref = PyUnicode_FromObject(s2);
+        if (unlikely(!owned_ref))
+            return -1;
+        s2 = owned_ref;
+        s2_is_unicode = 1;
+    } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+        owned_ref = PyUnicode_FromObject(s1);
+        if (unlikely(!owned_ref))
+            return -1;
+        s1 = owned_ref;
+        s1_is_unicode = 1;
+    } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+        return __Pyx_PyBytes_Equals(s1, s2, equals);
+    }
+#endif
+    if (s1_is_unicode & s2_is_unicode) {
+        Py_ssize_t length;
+        int kind;
+        void *data1, *data2;
+        if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+            return -1;
+        length = __Pyx_PyUnicode_GET_LENGTH(s1);
+        if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+            goto return_ne;
+        }
+        kind = __Pyx_PyUnicode_KIND(s1);
+        if (kind != __Pyx_PyUnicode_KIND(s2)) {
+            goto return_ne;
+        }
+        data1 = __Pyx_PyUnicode_DATA(s1);
+        data2 = __Pyx_PyUnicode_DATA(s2);
+        if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+            goto return_ne;
+        } else if (length == 1) {
+            goto return_eq;
+        } else {
+            int result = memcmp(data1, data2, (size_t)(length * kind));
+            #if PY_MAJOR_VERSION < 3
+            Py_XDECREF(owned_ref);
+            #endif
+            return (equals == Py_EQ) ? (result == 0) : (result != 0);
+        }
+    } else if ((s1 == Py_None) & s2_is_unicode) {
+        goto return_ne;
+    } else if ((s2 == Py_None) & s1_is_unicode) {
+        goto return_ne;
+    } else {
+        int result;
+        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+        if (!py_result)
+            return -1;
+        result = __Pyx_PyObject_IsTrue(py_result);
+        Py_DECREF(py_result);
+        return result;
+    }
+return_eq:
+    #if PY_MAJOR_VERSION < 3
+    Py_XDECREF(owned_ref);
+    #endif
+    return (equals == Py_EQ);
+return_ne:
+    #if PY_MAJOR_VERSION < 3
+    Py_XDECREF(owned_ref);
+    #endif
+    return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->exc_type;
+    *value = tstate->exc_value;
+    *tb = tstate->exc_traceback;
+    Py_XINCREF(*type);
+    Py_XINCREF(*value);
+    Py_XINCREF(*tb);
+#else
+    PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = type;
+    tstate->exc_value = value;
+    tstate->exc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    local_type = tstate->curexc_type;
+    local_value = tstate->curexc_value;
+    local_tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (unlikely(tstate->curexc_type))
+#else
+    if (unlikely(PyErr_Occurred()))
+#endif
+        goto bad;
+    #if PY_MAJOR_VERSION >= 3
+    if (local_tb) {
+        if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+            goto bad;
+    }
+    #endif
+    Py_XINCREF(local_tb);
+    Py_XINCREF(local_type);
+    Py_XINCREF(local_value);
+    *type = local_type;
+    *value = local_value;
+    *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = local_type;
+    tstate->exc_value = local_value;
+    tstate->exc_traceback = local_tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+    return 0;
+bad:
+    *type = 0;
+    *value = 0;
+    *tb = 0;
+    Py_XDECREF(local_type);
+    Py_XDECREF(local_value);
+    Py_XDECREF(local_tb);
+    return -1;
+}
+
+#if !CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
+    return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL);
+}
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
+    PyObject *method, *result = NULL;
+    method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+    if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyMethod_Check(method))) {
+        PyObject *self = PyMethod_GET_SELF(method);
+        if (likely(self)) {
+            PyObject *args;
+            PyObject *function = PyMethod_GET_FUNCTION(method);
+            args = PyTuple_New(2);
+            if (unlikely(!args)) goto bad;
+            Py_INCREF(self);
+            PyTuple_SET_ITEM(args, 0, self);
+            Py_INCREF(arg);
+            PyTuple_SET_ITEM(args, 1, arg);
+            Py_INCREF(function);
+            Py_DECREF(method); method = NULL;
+            result = __Pyx_PyObject_Call(function, args, NULL);
+            Py_DECREF(args);
+            Py_DECREF(function);
+            return result;
+        }
+    }
+#endif
+    result = __Pyx_PyObject_CallOneArg(method, arg);
+bad:
+    Py_XDECREF(method);
+    return result;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
+    } else {
+        PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
+        if (unlikely(!retval))
+            return -1;
+        Py_DECREF(retval);
+    }
+    return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
+    PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_slice(obj, cstart, cstop);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_subscript))
+#endif
+    {
+        PyObject* result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_subscript(obj, py_slice);
+#else
+        result = PyObject_GetItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
+bad:
+    return NULL;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+        PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_ass_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_ass_slice(obj, cstart, cstop, value);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_ass_subscript))
+#endif
+    {
+        int result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_ass_subscript(obj, py_slice, value);
+#else
+        result = value ? PyObject_SetItem(obj, py_slice, value) : PyObject_DelItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "'%.200s' object does not support slice %.10s",
+        Py_TYPE(obj)->tp_name, value ? "assignment" : "deletion");
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+        name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact)
+{
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (none_allowed && obj == Py_None) return 1;
+    else if (exact) {
+        if (likely(Py_TYPE(obj) == type)) return 1;
+        #if PY_MAJOR_VERSION == 2
+        else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+        #endif
+    }
+    else {
+        if (likely(PyObject_TypeCheck(obj, type))) return 1;
+    }
+    __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+    return 0;
+}
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
+    PyObject *method, *result = NULL;
+    method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+    if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyMethod_Check(method))) {
+        PyObject *self = PyMethod_GET_SELF(method);
+        if (likely(self)) {
+            PyObject *function = PyMethod_GET_FUNCTION(method);
+            result = __Pyx_PyObject_CallOneArg(function, self);
+            Py_DECREF(method);
+            return result;
+        }
+    }
+#endif
+    result = __Pyx_PyObject_CallNoArg(method);
+    Py_DECREF(method);
+bad:
+    return result;
+}
+
+static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (Py_TYPE(L) == &PySet_Type) {
+        return PySet_Pop(L);
+    }
+#endif
+    return __Pyx_PyObject_CallMethod0(L, __pyx_n_s_pop);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
+        Py_SIZE(L) -= 1;
+        return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
+    }
+#endif
+    return __Pyx_PyObject_CallMethod0(L, __pyx_n_s_pop);
+}
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj) {
+    PyObject* float_value;
+#if CYTHON_COMPILING_IN_PYPY
+    float_value = PyNumber_Float(obj);
+#else
+    PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number;
+    if (likely(nb) && likely(nb->nb_float)) {
+        float_value = nb->nb_float(obj);
+        if (likely(float_value) && unlikely(!PyFloat_Check(float_value))) {
+            PyErr_Format(PyExc_TypeError,
+                "__float__ returned non-float (type %.200s)",
+                Py_TYPE(float_value)->tp_name);
+            Py_DECREF(float_value);
+            goto bad;
+        }
+    } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
+#if PY_MAJOR_VERSION >= 3
+        float_value = PyFloat_FromString(obj);
+#else
+        float_value = PyFloat_FromString(obj, 0);
+#endif
+    } else {
+        PyObject* args = PyTuple_New(1);
+        if (unlikely(!args)) goto bad;
+        PyTuple_SET_ITEM(args, 0, obj);
+        float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
+        PyTuple_SET_ITEM(args, 0, 0);
+        Py_DECREF(args);
+    }
+#endif
+    if (likely(float_value)) {
+        double value = PyFloat_AS_DOUBLE(float_value);
+        Py_DECREF(float_value);
+        return value;
+    }
+bad:
+    return (double)-1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) {
+    PyObject* next;
+    iternextfunc iternext = Py_TYPE(iterator)->tp_iternext;
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (unlikely(!iternext)) {
+#else
+    if (unlikely(!iternext) || unlikely(!PyIter_Check(iterator))) {
+#endif
+        PyErr_Format(PyExc_TypeError,
+            "%.200s object is not an iterator", Py_TYPE(iterator)->tp_name);
+        return NULL;
+    }
+    next = iternext(iterator);
+    if (likely(next))
+        return next;
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_VERSION_HEX >= 0x02070000
+    if (unlikely(iternext == &_PyObject_NextNotImplemented))
+        return NULL;
+#endif
+#endif
+    if (defval) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+            if (unlikely(exc_type != PyExc_StopIteration) &&
+                    !PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))
+                return NULL;
+            PyErr_Clear();
+        }
+        Py_INCREF(defval);
+        return defval;
+    }
+    if (!PyErr_Occurred())
+        PyErr_SetNone(PyExc_StopIteration);
+    return NULL;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+        if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return -1;
+                }
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+    if (is_list || PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+    PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE void __Pyx_crop_slice(Py_ssize_t* _start, Py_ssize_t* _stop, Py_ssize_t* _length) {
+    Py_ssize_t start = *_start, stop = *_stop, length = *_length;
+    if (start < 0) {
+        start += length;
+        if (start < 0)
+            start = 0;
+    }
+    if (stop < 0)
+        stop += length;
+    else if (stop > length)
+        stop = length;
+    *_length = stop - start;
+    *_start = start;
+    *_stop = stop;
+}
+static CYTHON_INLINE void __Pyx_copy_object_array(PyObject** CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) {
+    PyObject *v;
+    Py_ssize_t i;
+    for (i = 0; i < length; i++) {
+        v = dest[i] = src[i];
+        Py_INCREF(v);
+    }
+}
+static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(
+            PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
+    PyObject* dest;
+    Py_ssize_t length = PyList_GET_SIZE(src);
+    __Pyx_crop_slice(&start, &stop, &length);
+    if (unlikely(length <= 0))
+        return PyList_New(0);
+    dest = PyList_New(length);
+    if (unlikely(!dest))
+        return NULL;
+    __Pyx_copy_object_array(
+        ((PyListObject*)src)->ob_item + start,
+        ((PyListObject*)dest)->ob_item,
+        length);
+    return dest;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(
+            PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
+    PyObject* dest;
+    Py_ssize_t length = PyTuple_GET_SIZE(src);
+    __Pyx_crop_slice(&start, &stop, &length);
+    if (unlikely(length <= 0))
+        return PyTuple_New(0);
+    dest = PyTuple_New(length);
+    if (unlikely(!dest))
+        return NULL;
+    __Pyx_copy_object_array(
+        ((PyTupleObject*)src)->ob_item + start,
+        ((PyTupleObject*)dest)->ob_item,
+        length);
+    return dest;
+}
+#endif
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+    PyObject* fake_module;
+    PyTypeObject* cached_type = NULL;
+    fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+    if (!fake_module) return NULL;
+    Py_INCREF(fake_module);
+    cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+    if (cached_type) {
+        if (!PyType_Check((PyObject*)cached_type)) {
+            PyErr_Format(PyExc_TypeError,
+                "Shared Cython type %.200s is not a type object",
+                type->tp_name);
+            goto bad;
+        }
+        if (cached_type->tp_basicsize != type->tp_basicsize) {
+            PyErr_Format(PyExc_TypeError,
+                "Shared Cython type %.200s has the wrong size, try recompiling",
+                type->tp_name);
+            goto bad;
+        }
+    } else {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+        PyErr_Clear();
+        if (PyType_Ready(type) < 0) goto bad;
+        if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+            goto bad;
+        Py_INCREF(type);
+        cached_type = type;
+    }
+done:
+    Py_DECREF(fake_module);
+    return cached_type;
+bad:
+    Py_XDECREF(cached_type);
+    cached_type = NULL;
+    goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+    if (unlikely(op->func_doc == NULL)) {
+        if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+            op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+            op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+            if (unlikely(op->func_doc == NULL))
+                return NULL;
+        } else {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+    }
+    Py_INCREF(op->func_doc);
+    return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp = op->func_doc;
+    if (value == NULL) {
+        value = Py_None;
+    }
+    Py_INCREF(value);
+    op->func_doc = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+    if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+        op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+        op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+        if (unlikely(op->func_name == NULL))
+            return NULL;
+    }
+    Py_INCREF(op->func_name);
+    return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__name__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_name;
+    Py_INCREF(value);
+    op->func_name = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+    Py_INCREF(op->func_qualname);
+    return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__qualname__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_qualname;
+    Py_INCREF(value);
+    op->func_qualname = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+    PyObject *self;
+    self = m->func_closure;
+    if (self == NULL)
+        self = Py_None;
+    Py_INCREF(self);
+    return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+    if (unlikely(op->func_dict == NULL)) {
+        op->func_dict = PyDict_New();
+        if (unlikely(op->func_dict == NULL))
+            return NULL;
+    }
+    Py_INCREF(op->func_dict);
+    return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+    if (unlikely(value == NULL)) {
+        PyErr_SetString(PyExc_TypeError,
+               "function's dictionary may not be deleted");
+        return -1;
+    }
+    if (unlikely(!PyDict_Check(value))) {
+        PyErr_SetString(PyExc_TypeError,
+               "setting function's dictionary to a non-dict");
+        return -1;
+    }
+    tmp = op->func_dict;
+    Py_INCREF(value);
+    op->func_dict = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+    Py_INCREF(op->func_globals);
+    return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+    PyObject* result = (op->func_code) ? op->func_code : Py_None;
+    Py_INCREF(result);
+    return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+    PyObject *res = op->defaults_getter((PyObject *) op);
+    if (unlikely(!res))
+        return -1;
+    op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+    Py_INCREF(op->defaults_tuple);
+    op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+    Py_INCREF(op->defaults_kwdict);
+    Py_DECREF(res);
+    return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+    PyObject* tmp;
+    if (!value) {
+        value = Py_None;
+    } else if (value != Py_None && !PyTuple_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__defaults__ must be set to a tuple object");
+        return -1;
+    }
+    Py_INCREF(value);
+    tmp = op->defaults_tuple;
+    op->defaults_tuple = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+    PyObject* result = op->defaults_tuple;
+    if (unlikely(!result)) {
+        if (op->defaults_getter) {
+            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+            result = op->defaults_tuple;
+        } else {
+            result = Py_None;
+        }
+    }
+    Py_INCREF(result);
+    return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+    PyObject* tmp;
+    if (!value) {
+        value = Py_None;
+    } else if (value != Py_None && !PyDict_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__kwdefaults__ must be set to a dict object");
+        return -1;
+    }
+    Py_INCREF(value);
+    tmp = op->defaults_kwdict;
+    op->defaults_kwdict = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+    PyObject* result = op->defaults_kwdict;
+    if (unlikely(!result)) {
+        if (op->defaults_getter) {
+            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+            result = op->defaults_kwdict;
+        } else {
+            result = Py_None;
+        }
+    }
+    Py_INCREF(result);
+    return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+    PyObject* tmp;
+    if (!value || value == Py_None) {
+        value = NULL;
+    } else if (!PyDict_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__annotations__ must be set to a dict object");
+        return -1;
+    }
+    Py_XINCREF(value);
+    tmp = op->func_annotations;
+    op->func_annotations = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+    PyObject* result = op->func_annotations;
+    if (unlikely(!result)) {
+        result = PyDict_New();
+        if (unlikely(!result)) return NULL;
+        op->func_annotations = result;
+    }
+    Py_INCREF(result);
+    return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+    {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+    {(char *) "__doc__",  (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+    {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+    {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+    {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+    {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+    {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+    {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+    {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+    {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+    {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+    {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+    {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+    {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+    {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+    {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+    {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+    {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+    {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+    {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+    {0, 0, 0,  0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+    return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+    return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+    {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+    {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+                                      PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+    __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+    if (op == NULL)
+        return NULL;
+    op->flags = flags;
+    __Pyx_CyFunction_weakreflist(op) = NULL;
+    op->func.m_ml = ml;
+    op->func.m_self = (PyObject *) op;
+    Py_XINCREF(closure);
+    op->func_closure = closure;
+    Py_XINCREF(module);
+    op->func.m_module = module;
+    op->func_dict = NULL;
+    op->func_name = NULL;
+    Py_INCREF(qualname);
+    op->func_qualname = qualname;
+    op->func_doc = NULL;
+    op->func_classobj = NULL;
+    op->func_globals = globals;
+    Py_INCREF(op->func_globals);
+    Py_XINCREF(code);
+    op->func_code = code;
+    op->defaults_pyobjects = 0;
+    op->defaults = NULL;
+    op->defaults_tuple = NULL;
+    op->defaults_kwdict = NULL;
+    op->defaults_getter = NULL;
+    op->func_annotations = NULL;
+    PyObject_GC_Track(op);
+    return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+    Py_CLEAR(m->func_closure);
+    Py_CLEAR(m->func.m_module);
+    Py_CLEAR(m->func_dict);
+    Py_CLEAR(m->func_name);
+    Py_CLEAR(m->func_qualname);
+    Py_CLEAR(m->func_doc);
+    Py_CLEAR(m->func_globals);
+    Py_CLEAR(m->func_code);
+    Py_CLEAR(m->func_classobj);
+    Py_CLEAR(m->defaults_tuple);
+    Py_CLEAR(m->defaults_kwdict);
+    Py_CLEAR(m->func_annotations);
+    if (m->defaults) {
+        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+        int i;
+        for (i = 0; i < m->defaults_pyobjects; i++)
+            Py_XDECREF(pydefaults[i]);
+        PyMem_Free(m->defaults);
+        m->defaults = NULL;
+    }
+    return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+    PyObject_GC_UnTrack(m);
+    if (__Pyx_CyFunction_weakreflist(m) != NULL)
+        PyObject_ClearWeakRefs((PyObject *) m);
+    __Pyx_CyFunction_clear(m);
+    PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+    Py_VISIT(m->func_closure);
+    Py_VISIT(m->func.m_module);
+    Py_VISIT(m->func_dict);
+    Py_VISIT(m->func_name);
+    Py_VISIT(m->func_qualname);
+    Py_VISIT(m->func_doc);
+    Py_VISIT(m->func_globals);
+    Py_VISIT(m->func_code);
+    Py_VISIT(m->func_classobj);
+    Py_VISIT(m->defaults_tuple);
+    Py_VISIT(m->defaults_kwdict);
+    if (m->defaults) {
+        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+        int i;
+        for (i = 0; i < m->defaults_pyobjects; i++)
+            Py_VISIT(pydefaults[i]);
+    }
+    return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+        Py_INCREF(func);
+        return func;
+    }
+    if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+        if (type == NULL)
+            type = (PyObject *)(Py_TYPE(obj));
+        return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+    }
+    if (obj == Py_None)
+        obj = NULL;
+    return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+    return PyUnicode_FromFormat("<cyfunction %U at %p>",
+                                op->func_qualname, (void *)op);
+#else
+    return PyString_FromFormat("<cyfunction %s at %p>",
+                               PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyCFunctionObject* f = (PyCFunctionObject*)func;
+    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+    PyObject *self = PyCFunction_GET_SELF(func);
+    Py_ssize_t size;
+    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+    case METH_VARARGS:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+            return (*meth)(self, arg);
+        break;
+    case METH_VARARGS | METH_KEYWORDS:
+        return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+    case METH_NOARGS:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 0)
+                return (*meth)(self, NULL);
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes no arguments (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    case METH_O:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 1)
+                return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes exactly one argument (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    default:
+        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+                        "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+                        "longer supported!");
+        return NULL;
+    }
+    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+                 f->m_ml->ml_name);
+    return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+	return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+    PyVarObject_HEAD_INIT(0, 0)
+    "cython_function_or_method",
+    sizeof(__pyx_CyFunctionObject),
+    0,
+    (destructor) __Pyx_CyFunction_dealloc,
+    0,
+    0,
+    0,
+#if PY_MAJOR_VERSION < 3
+    0,
+#else
+    0,
+#endif
+    (reprfunc) __Pyx_CyFunction_repr,
+    0,
+    0,
+    0,
+    0,
+    __Pyx_CyFunction_Call,
+    0,
+    0,
+    0,
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+    0,
+    (traverseproc) __Pyx_CyFunction_traverse,
+    (inquiry) __Pyx_CyFunction_clear,
+    0,
+#if PY_VERSION_HEX < 0x030500A0
+    offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+    offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+    0,
+    0,
+    __pyx_CyFunction_methods,
+    __pyx_CyFunction_members,
+    __pyx_CyFunction_getsets,
+    0,
+    0,
+    __Pyx_CyFunction_descr_get,
+    0,
+    offsetof(__pyx_CyFunctionObject, func_dict),
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+#if PY_VERSION_HEX >= 0x030400a1
+    0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+    __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+    __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+    if (__pyx_CyFunctionType == NULL) {
+        return -1;
+    }
+    return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->defaults = PyMem_Malloc(size);
+    if (!m->defaults)
+        return PyErr_NoMemory();
+    memset(m->defaults, 0, size);
+    m->defaults_pyobjects = pyobjects;
+    return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->defaults_tuple = tuple;
+    Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->defaults_kwdict = dict;
+    Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->func_annotations = dict;
+    Py_INCREF(dict);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Format(PyExc_ImportError,
+        #if PY_MAJOR_VERSION < 3
+            "cannot import name %.230s", PyString_AS_STRING(name));
+        #else
+            "cannot import name %S", name);
+        #endif
+    }
+    return value;
+}
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) {
+    Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases);
+    for (i=0; i < nbases; i++) {
+        PyTypeObject *tmptype;
+        PyObject *tmp = PyTuple_GET_ITEM(bases, i);
+        tmptype = Py_TYPE(tmp);
+#if PY_MAJOR_VERSION < 3
+        if (tmptype == &PyClass_Type)
+            continue;
+#endif
+        if (!metaclass) {
+            metaclass = tmptype;
+            continue;
+        }
+        if (PyType_IsSubtype(metaclass, tmptype))
+            continue;
+        if (PyType_IsSubtype(tmptype, metaclass)) {
+            metaclass = tmptype;
+            continue;
+        }
+        PyErr_SetString(PyExc_TypeError,
+                        "metaclass conflict: "
+                        "the metaclass of a derived class "
+                        "must be a (non-strict) subclass "
+                        "of the metaclasses of all its bases");
+        return NULL;
+    }
+    if (!metaclass) {
+#if PY_MAJOR_VERSION < 3
+        metaclass = &PyClass_Type;
+#else
+        metaclass = &PyType_Type;
+#endif
+    }
+    Py_INCREF((PyObject*) metaclass);
+    return (PyObject*) metaclass;
+}
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
+                                           PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
+    PyObject *ns;
+    if (metaclass) {
+        PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare);
+        if (prep) {
+            PyObject *pargs = PyTuple_Pack(2, name, bases);
+            if (unlikely(!pargs)) {
+                Py_DECREF(prep);
+                return NULL;
+            }
+            ns = PyObject_Call(prep, pargs, mkw);
+            Py_DECREF(prep);
+            Py_DECREF(pargs);
+        } else {
+            if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
+                return NULL;
+            PyErr_Clear();
+            ns = PyDict_New();
+        }
+    } else {
+        ns = PyDict_New();
+    }
+    if (unlikely(!ns))
+        return NULL;
+    if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad;
+    if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad;
+    if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad;
+    return ns;
+bad:
+    Py_DECREF(ns);
+    return NULL;
+}
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
+                                      PyObject *dict, PyObject *mkw,
+                                      int calculate_metaclass, int allow_py2_metaclass) {
+    PyObject *result, *margs;
+    PyObject *owned_metaclass = NULL;
+    if (allow_py2_metaclass) {
+        owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass);
+        if (owned_metaclass) {
+            metaclass = owned_metaclass;
+        } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) {
+            PyErr_Clear();
+        } else {
+            return NULL;
+        }
+    }
+    if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) {
+        metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases);
+        Py_XDECREF(owned_metaclass);
+        if (unlikely(!metaclass))
+            return NULL;
+        owned_metaclass = metaclass;
+    }
+    margs = PyTuple_Pack(3, name, bases, dict);
+    if (unlikely(!margs)) {
+        result = NULL;
+    } else {
+        result = PyObject_Call(metaclass, margs, mkw);
+        Py_DECREF(margs);
+    }
+    Py_XDECREF(owned_metaclass);
+    return result;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
+    }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
+    {                                                                     \
+        func_type value = func_value;                                     \
+        if (sizeof(target_type) < sizeof(func_type)) {                    \
+            if (unlikely(value != (func_type) (target_type) value)) {     \
+                func_type zero = 0;                                       \
+                if (is_unsigned && unlikely(value < zero))                \
+                    goto raise_neg_overflow;                              \
+                else                                                      \
+                    goto raise_overflow;                                  \
+            }                                                             \
+        }                                                                 \
+        return (target_type) value;                                       \
+    }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
+        }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+    const char neg_one = (char) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(char) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (char) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(char) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(char) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(char,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(char) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+            } else if (sizeof(char) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            char val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (char) -1;
+        }
+    } else {
+        char val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (char) -1;
+        val = __Pyx_PyInt_As_char(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to char");
+    return (char) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to char");
+    return (char) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_char(char value) {
+    const char neg_one = (char) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(char) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(char) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(char) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(char) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(char) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(char),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = *type;
+    tstate->exc_value = *value;
+    tstate->exc_traceback = *tb;
+#else
+    PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+    PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+    *type = tmp_type;
+    *value = tmp_value;
+    *tb = tmp_tb;
+}
+
+static PyObject *__Pyx_Generator_Next(PyObject *self);
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
+static PyObject *__Pyx_Generator_Close(PyObject *self);
+static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
+static PyTypeObject *__pyx_GeneratorType = 0;
+#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
+#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
+    PyObject *et, *ev, *tb;
+    PyObject *value = NULL;
+    __Pyx_ErrFetch(&et, &ev, &tb);
+    if (!et) {
+        Py_XDECREF(tb);
+        Py_XDECREF(ev);
+        Py_INCREF(Py_None);
+        *pvalue = Py_None;
+        return 0;
+    }
+    if (unlikely(et != PyExc_StopIteration) &&
+            unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
+        __Pyx_ErrRestore(et, ev, tb);
+        return -1;
+    }
+    if (likely(et == PyExc_StopIteration)) {
+        if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
+            if (!ev) {
+                Py_INCREF(Py_None);
+                ev = Py_None;
+            }
+            Py_XDECREF(tb);
+            Py_DECREF(et);
+            *pvalue = ev;
+            return 0;
+        }
+    }
+    PyErr_NormalizeException(&et, &ev, &tb);
+    if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
+        __Pyx_ErrRestore(et, ev, tb);
+        return -1;
+    }
+    Py_XDECREF(tb);
+    Py_DECREF(et);
+#if PY_VERSION_HEX >= 0x030300A0
+    value = ((PyStopIterationObject *)ev)->value;
+    Py_INCREF(value);
+    Py_DECREF(ev);
+#else
+    {
+        PyObject* args = PyObject_GetAttr(ev, __pyx_n_s_args);
+        Py_DECREF(ev);
+        if (likely(args)) {
+            value = PyObject_GetItem(args, 0);
+            Py_DECREF(args);
+        }
+        if (unlikely(!value)) {
+            __Pyx_ErrRestore(NULL, NULL, NULL);
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+    }
+#endif
+    *pvalue = value;
+    return 0;
+}
+#endif
+static CYTHON_INLINE
+void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
+    PyObject *exc_type = self->exc_type;
+    PyObject *exc_value = self->exc_value;
+    PyObject *exc_traceback = self->exc_traceback;
+    self->exc_type = NULL;
+    self->exc_value = NULL;
+    self->exc_traceback = NULL;
+    Py_XDECREF(exc_type);
+    Py_XDECREF(exc_value);
+    Py_XDECREF(exc_traceback);
+}
+static CYTHON_INLINE
+int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
+    if (unlikely(gen->is_running)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "generator already executing");
+        return 1;
+    }
+    return 0;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
+    PyObject *retval;
+    assert(!self->is_running);
+    if (unlikely(self->resume_label == 0)) {
+        if (unlikely(value && value != Py_None)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "can't send non-None value to a "
+                            "just-started generator");
+            return NULL;
+        }
+    }
+    if (unlikely(self->resume_label == -1)) {
+        PyErr_SetNone(PyExc_StopIteration);
+        return NULL;
+    }
+    if (value) {
+#if CYTHON_COMPILING_IN_PYPY
+#else
+        if (self->exc_traceback) {
+            PyThreadState *tstate = PyThreadState_GET();
+            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+            PyFrameObject *f = tb->tb_frame;
+            Py_XINCREF(tstate->frame);
+            assert(f->f_back == NULL);
+            f->f_back = tstate->frame;
+        }
+#endif
+        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+                            &self->exc_traceback);
+    } else {
+        __Pyx_Generator_ExceptionClear(self);
+    }
+    self->is_running = 1;
+    retval = self->body((PyObject *) self, value);
+    self->is_running = 0;
+    if (retval) {
+        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+                            &self->exc_traceback);
+#if CYTHON_COMPILING_IN_PYPY
+#else
+        if (self->exc_traceback) {
+            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+            PyFrameObject *f = tb->tb_frame;
+            Py_CLEAR(f->f_back);
+        }
+#endif
+    } else {
+        __Pyx_Generator_ExceptionClear(self);
+    }
+    return retval;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
+    PyObject *ret;
+    PyObject *val = NULL;
+    __Pyx_Generator_Undelegate(gen);
+    __Pyx_PyGen_FetchStopIterationValue(&val);
+    ret = __Pyx_Generator_SendEx(gen, val);
+    Py_XDECREF(val);
+    return ret;
+}
+static PyObject *__Pyx_Generator_Next(PyObject *self) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+    PyObject *yf = gen->yieldfrom;
+    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+        return NULL;
+    if (yf) {
+        PyObject *ret;
+        gen->is_running = 1;
+        ret = Py_TYPE(yf)->tp_iternext(yf);
+        gen->is_running = 0;
+        if (likely(ret)) {
+            return ret;
+        }
+        return __Pyx_Generator_FinishDelegation(gen);
+    }
+    return __Pyx_Generator_SendEx(gen, Py_None);
+}
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+    PyObject *yf = gen->yieldfrom;
+    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+        return NULL;
+    if (yf) {
+        PyObject *ret;
+        gen->is_running = 1;
+        if (__Pyx_Generator_CheckExact(yf)) {
+            ret = __Pyx_Generator_Send(yf, value);
+        } else {
+            if (value == Py_None)
+                ret = PyIter_Next(yf);
+            else
+                ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value);
+        }
+        gen->is_running = 0;
+        if (likely(ret)) {
+            return ret;
+        }
+        return __Pyx_Generator_FinishDelegation(gen);
+    }
+    return __Pyx_Generator_SendEx(gen, value);
+}
+static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
+    PyObject *retval = NULL;
+    int err = 0;
+    if (__Pyx_Generator_CheckExact(yf)) {
+        retval = __Pyx_Generator_Close(yf);
+        if (!retval)
+            return -1;
+    } else {
+        PyObject *meth;
+        gen->is_running = 1;
+        meth = PyObject_GetAttr(yf, __pyx_n_s_close);
+        if (unlikely(!meth)) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                PyErr_WriteUnraisable(yf);
+            }
+            PyErr_Clear();
+        } else {
+            retval = PyObject_CallFunction(meth, NULL);
+            Py_DECREF(meth);
+            if (!retval)
+                err = -1;
+        }
+        gen->is_running = 0;
+    }
+    Py_XDECREF(retval);
+    return err;
+}
+static PyObject *__Pyx_Generator_Close(PyObject *self) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    PyObject *retval, *raised_exception;
+    PyObject *yf = gen->yieldfrom;
+    int err = 0;
+    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+        return NULL;
+    if (yf) {
+        Py_INCREF(yf);
+        err = __Pyx_Generator_CloseIter(gen, yf);
+        __Pyx_Generator_Undelegate(gen);
+        Py_DECREF(yf);
+    }
+    if (err == 0)
+        PyErr_SetNone(PyExc_GeneratorExit);
+    retval = __Pyx_Generator_SendEx(gen, NULL);
+    if (retval) {
+        Py_DECREF(retval);
+        PyErr_SetString(PyExc_RuntimeError,
+                        "generator ignored GeneratorExit");
+        return NULL;
+    }
+    raised_exception = PyErr_Occurred();
+    if (!raised_exception
+        || raised_exception == PyExc_StopIteration
+        || raised_exception == PyExc_GeneratorExit
+        || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
+        || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
+    {
+        if (raised_exception) PyErr_Clear();
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return NULL;
+}
+static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    PyObject *typ;
+    PyObject *tb = NULL;
+    PyObject *val = NULL;
+    PyObject *yf = gen->yieldfrom;
+    if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
+        return NULL;
+    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+        return NULL;
+    if (yf) {
+        PyObject *ret;
+        Py_INCREF(yf);
+        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
+            int err = __Pyx_Generator_CloseIter(gen, yf);
+            Py_DECREF(yf);
+            __Pyx_Generator_Undelegate(gen);
+            if (err < 0)
+                return __Pyx_Generator_SendEx(gen, NULL);
+            goto throw_here;
+        }
+        gen->is_running = 1;
+        if (__Pyx_Generator_CheckExact(yf)) {
+            ret = __Pyx_Generator_Throw(yf, args);
+        } else {
+            PyObject *meth = PyObject_GetAttr(yf, __pyx_n_s_throw);
+            if (unlikely(!meth)) {
+                Py_DECREF(yf);
+                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                    gen->is_running = 0;
+                    return NULL;
+                }
+                PyErr_Clear();
+                __Pyx_Generator_Undelegate(gen);
+                gen->is_running = 0;
+                goto throw_here;
+            }
+            ret = PyObject_CallObject(meth, args);
+            Py_DECREF(meth);
+        }
+        gen->is_running = 0;
+        Py_DECREF(yf);
+        if (!ret) {
+            ret = __Pyx_Generator_FinishDelegation(gen);
+        }
+        return ret;
+    }
+throw_here:
+    __Pyx_Raise(typ, val, tb, NULL);
+    return __Pyx_Generator_SendEx(gen, NULL);
+}
+static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    Py_VISIT(gen->closure);
+    Py_VISIT(gen->classobj);
+    Py_VISIT(gen->yieldfrom);
+    Py_VISIT(gen->exc_type);
+    Py_VISIT(gen->exc_value);
+    Py_VISIT(gen->exc_traceback);
+    return 0;
+}
+static int __Pyx_Generator_clear(PyObject *self) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    Py_CLEAR(gen->closure);
+    Py_CLEAR(gen->classobj);
+    Py_CLEAR(gen->yieldfrom);
+    Py_CLEAR(gen->exc_type);
+    Py_CLEAR(gen->exc_value);
+    Py_CLEAR(gen->exc_traceback);
+    Py_CLEAR(gen->gi_name);
+    Py_CLEAR(gen->gi_qualname);
+    return 0;
+}
+static void __Pyx_Generator_dealloc(PyObject *self) {
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    PyObject_GC_UnTrack(gen);
+    if (gen->gi_weakreflist != NULL)
+        PyObject_ClearWeakRefs(self);
+    if (gen->resume_label > 0) {
+        PyObject_GC_Track(self);
+#if PY_VERSION_HEX >= 0x030400a1
+        if (PyObject_CallFinalizerFromDealloc(self))
+#else
+        Py_TYPE(gen)->tp_del(self);
+        if (self->ob_refcnt > 0)
+#endif
+        {
+            return;
+        }
+        PyObject_GC_UnTrack(self);
+    }
+    __Pyx_Generator_clear(self);
+    PyObject_GC_Del(gen);
+}
+static void __Pyx_Generator_del(PyObject *self) {
+    PyObject *res;
+    PyObject *error_type, *error_value, *error_traceback;
+    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+    if (gen->resume_label <= 0)
+        return ;
+#if PY_VERSION_HEX < 0x030400a1
+    assert(self->ob_refcnt == 0);
+    self->ob_refcnt = 1;
+#endif
+    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
+    res = __Pyx_Generator_Close(self);
+    if (res == NULL)
+        PyErr_WriteUnraisable(self);
+    else
+        Py_DECREF(res);
+    __Pyx_ErrRestore(error_type, error_value, error_traceback);
+#if PY_VERSION_HEX < 0x030400a1
+    assert(self->ob_refcnt > 0);
+    if (--self->ob_refcnt == 0) {
+        return;
+    }
+    {
+        Py_ssize_t refcnt = self->ob_refcnt;
+        _Py_NewReference(self);
+        self->ob_refcnt = refcnt;
+    }
+#if CYTHON_COMPILING_IN_CPYTHON
+    assert(PyType_IS_GC(self->ob_type) &&
+           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+    _Py_DEC_REFTOTAL;
+#endif
+#ifdef COUNT_ALLOCS
+    --Py_TYPE(self)->tp_frees;
+    --Py_TYPE(self)->tp_allocs;
+#endif
+#endif
+}
+static PyObject *
+__Pyx_Generator_get_name(__pyx_GeneratorObject *self)
+{
+    Py_INCREF(self->gi_name);
+    return self->gi_name;
+}
+static int
+__Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__name__ must be set to a string object");
+        return -1;
+    }
+    tmp = self->gi_name;
+    Py_INCREF(value);
+    self->gi_name = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_Generator_get_qualname(__pyx_GeneratorObject *self)
+{
+    Py_INCREF(self->gi_qualname);
+    return self->gi_qualname;
+}
+static int
+__Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__qualname__ must be set to a string object");
+        return -1;
+    }
+    tmp = self->gi_qualname;
+    Py_INCREF(value);
+    self->gi_qualname = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyGetSetDef __pyx_Generator_getsets[] = {
+    {(char *) "__name__", (getter)__Pyx_Generator_get_name, (setter)__Pyx_Generator_set_name,
+     (char*) PyDoc_STR("name of the generator"), 0},
+    {(char *) "__qualname__", (getter)__Pyx_Generator_get_qualname, (setter)__Pyx_Generator_set_qualname,
+     (char*) PyDoc_STR("qualified name of the generator"), 0},
+    {0, 0, 0, 0, 0}
+};
+static PyMemberDef __pyx_Generator_memberlist[] = {
+    {(char *) "gi_running", T_BOOL, offsetof(__pyx_GeneratorObject, is_running), READONLY, NULL},
+    {0, 0, 0, 0, 0}
+};
+static PyMethodDef __pyx_Generator_methods[] = {
+    {"send", (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
+    {"throw", (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
+    {"close", (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
+    {0, 0, 0, 0}
+};
+static PyTypeObject __pyx_GeneratorType_type = {
+    PyVarObject_HEAD_INIT(0, 0)
+    "generator",
+    sizeof(__pyx_GeneratorObject),
+    0,
+    (destructor) __Pyx_Generator_dealloc,
+    0,
+    0,
+    0,
+#if PY_MAJOR_VERSION < 3
+    0,
+#else
+    0,
+#endif
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
+    0,
+    (traverseproc) __Pyx_Generator_traverse,
+    0,
+    0,
+    offsetof(__pyx_GeneratorObject, gi_weakreflist),
+    0,
+    (iternextfunc) __Pyx_Generator_Next,
+    __pyx_Generator_methods,
+    __pyx_Generator_memberlist,
+    __pyx_Generator_getsets,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+#if PY_VERSION_HEX >= 0x030400a1
+    0,
+#else
+    __Pyx_Generator_del,
+#endif
+    0,
+#if PY_VERSION_HEX >= 0x030400a1
+    __Pyx_Generator_del,
+#endif
+};
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+                                                  PyObject *closure, PyObject *name, PyObject *qualname) {
+    __pyx_GeneratorObject *gen =
+        PyObject_GC_New(__pyx_GeneratorObject, &__pyx_GeneratorType_type);
+    if (gen == NULL)
+        return NULL;
+    gen->body = body;
+    gen->closure = closure;
+    Py_XINCREF(closure);
+    gen->is_running = 0;
+    gen->resume_label = 0;
+    gen->classobj = NULL;
+    gen->yieldfrom = NULL;
+    gen->exc_type = NULL;
+    gen->exc_value = NULL;
+    gen->exc_traceback = NULL;
+    gen->gi_weakreflist = NULL;
+    Py_XINCREF(qualname);
+    gen->gi_qualname = qualname;
+    Py_XINCREF(name);
+    gen->gi_name = name;
+    PyObject_GC_Track(gen);
+    return gen;
+}
+static int __pyx_Generator_init(void) {
+    __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
+    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
+    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
+    if (__pyx_GeneratorType == NULL) {
+        return -1;
+    }
+    return 0;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        return PyErr_WarnEx(NULL, message, 1);
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s.%.200s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%.200s.%.200s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_MAJOR_VERSION < 3
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%.4s__ returned non-%.4s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b)))
+      return PyInt_AS_LONG(b);
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+     #if CYTHON_USE_PYLONG_INTERNALS
+       switch (Py_SIZE(b)) {
+       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+       case  0: return 0;
+       case  1: return ((PyLongObject*)b)->ob_digit[0];
+       }
+     #endif
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+    return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/astropy/io/ascii/cparser.pyx b/astropy/io/ascii/cparser.pyx
new file mode 100644
index 0000000..7821936
--- /dev/null
+++ b/astropy/io/ascii/cparser.pyx
@@ -0,0 +1,1068 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import csv
+import os
+import math
+import multiprocessing
+import mmap
+
+import numpy as np
+cimport numpy as np
+from numpy import ma
+from libc cimport stdio
+from cpython.buffer cimport PyBUF_SIMPLE
+from cpython.buffer cimport Py_buffer
+from cpython.buffer cimport PyObject_GetBuffer, PyBuffer_Release
+
+from ...utils.data import get_readable_fileobj
+from ...table import pprint
+from ...extern import six
+from . import core
+
+try:
+    import Queue
+except ImportError: # in python 3, the module is named queue
+    import queue as Queue
+
+cdef extern from "src/tokenizer.h":
+    ctypedef enum tokenizer_state:
+        START_LINE
+        START_FIELD
+        START_QUOTED_FIELD
+        FIELD
+        QUOTED_FIELD
+        QUOTED_FIELD_NEWLINE
+        COMMENT
+        CARRIAGE_RETURN
+
+    ctypedef enum err_code:
+        NO_ERROR
+        INVALID_LINE
+        TOO_MANY_COLS
+        NOT_ENOUGH_COLS
+        CONVERSION_ERROR
+        OVERFLOW_ERROR
+
+    ctypedef struct tokenizer_t:
+        char *source           # single string containing all of the input
+        int source_len         # length of the input
+        int source_pos         # current index in source for tokenization
+        char delimiter         # delimiter character
+        char comment           # comment character
+        char quotechar         # quote character
+        char **output_cols     # array of output strings for each column
+        char **col_ptrs        # array of pointers to current output position for each col
+        int *output_len        # length of each output column string
+        int num_cols           # number of table columns
+        int num_rows           # number of table rows
+        int fill_extra_cols    # represents whether or not to fill rows with too few values
+        tokenizer_state state  # current state of the tokenizer
+        err_code code          # represents the latest error that has occurred
+        int iter_col           # index of the column being iterated over
+        char *curr_pos         # current iteration position
+        char *buf              # buffer for empty data
+        int strip_whitespace_lines  # whether to strip whitespace at the beginning and end of lines
+        int strip_whitespace_fields # whether to strip whitespace at the beginning and end of fields
+        int use_fast_converter      # whether to use the fast converter for floats
+        char *comment_lines    # single null-delimited string containing comment lines
+        int comment_lines_len  # length of comment_lines in memory
+        int comment_pos        # current index in comment_lines
+        # Example input/output
+        # --------------------
+        # source: "A,B,C\n10,5.,6\n1,2,3"
+        # output_cols: ["A\x0010\x001", "B\x005.\x002", "C\x006\x003"]
+
+    ctypedef struct memory_map:
+        char *ptr
+        int len
+        void *file_ptr
+        void *handle
+
+    tokenizer_t *create_tokenizer(char delimiter, char comment, char quotechar,
+                                  int fill_extra_cols, int strip_whitespace_lines,
+                                  int strip_whitespace_fields, int use_fast_converter)
+    void delete_tokenizer(tokenizer_t *tokenizer)
+    int skip_lines(tokenizer_t *self, int offset, int header)
+    int tokenize(tokenizer_t *self, int end, int header, int num_cols)
+    long str_to_long(tokenizer_t *self, char *str)
+    double fast_str_to_double(tokenizer_t *self, char *str)
+    double str_to_double(tokenizer_t *self, char *str)
+    void start_iteration(tokenizer_t *self, int col)
+    char *next_field(tokenizer_t *self, int *size)
+    char *get_line(char *ptr, int *len, int map_len)
+    void reset_comments(tokenizer_t *self)
+
+cdef extern from "Python.h":
+    int PyObject_AsReadBuffer(object obj, const void **buffer, Py_ssize_t *buffer_len)
+
+class CParserError(Exception):
+    """
+    An instance of this class is thrown when an error occurs
+    during C parsing.
+    """
+
+ERR_CODES = dict(enumerate([
+    "no error",
+    "invalid line supplied",
+    lambda line: "too many columns found in line {0} of data".format(line),
+    lambda line: "not enough columns found in line {0} of data".format(line),
+    "type conversion error",
+    "overflow error"
+    ]))
+
+cdef class FileString:
+    """
+    A wrapper class for a memory-mapped file pointer.
+    """
+    cdef:
+        object fhandle
+        object mmap
+        void *mmap_ptr
+        Py_buffer buf
+
+    def __cinit__(self, fname):
+        self.fhandle = open(fname, 'r')
+        if not self.fhandle:
+            raise IOError('File "{0}" could not be opened'.format(fname))
+        self.mmap = mmap.mmap(self.fhandle.fileno(), 0, prot=mmap.PROT_READ)
+        cdef Py_ssize_t buf_len = len(self.mmap)
+        if six.PY2:
+            PyObject_AsReadBuffer(self.mmap, &self.mmap_ptr, &buf_len)
+        else:
+            PyObject_GetBuffer(self.mmap, &self.buf, PyBUF_SIMPLE)
+            self.mmap_ptr = self.buf.buf
+
+    def __dealloc__(self):
+        if self.mmap:
+            if not six.PY2: # free buffer memory to prevent a resource leak
+                PyBuffer_Release(&self.buf)
+            self.mmap.close()
+            self.fhandle.close()
+
+    def __len__(self):
+        return len(self.mmap)
+
+    def __getitem__(self, i):
+        return self.mmap[i]
+
+    def splitlines(self):
+        """
+        Return a generator yielding lines from the memory map.
+        """
+        cdef char *ptr = <char *>self.mmap_ptr
+        cdef char *tmp
+        cdef int line_len
+        cdef int map_len = len(self.mmap)
+
+        while ptr:
+            tmp = get_line(ptr, &line_len, map_len)
+            yield ptr[:line_len].decode('ascii')
+            ptr = tmp
+
+cdef class CParser:
+    """
+    A fast Cython parser class which uses underlying C code
+    for tokenization.
+    """
+
+    cdef:
+        tokenizer_t *tokenizer
+        object names
+        int data_start
+        object data_end
+        object include_names
+        object exclude_names
+        object fill_values
+        object fill_empty
+        object fill_include_names
+        object fill_exclude_names
+        object fill_names
+        int fill_extra_cols
+        bytes source_bytes
+        char *source_ptr
+        object parallel
+        set use_cols
+
+    cdef public:
+        int width
+        object source
+        object header_start
+
+    def __cinit__(self, source, strip_line_whitespace, strip_line_fields,
+                  delimiter=',',
+                  comment=None,
+                  quotechar='"',
+                  header_start=0,
+                  data_start=1,
+                  data_end=None,
+                  names=None,
+                  include_names=None,
+                  exclude_names=None,
+                  fill_values=('', '0'),
+                  fill_include_names=None,
+                  fill_exclude_names=None,
+                  fill_extra_cols=0,
+                  fast_reader=True):
+
+        # Handle fast_reader parameter (True or dict specifying options)
+        if fast_reader is True or fast_reader == 'force':
+            fast_reader = {}
+        elif fast_reader is False: # shouldn't happen
+            raise core.ParameterError("fast_reader cannot be False for fast readers")
+        # parallel and use_fast_reader are False by default
+        use_fast_converter = fast_reader.pop('use_fast_converter', False)
+        parallel = fast_reader.pop('parallel', False)
+        if fast_reader:
+            raise core.FastOptionsError("Invalid parameter in fast_reader dict")
+        if parallel and os.name == 'nt':
+            raise NotImplementedError("Multiprocessing is not yet supported on Windows")
+
+        if comment is None:
+            comment = '\x00' # tokenizer ignores all comments if comment='\x00'
+        self.tokenizer = create_tokenizer(ord(delimiter), ord(comment), ord(quotechar),
+                                          fill_extra_cols,
+                                          strip_line_whitespace,
+                                          strip_line_fields,
+                                          use_fast_converter)
+        self.source = None
+        if source is not None:
+            self.setup_tokenizer(source)
+        self.header_start = header_start
+        self.data_start = data_start
+        self.data_end = data_end
+        self.names = names
+        self.include_names = include_names
+        self.exclude_names = exclude_names
+        self.fill_values = fill_values
+        self.fill_include_names = fill_include_names
+        self.fill_exclude_names = fill_exclude_names
+        self.fill_names = None
+        self.fill_extra_cols = fill_extra_cols
+
+        # parallel=True indicates that we should use the CPU count
+        if parallel is True:
+            parallel = multiprocessing.cpu_count()
+        # If parallel = 1 or 0, don't use multiprocessing
+        elif parallel is not False and parallel < 2:
+            parallel = False
+        self.parallel = parallel
+
+    def __dealloc__(self):
+        if self.tokenizer:
+            delete_tokenizer(self.tokenizer) # perform C memory cleanup
+
+    cdef get_error(self, code, num_rows, msg):
+        err_msg = ERR_CODES.get(code, "unknown error")
+
+        # error code is lambda function taking current line as input
+        if callable(err_msg):
+            err_msg = err_msg(num_rows + 1)
+
+        return CParserError("{0}: {1}".format(msg, err_msg))
+
+    cdef raise_error(self, msg):
+        raise self.get_error(self.tokenizer.code, self.tokenizer.num_rows, msg)
+
+    cpdef setup_tokenizer(self, source):
+        cdef FileString fstring
+
+        if isinstance(source, six.string_types): # filename or data
+            if '\n' not in source and '\r' not in source: # filename
+                fstring = FileString(source)
+                self.tokenizer.source = <char *>fstring.mmap_ptr
+                self.source_ptr = <char *>fstring.mmap_ptr
+                self.source = fstring
+                self.tokenizer.source_len = len(fstring)
+                return
+            # Otherwise, source is the actual data so we leave it be
+        elif hasattr(source, 'read'): # file-like object
+            with get_readable_fileobj(source) as file_obj:
+                source = file_obj.read()
+        elif isinstance(source, FileString):
+            self.tokenizer.source = <char *>((<FileString>source).mmap_ptr)
+            self.source = source
+            self.tokenizer.source_len = len(source)
+            return
+        else:
+            try:
+                source = '\n'.join(source) # iterable sequence of lines
+            except TypeError:
+                raise TypeError('Input "table" must be a file-like object, a '
+                                'string (filename or data), or an iterable')
+        # Create a reference to the Python object so its char * pointer remains valid
+        self.source = source
+
+        # encode in ASCII for char * handling
+        self.source_bytes = self.source.encode('ascii')
+        self.tokenizer.source = self.source_bytes
+        self.tokenizer.source_len = len(self.source_bytes)
+
+    def read_header(self):
+        self.tokenizer.source_pos = 0
+
+        if self.names:
+            self.width = len(self.names)
+
+        # header_start is a valid line number
+        elif self.header_start is not None and self.header_start >= 0:
+            if skip_lines(self.tokenizer, self.header_start, 1) != 0:
+                self.raise_error("an error occurred while advancing to the "
+                                 "first header line")
+            if tokenize(self.tokenizer, -1, 1, 0) != 0:
+                self.raise_error("an error occurred while tokenizing the header line")
+            self.names = []
+            name = ''
+
+            for i in range(self.tokenizer.output_len[0]): # header is in first col string
+                c = self.tokenizer.output_cols[0][i] # next char in header string
+                if not c: # zero byte -- field terminator
+                    if name:
+                        # replace empty placeholder with ''
+                        self.names.append(name.replace('\x01', ''))
+                        name = ''
+                    else:
+                        break # end of string
+                else:
+                    name += chr(c)
+            self.width = len(self.names)
+
+        else:
+            # Get number of columns from first data row
+            if tokenize(self.tokenizer, -1, 1, 0) != 0:
+                self.raise_error("an error occurred while tokenizing the first line of data")
+            self.width = 0
+            for i in range(self.tokenizer.output_len[0]): # header is in first col string
+                # zero byte -- field terminator
+                if not self.tokenizer.output_cols[0][i]:
+                    # ends valid field
+                    if i > 0 and self.tokenizer.output_cols[0][i - 1]:
+                        self.width += 1
+                    else: # end of line
+                        break
+            if self.width == 0: # no data
+                raise core.InconsistentTableError('No data lines found, C reader '
+                                            'cannot autogenerate column names')
+            # auto-generate names
+            self.names = ['col{0}'.format(i + 1) for i in range(self.width)]
+
+        # self.use_cols should only contain columns included in output
+        self.use_cols = set(self.names)
+        if self.include_names is not None:
+            self.use_cols.intersection_update(self.include_names)
+        if self.exclude_names is not None:
+            self.use_cols.difference_update(self.exclude_names)
+
+        self.width = len(self.names)
+
+    def read(self, try_int, try_float, try_string):
+        if self.parallel:
+            return self._read_parallel(try_int, try_float, try_string)
+
+        # Read in a single process
+        self.tokenizer.source_pos = 0
+        if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+            self.raise_error("an error occurred while advancing to the first "
+                             "line of data")
+
+        cdef int data_end = -1 # keep reading data until the end
+        if self.data_end is not None and self.data_end >= 0:
+            data_end = max(self.data_end - self.data_start, 0) # read nothing if data_end < 0
+
+        if tokenize(self.tokenizer, data_end, 0, len(self.names)) != 0:
+            self.raise_error("an error occurred while parsing table data")
+        elif self.tokenizer.num_rows == 0: # no data
+            return ([np.array([], dtype=np.int_)] * self.width, [])
+        self._set_fill_values()
+        cdef int num_rows = self.tokenizer.num_rows
+        if self.data_end is not None and self.data_end < 0: # negative indexing
+            num_rows += self.data_end
+        return self._convert_data(self.tokenizer, try_int, try_float,
+                                  try_string, num_rows)
+
+    def _read_parallel(self, try_int, try_float, try_string):
+        cdef int source_len = len(self.source)
+        self.tokenizer.source_pos = 0
+
+        if skip_lines(self.tokenizer, self.data_start, 0) != 0:
+            self.raise_error("an error occurred while advancing to the first "
+                             "line of data")
+
+        cdef list line_comments = self._get_comments(self.tokenizer)
+        cdef int N = self.parallel
+        queue = multiprocessing.Queue()
+        cdef int offset = self.tokenizer.source_pos
+
+        if offset == source_len: # no data
+            return (dict((name, np.array([], dtype=np.int_)) for name in
+                         self.names), [])
+
+        cdef int chunksize = math.ceil((source_len - offset) / float(N))
+        cdef list chunkindices = [offset]
+
+        # This queue is used to signal processes to reconvert if necessary
+        reconvert_queue = multiprocessing.Queue()
+
+        for i in range(1, N):
+            index = max(offset + chunksize * i, chunkindices[i - 1])
+            while index < source_len and self.source[index] != '\n':
+                index += 1
+            if index < source_len:
+                chunkindices.append(index + 1)
+            else:
+                N = i
+                break
+
+        self._set_fill_values()
+        chunkindices.append(source_len)
+        cdef list processes = []
+
+        for i in range(N):
+            process = multiprocessing.Process(target=_read_chunk, args=(self,
+                chunkindices[i], chunkindices[i + 1],
+                try_int, try_float, try_string, queue, reconvert_queue, i))
+            processes.append(process)
+            process.start()
+
+        cdef list chunks = [None] * N
+        cdef dict failed_procs = {}
+
+        for i in range(N):
+            queue_ret, err, proc = queue.get()
+            if isinstance(err, Exception):
+                for process in processes:
+                    process.terminate()
+                raise err
+            elif err is not None: # err is (error code, error line)
+                failed_procs[proc] = err
+            comments, data = queue_ret
+            line_comments.extend(comments)
+            chunks[proc] = data
+
+        if failed_procs:
+            # find the line number of the error
+            line_no = 0
+            for i in range(N):
+                # ignore errors after data_end
+                if i in failed_procs and self.data_end is None or line_no < self.data_end:
+                    for process in processes:
+                        process.terminate()
+                    raise self.get_error(failed_procs[i][0], failed_procs[i][1] + line_no,
+                                         "an error occurred while parsing table data")
+                line_no += len(chunks[i][self.names[0]])
+
+        seen_str = {}
+        seen_numeric = {}
+        for name in self.names:
+            seen_str[name] = False
+            seen_numeric[name] = False
+
+        for chunk in chunks:
+            for name in chunk:
+                if chunk[name].dtype.kind in ('S', 'U'):
+                    # string values in column
+                    seen_str[name] = True
+                elif len(chunk[name]) > 0: # ignore empty chunk columns
+                    seen_numeric[name] = True
+
+        reconvert_cols = []
+
+        for i, name in enumerate(self.names):
+            if seen_str[name] and seen_numeric[name]:
+                # Reconvert to str to avoid conversion issues, e.g.
+                # 5 (int) -> 5.0 (float) -> 5.0 (string)
+                reconvert_cols.append(i)
+
+        reconvert_queue.put(reconvert_cols)
+        for process in processes:
+            process.join() # wait for each process to finish
+        try:
+            while True:
+                reconverted, proc, col = queue.get(False)
+                chunks[proc][self.names[col]] = reconverted
+        except Queue.Empty:
+            pass
+
+        if self.data_end is not None:
+            if self.data_end < 0:
+                # e.g. if data_end = -1, cut the last row
+                num_rows = 0
+                for chunk in chunks:
+                    num_rows += len(chunk[self.names[0]])
+                self.data_end += num_rows
+            else:
+                self.data_end -= self.data_start # ignore header
+
+            if self.data_end < 0: # no data
+                chunks = [dict((name, []) for name in self.names)]
+            else:
+                line_no = 0
+                for i, chunk in enumerate(chunks):
+                    num_rows = len(chunk[self.names[0]])
+                    if line_no + num_rows > self.data_end:
+                        for name in self.names:
+                            # truncate columns
+                            chunk[name] = chunk[name][:self.data_end - line_no]
+                        del chunks[i + 1:]
+                        break
+                    line_no += num_rows
+
+        ret = {}
+        for name in self.get_names():
+            col_chunks = [chunk.pop(name) for chunk in chunks]
+            if any(isinstance(col_chunk, ma.masked_array) for col_chunk in col_chunks):
+                ret[name] = ma.concatenate(col_chunks)
+            else:
+                ret[name] = np.concatenate(col_chunks)
+
+        for process in processes:
+            process.terminate()
+
+        return ret, line_comments
+
+    cdef _set_fill_values(self):
+        if self.fill_names is None:
+            self.fill_names = set(self.names)
+            if self.fill_include_names is not None:
+                self.fill_names.intersection_update(self.fill_include_names)
+            if self.fill_exclude_names is not None:
+                self.fill_names.difference_update(self.fill_exclude_names)
+        self.fill_values, self.fill_empty = get_fill_values(self.fill_values)
+
+    cdef _get_comments(self, tokenizer_t *t):
+        line_comments = []
+        comment = ''
+        for i in range(t.comment_pos):
+            c = t.comment_lines[i] # next char in comment string
+            if not c: # zero byte -- line terminator
+                # replace empty placeholder with ''
+                line_comments.append(comment.replace('\x01', '').strip())
+                comment = ''
+            else:
+                comment += chr(c)
+        return line_comments
+
+    cdef _convert_data(self, tokenizer_t *t, try_int, try_float, try_string, num_rows):
+        cols = {}
+
+        for i, name in enumerate(self.names):
+            if name not in self.use_cols:
+                continue
+            # Try int first, then float, then string
+            try:
+                if try_int and not try_int[name]:
+                    raise ValueError()
+                cols[name] = self._convert_int(t, i, num_rows)
+            except ValueError:
+                try:
+                    if try_float and not try_float[name]:
+                        raise ValueError()
+                    cols[name] = self._convert_float(t, i, num_rows)
+                except ValueError:
+                    if try_string and not try_string[name]:
+                        raise ValueError('Column {0} failed to convert'.format(name))
+                    cols[name] = self._convert_str(t, i, num_rows)
+
+        return cols, self._get_comments(t)
+
+    cdef np.ndarray _convert_int(self, tokenizer_t *t, int i, int nrows):
+        cdef int num_rows = t.num_rows
+        if nrows != -1:
+            num_rows = nrows
+        # intialize ndarray
+        cdef np.ndarray col = np.empty(num_rows, dtype=np.int_)
+        cdef long converted
+        cdef int row = 0
+        cdef long *data = <long *> col.data # pointer to raw data
+        cdef char *field
+        cdef char *empty_field = t.buf # memory address of designated empty buffer
+        cdef bytes new_value
+        mask = set() # set of indices for masked values
+        start_iteration(t, i) # begin the iteration process in C
+
+        for row in range(num_rows):
+            # retrieve the next field as a C pointer
+            field = next_field(t, <int *>0)
+            replace_info = None
+
+            if field == empty_field and self.fill_empty:
+                replace_info = self.fill_empty
+            # hopefully this implicit char * -> byte conversion for fill values
+            # checking can be avoided in most cases, since self.fill_values will
+            # be empty in the default case (self.fill_empty will do the work
+            # instead)
+            elif field != empty_field and self.fill_values and field in self.fill_values:
+                replace_info = self.fill_values[field]
+
+            if replace_info is not None:
+                # Either this column applies to the field as specified in the
+                # fill_values parameter, or no specific columns are specified
+                # and this column should apply fill_values.
+                if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+                   or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+                    mask.add(row)
+                    new_value = str(replace_info[0]).encode('ascii')
+                    # try converting the new value
+                    converted = str_to_long(t, new_value)
+                else:
+                    converted = str_to_long(t, field)
+            else:
+                # convert the field to long (widest integer type)
+                converted = str_to_long(t, field)
+
+            if t.code in (CONVERSION_ERROR, OVERFLOW_ERROR):
+                # no dice
+                t.code = NO_ERROR
+                raise ValueError()
+
+            data[row] = converted
+            row += 1
+
+        if mask:
+            # convert to masked_array
+            return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+                                              range(row)])
+        else:
+            return col
+
+    cdef np.ndarray _convert_float(self, tokenizer_t *t, int i, int nrows):
+        # very similar to _convert_int()
+        cdef int num_rows = t.num_rows
+        if nrows != -1:
+            num_rows = nrows
+
+        cdef np.ndarray col = np.empty(num_rows, dtype=np.float_)
+        cdef double converted
+        cdef int row = 0
+        cdef double *data = <double *> col.data
+        cdef char *field
+        cdef char *empty_field = t.buf
+        cdef bytes new_value
+        cdef int replacing
+        mask = set()
+
+        start_iteration(t, i)
+        for row in range(num_rows):
+            field = next_field(t, <int *>0)
+            replace_info = None
+            replacing = False
+
+            if field == empty_field and self.fill_empty:
+                replace_info = self.fill_empty
+
+            elif field != empty_field and self.fill_values and field in self.fill_values:
+                replace_info = self.fill_values[field]
+
+            if replace_info is not None:
+                if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+                   or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+                    mask.add(row)
+                    new_value = str(replace_info[0]).encode('ascii')
+                    replacing = True
+                    converted = str_to_double(t, new_value)
+                else:
+                    converted = str_to_double(t, field)
+            else:
+                converted = str_to_double(t, field)
+
+            if t.code == CONVERSION_ERROR:
+                t.code = NO_ERROR
+                raise ValueError()
+            elif t.code == OVERFLOW_ERROR:
+                t.code = NO_ERROR
+                raise ValueError()
+            else:
+                data[row] = converted
+            row += 1
+
+        if mask:
+            return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+                                              range(row)])
+        else:
+            return col
+
+    cdef _convert_str(self, tokenizer_t *t, int i, int nrows):
+        # similar to _convert_int, but no actual conversion
+        cdef int num_rows = t.num_rows
+        if nrows != -1:
+            num_rows = nrows
+
+        cdef int row = 0
+        cdef bytes field
+        cdef int field_len
+        cdef int max_len = 0
+        cdef list fields_list = []
+        mask = set()
+
+        start_iteration(t, i)
+        for row in range(num_rows):
+            field = next_field(t, &field_len)
+            replace_info = None
+
+            if field_len == 0 and self.fill_empty:
+                replace_info = self.fill_empty
+
+            elif field_len > 0 and self.fill_values and field in self.fill_values:
+                replace_info = self.fill_values[field]
+
+            if replace_info is not None:
+                el = replace_info[0].encode('ascii')
+                if (len(replace_info) > 1 and self.names[i] in replace_info[1:]) \
+                   or (len(replace_info) == 1 and self.names[i] in self.fill_names):
+                    mask.add(row)
+                    field = el
+
+            fields_list.append(field)
+            if field_len > max_len:
+                max_len = field_len
+            row += 1
+
+        cdef np.ndarray col = np.array(fields_list, dtype=(np.str, max_len))
+
+        if mask:
+            return ma.masked_array(col, mask=[1 if i in mask else 0 for i in
+                                              range(row)])
+        else:
+            return col
+
+    def get_names(self):
+        # ignore excluded columns
+        return [name for name in self.names if name in self.use_cols]
+
+    def set_names(self, names):
+        self.names = names
+
+    def __reduce__(self):
+        cdef bytes source_ptr = self.source_ptr if self.source_ptr else b''
+        return (_copy_cparser, (source_ptr, self.source_bytes, self.use_cols, self.fill_names,
+                                self.fill_values, self.tokenizer.strip_whitespace_lines,
+                                self.tokenizer.strip_whitespace_fields,
+                                dict(delimiter=chr(self.tokenizer.delimiter),
+                                comment=chr(self.tokenizer.comment),
+                                quotechar=chr(self.tokenizer.quotechar),
+                                header_start=self.header_start,
+                                data_start=self.data_start,
+                                data_end=self.data_end,
+                                names=self.names,
+                                include_names=self.include_names,
+                                exclude_names=self.exclude_names,
+                                fill_values=None,
+                                fill_include_names=self.fill_include_names,
+                                fill_exclude_names=self.fill_exclude_names,
+                                fill_extra_cols=self.tokenizer.fill_extra_cols,
+                                use_fast_converter=self.tokenizer.use_fast_converter,
+                                parallel=False)))
+
+def _copy_cparser(bytes src_ptr, bytes source_bytes, use_cols, fill_names, fill_values,
+                  strip_whitespace_lines, strip_whitespace_fields, kwargs):
+    parser = CParser(None, strip_whitespace_lines, strip_whitespace_fields, **kwargs)
+    parser.use_cols = use_cols
+    parser.fill_names = fill_names
+    parser.fill_values = fill_values
+
+    if src_ptr:
+        parser.tokenizer.source = src_ptr
+    else:
+        parser.tokenizer.source = source_bytes
+    return parser
+
+def _read_chunk(CParser self, start, end, try_int,
+                try_float, try_string, queue, reconvert_queue, i):
+    cdef tokenizer_t *chunk_tokenizer = self.tokenizer
+    chunk_tokenizer.source_len = end
+    chunk_tokenizer.source_pos = start
+    reset_comments(chunk_tokenizer)
+
+    data = None
+    err = None
+
+    if tokenize(chunk_tokenizer, -1, 0, len(self.names)) != 0:
+        err = (chunk_tokenizer.code, chunk_tokenizer.num_rows)
+    if chunk_tokenizer.num_rows == 0: # no data
+        data = dict((name, np.array([], np.int_)) for name in self.get_names())
+        line_comments = self._get_comments(chunk_tokenizer)
+    else:
+        try:
+            data, line_comments = self._convert_data(chunk_tokenizer,
+                                      try_int, try_float, try_string, -1)
+        except Exception as e:
+            delete_tokenizer(chunk_tokenizer)
+            queue.put((None, e, i))
+            return
+
+    try:
+        queue.put(((line_comments, data), err, i))
+    except Queue.Full as e:
+        # hopefully this shouldn't happen
+        delete_tokenizer(chunk_tokenizer)
+        queue.pop()
+        queue.put((None, e, i))
+    reconvert_cols = reconvert_queue.get()
+    for col in reconvert_cols:
+        queue.put((self._convert_str(chunk_tokenizer, col, -1), i, col))
+    delete_tokenizer(chunk_tokenizer)
+    reconvert_queue.put(reconvert_cols) # return to the queue for other processes
+
+cdef class FastWriter:
+    """
+    A fast Cython writing class for writing tables
+    as ASCII data.
+    """
+
+    cdef:
+        object table
+        list use_names
+        dict fill_values
+        set fill_cols
+        list col_iters
+        list formats
+        list format_funcs
+        list types
+        list line_comments
+        str quotechar
+        str delimiter
+        int strip_whitespace
+        object comment
+
+    def __cinit__(self, table,
+                  delimiter=',',
+                  comment='# ',
+                  quotechar='"',
+                  formats=None,
+                  strip_whitespace=True,
+                  names=None, # ignore, already used in _get_writer
+                  include_names=None,
+                  exclude_names=None,
+                  fill_values=[],
+                  fill_include_names=None,
+                  fill_exclude_names=None,
+                  fast_writer=True):
+
+        if fast_writer is True:
+            fast_writer = {}
+        # fast_writer might contain custom writing options
+
+        self.table = table
+        self.comment = comment
+        self.strip_whitespace = strip_whitespace
+        use_names = set(table.colnames)
+
+        # Apply include_names before exclude_names
+        if include_names is not None:
+            use_names.intersection_update(include_names)
+        if exclude_names is not None:
+            use_names.difference_update(exclude_names)
+        # preserve column ordering via list
+        self.use_names = [x for x in table.colnames if x in use_names]
+
+        fill_values = get_fill_values(fill_values, False)
+        self.fill_values = fill_values.copy()
+
+        # Add int/float versions of each fill value (if applicable)
+        # to the fill_values dict. This prevents the writer from having
+        # to call unicode() on every value, which is a major
+        # performance hit.
+        for key, val in six.iteritems(fill_values):
+            try:
+                self.fill_values[int(key)] = val
+                self.fill_values[float(key)] = val
+            except (ValueError, np.ma.MaskError):
+                pass
+
+        fill_names = set(self.use_names)
+        # Apply fill_include_names before fill_exclude_names
+        if fill_include_names is not None:
+            fill_names.intersection_update(fill_include_names)
+        if fill_exclude_names is not None:
+            fill_names.difference_update(fill_exclude_names)
+        # Preserve column ordering
+        self.fill_cols = set([i for i, name in enumerate(self.use_names) if
+                              name in fill_names])
+
+        # formats in user-specified dict should override
+        # existing column formats
+        if formats is not None:
+            for name in self.use_names:
+                if name in formats:
+                    self.table[name].format = formats[name]
+
+        self.col_iters = []
+        self.formats = []
+        self.format_funcs = []
+        self.line_comments = table.meta.get('comments', [])
+
+        for col in six.itervalues(table.columns):
+            if col.name in self.use_names: # iterate over included columns
+                if col.format is None:
+                    self.format_funcs.append(None)
+                else:
+                    self.format_funcs.append(pprint._format_funcs.get(col.format,
+                                                            auto_format_func))
+                # col is a numpy.ndarray, so we convert it to
+                # an ordinary list because csv.writer will call
+                # np.array_str() on each numpy value, which is
+                # very inefficient
+                self.col_iters.append(iter(col.tolist()))
+                self.formats.append(col.format)
+
+        self.quotechar = None if quotechar is None else str(quotechar)
+        self.delimiter = ' ' if delimiter is None else str(delimiter)
+        # 'S' for string types, 'N' for numeric types
+        self.types = ['S' if self.table[name].dtype.kind in ('S', 'U') else 'N'
+                      for name in self.use_names]
+
+    cdef _write_comments(self, output):
+        if self.comment is not False:
+            for comment_line in self.line_comments:
+                output.write(self.comment + comment_line + '\n')
+
+    def _write_header(self, output, writer, header_output, output_types):
+        if header_output is not None and header_output == 'comment':
+            output.write(self.comment)
+            writer.writerow([x.strip() for x in self.use_names] if
+                            self.strip_whitespace else self.use_names)
+            self._write_comments(output)
+        else:
+            self._write_comments(output)
+            if header_output is not None:
+                writer.writerow([x.strip() for x in self.use_names] if
+                            self.strip_whitespace else self.use_names)
+        if output_types:
+            writer.writerow(self.types)
+
+    def write(self, output, header_output, output_types):
+        opened_file = False
+
+        if not hasattr(output, 'write'): # output is a filename
+            output = open(output, 'w')
+            opened_file = True # remember to close file afterwards
+        writer = csv.writer(output,
+                            delimiter=self.delimiter,
+                            doublequote=True,
+                            escapechar=None,
+                            quotechar=self.quotechar,
+                            quoting=csv.QUOTE_MINIMAL,
+                            lineterminator=os.linesep)
+        self._write_header(output, writer, header_output, output_types)
+
+        # Split rows into N-sized chunks, since we don't want to
+        # store all the rows in memory at one time (inefficient)
+        # or fail to take advantage of the speed boost of writerows()
+        # over writerow().
+        cdef int N = 100
+        cdef int num_cols = len(self.use_names)
+        cdef int num_rows = len(self.table)
+        # cache string columns beforehand
+        cdef set string_rows = set([i for i, type in enumerate(self.types) if
+                                    type == 'S'])
+        cdef list rows = [[None] * num_cols for i in range(N)]
+
+        for i in range(num_rows):
+            for j in range(num_cols):
+                orig_field = next(self.col_iters[j]) # get field
+                # str_val monitors whether we should check if the field
+                # should be stripped
+                str_val = True
+
+                if orig_field is None: # tolist() converts ma.masked to None
+                    field = core.masked
+                    rows[i % N][j] = '--'
+
+                elif self.format_funcs[j] is not None:
+                    field = self.format_funcs[j](self.formats[j], orig_field)
+                    rows[i % N][j] = field
+
+                else:
+                    field = orig_field
+                    rows[i % N][j] = field
+                    str_val = j in string_rows
+
+                if field in self.fill_values:
+                    new_val = self.fill_values[field][0]
+                    # Either this column applies to the field as specified in
+                    # the fill_values parameter, or no specific columns are
+                    # specified and this column should apply fill_values.
+                    if (len(self.fill_values[field]) > 1 and self.use_names[j] in self.fill_values[field][1:]) \
+                       or (len(self.fill_values[field]) == 1 and j in self.fill_cols):
+                        str_val = True
+                        rows[i % N][j] = new_val
+                        if self.strip_whitespace: # new_val should be a string
+                            rows[i % N][j] = rows[i % N][j].strip()
+
+                if str_val and self.strip_whitespace:
+                    rows[i % N][j] = rows[i % N][j].strip()
+
+            if i >= N - 1 and i % N == N - 1: # rows is now full
+                writer.writerows(rows)
+
+        # Write leftover rows not included in previous chunks
+        if i % N != N - 1:
+            writer.writerows(rows[:i % N + 1])
+
+        if opened_file:
+            output.close()
+
+def get_fill_values(fill_values, read=True):
+    if len(fill_values) > 0 and isinstance(fill_values[0], six.string_types):
+        # e.g. fill_values=('999', '0')
+        fill_values = [fill_values]
+    else:
+        fill_values = fill_values
+
+    # look for an empty replacement to cache for speedy conversion
+    fill_empty = None
+    for el in fill_values:
+        if el[0] == '':
+            fill_empty = el[1:]
+            break
+
+    try:
+        # Create a dict with the values to be replaced as keys
+        if read:
+            fill_values = dict([(l[0].encode('ascii'), l[1:]) for
+                                l in fill_values if l[0] != ''])
+        else:
+            # don't worry about encoding for writing
+            fill_values = dict([(l[0], l[1:]) for l in fill_values])
+
+    except IndexError:
+        raise ValueError("Format of fill_values must be "
+                         "(<bad>, <fill>, <optional col1>, ...)")
+    if read:
+        return (fill_values, fill_empty)
+    else:
+        return fill_values # cache for empty values doesn't matter for writing
+
+def auto_format_func(format_, val):
+    """
+    Mimics pprint._auto_format_func for non-numpy values.
+    """
+    if six.callable(format_):
+        format_func = lambda format_, val: format_(val)
+        try:
+            out = format_func(format_, val)
+            if not isinstance(out, six.string_types):
+                raise ValueError('Format function for value {0} returned {1} instead of string type'
+                                 .format(val, type(val)))
+        except Exception as err:
+            raise ValueError('Format function for value {0} failed: {1}'
+                             .format(val, err))
+    else:
+        try:
+            # Convert val to Python object with tolist().  See
+            # https://github.com/astropy/astropy/issues/148#issuecomment-3930809
+            out = format_.format(val)
+            # Require that the format statement actually did something
+            if out == format_:
+                raise ValueError
+            format_func = lambda format_, val: format_.format(val)
+        except:  # Not sure what exceptions might be raised
+            try:
+                out = format_ % val
+                if out == format_:
+                    raise ValueError
+                format_func = lambda format_, val: format_ % val
+            except:
+                raise ValueError('Unable to parse format string {0}'
+                                 .format(format_))
+    pprint._format_funcs[format_] = format_func
+    return out
diff --git a/astropy/io/ascii/daophot.py b/astropy/io/ascii/daophot.py
index 00d36ad..bb6ac22 100644
--- a/astropy/io/ascii/daophot.py
+++ b/astropy/io/ascii/daophot.py
@@ -18,90 +18,9 @@ from . import fixedwidth
 from ...utils import OrderedDict
 
 
-class Daophot(core.BaseReader):
-    """Read a DAOphot file.
-    Example::
-
-      #K MERGERAD   = INDEF                   scaleunit  %-23.7g
-      #K IRAF = NOAO/IRAFV2.10EXPORT version %-23s
-      #K USER = davis name %-23s
-      #K HOST = tucana computer %-23s
-      #
-      #N ID    XCENTER   YCENTER   MAG         MERR          MSKY           NITER    \\
-      #U ##    pixels    pixels    magnitudes  magnitudes    counts         ##       \\
-      #F %-9d  %-10.3f   %-10.3f   %-12.3f     %-14.3f       %-15.7g        %-6d
-      #
-      #N         SHARPNESS   CHI         PIER  PERROR                                \\
-      #U         ##          ##          ##    perrors                               \\
-      #F         %-23.3f     %-12.3f     %-6d  %-13s
-      #
-      14       138.538     INDEF   15.461      0.003         34.85955       4        \\
-                  -0.032      0.802       0     No_error
-
-    The keywords defined in the #K records are available via the output table
-    ``meta`` attribute::
-
-      >>> import os
-      >>> from astropy.io import ascii
-      >>> filename = os.path.join(ascii.__path__[0], 'tests/t/daophot.dat')
-      >>> data = ascii.read(filename)
-      >>> for name, keyword in data.meta['keywords'].items():
-      ...     print(name, keyword['value'], keyword['units'], keyword['format'])
-      ...
-      MERGERAD INDEF scaleunit %-23.7g
-      IRAF NOAO/IRAFV2.10EXPORT version %-23s
-      USER  name %-23s
-      ...
-
-    The unit and formats are available in the output table columns::
-
-      >>> for colname in data.colnames:
-      ...     col = data[colname]
-      ...     print(colname, col.unit, col.format)
-      ...
-      ID None %-9d
-      XCENTER pixels %-10.3f
-      YCENTER pixels %-10.3f
-      ...
-
-    Any column values of INDEF are interpreted as a missing value and will be
-    masked out in the resultant table.
-
-    In case of multi-aperture daophot files containing repeated entries for the last 
-    row of fields, extra unique column names will be created by suffixing 
-    corresponding field names with numbers starting from 2 to N (where N is the 
-    total number of apertures).
-    For example, 
-    first aperture radius will be RAPERT and corresponding magnitude will be MAG, 
-    second aperture radius will be RAPERT2 and corresponding magnitude will be MAG2, 
-    third aperture radius will be RAPERT3 and corresponding magnitude will be MAG3, 
-    and so on.
-
-    """
-    _format_name = 'daophot'
-    _io_registry_format_aliases = ['daophot']
-    _io_registry_can_write = False
-    _description = 'IRAF DAOphot format table'
-
-    def __init__(self):
-        core.BaseReader.__init__(self)
-        self.header = DaophotHeader()
-        self.inputter = core.ContinuationLinesInputter()
-        self.inputter.no_continue = r'\s*#'
-        self.data.splitter = fixedwidth.FixedWidthSplitter()
-        self.data.start_line = 0
-        self.data.comment = r'\s*#'
-
-    def write(self, table=None):
-        raise NotImplementedError
-
-
 class DaophotHeader(core.BaseHeader):
-    """Read the header from a file produced by the IRAF DAOphot routine."""
-    def __init__(self):
-        core.BaseHeader.__init__(self)
-        self.comment = r'\s*#K'
-        self.aperture_values = ''
+    comment = r'\s*#K'
+    aperture_values = ''
 
     def update_meta(self, lines, meta):
         """
@@ -126,7 +45,7 @@ class DaophotHeader(core.BaseHeader):
                                     'format': vals[-1]}
                     keyword_dict['value'] = (vals[0] if len(vals) > 2 else "")
                     table_meta['keywords'][m.group('name')] = keyword_dict
-                    if m.group('name') == 'APERTURES': 
+                    if m.group('name') == 'APERTURES':
                         self.aperture_values = keyword_dict['value']
 
     def get_cols(self, lines):
@@ -138,7 +57,7 @@ class DaophotHeader(core.BaseHeader):
         :returns: list of table Columns
         """
 
-        # Parse a series of column defintion lines like below.  There may be several
+        # Parse a series of column definition lines like below.  There may be several
         # such blocks in a single file (where continuation characters have already been
         # stripped).
         # #N ID    XCENTER   YCENTER   MAG         MERR          MSKY           NITER
@@ -170,16 +89,16 @@ class DaophotHeader(core.BaseHeader):
                         last_coldef_line[i] = line_stripped
                         break
 
-        # We need to check wheter daophot file has multiple aperture data, in its keywords
+        # We need to check whether daophot file has multiple aperture data, in its keywords
         if (',' in self.aperture_values) or (':' in self.aperture_values):
             apertures=[]
             for aper in self.aperture_values.split(','):
                 if ':' in aper:
-                    # Generate list of apertures from daophot's closed interval range 
+                    # Generate list of apertures from daophot's closed interval range
                     # syntax ap1:apN:apstep
                     ap1, apN, apstep = (float(i) for i in aper.split(':'))
                     apertures.extend(list(np.arange(ap1, apN, apstep)))
-                    if (apN-ap1)%apstep == 0: 
+                    if (apN-ap1)%apstep == 0:
                         apertures.append(apN)
                 else:
                     apertures.append(float(aper))
@@ -236,3 +155,87 @@ class DaophotHeader(core.BaseHeader):
 
         # INDEF is the missing value marker
         self.data.fill_values.append(('INDEF', '0'))
+
+
+class DaophotData(core.BaseData):
+    splitter_class = fixedwidth.FixedWidthSplitter
+    start_line = 0
+    comment = r'\s*#'
+
+
+class DaophotInputter(core.ContinuationLinesInputter):
+    no_continue = r'\s*#'
+
+
+class Daophot(core.BaseReader):
+    """Read a DAOphot file.
+    Example::
+
+      #K MERGERAD   = INDEF                   scaleunit  %-23.7g
+      #K IRAF = NOAO/IRAFV2.10EXPORT version %-23s
+      #K USER = davis name %-23s
+      #K HOST = tucana computer %-23s
+      #
+      #N ID    XCENTER   YCENTER   MAG         MERR          MSKY           NITER    \\
+      #U ##    pixels    pixels    magnitudes  magnitudes    counts         ##       \\
+      #F %-9d  %-10.3f   %-10.3f   %-12.3f     %-14.3f       %-15.7g        %-6d
+      #
+      #N         SHARPNESS   CHI         PIER  PERROR                                \\
+      #U         ##          ##          ##    perrors                               \\
+      #F         %-23.3f     %-12.3f     %-6d  %-13s
+      #
+      14       138.538     INDEF   15.461      0.003         34.85955       4        \\
+                  -0.032      0.802       0     No_error
+
+    The keywords defined in the #K records are available via the output table
+    ``meta`` attribute::
+
+      >>> import os
+      >>> from astropy.io import ascii
+      >>> filename = os.path.join(ascii.__path__[0], 'tests/t/daophot.dat')
+      >>> data = ascii.read(filename)
+      >>> for name, keyword in data.meta['keywords'].items():
+      ...     print(name, keyword['value'], keyword['units'], keyword['format'])
+      ...
+      MERGERAD INDEF scaleunit %-23.7g
+      IRAF NOAO/IRAFV2.10EXPORT version %-23s
+      USER  name %-23s
+      ...
+
+    The unit and formats are available in the output table columns::
+
+      >>> for colname in data.colnames:
+      ...     col = data[colname]
+      ...     print(colname, col.unit, col.format)
+      ...
+      ID None %-9d
+      XCENTER pixels %-10.3f
+      YCENTER pixels %-10.3f
+      ...
+
+    Any column values of INDEF are interpreted as a missing value and will be
+    masked out in the resultant table.
+
+    In case of multi-aperture daophot files containing repeated entries for the last
+    row of fields, extra unique column names will be created by suffixing
+    corresponding field names with numbers starting from 2 to N (where N is the
+    total number of apertures).
+    For example,
+    first aperture radius will be RAPERT and corresponding magnitude will be MAG,
+    second aperture radius will be RAPERT2 and corresponding magnitude will be MAG2,
+    third aperture radius will be RAPERT3 and corresponding magnitude will be MAG3,
+    and so on.
+
+    """
+    _format_name = 'daophot'
+    _io_registry_format_aliases = ['daophot']
+    _io_registry_can_write = False
+    _description = 'IRAF DAOphot format table'
+
+    header_class = DaophotHeader
+    data_class = DaophotData
+    inputter_class = DaophotInputter
+
+
+    def write(self, table=None):
+        raise NotImplementedError
diff --git a/astropy/io/ascii/ecsv.py b/astropy/io/ascii/ecsv.py
new file mode 100644
index 0000000..d890f8a
--- /dev/null
+++ b/astropy/io/ascii/ecsv.py
@@ -0,0 +1,424 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+Define the Enhanced Character-Separated-Values (ECSV) which allows for reading and
+writing all the meta data associated with an astropy Table object.
+"""
+
+import re
+
+from ...utils import OrderedDict
+from ...extern import six
+
+from . import core, basic
+from ...table.column import col_getattr
+
+ECSV_VERSION = '0.9'
+DELIMITERS = (' ', ',')
+
+class ColumnOrderList(list):
+    """
+    List of tuples that sorts in a specific order that makes sense for
+    astropy table column attributes.
+    """
+    def sort(self, *args, **kwargs):
+        super(ColumnOrderList, self).sort()
+
+        column_keys = ['name', 'unit', 'datatype', 'format', 'description', 'meta']
+        in_dict = dict(self)
+        out_list = []
+
+        for key in column_keys:
+            if key in in_dict:
+                out_list.append((key, in_dict[key]))
+        for key, val in self:
+            if key not in column_keys:
+                out_list.append((key, val))
+
+        # Clear list in-place
+        del self[:]
+
+        self.extend(out_list)
+
+class ColumnDict(dict):
+    """
+    Specialized dict subclass to represent attributes of a Column
+    and return items() in a preferred order.  This is only for use
+    in generating a YAML map representation that has a fixed order.
+    """
+
+    def items(self):
+        """
+        Return items as a ColumnOrderList, which sorts in the preferred
+        way for column attributes.
+        """
+        return ColumnOrderList(super(ColumnDict, self).items())
+
+def _construct_odict(load, node):
+    """
+    Construct OrderedDict from !!omap in yaml safe load.
+
+    Source: https://gist.github.com/weaver/317164
+    License: Unspecified
+
+    This is the same as SafeConstructor.construct_yaml_omap(),
+    except the data type is changed to OrderedDict() and setitem is
+    used instead of append in the loop
+
+    Examples
+    --------
+    ::
+
+      >>> yaml.load('''  # doctest: +SKIP
+      ... !!omap
+      ... - foo: bar
+      ... - mumble: quux
+      ... - baz: gorp
+      ... ''')
+      OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
+
+      >>> yaml.load('''!!omap [ foo: bar, mumble: quux, baz : gorp ]''')  # doctest: +SKIP
+      OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
+    """
+    import yaml
+
+    omap = OrderedDict()
+    yield omap
+    if not isinstance(node, yaml.SequenceNode):
+        raise yaml.constructor.ConstructorError(
+            "while constructing an ordered map",
+            node.start_mark,
+            "expected a sequence, but found %s" % node.id, node.start_mark
+        )
+    for subnode in node.value:
+        if not isinstance(subnode, yaml.MappingNode):
+            raise yaml.constructor.ConstructorError(
+                "while constructing an ordered map", node.start_mark,
+                "expected a mapping of length 1, but found %s" % subnode.id,
+                subnode.start_mark
+            )
+        if len(subnode.value) != 1:
+            raise yaml.constructor.ConstructorError(
+                "while constructing an ordered map", node.start_mark,
+                "expected a single mapping item, but found %d items" % len(subnode.value),
+                subnode.start_mark
+            )
+        key_node, value_node = subnode.value[0]
+        key = load.construct_object(key_node)
+        value = load.construct_object(value_node)
+        omap[key] = value
+
+
+def _repr_pairs(dump, tag, sequence, flow_style=None):
+    """
+    This is the same code as BaseRepresenter.represent_sequence(),
+    but the value passed to dump.represent_data() in the loop is a
+    dictionary instead of a tuple.
+
+    Source: https://gist.github.com/weaver/317164
+    License: Unspecified
+    """
+    import yaml
+
+    value = []
+    node = yaml.SequenceNode(tag, value, flow_style=flow_style)
+    if dump.alias_key is not None:
+        dump.represented_objects[dump.alias_key] = node
+    best_style = True
+    for (key, val) in sequence:
+        item = dump.represent_data({key: val})
+        if not (isinstance(item, yaml.ScalarNode) and not item.style):
+            best_style = False
+        value.append(item)
+    if flow_style is None:
+        if dump.default_flow_style is not None:
+            node.flow_style = dump.default_flow_style
+        else:
+            node.flow_style = best_style
+    return node
+
+
+def _repr_odict(dumper, data):
+    """
+    Represent OrderedDict in yaml dump.
+
+    Source: https://gist.github.com/weaver/317164
+    License: Unspecified
+
+    >>> data = OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
+    >>> yaml.dump(data, default_flow_style=False)  # doctest: +SKIP
+    '!!omap\\n- foo: bar\\n- mumble: quux\\n- baz: gorp\\n'
+    >>> yaml.dump(data, default_flow_style=True)  # doctest: +SKIP
+    '!!omap [foo: bar, mumble: quux, baz: gorp]\\n'
+    """
+    return _repr_pairs(dumper, u'tag:yaml.org,2002:omap', six.iteritems(data))
+
+
+def _repr_column_dict(dumper, data):
+    """
+    Represent ColumnDict in yaml dump.
+
+    This is the same as an ordinary mapping except that the keys
+    are written in a fixed order that makes sense for astropy table
+    columns.
+    """
+    return dumper.represent_mapping(u'tag:yaml.org,2002:map', data)
+
+
+def _get_col_attributes(col):
+    """
+    Extract information from a column (apart from the values) that is required
+    to fully serialize the column.
+    """
+    if len(getattr(col, 'shape', ())) > 1:
+        raise ValueError("ECSV format does not support multidimensional column '{0}'"
+                         .format(col_getattr(col, 'name')))
+
+    attrs = ColumnDict()
+    attrs['name'] = col_getattr(col, 'name')
+
+    type_name = col_getattr(col, 'dtype').type.__name__
+    if six.PY3 and (type_name.startswith('bytes') or type_name.startswith('str')):
+        type_name = 'string'
+    if type_name.endswith('_'):
+        type_name = type_name[:-1]  # string_ and bool_ lose the final _ for ECSV
+    attrs['datatype'] = type_name
+
+    # Set the output attributes
+    for attr, nontrivial, xform in (('unit', lambda x: x is not None, str),
+                                    ('format', lambda x: x is not None, None),
+                                    ('description', lambda x: x is not None, None),
+                                    ('meta', lambda x: x, None)):
+        col_attr = col_getattr(col, attr)
+        if nontrivial(col_attr):
+            attrs[attr] = xform(col_attr) if xform else col_attr
+
+    return attrs
+
+
+
+class EcsvHeader(basic.BasicHeader):
+    """Header class for which the column definition line starts with the
+    comment character.  See the :class:`CommentedHeader` class  for an example.
+    """
+    def process_lines(self, lines):
+        """Return only non-blank lines that start with the comment regexp.  For these
+        lines strip out the matching characters and leading/trailing whitespace."""
+        re_comment = re.compile(self.comment)
+        for line in lines:
+            line = line.strip()
+            if not line:
+                continue
+            match = re_comment.match(line)
+            if match:
+                out = line[match.end():]
+                if out:
+                    yield out
+            else:
+                # Stop iterating on first failed match for a non-blank line
+                return
+
+    def write(self, lines):
+        """
+        Write header information in the ECSV ASCII format.  This format
+        starts with a delimiter separated list of the column names in order
+        to make this format readable by humans and simple csv-type readers.
+        It then encodes the full table meta and column attributes and meta
+        as YAML and pretty-prints this in the header.  Finally the delimited
+        column names are repeated again, for humans and readers that look
+        for the *last* comment line as defining the column names.
+        """
+        try:
+            import yaml
+        except ImportError:
+            raise ImportError('`import yaml` failed, PyYAML package is required for ECSV format')
+
+        class TableDumper(yaml.Dumper):
+            """
+            Custom Dumper that represents OrderedDict as an !!omap object.
+            """
+            def represent_mapping(self, tag, mapping, flow_style=None):
+                """
+                This is a combination of the Python 2 and 3 versions of this method
+                in the PyYAML library to allow the required key ordering via the
+                ColumnOrderList object.  The Python 3 version insists on turning the
+                items() mapping into a list object and sorting, which results in
+                alphabetical order for the column keys.
+                """
+                value = []
+                node = yaml.MappingNode(tag, value, flow_style=flow_style)
+                if self.alias_key is not None:
+                    self.represented_objects[self.alias_key] = node
+                best_style = True
+                if hasattr(mapping, 'items'):
+                    mapping = mapping.items()
+                    if hasattr(mapping, 'sort'):
+                        mapping.sort()
+                    else:
+                        mapping = list(mapping)
+                        try:
+                            mapping = sorted(mapping)
+                        except TypeError:
+                            pass
+
+                for item_key, item_value in mapping:
+                    node_key = self.represent_data(item_key)
+                    node_value = self.represent_data(item_value)
+                    if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
+                        best_style = False
+                    if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style):
+                        best_style = False
+                    value.append((node_key, node_value))
+                if flow_style is None:
+                    if self.default_flow_style is not None:
+                        node.flow_style = self.default_flow_style
+                    else:
+                        node.flow_style = best_style
+                return node
+
+        TableDumper.add_representer(OrderedDict, _repr_odict)
+        TableDumper.add_representer(ColumnDict, _repr_column_dict)
+
+        if self.splitter.delimiter not in DELIMITERS:
+            raise ValueError('only space and comma are allowed for delimiter in ECVS format')
+
+        # Now assemble the header dict that will be serialized by the YAML dumper
+        header = {}
+        if self.table_meta:
+            header['meta'] = self.table_meta
+
+        header['datatype'] = [_get_col_attributes(col) for col in self.cols]
+
+        # Set the delimiter only for the non-default option(s)
+        if self.splitter.delimiter != ' ':
+            header['delimiter'] = self.splitter.delimiter
+
+        header_yaml = yaml.dump(header, Dumper=TableDumper)
+        outs = ['%ECSV {0}'.format(ECSV_VERSION), '---']
+        outs.extend(header_yaml.splitlines())
+
+        lines.extend([self.write_comment + line for line in outs])
+        lines.append(self.splitter.join([col_getattr(x, 'name') for x in self.cols]))
+
+    def write_comments(self, lines, meta):
+        """
+        Override the default write_comments to do nothing since this is handled
+        in the custom write method.
+        """
+        pass
+
+    def update_meta(self, lines, meta):
+        """
+        Override the default update_meta to do nothing.  This process is done
+        in get_cols() for this reader.
+        """
+        pass
+
+    def get_cols(self, lines):
+        """Initialize the header Column objects from the table ``lines``.
+
+        :param lines: list of table lines
+        :returns: None (but sets self.cols)
+        """
+        import textwrap
+        try:
+            import yaml
+        except ImportError:
+            raise ImportError('`import yaml` failed, PyYAML package is required for ECSV format')
+
+        class TableLoader(yaml.SafeLoader):
+            """
+            Custom Loader that constructs OrderedDict from an !!omap object.
+            This does nothing but provide a namespace for adding the
+            custom odict constructor.
+            """
+
+        TableLoader.add_constructor(u'tag:yaml.org,2002:omap', _construct_odict)
+
+        # Extract non-blank comment (header) lines with comment character stripped
+        lines = list(self.process_lines(lines))
+
+        # Validate that this is a ECSV file
+        ecsv_header_re = r"""%ECSV [ ]
+                             (?P<major> \d+)
+                             \. (?P<minor> \d+)
+                             \.? (?P<bugfix> \d+)? $"""
+
+        no_header_msg = ('ECSV header line like "# %ECSV <version>" not found as first line.'
+                         '  This is required for a ECSV file.')
+
+        if not lines:
+            raise core.InconsistentTableError(no_header_msg)
+
+        match = re.match(ecsv_header_re, lines[0].strip(), re.VERBOSE)
+        if not match:
+            raise core.InconsistentTableError(no_header_msg)
+        # ecsv_version could be constructed here, but it is not currently used.
+
+        # Now actually load the YAML data structure into `meta`
+        header_yaml = textwrap.dedent('\n'.join(lines))
+        try:
+            header = yaml.load(header_yaml, Loader=TableLoader)
+        except:
+            raise core.InconsistentTableError('unable to parse yaml in header')
+
+        if 'meta' in header:
+            self.table_meta = header['meta']
+
+        if 'delimiter' in header:
+            delimiter = header['delimiter']
+            if delimiter not in DELIMITERS:
+                raise ValueError('only space and comma are allowed for delimiter in ECVS format')
+            self.splitter.delimiter = delimiter
+            self.data.splitter.delimiter = delimiter
+
+        # Create the list of io.ascii column objects from `header`
+        header_cols = OrderedDict((x['name'], x) for x in header['datatype'])
+        self.names = [x['name'] for x in header['datatype']]
+        self._set_cols_from_names()  # BaseHeader method to create self.cols
+
+        # Transfer attributes from the column descriptor stored in the input
+        # header YAML metadata to the new columns to create this table.
+        for col in self.cols:
+            for attr in ('description', 'format', 'unit', 'meta'):
+                if attr in header_cols[col.name]:
+                    setattr(col, attr, header_cols[col.name][attr])
+            col.dtype = header_cols[col.name]['datatype']
+            # ECSV "string" means numpy dtype.kind == 'U' AKA str in Python 3
+            if six.PY3 and col.dtype == 'string':
+                col.dtype = 'str'
+            if col.dtype.startswith('complex'):
+                raise TypeError('ecsv reader does not support complex number types')
+
+
+class EcsvOutputter(core.TableOutputter):
+    """
+    Output the table as an astropy.table.Table object.  This overrides the
+    default converters to be an empty list because there is no "guessing"
+    of the conversion function.
+    """
+    default_converters = []
+
+
+class Ecsv(basic.Basic):
+    """
+    Read a file which conforms to the ECSV (Enhanced Character Separated
+    Values) format.  This format allows for specification of key table
+    and column meta-data, in particular the data type and unit.  For details
+    see: https://github.com/astropy/astropy-APEs/blob/master/APE6.rst.
+
+    For example::
+
+      # %ECSV 0.9
+      # ---
+      # columns:
+      # - {name: a, unit: m / s, type: int64, format: '%03d'}
+      # - {name: b, unit: km, type: int64, description: This is column b}
+      a b
+      001 2
+      004 3
+    """
+    _format_name = 'ecsv'
+    _description = 'Enhanced CSV'
+
+    header_class = EcsvHeader
+    outputter_class = EcsvOutputter
diff --git a/astropy/io/ascii/fastbasic.py b/astropy/io/ascii/fastbasic.py
new file mode 100644
index 0000000..a020788
--- /dev/null
+++ b/astropy/io/ascii/fastbasic.py
@@ -0,0 +1,304 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from . import core
+from ...extern import six
+from ...table import Table
+from . import cparser
+from ...extern.six.moves import zip as izip
+import re
+
+ at six.add_metaclass(core.MetaBaseReader)
+class FastBasic(object):
+    """
+    This class is intended to handle the same format addressed by the
+    ordinary :class:`Basic` writer, but it acts as a wrapper for underlying C
+    code and is therefore much faster. Unlike the other ASCII readers and
+    writers, this class is not very extensible and is restricted
+    by optimization requirements.
+    """
+    _format_name = 'fast_basic'
+    _description = 'Basic table with custom delimiter using the fast C engine'
+    _fast = True
+    fill_extra_cols = False
+    guessing = False
+    strict_names = False
+
+    def __init__(self, default_kwargs={}, **user_kwargs):
+        kwargs = default_kwargs.copy()
+        kwargs.update(user_kwargs) # user kwargs take precedence over defaults
+        delimiter = kwargs.pop('delimiter', ' ')
+        self.delimiter = str(delimiter) if delimiter is not None else None
+        self.write_comment = kwargs.get('comment', '# ')
+        self.comment = kwargs.pop('comment', '#')
+        if self.comment is not None:
+            self.comment = str(self.comment)
+        self.quotechar = str(kwargs.pop('quotechar', '"'))
+        self.header_start = kwargs.pop('header_start', 0)
+        # If data_start is not specified, start reading
+        # data right after the header line
+        data_start_default = user_kwargs.get('data_start', self.header_start +
+                                    1 if self.header_start is not None else 1)
+        self.data_start = kwargs.pop('data_start', data_start_default)
+        self.kwargs = kwargs
+        self.strip_whitespace_lines = True
+        self.strip_whitespace_fields = True
+
+    def _read_header(self):
+        # Use the tokenizer by default -- this method
+        # can be overridden for specialized headers
+        self.engine.read_header()
+
+    def read(self, table):
+        """
+        Read input data (file-like object, filename, list of strings, or
+        single string) into a Table and return the result.
+        """
+        if self.comment is not None and len(self.comment) != 1:
+            raise core.ParameterError("The C reader does not support a comment regex")
+        elif self.data_start is None:
+            raise core.ParameterError("The C reader does not allow data_start to be None")
+        elif self.header_start is not None and self.header_start < 0 and \
+             not isinstance(self, FastCommentedHeader):
+            raise core.ParameterError("The C reader does not allow header_start to be "
+                                      "negative except for commented-header files")
+        elif self.data_start < 0:
+            raise core.ParameterError("The C reader does not allow data_start to be negative")
+        elif len(self.delimiter) != 1:
+            raise core.ParameterError("The C reader only supports 1-char delimiters")
+        elif len(self.quotechar) != 1:
+            raise core.ParameterError("The C reader only supports a length-1 quote character")
+        elif 'converters' in self.kwargs:
+            raise core.ParameterError("The C reader does not support passing "
+                                      "specialized converters")
+        elif 'Outputter' in self.kwargs:
+            raise core.ParameterError("The C reader does not use the Outputter parameter")
+        elif 'Inputter' in self.kwargs:
+            raise core.ParameterError("The C reader does not use the Inputter parameter")
+        elif 'data_Splitter' in self.kwargs or 'header_Splitter' in self.kwargs:
+            raise core.ParameterError("The C reader does not use a Splitter class")
+
+        self.engine = cparser.CParser(table, self.strip_whitespace_lines,
+                                      self.strip_whitespace_fields,
+                                      delimiter=self.delimiter,
+                                      header_start=self.header_start,
+                                      comment=self.comment,
+                                      quotechar=self.quotechar,
+                                      data_start=self.data_start,
+                                      fill_extra_cols=self.fill_extra_cols,
+                                      **self.kwargs)
+        conversion_info = self._read_header()
+        self.check_header()
+        if conversion_info is not None:
+            try_int, try_float, try_string = conversion_info
+        else:
+            try_int = {}
+            try_float = {}
+            try_string = {}
+
+        data, comments = self.engine.read(try_int, try_float, try_string)
+        meta = {}
+        if comments:
+            meta['comments'] = comments
+        return Table(data, names=list(self.engine.get_names()), meta=meta)
+
+    def check_header(self):
+        if self.strict_names:
+            # Impose strict requirements on column names (normally used in guessing)
+            bads = [" ", ",", "|", "\t", "'", '"']
+            for name in self.engine.get_names():
+                if (_is_number(name) or
+                    len(name) == 0 or
+                    name[0] in bads or
+                    name[-1] in bads):
+                    raise ValueError('Column name {0!r} does not meet strict name requirements'
+                                     .format(name))
+        # When guessing require at least two columns
+        if self.guessing and len(self.engine.get_names()) <= 1:
+            raise ValueError
+
+    def write(self, table, output):
+        """
+        Use a fast Cython method to write table data to output,
+        where output is a filename or file-like object.
+        """
+        self._write(table, output, {})
+
+    def _write(self, table, output, default_kwargs,
+               header_output=True, output_types=False):
+
+        write_kwargs = {'delimiter': self.delimiter,
+                         'quotechar': self.quotechar,
+                         'strip_whitespace': self.strip_whitespace_fields,
+                         'comment': self.write_comment
+                         }
+        write_kwargs.update(default_kwargs)
+        # user kwargs take precedence over default kwargs
+        write_kwargs.update(self.kwargs)
+        writer = cparser.FastWriter(table, **write_kwargs)
+        writer.write(output, header_output, output_types)
+
+class FastCsv(FastBasic):
+    """
+    A faster version of the ordinary :class:`Csv` writer that uses the
+    optimized C parsing engine. Note that this reader will append empty
+    field values to the end of any row with not enough columns, while
+    :class:`FastBasic` simply raises an error.
+    """
+    _format_name = 'fast_csv'
+    _description = 'Comma-separated values table using the fast C engine'
+    _fast = True
+    fill_extra_cols = True
+
+    def __init__(self, **kwargs):
+        super(FastCsv, self).__init__({'delimiter': ',', 'comment': None}, **kwargs)
+
+    def write(self, table, output):
+        """
+        Override the default write method of `FastBasic` to
+        output masked values as empty fields.
+        """
+        self._write(table, output, { 'fill_values': [(core.masked, '')] })
+
+class FastTab(FastBasic):
+    """
+    A faster version of the ordinary :class:`Tab` reader that uses
+    the optimized C parsing engine.
+    """
+    _format_name = 'fast_tab'
+    _description = 'Tab-separated values table using the fast C engine'
+    _fast = True
+
+    def __init__(self, **kwargs):
+        super(FastTab, self).__init__({'delimiter': '\t'}, **kwargs)
+        self.strip_whitespace_lines = False
+        self.strip_whitespace_fields = False
+
+class FastNoHeader(FastBasic):
+    """
+    This class uses the fast C engine to read tables with no header line. If
+    the names parameter is unspecified, the columns will be autonamed with
+    "col%d".
+    """
+    _format_name = 'fast_no_header'
+    _description = 'Basic table with no headers using the fast C engine'
+    _fast = True
+
+    def __init__(self, **kwargs):
+        super(FastNoHeader, self).__init__({'header_start': None, 'data_start': 0}, **kwargs)
+
+    def write(self, table, output):
+        """
+        Override the default writing behavior in `FastBasic` so
+        that columns names are not included in output.
+        """
+        self._write(table, output, {}, header_output=None)
+
+class FastCommentedHeader(FastBasic):
+    """
+    A faster version of the :class:`CommentedHeader` reader, which looks for
+    column names in a commented line. ``header_start`` denotes the index of
+    the header line among all commented lines and is 0 by default.
+    """
+    _format_name = 'fast_commented_header'
+    _description = 'Columns name in a commented line using the fast C engine'
+    _fast = True
+
+    def __init__(self, **kwargs):
+        super(FastCommentedHeader, self).__init__({}, **kwargs)
+        # Mimic CommentedHeader's behavior in which data_start
+        # is relative to header_start if unspecified; see #2692
+        if 'data_start' not in kwargs:
+            self.data_start = 0
+
+    def _read_header(self):
+        tmp = self.engine.source
+        commented_lines = []
+
+        for line in tmp.splitlines():
+            line = line.lstrip()
+            if line and line[0] == self.comment: # line begins with a comment
+                commented_lines.append(line[1:])
+                if len(commented_lines) == self.header_start + 1:
+                    break
+
+        self.engine.setup_tokenizer([commented_lines[self.header_start]])
+        self.engine.header_start = 0
+        self.engine.read_header()
+        self.engine.setup_tokenizer(tmp)
+
+    def write(self, table, output):
+        """
+        Override the default writing behavior in `FastBasic` so
+        that column names are commented.
+        """
+        self._write(table, output, {}, header_output='comment')
+
+class FastRdb(FastBasic):
+    """
+    A faster version of the :class:`Rdb` reader. This format is similar to
+    tab-delimited, but it also contains a header line after the column
+    name line denoting the type of each column (N for numeric, S for string).
+    """
+    _format_name = 'fast_rdb'
+    _description = 'Tab-separated with a type definition header line'
+    _fast = True
+
+    def __init__(self, **kwargs):
+        super(FastRdb, self).__init__({'delimiter': '\t', 'data_start': 2}, **kwargs)
+        self.strip_whitespace_lines = False
+        self.strip_whitespace_fields = False
+
+    def _read_header(self):
+        tmp = self.engine.source
+        line1 = ''
+        line2 = ''
+        for line in tmp.splitlines():
+            # valid non-comment line
+            if not line1 and line.strip() and line.lstrip()[0] != self.comment:
+                line1 = line
+            elif not line2 and line.strip() and line.lstrip()[0] != self.comment:
+                line2 = line
+                break
+        else: # less than 2 lines in table
+            raise ValueError('RDB header requires 2 lines')
+
+        # tokenize the two header lines separately
+        self.engine.setup_tokenizer([line2])
+        self.engine.header_start = 0
+        self.engine.read_header()
+        types = self.engine.get_names()
+        self.engine.setup_tokenizer([line1])
+        self.engine.set_names([])
+        self.engine.read_header()
+
+        if len(self.engine.get_names()) != len(types):
+            raise ValueError('RDB header mismatch between number of '
+                             'column names and column types')
+
+        if any(not re.match(r'\d*(N|S)$', x, re.IGNORECASE) for x in types):
+            raise ValueError('RDB type definitions do not all match '
+                             '[num](N|S): {0}'.format(types))
+
+        try_int = {}
+        try_float = {}
+        try_string = {}
+
+        for name, col_type in izip(self.engine.get_names(), types):
+            if col_type[-1].lower() == 's':
+                try_int[name] = 0
+                try_float[name] = 0
+                try_string[name] = 1
+            else:
+                try_int[name] = 1
+                try_float[name] = 1
+                try_string[name] = 0
+
+        self.engine.setup_tokenizer(tmp)
+        return (try_int, try_float, try_string)
+
+    def write(self, table, output):
+        """
+        Override the default writing behavior in `FastBasic` to
+        output a line with column types after the column name line.
+        """
+        self._write(table, output, {}, output_types=True)
diff --git a/astropy/io/ascii/fixedwidth.py b/astropy/io/ascii/fixedwidth.py
index 8da52c2..c4a07db 100644
--- a/astropy/io/ascii/fixedwidth.py
+++ b/astropy/io/ascii/fixedwidth.py
@@ -11,9 +11,11 @@ fixedwidth.py:
 from __future__ import absolute_import, division, print_function
 
 from ...extern.six.moves import zip
+from ...table.column import col_getattr
 
 from . import core
-from .core import InconsistentTableError
+from .core import InconsistentTableError, DefaultSplitter
+from . import basic
 
 
 class FixedWidthSplitter(core.BaseSplitter):
@@ -32,6 +34,7 @@ class FixedWidthSplitter(core.BaseSplitter):
     """
     delimiter_pad = ''
     bookend = False
+    delimiter = '|'
 
     def __call__(self, lines):
         for line in lines:
@@ -55,7 +58,12 @@ class FixedWidthSplitter(core.BaseSplitter):
         return bookend_left + padded_delim.join(vals) + bookend_right
 
 
-class FixedWidthHeader(core.BaseHeader):
+class FixedWidthHeaderSplitter(DefaultSplitter):
+    '''Splitter class that splits on ``|``.'''
+    delimiter = '|'
+
+
+class FixedWidthHeader(basic.BasicHeader):
     """Fixed width table header reader.
 
     The key settable class attributes are:
@@ -71,8 +79,9 @@ class FixedWidthHeader(core.BaseHeader):
     :param delimiter_pad: padding around delimiter when writing (default = None)
     :param bookend: put the delimiter at start and end of line when writing (default = False)
     """
-
+    splitter_class = FixedWidthHeaderSplitter
     position_line = None   # secondary header line position
+    set_of_position_line_characters = set(r'`~!#$%^&*-_+=\|":' + "'")
 
     def get_line(self, lines, index):
         for i, line in enumerate(self.process_lines(lines)):
@@ -86,7 +95,7 @@ class FixedWidthHeader(core.BaseHeader):
         """Initialize the header Column objects from the table ``lines``.
 
         Based on the previously set Header attributes find or create the column names.
-        Sets ``self.cols`` with the list of Columns. 
+        Sets ``self.cols`` with the list of Columns.
 
         :param lines: list of table lines
         :returns: None
@@ -126,6 +135,16 @@ class FixedWidthHeader(core.BaseHeader):
                 # slice col_ends but expects inclusive col_ends on input (for
                 # more intuitive user interface).
                 line = self.get_line(lines, position_line)
+                if len(set(line) - set([self.splitter.delimiter, ' '])) != 1:
+                    raise InconsistentTableError('Position line should only contain delimiters and one other character, e.g. "--- ------- ---".')
+                    # The line above lies. It accepts white space as well.
+                    # We don't want to encourage using three different
+                    # characters, because that can cause ambiguities, but white
+                    # spaces are so common everywhere that practicality beats
+                    # purity here.
+                charset = self.set_of_position_line_characters.union(set([self.splitter.delimiter, ' ']))
+                if not set(line).issubset(charset):
+                    raise InconsistentTableError('Characters in position line must be part of {0}'.format(charset))
                 vals, self.col_starts, col_ends = self.get_fixedwidth_params(line)
                 self.col_ends = [x - 1 for x in col_ends]
 
@@ -137,7 +156,7 @@ class FixedWidthHeader(core.BaseHeader):
 
         self._set_cols_from_names()
 
-        # Set column start and end positions. 
+        # Set column start and end positions.
         for i, col in enumerate(self.cols):
             col.start = starts[i]
             col.end = ends[i]
@@ -186,7 +205,7 @@ class FixedWidthHeader(core.BaseHeader):
         pass
 
 
-class FixedWidthData(core.BaseData):
+class FixedWidthData(basic.BasicData):
     """Base table data reader.
 
     :param start_line: None, int, or a function of ``lines`` that returns None or int
@@ -198,29 +217,21 @@ class FixedWidthData(core.BaseData):
     splitter_class = FixedWidthSplitter
 
     def write(self, lines):
-
-        self._set_fill_values(self.cols)
-        self._set_col_formats()
-        for col in self.cols:
-            col.str_vals = list(col.iter_str_vals())
-        self._replace_vals(self.cols)
-        col_str_iters = [col.str_vals for col in self.cols]
-
         vals_list = []
-        # Col iterator does the formatting defined above so each val is a string
-        # and vals is a tuple of strings for all columns of each row
+        col_str_iters = self.str_vals()
         for vals in zip(*col_str_iters):
             vals_list.append(vals)
 
         for i, col in enumerate(self.cols):
             col.width = max([len(vals[i]) for vals in vals_list])
             if self.header.start_line is not None:
-                col.width = max(col.width, len(col.name))
+                col.width = max(col.width, len(col_getattr(col, 'name')))
 
         widths = [col.width for col in self.cols]
 
         if self.header.start_line is not None:
-            lines.append(self.splitter.join([col.name for col in self.cols], widths))
+            lines.append(self.splitter.join([col_getattr(col, 'name') for col in self.cols],
+                                            widths))
 
         if self.header.position_line is not None:
             char = self.header.position_char
@@ -235,7 +246,7 @@ class FixedWidthData(core.BaseData):
         return lines
 
 
-class FixedWidth(core.BaseReader):
+class FixedWidth(basic.Basic):
     """Read or write a fixed width table with a single header line that defines column
     names and positions.  Examples::
 
@@ -267,28 +278,28 @@ class FixedWidth(core.BaseReader):
     _format_name = 'fixed_width'
     _description = 'Fixed width'
 
-    def __init__(self, col_starts=None, col_ends=None, delimiter_pad=' ', bookend=True):
-        core.BaseReader.__init__(self)
+    header_class = FixedWidthHeader
+    data_class = FixedWidthData
 
-        self.header = FixedWidthHeader()
-        self.data = FixedWidthData()
-        self.data.header = self.header
-        self.header.data = self.data
 
-        self.header.splitter.delimiter = '|'
-        self.data.splitter.delimiter = '|'
+    def __init__(self, col_starts=None, col_ends=None, delimiter_pad=' ', bookend=True):
+        super(FixedWidth, self).__init__()
         self.data.splitter.delimiter_pad = delimiter_pad
         self.data.splitter.bookend = bookend
-        self.header.start_line = 0
-        self.data.start_line = 1
-        self.header.comment = r'\s*#'
-        self.header.write_comment = '# '
-        self.data.comment = r'\s*#'
-        self.data.write_comment = '# '
         self.header.col_starts = col_starts
         self.header.col_ends = col_ends
 
 
+class FixedWidthNoHeaderHeader(FixedWidthHeader):
+    '''Header reader for fixed with tables with no header line'''
+    start_line = None
+
+
+class FixedWidthNoHeaderData(FixedWidthData):
+    '''Data reader for fixed width tables with no header line'''
+    start_line = 0
+
+
 class FixedWidthNoHeader(FixedWidth):
     """Read or write a fixed width table which has no header line.  Column
     names are either input (``names`` keyword) or auto-generated.  Column
@@ -320,12 +331,33 @@ class FixedWidthNoHeader(FixedWidth):
     """
     _format_name = 'fixed_width_no_header'
     _description = 'Fixed width with no header'
+    header_class = FixedWidthNoHeaderHeader
+    data_class = FixedWidthNoHeaderData
+
 
     def __init__(self, col_starts=None, col_ends=None, delimiter_pad=' ', bookend=True):
-        FixedWidth.__init__(self, col_starts, col_ends,
+        super(FixedWidthNoHeader, self).__init__(col_starts, col_ends,
                             delimiter_pad=delimiter_pad, bookend=bookend)
-        self.header.start_line = None
-        self.data.start_line = 0
+
+
+class FixedWidthTwoLineHeader(FixedWidthHeader):
+    '''Header reader for fixed width tables splitting on whitespace.
+
+    For fixed width tables with several header lines, there is typically
+    a white-space delimited format line, so splitting on white space is
+    needed.
+    '''
+    splitter_class = DefaultSplitter
+
+
+class FixedWidthTwoLineDataSplitter(FixedWidthSplitter):
+    '''Splitter for fixed width tables splitting on ``' '``.'''
+    delimiter = ' '
+
+
+class FixedWidthTwoLineData(FixedWidthData):
+    '''Data reader for fixed with tables with two header lines.'''
+    splitter_class = FixedWidthTwoLineDataSplitter
 
 
 class FixedWidthTwoLine(FixedWidth):
@@ -358,11 +390,11 @@ class FixedWidthTwoLine(FixedWidth):
     """
     _format_name = 'fixed_width_two_line'
     _description = 'Fixed width with second header line'
+    data_class = FixedWidthTwoLineData
+    header_class = FixedWidthTwoLineHeader
 
     def __init__(self, position_line=1, position_char='-', delimiter_pad=None, bookend=False):
-        FixedWidth.__init__(self, delimiter_pad=delimiter_pad, bookend=bookend)
+        super(FixedWidthTwoLine, self).__init__(delimiter_pad=delimiter_pad, bookend=bookend)
         self.header.position_line = position_line
         self.header.position_char = position_char
         self.data.start_line = position_line + 1
-        self.header.splitter.delimiter = ' '
-        self.data.splitter.delimiter = ' '
diff --git a/astropy/io/ascii/html.py b/astropy/io/ascii/html.py
index 679791e..25d76ac 100644
--- a/astropy/io/ascii/html.py
+++ b/astropy/io/ascii/html.py
@@ -14,6 +14,7 @@ from ...extern.six.moves import zip as izip
 
 from . import core
 from ...table import Column
+from ...table.column import col_iter_str_vals, col_getattr
 from ...utils.xml import writer
 
 from copy import deepcopy
@@ -57,10 +58,10 @@ def identify_table(soup, htmldict, numtable):
         return 'id' in soup.attrs and soup['id'] == table_id
     elif isinstance(table_id, int):
         return table_id == numtable
-    
+
     # Return False if an invalid parameter is given
     return False
-    
+
 
 class HTMLInputter(core.BaseInputter):
     """
@@ -75,14 +76,17 @@ class HTMLInputter(core.BaseInputter):
         Convert the given input into a list of SoupString rows
         for further processing.
         """
-        
+
         try:
             from bs4 import BeautifulSoup
         except ImportError:
             raise core.OptionalTableImportError('BeautifulSoup must be '
                                         'installed to read HTML tables')
-        
-        soup = BeautifulSoup('\n'.join(lines))
+
+        if 'parser' not in self.html:
+            soup = BeautifulSoup('\n'.join(lines))
+        else: # use a custom backend parser
+            soup = BeautifulSoup('\n'.join(lines), self.html['parser'])
         tables = soup.find_all('table')
         for i, possible_table in enumerate(tables):
             if identify_table(possible_table, self.html, i + 1):
@@ -95,12 +99,12 @@ class HTMLInputter(core.BaseInputter):
                 err_descr = "id '{0}'".format(self.html['table_id'])
             raise core.InconsistentTableError(
                 'ERROR: HTML table {0} not found'.format(err_descr))
-        
+
         # Get all table rows
         soup_list = [SoupString(x) for x in table.find_all('tr')]
 
         return soup_list
-        
+
 class HTMLSplitter(core.BaseSplitter):
     """
     Split HTML table data.
@@ -156,14 +160,16 @@ class HTMLOutputter(core.TableOutputter):
                 col_num += 1
 
         return super(HTMLOutputter, self).__call__(new_cols, meta)
-        
+
 
 class HTMLHeader(core.BaseHeader):
+    splitter_class = HTMLSplitter
+
     def start_line(self, lines):
         """
         Return the line number at which header data begins.
         """
-        
+
         for i, line in enumerate(lines):
             if not isinstance(line, SoupString):
                 raise TypeError('HTML lines should be of type SoupString')
@@ -195,25 +201,27 @@ class HTMLHeader(core.BaseHeader):
                 new_names.append(name)
 
         self.names = new_names
-    
+
 
 class HTMLData(core.BaseData):
+    splitter_class = HTMLSplitter
+
     def start_line(self, lines):
         """
         Return the line number at which table data begins.
         """
-        
+
         for i, line in enumerate(lines):
             if not isinstance(line, SoupString):
                 raise TypeError('HTML lines should be of type SoupString')
             soup = line.soup
-            
+
             if soup.td is not None:
                 if soup.th is not None:
                     raise core.InconsistentTableError('HTML tables cannot '
                                 'have headings and data in the same row')
                 return i
-        
+
         raise core.InconsistentTableError('No start line found for HTML data')
 
     def end_line(self, lines):
@@ -221,7 +229,7 @@ class HTMLData(core.BaseData):
         Return the line number at which table data ends.
         """
         last_index = -1
-        
+
         for i, line in enumerate(lines):
             if not isinstance(line, SoupString):
                 raise TypeError('HTML lines should be of type SoupString')
@@ -248,7 +256,7 @@ class HTML(core.BaseReader):
 
         * table_id : ID for the input table
             If a string, this defines the HTML id of the table to be processed.
-            If an integer, this specificies the index of the input table in the
+            If an integer, this specifies the index of the input table in the
             available tables. Unless this parameter is given, the reader will
             use the first table found in the input file.
 
@@ -257,28 +265,37 @@ class HTML(core.BaseReader):
             columns if this parameter is true, and if not then it will
             use the syntax 1.36583e-13 .. 1.36583e-13 for output. If not
             present, this parameter will be true by default.
-    
+
+        * parser : Specific HTML parsing library to use
+            If specified, this specifies which HTML parsing library
+            BeautifulSoup should use as a backend. The options to choose
+            from are 'html.parser' (the standard library parser), 'lxml'
+            (the recommended parser), 'xml' (lxml's XML parser), and
+            'html5lib'. html5lib is a highly lenient parser and therefore
+            might work correctly for unusual input if a different parser
+            fails.
+
+        * jsfiles : list of js files to include when writing table.
+
+        * cssfiles : list of css files to include when writing table.
+
+        * js : js script to include in the body when writing table.
     """
-    
+
     _format_name = 'html'
     _io_registry_format_aliases = ['html']
     _io_registry_suffix = '.html'
     _description = 'HTML table'
 
+    header_class = HTMLHeader
+    data_class = HTMLData
+    inputter_class = HTMLInputter
+
     def __init__(self, htmldict={}):
         """
         Initialize classes for HTML reading and writing.
         """
-        core.BaseReader.__init__(self)
-        self.inputter = HTMLInputter()
-        self.header = HTMLHeader()
-        self.data = HTMLData()
-        self.header.splitter = HTMLSplitter()
-        self.header.inputter = HTMLInputter()
-        self.data.splitter = HTMLSplitter()
-        self.data.inputter = HTMLInputter()
-        self.data.header = self.header
-        self.header.data = self.data
+        super(HTML, self).__init__()
         self.html = deepcopy(htmldict)
         if 'multicol' not in htmldict:
             self.html['multicol'] = True
@@ -293,7 +310,7 @@ class HTML(core.BaseReader):
 
         self.outputter = HTMLOutputter()
         return core.BaseReader.read(self, table)
-    
+
     def write(self, table):
         """
         Return data in ``table`` converted to HTML as a list of strings.
@@ -304,7 +321,7 @@ class HTML(core.BaseReader):
 
         # Use XMLWriter to output HTML to lines
         w = writer.XMLWriter(ListWriter(lines))
-        
+
         with w.tag('html'):
             with w.tag('head'):
                 # Declare encoding and set CSS style for table
@@ -316,27 +333,43 @@ class HTML(core.BaseReader):
                 if 'css' in self.html:
                     with w.tag('style'):
                         w.data(self.html['css'])
+                if 'cssfiles' in self.html:
+                    for filename in self.html['cssfiles']:
+                        with w.tag('link', rel="stylesheet", href=filename, type='text/css'):
+                            pass
+                if 'jsfiles' in self.html:
+                    for filename in self.html['jsfiles']:
+                        with w.tag('script', src=filename):
+                            w.data('')  # need this instead of pass to get <script></script>
             with w.tag('body'):
-                with w.tag('table'):
-                    with w.tag('tr'):
+                if 'js' in self.html:
+                    with w.tag('script'):
+                        w.data(self.html['js'])
+                if isinstance(self.html['table_id'], six.string_types):
+                    html_table_id = self.html['table_id']
+                else:
+                    html_table_id = None
+                with w.tag('table', id=html_table_id):
+                    with w.tag('thead'):
+                        with w.tag('tr'):
+                            for col in cols:
+                                if len(col.shape) > 1 and self.html['multicol']:
+                                    # Set colspan attribute for multicolumns
+                                    w.start('th', colspan=col.shape[1])
+                                else:
+                                    w.start('th')
+                                w.data(col_getattr(col, 'name').strip())
+                                w.end(indent=False)
+                        col_str_iters = []
                         for col in cols:
                             if len(col.shape) > 1 and self.html['multicol']:
-                                # Set colspan attribute for multicolumns
-                                w.start('th', colspan=col.shape[1])
+                                span = col.shape[1]
+                                for i in range(span):
+                                    # Split up multicolumns into separate columns
+                                    new_col = Column([el[i] for el in col])
+                                    col_str_iters.append(col_iter_str_vals(new_col))
                             else:
-                                w.start('th')
-                            w.data(col.name.strip())
-                            w.end(indent=False)
-                    col_str_iters = []
-                    for col in cols:
-                        if len(col.shape) > 1 and self.html['multicol']:
-                            span = col.shape[1]
-                            for i in range(span):
-                                # Split up multicolumns into separate columns
-                                new_col = Column([el[i] for el in col])
-                                col_str_iters.append(new_col.iter_str_vals())
-                        else:
-                            col_str_iters.append(col.iter_str_vals())
+                                col_str_iters.append(col_iter_str_vals(col))
 
                     for row in izip(*col_str_iters):
                         with w.tag('tr'):
diff --git a/astropy/io/ascii/ipac.py b/astropy/io/ascii/ipac.py
index 3a49c4d..3654ee6 100644
--- a/astropy/io/ascii/ipac.py
+++ b/astropy/io/ascii/ipac.py
@@ -20,9 +20,11 @@ from ...extern.six.moves import zip
 
 from . import core
 from . import fixedwidth
+from . import basic
 from ...utils import OrderedDict
 from ...utils.exceptions import AstropyUserWarning
 from ...table.pprint import _format_funcs, _auto_format_func
+from ...table.column import col_getattr
 
 
 class IpacFormatErrorDBMS(Exception):
@@ -39,155 +41,6 @@ class IpacFormatError(Exception):
             'http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html')
 
 
-class Ipac(fixedwidth.FixedWidth):
-    """Read or write an IPAC format table.  See
-    http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html::
-
-      \\name=value
-      \\ Comment
-      |  column1 |   column2 | column3 | column4  |    column5    |
-      |  double  |   double  |   int   |   double |     char      |
-      |  unit    |   unit    |   unit  |    unit  |     unit      |
-      |  null    |   null    |   null  |    null  |     null      |
-       2.0978     29.09056    73765     2.06000    B8IVpMnHg
-
-    Or::
-
-      |-----ra---|----dec---|---sao---|------v---|----sptype--------|
-        2.09708   29.09056     73765   2.06000    B8IVpMnHg
-
-    The comments and keywords defined in the header are available via the output
-    table ``meta`` attribute::
-
-      >>> import os
-      >>> from astropy.io import ascii
-      >>> filename = os.path.join(ascii.__path__[0], 'tests/t/ipac.dat')
-      >>> data = ascii.read(filename)
-      >>> print(data.meta['comments'])
-      ['This is an example of a valid comment']
-      >>> for name, keyword in data.meta['keywords'].items():
-      ...     print(name, keyword['value'])
-      ...
-      intval 1
-      floatval 2300.0
-      date Wed Sp 20 09:48:36 1995
-      key_continue IPAC keywords can continue across lines
-
-    Note that there are different conventions for characters occuring below the
-    position of the ``|`` symbol in IPAC tables. By default, any character
-    below a ``|`` will be ignored (since this is the current standard),
-    but if you need to read files that assume characters below the ``|``
-    symbols belong to the column before or after the ``|``, you can specify
-    ``definition='left'`` or ``definition='right'`` respectively when reading
-    the table (the default is ``definition='ignore'``). The following examples
-    demonstrate the different conventions:
-
-    * ``definition='ignore'``::
-
-        |   ra  |  dec  |
-        | float | float |
-          1.2345  6.7890
-
-    * ``definition='left'``::
-
-        |   ra  |  dec  |
-        | float | float |
-           1.2345  6.7890
-
-    * ``definition='right'``::
-
-        |   ra  |  dec  |
-        | float | float |
-        1.2345  6.7890
-
-    Parameters
-    ----------
-    definition : str, optional
-        Specify the convention for characters in the data table that occur
-        directly below the pipe (``|``) symbol in the header column definition:
-
-          * 'ignore' - Any character beneath a pipe symbol is ignored (default)
-          * 'right' - Character is associated with the column to the right
-          * 'left' - Character is associated with the column to the left
-
-    DBMS : bool, optional
-        If true, this varifies that written tables adhere (semantically)
-        to the `IPAC/DBMS <http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/DBMSrestriction.html>`_
-        definiton of IPAC tables. If 'False' it only checks for the (less strict)
-        `IPAC <http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html>`_
-        definition.
-    """
-    _format_name = 'ipac'
-    _io_registry_format_aliases = ['ipac']
-    _io_registry_can_write = True
-    _description = 'IPAC format table'
-
-    def __init__(self, definition='ignore', DBMS=False):
-        super(fixedwidth.FixedWidth, self).__init__()
-        self.header = IpacHeader(definition=definition)
-        self.data = IpacData()
-        self.data.header = self.header
-        self.header.data = self.data
-        self.header.DBMS = DBMS
-        self.data.splitter.delimiter = ' '
-        self.data.splitter.delimiter_pad = ''
-        self.data.splitter.bookend = True
-
-    def write(self, table):
-        """Write ``table`` as list of strings.
-
-        :param table: input table data (astropy.table.Table object)
-        :returns: list of strings corresponding to ASCII table
-        """
-
-        core._apply_include_exclude_names(table, self.names, self.include_names,
-                                          self.exclude_names, self.strict_names)
-
-        # link information about the columns to the writer object (i.e. self)
-        self.header.cols = list(six.itervalues(table.columns))
-        self.data.cols = list(six.itervalues(table.columns))
-
-        # Write header and data to lines list
-        lines = []
-        # Write meta information
-        if 'comments' in table.meta:
-            for comment in table.meta['comments']:
-                if len(str(comment)) > 78:
-                    warn('Comment string > 78 characters was automatically wrapped.',
-                         AstropyUserWarning)
-                for line in wrap(str(comment), 80, initial_indent='\\ ', subsequent_indent='\\ '):
-                    lines.append(line)
-        if 'keywords' in table.meta:
-            keydict = table.meta['keywords']
-            for keyword in keydict:
-                try:
-                    val = keydict[keyword]['value']
-                    lines.append('\\{0}={1!r}'.format(keyword.strip(), val))
-                    # meta is not standardized: Catch some common Errors.
-                except TypeError:
-                    pass
-
-        # get header and data as strings to find width of each column
-        for i, col in enumerate(table.columns.values()):
-            col.headwidth = max([len(vals[i]) for vals in self.header.str_vals()])
-        # keep data_str_vals because they take some time to make
-        data_str_vals = self.data.str_vals()
-        for i, col in enumerate(table.columns.values()):
-            # FIXME: In Python 3.4, use max([], default=0).
-            # See: https://docs.python.org/3/library/functions.html#max
-            if data_str_vals:
-                col.width = max([len(vals[i]) for vals in data_str_vals])
-            else:
-                col.width = 0
-
-        widths = [max(col.width, col.headwidth) for col in table.columns.values()]
-        # then write table
-        self.header.write(lines, widths)
-        self.data.write(lines, widths, data_str_vals)
-
-        return lines
-
-
 class IpacHeaderSplitter(core.BaseSplitter):
     '''Splitter for Ipac Headers.
 
@@ -218,28 +71,19 @@ class IpacHeaderSplitter(core.BaseSplitter):
 class IpacHeader(fixedwidth.FixedWidthHeader):
     """IPAC table header"""
     splitter_class = IpacHeaderSplitter
-    col_type_map = {'int': core.IntType,
-                    'integer': core.IntType,
-                    'long': core.IntType,
-                    'double': core.FloatType,
-                    'float': core.FloatType,
-                    'real': core.FloatType,
-                    'char': core.StrType,
-                    'date': core.StrType,
-                    'i': core.IntType,
-                    'l': core.IntType,
-                    'd': core.FloatType,
-                    'f': core.FloatType,
-                    'r': core.FloatType,
-                    'c': core.StrType}
-
-    def __init__(self, definition='ignore'):
-
-        fixedwidth.FixedWidthHeader.__init__(self)
-        if definition in ['ignore', 'left', 'right']:
-            self.ipac_definition = definition
-        else:
-            raise ValueError("definition should be one of ignore/left/right")
+
+    # Defined ordered list of possible types.  Ordering is needed to
+    # distinguish between "d" (double) and "da" (date) as defined by
+    # the IPAC standard for abbreviations.  This gets used in get_col_type().
+    col_type_list = (('integer', core.IntType),
+                     ('long', core.IntType),
+                     ('double', core.FloatType),
+                     ('float', core.FloatType),
+                     ('real', core.FloatType),
+                     ('char', core.StrType),
+                     ('date', core.StrType))
+    definition='ignore'
+    start_line = None
 
     def process_lines(self, lines):
         """Generator to yield IPAC header lines, i.e. those starting and ending with
@@ -310,6 +154,14 @@ class IpacHeader(fixedwidth.FixedWidthHeader):
                     if val:
                         table_meta['comments'].append(val)
 
+    def get_col_type(self, col):
+        for (col_type_key, col_type) in self.col_type_list:
+            if col_type_key.startswith(col.raw_type.lower()):
+                return col_type
+        else:
+            raise ValueError('Unknown data type ""%s"" for column "%s"' % (
+                col.raw_type, col.name))
+
     def get_cols(self, lines):
         """Initialize the header Column objects from the table ``lines``.
 
@@ -371,11 +223,11 @@ class IpacHeader(fixedwidth.FixedWidthHeader):
         else:
             IpacFormatE = IpacFormatError
 
-        namelist = [col.name for col in self.cols]
+        namelist = self.colnames
         if self.DBMS:
             countnamelist = defaultdict(int)
-            for col in self.cols:
-                countnamelist[col.name.lower()] += 1
+            for name in self.colnames:
+                countnamelist[name.lower()] += 1
             doublenames = [x for x in countnamelist if countnamelist[x] > 1]
             if doublenames != []:
                 raise IpacFormatE('IPAC DBMS tables are not case sensitive. '
@@ -384,7 +236,7 @@ class IpacHeader(fixedwidth.FixedWidthHeader):
         for name in namelist:
             m = re.match('\w+', name)
             if m.end() != len(name):
-                raise IpacFormatE('{0} - Only alphanumaric characters and _ '
+                raise IpacFormatE('{0} - Only alphanumeric characters and _ '
                                   'are allowed in column names.'.format(name))
             if self.DBMS and not(name[0].isalpha() or (name[0] == '_')):
                 raise IpacFormatE('Column name cannot start with numbers: {}'.format(name))
@@ -404,23 +256,29 @@ class IpacHeader(fixedwidth.FixedWidthHeader):
         unitlist = []
         nullist = []
         for col in self.cols:
-            if col.dtype.kind in ['i', 'u']:
+            col_dtype = col_getattr(col, 'dtype')
+            col_unit = col_getattr(col, 'unit')
+            col_format = col_getattr(col, 'format')
+
+            if col_dtype.kind in ['i', 'u']:
                 dtypelist.append('long')
-            elif col.dtype.kind == 'f':
+            elif col_dtype.kind == 'f':
                 dtypelist.append('double')
             else:
                 dtypelist.append('char')
-            if col.unit is None:
+
+            if col_unit is None:
                 unitlist.append('')
             else:
                 unitlist.append(str(col.unit))
-            null = getattr(col, 'fill_value', 'null')
+            # This may be incompatible with mixin columns
+            null = col.fill_values[core.masked]
             try:
-                format_func = _format_funcs.get(col.format, _auto_format_func)
-                nullist.append((format_func(col.format, null)).strip())
+                format_func = _format_funcs.get(col_format, _auto_format_func)
+                nullist.append((format_func(col_format, null)).strip())
             except:
-                # It is pssible that null and the column values have different
-                # data types (e.g. number und null = 'null' (i.e. a string).
+                # It is possible that null and the column values have different
+                # data types (e.g. number and null = 'null' (i.e. a string).
                 # This could cause all kinds of exceptions, so a catch all
                 # block is needed here
                 nullist.append(str(null).strip())
@@ -440,23 +298,208 @@ class IpacHeader(fixedwidth.FixedWidthHeader):
         return lines
 
 
+class IpacDataSplitter(fixedwidth.FixedWidthSplitter):
+    delimiter = ' '
+    delimiter_pad = ''
+    bookend = True
+
+
 class IpacData(fixedwidth.FixedWidthData):
     """IPAC table data reader"""
     comment = r'[|\\]'
-
-    def str_vals(self):
-        '''return str vals for each in the table'''
-        vals_list = []
-        # just to make sure
-        self._set_col_formats()
-        col_str_iters = [col.iter_str_vals() for col in self.cols]
-        for vals in zip(*col_str_iters):
-            vals_list.append(vals)
-
-        return vals_list
+    start_line = 0
+    splitter_class = IpacDataSplitter
+    fill_values = [(core.masked, 'null')]
 
     def write(self, lines, widths, vals_list):
         """ IPAC writer, modified from FixedWidth writer """
         for vals in vals_list:
             lines.append(self.splitter.join(vals, widths))
         return lines
+
+
+class Ipac(basic.Basic):
+    """Read or write an IPAC format table.  See
+    http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html::
+
+      \\name=value
+      \\ Comment
+      |  column1 |   column2 | column3 | column4  |    column5    |
+      |  double  |   double  |   int   |   double |     char      |
+      |  unit    |   unit    |   unit  |    unit  |     unit      |
+      |  null    |   null    |   null  |    null  |     null      |
+       2.0978     29.09056    73765     2.06000    B8IVpMnHg
+
+    Or::
+
+      |-----ra---|----dec---|---sao---|------v---|----sptype--------|
+        2.09708   29.09056     73765   2.06000    B8IVpMnHg
+
+    The comments and keywords defined in the header are available via the output
+    table ``meta`` attribute::
+
+      >>> import os
+      >>> from astropy.io import ascii
+      >>> filename = os.path.join(ascii.__path__[0], 'tests/t/ipac.dat')
+      >>> data = ascii.read(filename)
+      >>> print(data.meta['comments'])
+      ['This is an example of a valid comment']
+      >>> for name, keyword in data.meta['keywords'].items():
+      ...     print(name, keyword['value'])
+      ...
+      intval 1
+      floatval 2300.0
+      date Wed Sp 20 09:48:36 1995
+      key_continue IPAC keywords can continue across lines
+
+    Note that there are different conventions for characters occuring below the
+    position of the ``|`` symbol in IPAC tables. By default, any character
+    below a ``|`` will be ignored (since this is the current standard),
+    but if you need to read files that assume characters below the ``|``
+    symbols belong to the column before or after the ``|``, you can specify
+    ``definition='left'`` or ``definition='right'`` respectively when reading
+    the table (the default is ``definition='ignore'``). The following examples
+    demonstrate the different conventions:
+
+    * ``definition='ignore'``::
+
+        |   ra  |  dec  |
+        | float | float |
+          1.2345  6.7890
+
+    * ``definition='left'``::
+
+        |   ra  |  dec  |
+        | float | float |
+           1.2345  6.7890
+
+    * ``definition='right'``::
+
+        |   ra  |  dec  |
+        | float | float |
+        1.2345  6.7890
+
+    IPAC tables can specify a null value in the header that is shown in place
+    of missing or bad data. On writing, this value defaults to ``null``.
+    To specify a different null value, use the ``fill_values`` option to
+    replace masked values with a string or number of your choice as
+    described in :ref:`io_ascii_write_parameters`::
+
+        >>> from astropy.io.ascii import masked
+        >>> fill = [(masked, 'N/A', 'ra'), (masked, -999, 'sptype')]
+        >>> ascii.write(data, format='ipac', fill_values=fill)
+        \ This is an example of a valid comment
+        ...
+        |          ra|         dec|      sai|          v2|            sptype|
+        |      double|      double|     long|      double|              char|
+        |        unit|        unit|     unit|        unit|              ergs|
+        |         N/A|        null|     null|        null|              -999|
+                  N/A     29.09056      null         2.06               -999
+         2345678901.0 3456789012.0 456789012 4567890123.0 567890123456789012
+
+
+    Parameters
+    ----------
+    definition : str, optional
+        Specify the convention for characters in the data table that occur
+        directly below the pipe (``|``) symbol in the header column definition:
+
+          * 'ignore' - Any character beneath a pipe symbol is ignored (default)
+          * 'right' - Character is associated with the column to the right
+          * 'left' - Character is associated with the column to the left
+
+    DBMS : bool, optional
+        If true, this verifies that written tables adhere (semantically)
+        to the `IPAC/DBMS <http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/DBMSrestriction.html>`_
+        definition of IPAC tables. If 'False' it only checks for the (less strict)
+        `IPAC <http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html>`_
+        definition.
+    """
+    _format_name = 'ipac'
+    _io_registry_format_aliases = ['ipac']
+    _io_registry_can_write = True
+    _description = 'IPAC format table'
+
+    data_class = IpacData
+    header_class = IpacHeader
+
+    def __init__(self, definition='ignore', DBMS=False):
+        super(Ipac, self).__init__()
+        # Usually the header is not defined in __init__, but here it need a keyword
+        if definition in ['ignore', 'left', 'right']:
+            self.header.ipac_definition = definition
+        else:
+            raise ValueError("definition should be one of ignore/left/right")
+        self.header.DBMS = DBMS
+
+    def write(self, table):
+        """Write ``table`` as list of strings.
+
+        :param table: input table data (astropy.table.Table object)
+        :returns: list of strings corresponding to ASCII table
+        """
+        # Set a default null value for all columns by adding at the end, which
+        # is the position with the lowest priority.
+        # We have to do it this late, because the fill_value
+        # defined in the class can be overwritten by ui.write
+        self.data.fill_values.append((core.masked, 'null'))
+
+        # Check column names before altering
+        self.header.cols = list(six.itervalues(table.columns))
+        self.header.check_column_names(self.names, self.strict_names, self.guessing)
+
+        core._apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names)
+
+        # Now use altered columns
+        new_cols = list(six.itervalues(table.columns))
+        # link information about the columns to the writer object (i.e. self)
+        self.header.cols = new_cols
+        self.data.cols = new_cols
+
+        # Write header and data to lines list
+        lines = []
+        # Write meta information
+        if 'comments' in table.meta:
+            for comment in table.meta['comments']:
+                if len(str(comment)) > 78:
+                    warn('Comment string > 78 characters was automatically wrapped.',
+                         AstropyUserWarning)
+                for line in wrap(str(comment), 80, initial_indent='\\ ', subsequent_indent='\\ '):
+                    lines.append(line)
+        if 'keywords' in table.meta:
+            keydict = table.meta['keywords']
+            for keyword in keydict:
+                try:
+                    val = keydict[keyword]['value']
+                    lines.append('\\{0}={1!r}'.format(keyword.strip(), val))
+                    # meta is not standardized: Catch some common Errors.
+                except TypeError:
+                    pass
+
+        # Usually, this is done in data.write, but since the header is written
+        # first, we need that here.
+        self.data._set_fill_values(self.data.cols)
+
+        # get header and data as strings to find width of each column
+        for i, col in enumerate(table.columns.values()):
+            col.headwidth = max([len(vals[i]) for vals in self.header.str_vals()])
+        # keep data_str_vals because they take some time to make
+        data_str_vals = []
+        col_str_iters = self.data.str_vals()
+        for vals in zip(*col_str_iters):
+            data_str_vals.append(vals)
+
+        for i, col in enumerate(table.columns.values()):
+            # FIXME: In Python 3.4, use max([], default=0).
+            # See: https://docs.python.org/3/library/functions.html#max
+            if data_str_vals:
+                col.width = max([len(vals[i]) for vals in data_str_vals])
+            else:
+                col.width = 0
+
+        widths = [max(col.width, col.headwidth) for col in table.columns.values()]
+        # then write table
+        self.header.write(lines, widths)
+        self.data.write(lines, widths, data_str_vals)
+
+        return lines
diff --git a/astropy/io/ascii/latex.py b/astropy/io/ascii/latex.py
index fe90491..de59c04 100644
--- a/astropy/io/ascii/latex.py
+++ b/astropy/io/ascii/latex.py
@@ -14,6 +14,7 @@ import re
 
 from ...extern import six
 from . import core
+from ...table.column import col_getattr
 
 latexdicts = {'AA':  {'tabletype': 'table',
                       'header_start': r'\hline \hline', 'header_end': r'\hline',
@@ -60,8 +61,39 @@ def find_latex_line(lines, latex):
         return None
 
 
+class LatexSplitter(core.BaseSplitter):
+    '''Split LaTeX table date. Default delimiter is `&`.
+    '''
+    delimiter = '&'
+
+    def process_line(self, line):
+        """Remove whitespace at the beginning or end of line. Also remove
+        \\ at end of line"""
+        line = line.split('%')[0]
+        line = line.strip()
+        if line[-2:] == r'\\':
+            line = line.strip(r'\\')
+        else:
+            raise core.InconsistentTableError(r'Lines in LaTeX table have to end with \\')
+        return line
+
+    def process_val(self, val):
+        """Remove whitespace and {} at the beginning or end of value."""
+        val = val.strip()
+        if val and (val[0] == '{') and (val[-1] == '}'):
+            val = val[1:-1]
+        return val
+
+    def join(self, vals):
+        '''Join values together and add a few extra spaces for readability'''
+        delimiter = ' ' + self.delimiter + ' '
+        return delimiter.join(x.strip() for x in vals) + r' \\'
+
+
 class LatexHeader(core.BaseHeader):
+    '''Class to read the header of Latex Tables'''
     header_start = r'\begin{tabular}'
+    splitter_class = LatexSplitter
 
     def start_line(self, lines):
         line = find_latex_line(lines, self.header_start)
@@ -83,16 +115,22 @@ class LatexHeader(core.BaseHeader):
             lines.append(r'\caption{' + self.latex['caption'] + '}')
         lines.append(self.header_start + r'{' + self.latex['col_align'] + r'}')
         add_dictval_to_list(self.latex, 'header_start', lines)
-        lines.append(self.splitter.join([x.name for x in self.cols]))
+        col_units = [col_getattr(col, 'unit') for col in self.cols]
+        lines.append(self.splitter.join(self.colnames))
+        units = dict((name, unit.to_string(format='latex_inline'))
+                     for name, unit in zip(self.colnames, col_units) if unit)
         if 'units' in self.latex:
-            lines.append(self.splitter.join([self.latex['units'].get(x.name, ' ')
-                                             for x in self.cols]))
+            units.update(self.latex['units'])
+        if units:
+            lines.append(self.splitter.join([units.get(name, ' ') for name in self.colnames]))
         add_dictval_to_list(self.latex, 'header_end', lines)
 
 
 class LatexData(core.BaseData):
+    '''Class to read the data in LaTeX tables'''
     data_start = None
     data_end = r'\end{tabular}'
+    splitter_class = LatexSplitter
 
     def start_line(self, lines):
         if self.data_start:
@@ -115,35 +153,6 @@ class LatexData(core.BaseData):
         lines.append(r'\end{' + self.latex['tabletype'] + '}')
 
 
-class LatexSplitter(core.BaseSplitter):
-    '''Split LaTeX table date. Default delimiter is `&`.
-    '''
-    delimiter = '&'
-
-    def process_line(self, line):
-        """Remove whitespace at the beginning or end of line. Also remove
-        \\ at end of line"""
-        line = line.split('%')[0]
-        line = line.strip()
-        if line[-2:] == r'\\':
-            line = line.strip(r'\\')
-        else:
-            raise core.InconsistentTableError(r'Lines in LaTeX table have to end with \\')
-        return line
-
-    def process_val(self, val):
-        """Remove whitespace and {} at the beginning or end of value."""
-        val = val.strip()
-        if val and (val[0] == '{') and (val[-1] == '}'):
-            val = val[1:-1]
-        return val
-
-    def join(self, vals):
-        '''Join values together and add a few extra spaces for readability'''
-        delimiter = ' ' + self.delimiter + ' '
-        return delimiter.join(x.strip() for x in vals) + r' \\'
-
-
 class Latex(core.BaseReader):
     r'''Write and read LaTeX tables.
 
@@ -183,7 +192,7 @@ class Latex(core.BaseReader):
                             latexdict = {'tabletype': 'table*'})
 
         * tablealign : positioning of table in text.
-            The default is not to specifiy a position preference in the text.
+            The default is not to specify a position preference in the text.
             If, e.g. the alignment is ``ht``, then the LaTeX will be ``\\begin{table}[ht]``.
 
         * col_align : Alignment of columns
@@ -212,7 +221,8 @@ class Latex(core.BaseReader):
                                latexdict = {'units': {'mass': 'kg', 'speed': 'km/h'}})
 
             If the column has no entry in the ``units`` dictionary, it defaults
-            to ``' '``.
+            to the **unit** attribute of the column. If this attribute is not
+            specified (i.e. it is None), the unit will be written as ``' '``.
 
         Run the following code to see where each element of the
         dictionary is inserted in the LaTeX table::
@@ -252,17 +262,14 @@ class Latex(core.BaseReader):
     _io_registry_suffix = '.tex'
     _description = 'LaTeX table'
 
+    header_class = LatexHeader
+    data_class = LatexData
+
     def __init__(self, ignore_latex_commands=['hline', 'vspace', 'tableline'],
                  latexdict={}, caption='', col_align=None):
 
-        core.BaseReader.__init__(self)
-        self.header = LatexHeader()
-        self.data = LatexData()
+        super(Latex, self).__init__()
 
-        self.header.splitter = LatexSplitter()
-        self.data.splitter = LatexSplitter()
-        self.data.header = self.header
-        self.header.data = self.data
         self.latex = {}
         # The latex dict drives the format of the table and needs to be shared
         # with data and header
@@ -286,6 +293,29 @@ class Latex(core.BaseReader):
         return core.BaseReader.write(self, table=table)
 
 
+class AASTexHeaderSplitter(LatexSplitter):
+    '''Extract column names from a `deluxetable`_.
+
+    This splitter expects the following LaTeX code **in a single line**:
+
+        \tablehead{\colhead{col1} & ... & \colhead{coln}}
+    '''
+    def process_line(self, line):
+        """extract column names from tablehead
+        """
+        line = line.split('%')[0]
+        line = line.replace(r'\tablehead', '')
+        line = line.strip()
+        if (line[0] == '{') and (line[-1] == '}'):
+            line = line[1:-1]
+        else:
+            raise core.InconsistentTableError(r'\tablehead is missing {}')
+        return line.replace(r'\colhead', '')
+
+    def join(self, vals):
+        return ' & '.join([r'\colhead{' + str(x) + '}' for x in vals])
+
+
 class AASTexHeader(LatexHeader):
     '''In a `deluxetable
     <http://fits.gsfc.nasa.gov/standard30/deluxetable.sty>`_ some header
@@ -294,6 +324,7 @@ class AASTexHeader(LatexHeader):
     This header is modified to take that into account.
     '''
     header_start = r'\tablehead'
+    splitter_class = AASTexHeaderSplitter
 
     def start_line(self, lines):
         return find_latex_line(lines, r'\tablehead')
@@ -310,10 +341,15 @@ class AASTexHeader(LatexHeader):
         add_dictval_to_list(self.latex, 'preamble', lines)
         if 'caption' in self.latex:
             lines.append(r'\tablecaption{' + self.latex['caption'] + '}')
-        tablehead = ' & '.join([r'\colhead{' + x.name + '}' for x in self.cols])
+        tablehead = ' & '.join([r'\colhead{' + name + '}' for name in self.colnames])
+        col_units = [col_getattr(col, 'unit') for col in self.cols]
+        units = dict((name, unit.to_string(format='latex_inline'))
+                     for name, unit in zip(self.colnames, col_units) if unit)
         if 'units' in self.latex:
-            tablehead += r'\\ ' + (self.splitter.join([self.latex[
-                                   'units'].get(x.name, ' ') for x in self.cols]))
+            units.update(self.latex['units'])
+        if units:
+            tablehead += r'\\ ' + self.splitter.join([units.get(name, ' ')
+                                                      for name in self.colnames])
         lines.append(r'\tablehead{' + tablehead + '}')
 
 
@@ -334,29 +370,6 @@ class AASTexData(LatexData):
         lines.append(r'\end{' + self.latex['tabletype'] + r'}')
 
 
-class AASTexHeaderSplitter(LatexSplitter):
-    '''Extract column names from a `deluxetable`_.
-
-    This splitter expects the following LaTeX code **in a single line**:
-
-        \tablehead{\colhead{col1} & ... & \colhead{coln}}
-    '''
-    def process_line(self, line):
-        """extract column names from tablehead
-        """
-        line = line.split('%')[0]
-        line = line.replace(r'\tablehead', '')
-        line = line.strip()
-        if (line[0] == '{') and (line[-1] == '}'):
-            line = line[1:-1]
-        else:
-            raise core.InconsistentTableError(r'\tablehead is missing {}')
-        return line.replace(r'\colhead', '')
-
-    def join(self, vals):
-        return ' & '.join([r'\colhead{' + str(x) + '}' for x in vals])
-
-
 class AASTex(Latex):
     '''Write and read AASTeX tables.
 
@@ -374,24 +387,11 @@ class AASTex(Latex):
     _io_registry_suffix = ''  # AASTex inherits from Latex, so override this class attr
     _description = 'AASTeX deluxetable used for AAS journals'
 
+    header_class = AASTexHeader
+    data_class = AASTexData
+
     def __init__(self, **kwargs):
-        Latex.__init__(self, **kwargs)
-        self.header = AASTexHeader()
-        self.data = AASTexData()
-        self.header.comment = '%|' + '|'.join(
-            [r'\\' + command for command in self.ignore_latex_commands])
-        self.header.splitter = AASTexHeaderSplitter()
-        self.data.splitter = LatexSplitter()
-        self.data.comment = self.header.comment
-        self.data.header = self.header
-        self.header.data = self.data
-        # The latex dict drives the format of the table and needs to be shared
-        # with data and header
-        self.header.latex = self.latex
-        self.data.latex = self.latex
+        super(AASTex, self).__init__(**kwargs)
         # check if tabletype was explicitly set by the user
         if not (('latexdict' in kwargs) and ('tabletype' in kwargs['latexdict'])):
             self.latex['tabletype'] = 'deluxetable'
-        self.header.comment = '%|' + '|'.join(
-            [r'\\' + command for command in self.ignore_latex_commands])
-        self.data.comment = self.header.comment
diff --git a/astropy/io/ascii/setup_package.py b/astropy/io/ascii/setup_package.py
index 8fcff27..982c084 100644
--- a/astropy/io/ascii/setup_package.py
+++ b/astropy/io/ascii/setup_package.py
@@ -1,6 +1,19 @@
 # Licensed under a 3-clause BSD style license
 from __future__ import absolute_import
 
+import os
+from distutils.extension import Extension
+
+ROOT = os.path.relpath(os.path.dirname(__file__))
+
+def get_extensions():
+    sources = [os.path.join(ROOT, 'cparser.pyx'),
+               os.path.join(ROOT, 'src', 'tokenizer.c')]
+    ascii_ext = Extension(
+        name="astropy.io.ascii.cparser",
+        include_dirs=["numpy"],
+        sources=sources)
+    return [ascii_ext]
 
 def get_package_data():
     # Installs the testing data files.  Unable to get package_data
@@ -63,6 +76,7 @@ def get_package_data():
                                    't/whitespace.dat',
                                    't/simple_csv.csv',
                                    't/simple_csv_missing.csv',
+                                   't/fixed_width_2_line.txt',
                                    ]
     }
 
diff --git a/astropy/io/ascii/sextractor.py b/astropy/io/ascii/sextractor.py
index 85b5e45..76ca706 100644
--- a/astropy/io/ascii/sextractor.py
+++ b/astropy/io/ascii/sextractor.py
@@ -11,62 +11,12 @@ from __future__ import absolute_import, division, print_function
 
 import re
 
-from ...extern import six
 from . import core
 
 
-class SExtractor(core.BaseReader):
-    """Read a SExtractor file.
-       SExtractor is a package for faint-galaxy photometry.
-       Bertin & Arnouts 1996, A&A Supp. 317, 393.
-       http://www.astromatic.net/software/sextractor
-
-    Example::
-
-      # 1 NUMBER
-      # 2 ALPHA_J2000
-      # 3 DELTA_J2000
-      # 4 FLUX_RADIUS
-      # 7 MAG_AUTO [mag]
-      # 8 X2_IMAGE Variance along x [pixel**2]
-      # 9 X_MAMA Barycenter position along MAMA x axis [m**(-6)]
-      # 10 MU_MAX Peak surface brightness above background [mag * arcsec**(-2)]
-      1 32.23222 10.1211 0.8 1.2 1.4 18.1 1000.0 0.00304 -3.498
-      2 38.12321 -88.1321 2.2 2.4 3.1 17.0 1500.0 0.00908 1.401
-
-    Note the skipped numbers since flux_radius has 3 columns.  The three FLUX_RADIUS
-    columns will be named FLUX_RADIUS, FLUX_RADIUS_1, FLUX_RADIUS_2
-    Also note that a post-ID description (e.g. "Variance along x") is
-    optional and that units may be specified at the end of a line in brackets.
-    """
-    _format_name = 'sextractor'
-    _io_registry_can_write = False
-    _description = 'SExtractor format table'
-
-    def __init__(self):
-        core.BaseReader.__init__(self)
-        self.header = SExtractorHeader()
-        self.inputter = core.ContinuationLinesInputter()
-        self.data.splitter.delimiter = ' '
-        self.data.start_line = 0
-        self.data.comment = r'\s*#'  # Comments embedded in the data start with #
-
-    def read(self, table):
-        output = core.BaseReader.read(self, table)
-        self.table = output
-        self.cols = self.header.cols
-
-        return self.table
-
-    def write(self, table=None):
-        raise NotImplementedError
-
-
 class SExtractorHeader(core.BaseHeader):
     """Read the header from a file produced by SExtractor."""
-    def __init__(self):
-        core.BaseHeader.__init__(self)
-        self.comment = r'^\s*#\s*\S\D.*'  # Find lines that dont have "# digit"
+    comment = r'^\s*#\s*\S\D.*'  # Find lines that don't have "# digit"
 
     def get_cols(self, lines):
         """Initialize the header Column objects from the table ``lines`` for a SExtractor
@@ -86,7 +36,7 @@ class SExtractorHeader(core.BaseHeader):
                                  (?P<colnumber> [0-9]+)\s+   # number of the column in table
                                  (?P<colname> \w+)           # name of the column
                                  (?:\s+(?P<coldescr> \w [^\[]*\w))? # column description, match non-[
-                                 (?:\s+\[(?P<colunit>.+)\])?.*   # match units in brackets 
+                                 (?:\s+\[(?P<colunit>.+)\])?.*   # match units in brackets
                                  """, re.VERBOSE)
         for line in lines:
             if not line.startswith('#'):
@@ -126,3 +76,45 @@ class SExtractorHeader(core.BaseHeader):
             col.description = columns[n][1]
             col.unit = columns[n][2]
             self.cols.append(col)
+
+
+class SExtractorData(core.BaseData):
+        start_line = 0
+        delimiter = ' '
+        comment = r'\s*#'
+
+
+class SExtractor(core.BaseReader):
+    """Read a SExtractor file.
+       SExtractor is a package for faint-galaxy photometry.
+       Bertin & Arnouts 1996, A&A Supp. 317, 393.
+       http://www.astromatic.net/software/sextractor
+
+    Example::
+
+      # 1 NUMBER
+      # 2 ALPHA_J2000
+      # 3 DELTA_J2000
+      # 4 FLUX_RADIUS
+      # 7 MAG_AUTO [mag]
+      # 8 X2_IMAGE Variance along x [pixel**2]
+      # 9 X_MAMA Barycenter position along MAMA x axis [m**(-6)]
+      # 10 MU_MAX Peak surface brightness above background [mag * arcsec**(-2)]
+      1 32.23222 10.1211 0.8 1.2 1.4 18.1 1000.0 0.00304 -3.498
+      2 38.12321 -88.1321 2.2 2.4 3.1 17.0 1500.0 0.00908 1.401
+
+    Note the skipped numbers since flux_radius has 3 columns.  The three FLUX_RADIUS
+    columns will be named FLUX_RADIUS, FLUX_RADIUS_1, FLUX_RADIUS_2
+    Also note that a post-ID description (e.g. "Variance along x") is
+    optional and that units may be specified at the end of a line in brackets.
+    """
+    _format_name = 'sextractor'
+    _io_registry_can_write = False
+    _description = 'SExtractor format table'
+
+    header_class = SExtractorHeader
+    data_class = SExtractorData
+    inputter_class = core.ContinuationLinesInputter
+
+    def write(self, table):
+        raise NotImplementedError
diff --git a/astropy/io/ascii/src/tokenizer.c b/astropy/io/ascii/src/tokenizer.c
new file mode 100644
index 0000000..92a78c8
--- /dev/null
+++ b/astropy/io/ascii/src/tokenizer.c
@@ -0,0 +1,888 @@
+// Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+#include "tokenizer.h"
+
+tokenizer_t *create_tokenizer(char delimiter, char comment, char quotechar,
+                              int fill_extra_cols, int strip_whitespace_lines,
+                              int strip_whitespace_fields, int use_fast_converter)
+{
+    // Create the tokenizer in memory
+    tokenizer_t *tokenizer = (tokenizer_t *) malloc(sizeof(tokenizer_t));
+
+    // Initialize the tokenizer fields
+    tokenizer->source = NULL;
+    tokenizer->source_len = 0;
+    tokenizer->source_pos = 0;
+    tokenizer->delimiter = delimiter;
+    tokenizer->comment = comment;
+    tokenizer->quotechar = quotechar;
+    tokenizer->output_cols = NULL;
+    tokenizer->col_ptrs = NULL;
+    tokenizer->output_len = NULL;
+    tokenizer->num_cols = 0;
+    tokenizer->num_rows = 0;
+    tokenizer->fill_extra_cols = fill_extra_cols;
+    tokenizer->state = START_LINE;
+    tokenizer->code = NO_ERROR;
+    tokenizer->iter_col = 0;
+    tokenizer->curr_pos = NULL;
+    tokenizer->strip_whitespace_lines = strip_whitespace_lines;
+    tokenizer->strip_whitespace_fields = strip_whitespace_fields;
+    tokenizer->use_fast_converter = use_fast_converter;
+    tokenizer->comment_lines = (char *) malloc(INITIAL_COMMENT_LEN);
+    tokenizer->comment_pos = 0;
+    tokenizer->comment_lines_len = 0;
+
+    // This is a bit of a hack -- buf holds an empty string to represent
+    // empty field values
+    tokenizer->buf = calloc(2, sizeof(char));
+
+    return tokenizer;
+}
+
+void delete_data(tokenizer_t *tokenizer)
+{
+    // Don't free tokenizer->source because it points to part of
+    // an already freed Python object
+    int i;
+
+    if (tokenizer->output_cols)
+	for (i = 0; i < tokenizer->num_cols; ++i)
+	    free(tokenizer->output_cols[i]);
+
+    free(tokenizer->output_cols);
+    free(tokenizer->col_ptrs);
+    free(tokenizer->output_len);
+
+    // Set pointers to 0 so we don't use freed memory when reading over again
+    tokenizer->output_cols = 0;
+    tokenizer->col_ptrs = 0;
+    tokenizer->output_len = 0;
+}
+
+void delete_tokenizer(tokenizer_t *tokenizer)
+{
+    delete_data(tokenizer);
+    free(tokenizer->comment_lines);
+    free(tokenizer->buf);
+    free(tokenizer);
+}
+
+void resize_col(tokenizer_t *self, int index)
+{
+    // Temporarily store the position in output_cols[index] to
+    // which col_ptrs[index] points
+    long diff = self->col_ptrs[index] - self->output_cols[index];
+
+    // Double the size of the column string
+    self->output_cols[index] = (char *) realloc(self->output_cols[index], 2 *
+                                                self->output_len[index] * sizeof(char));
+
+    // Set the second (newly allocated) half of the column string to all zeros
+    memset(self->output_cols[index] + self->output_len[index] * sizeof(char), 0,
+           self->output_len[index] * sizeof(char));
+
+    self->output_len[index] *= 2;
+    // realloc() might move the address in memory, so we have to move
+    // col_ptrs[index] to an offset of the new address
+    self->col_ptrs[index] = self->output_cols[index] + diff;
+}
+
+void resize_comments(tokenizer_t *self)
+{
+    // Double the size of the comments string
+    self->comment_lines = (char *) realloc(self->comment_lines,
+                                           2 * self->comment_lines_len);
+    // Set the second (newly allocated) half of the column string to all zeros
+    memset(self->comment_lines + self->comment_lines_len * sizeof(char), 0,
+           self->comment_lines_len * sizeof(char));
+
+    self->comment_lines_len *= 2;
+}
+
+/*
+  Resize the column string if necessary and then append c to the
+  end of the column string, incrementing the column position pointer.
+*/
+
+static inline void push(tokenizer_t *self, char c, int col)
+{
+    if (self->col_ptrs[col] - self->output_cols[col] >=
+        self->output_len[col])
+    {
+        resize_col(self, col);
+    }
+    *self->col_ptrs[col]++ = c;
+}
+
+/*
+  Resize the comment string if necessary and then append c to the
+  end of the comment string.
+*/
+
+static inline void push_comment(tokenizer_t *self, char c)
+{
+    if (self->comment_pos == self->comment_lines_len)
+        resize_comments(self);
+    self->comment_lines[self->comment_pos++] = c;
+}
+
+static inline void end_comment(tokenizer_t *self)
+{
+    // Signal empty comment by inserting \x01
+    if (self->comment_pos == 0 || self->comment_lines[self->comment_pos - 1] == '\x00')
+        push_comment(self, '\x01');
+    push_comment(self, '\x00');
+}
+
+#define PUSH(c) push(self, c, col)
+
+/* Set the state to START_FIELD and begin with the assumption that
+   the field is entirely whitespace in order to handle the possibility
+   that the comment character is found before any non-whitespace even
+   if whitespace stripping is disabled.
+*/
+
+#define BEGIN_FIELD()                           \
+    self->state = START_FIELD;                  \
+    whitespace = 1
+
+/*
+  First, backtrack to eliminate trailing whitespace if strip_whitespace_fields
+  is true. If the field is empty, push '\x01' as a marker.
+  Append a null byte to the end of the column string as a field delimiting marker.
+  Increment the variable col if we are tokenizing data.
+*/
+
+static inline void end_field(tokenizer_t *self, int *col, int header)
+{
+    if (self->strip_whitespace_fields && self->col_ptrs[*col]
+	!= self->output_cols[*col])
+    {
+        --self->col_ptrs[*col];
+        while (*self->col_ptrs[*col] == ' ' || *self->col_ptrs[*col] == '\t')
+        {
+            *self->col_ptrs[*col]-- = '\x00';
+        }
+        ++self->col_ptrs[*col];
+    }
+    if (self->col_ptrs[*col] == self->output_cols[*col] ||
+        self->col_ptrs[*col][-1] == '\x00')
+    {
+        push(self, '\x01', *col);
+    }
+    push(self, '\x00', *col);
+    if (!header)
+        ++*col;
+}
+
+#define END_FIELD() end_field(self, &col, header)
+
+// Set the error code to c for later retrieval and return c
+
+#define RETURN(c)                                               \
+    do {                                                        \
+        self->code = c;                                         \
+        return c;                                               \
+    } while (0)
+
+/*
+  If we are tokenizing the header, end after the first line.
+  Handle the possibility of insufficient columns appropriately;
+  if fill_extra_cols=1, then append empty fields, but otherwise
+  return an error. Increment our row count and possibly end if
+  all the necessary rows have already been parsed.
+*/
+
+static inline int end_line(tokenizer_t *self, int col, int header, int end,
+                    tokenizer_state *old_state)
+{
+    if (header)                                 
+    {                                           
+        ++self->source_pos;                     
+        RETURN(NO_ERROR);                       
+    }                                           
+    else if (self->fill_extra_cols)             
+	while (col < self->num_cols)            
+	{                                       
+            PUSH('\x01');                       
+	    END_FIELD();                        
+	}                                       
+    else if (col < self->num_cols)              
+	RETURN(NOT_ENOUGH_COLS);                
+    ++self->num_rows;                           
+    *old_state = START_LINE;                     
+    if (end != -1 && self->num_rows == end)     
+    {                                           
+        ++self->source_pos;                     
+        RETURN(NO_ERROR);                       
+    }
+    return -1;
+}
+
+#define END_LINE() if (end_line(self, col, header, end, &old_state) != -1) return self->code
+
+#define HANDLE_CR() old_state = self->state; self->state = CARRIAGE_RETURN
+
+int skip_lines(tokenizer_t *self, int offset, int header)
+{
+    int signif_chars = 0;
+    int comment = 0;
+    int i = 0;
+    char c;
+
+    while (i < offset)
+    {
+	if (self->source_pos >= self->source_len)
+        {
+            if (header)
+                RETURN(INVALID_LINE); // header line is required
+            else
+                RETURN(NO_ERROR); // no data in input
+        }
+
+        c = self->source[self->source_pos];
+
+        if (c == '\r' || c == '\n')
+        {
+            if (c == '\r' && self->source_pos < self->source_len - 1 &&
+                self->source[self->source_pos + 1] == '\n')
+            {
+                ++self->source_pos; // skip \n in \r\n
+            }
+            if (!comment && signif_chars > 0)
+                ++i;
+            else if (comment && !header)
+                end_comment(self);
+            // Start by assuming a line is empty and non-commented
+            signif_chars = 0;
+            comment = 0;
+        }
+
+	else if ((c != ' ' && c != '\t') || !self->strip_whitespace_lines || header)
+	{
+            // comment line
+            if (!signif_chars && self->comment != 0 && c == self->comment)
+                comment = 1;
+            else if (comment && !header)
+                push_comment(self, c);
+
+            // significant character encountered; during header
+            // tokenization, we count whitespace unlike data tokenization
+            // (see #2654)
+            ++signif_chars;
+	}
+
+        else if (comment && !header)
+            push_comment(self, c);
+
+        ++self->source_pos;
+    }
+
+    RETURN(NO_ERROR);
+}
+
+int tokenize(tokenizer_t *self, int end, int header, int num_cols)
+{
+    char c; // input character
+    int col = 0; // current column ignoring possibly excluded columns
+    tokenizer_state old_state = START_LINE; // last state the tokenizer was in before CR mode
+    int parse_newline = 0; // explicit flag to treat current char as a newline
+    int i = 0;
+    int whitespace = 1;
+    delete_data(self); // clear old reading data
+    self->num_rows = 0;
+    self->comment_lines_len = INITIAL_COMMENT_LEN;
+
+    if (header)
+        self->num_cols = 1; // store header output in one column
+    else
+        self->num_cols = num_cols;
+
+    // Allocate memory for structures used during tokenization
+    self->output_cols = (char **) malloc(self->num_cols * sizeof(char *));
+    self->col_ptrs = (char **) malloc(self->num_cols * sizeof(char *));
+    self->output_len = (int *) malloc(self->num_cols * sizeof(int));
+
+    for (i = 0; i < self->num_cols; ++i)
+    {
+        self->output_cols[i] = (char *) calloc(1, INITIAL_COL_SIZE *
+                                               sizeof(char));
+        // Make each col_ptrs pointer point to the beginning of the
+        // column string
+        self->col_ptrs[i] = self->output_cols[i];
+        self->output_len[i] = INITIAL_COL_SIZE;
+    }
+
+    if (end == 0)
+        RETURN(NO_ERROR); // don't read if end == 0
+
+    self->state = START_LINE;
+
+    // Loop until all of self->source has been read
+    while (self->source_pos < self->source_len + 1)
+    {
+        if (self->source_pos == self->source_len || parse_newline)
+            c = '\n';
+        else
+            c = self->source[self->source_pos];
+
+        parse_newline = 0;
+
+        switch (self->state)
+        {
+        case START_LINE:
+            if (c == '\n')
+                break;
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+                break;
+            }
+            else if ((c == ' ' || c == '\t') && self->strip_whitespace_lines)
+                break;
+            else if (self->comment != 0 && c == self->comment)
+            {
+                // comment line; ignore
+                self->state = COMMENT;
+                break;
+            }
+            // initialize variables for the beginning of line parsing
+            col = 0;
+            BEGIN_FIELD();
+            // parse in mode START_FIELD
+
+        case START_FIELD:
+            // strip whitespace before field begins
+            if ((c == ' ' || c == '\t') && self->strip_whitespace_fields)
+                break;
+            else if (!self->strip_whitespace_lines && self->comment != 0 &&
+                     c == self->comment)
+            {
+                // comment line, not caught earlier because of no stripping
+                self->state = COMMENT;
+                break;
+            }
+            else if (c == self->delimiter) // field ends before it begins
+            {
+                END_FIELD();
+                BEGIN_FIELD();
+                break;
+            }
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+                break;
+            }
+            else if (c == '\n')
+            {
+                if (self->strip_whitespace_lines)
+                {
+                    // Move on if the delimiter is whitespace, e.g.
+                    // '1 2 3   '->['1','2','3']
+                    if (self->delimiter == ' ' || self->delimiter == '\t')
+                        ;
+                    // Register an empty field if non-whitespace delimiter,
+                    // e.g. '1,2, '->['1','2','']
+                    else
+                    {
+                        END_FIELD();
+                    }
+                }
+
+                else if (!self->strip_whitespace_lines)
+                {
+                    // In this case we don't want to left-strip the field,
+                    // so we backtrack
+                    int tmp = self->source_pos;
+                    --self->source_pos;
+
+                    while (self->source_pos >= 0 &&
+                           self->source[self->source_pos] != self->delimiter
+                           && self->source[self->source_pos] != '\n'
+                           && self->source[self->source_pos] != '\r')
+                    {
+                        --self->source_pos;
+                    }
+
+                    // backtracked to line beginning
+                    if (self->source_pos == -1 || self->source[self->source_pos] == '\n'
+                        || self->source[self->source_pos] == '\r')
+                    {
+                        self->source_pos = tmp;
+                    }
+                    else
+                    {
+                        ++self->source_pos;
+
+                        if (self->source_pos == tmp)
+                            // no whitespace, just an empty field
+                            ;
+
+                        else
+                            while (self->source_pos < tmp)
+                            {
+                                // append whitespace characters
+                                PUSH(self->source[self->source_pos]);
+                                ++self->source_pos;
+                            }
+
+                        END_FIELD(); // whitespace counts as a field
+                    }
+                }
+
+                END_LINE();
+                self->state = START_LINE;
+                break;
+            }
+            else if (c == self->quotechar) // start parsing quoted field
+            {
+                self->state = START_QUOTED_FIELD;
+                break;
+            }
+            else
+            {
+                if (col >= self->num_cols)
+                    RETURN(TOO_MANY_COLS);
+                // Valid field character, parse again in FIELD mode
+                self->state = FIELD;
+            }
+
+        case FIELD:
+            if (self->comment != 0 && c == self->comment && whitespace && col == 0)
+            {
+                // No whitespace stripping, but the comment char is found
+                // before any data, e.g. '  # a b c'
+                self->state = COMMENT;
+            }
+            else if (c == self->delimiter)
+            {
+                // End of field, look for new field
+                END_FIELD();
+                BEGIN_FIELD();
+            }
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+            }
+            else if (c == '\n')
+            {
+                // Line ending, stop parsing both field and line
+                END_FIELD();
+                END_LINE();
+                self->state = START_LINE;
+            }
+            else
+            {
+                if (c != ' ' && c != '\t')
+                    whitespace = 0; // field is not all whitespace
+                PUSH(c);
+            }
+            break;
+
+        case START_QUOTED_FIELD:
+            if ((c == ' ' || c == '\t') && self->strip_whitespace_fields)
+            {
+                // ignore initial whitespace
+                break;
+            }
+            else if (c == self->quotechar) // empty quotes
+            {
+                END_FIELD();
+                break;
+            }
+            else
+            {
+                // Valid field character, parse again in QUOTED_FIELD mode
+                self->state = QUOTED_FIELD;
+            }
+
+        case QUOTED_FIELD_NEWLINE:
+            if (self->state == QUOTED_FIELD)
+                ; // fall through
+            // Ignore initial whitespace if strip_whitespace_lines and
+            // newlines regardless
+            else if (((c == ' ' || c == '\t') && self->strip_whitespace_lines)
+                     || c == '\n')
+                break;
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+                break;
+            }
+            else if (c == self->quotechar)
+            {
+                self->state = FIELD;
+                break;
+            }
+            else
+            {
+                // Once data begins, parse it as a normal quoted field
+                self->state = QUOTED_FIELD;
+            }
+
+        case QUOTED_FIELD:
+            if (c == self->quotechar) // Parse rest of field normally, e.g. "ab"c
+                self->state = FIELD;
+            else if (c == '\n')
+                self->state = QUOTED_FIELD_NEWLINE;
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+            }
+            else
+            {
+                PUSH(c);
+            }
+            break;
+
+        case COMMENT:
+            if (c == '\n')
+            {
+                self->state = START_LINE;
+                if (!header)
+                    end_comment(self);
+            }
+            else if (c == '\r')
+            {
+                HANDLE_CR();
+            }
+            else if (!header)
+                push_comment(self, c);
+            break; // keep looping until we find a newline
+
+        case CARRIAGE_RETURN:
+            self->state = old_state;
+            --self->source_pos; // parse the newline in the old state
+            if (c != '\n') // CR line terminator
+            {
+                --self->source_pos; // backtrack to the carriage return
+                parse_newline = 1; // explicitly treat the CR as a newline
+            }
+            break;
+        }
+
+        ++self->source_pos;
+    }
+
+    RETURN(0);
+}
+
+long str_to_long(tokenizer_t *self, char *str)
+{
+    char *tmp;
+    long ret;
+    errno = 0;
+    ret = strtol(str, &tmp, 0);
+
+    if (tmp == str || *tmp != '\0')
+ 	self->code = CONVERSION_ERROR;
+    else if (errno == ERANGE)
+        self->code = OVERFLOW_ERROR;
+
+    return ret;
+}
+
+double str_to_double(tokenizer_t *self, char *str)
+{
+    char *tmp;
+    double val;
+
+    if (self->use_fast_converter)
+    {
+        val = xstrtod(str, &tmp, '.', 'E', ',', 1);
+        if (*tmp)
+            self->code = CONVERSION_ERROR;
+        else if (errno == ERANGE)
+            self->code = OVERFLOW_ERROR;
+    }
+
+    else
+    {
+        val = strtod(str, &tmp);
+
+        if (tmp == str || *tmp != 0)
+            self->code = CONVERSION_ERROR;
+        else if (errno == ERANGE)
+            self->code = OVERFLOW_ERROR;
+    }
+
+    return val;
+}
+
+// ---------------------------------------------------------------------------
+// Implementation of xstrtod
+
+//
+// strtod.c
+//
+// Convert string to double
+//
+// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+//    may be used to endorse or promote products derived from this software
+//    without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// -----------------------------------------------------------------------
+// Modifications by Warren Weckesser, March 2011:
+// * Rename strtod() to xstrtod().
+// * Added decimal and sci arguments.
+// * Skip trailing spaces.
+// * Commented out the other functions.
+// Modifications by Richard T Guy, August 2013:
+// * Add tsep argument for thousands separator
+// Modifications by Michael Mueller, August 2014:
+// * Cache powers of 10 in memory to avoid rounding errors
+// * Stop parsing decimals after 17 significant figures
+//
+
+double xstrtod(const char *str, char **endptr, char decimal,
+               char sci, char tsep, int skip_trailing)
+{
+    double number;
+    int exponent;
+    int negative;
+    char *p = (char *) str;
+    int num_digits;
+    int num_decimals;
+    int max_digits = 17;
+    int n;
+    // Cache powers of 10 in memory
+    static double e[] = {1., 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
+                         1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20,
+                         1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30,
+                         1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 1e40,
+                         1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50,
+                         1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59, 1e60,
+                         1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 1e70,
+                         1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 1e80,
+                         1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 1e90,
+                         1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 1e100,
+                         1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 1e110,
+                         1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 1e120,
+                         1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 1e130,
+                         1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 1e140,
+                         1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 1e150,
+                         1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 1e160,
+                         1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, 1e170,
+                         1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, 1e180,
+                         1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, 1e190,
+                         1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, 1e200,
+                         1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, 1e210,
+                         1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, 1e220,
+                         1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, 1e230,
+                         1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, 1e240,
+                         1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, 1e250,
+                         1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, 1e260,
+                         1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, 1e270,
+                         1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, 1e280,
+                         1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, 1e290,
+                         1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, 1e300,
+                         1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308};
+    errno = 0;
+
+    // Skip leading whitespace
+    while (isspace(*p)) p++;
+
+    // Handle optional sign
+    negative = 0;
+    switch (*p)
+    {
+    case '-': negative = 1; // Fall through to increment position
+    case '+': p++;
+    }
+
+    number = 0.;
+    exponent = 0;
+    num_digits = 0;
+    num_decimals = 0;
+
+    // Process string of digits
+    while (isdigit(*p))
+    {
+        if (num_digits < max_digits)
+        {
+            number = number * 10. + (*p - '0');
+            num_digits++;
+        }
+        else
+            ++exponent;
+
+        p++;
+        p += (tsep != '\0' && *p == tsep);
+    }
+
+    // Process decimal part
+    if (*p == decimal)
+    {
+        p++;
+
+        while (num_digits < max_digits && isdigit(*p))
+        {
+            number = number * 10. + (*p - '0');
+            p++;
+            num_digits++;
+            num_decimals++;
+        }
+
+        if (num_digits >= max_digits) // consume extra decimal digits
+            while (isdigit(*p))
+                ++p;
+
+        exponent -= num_decimals;
+    }
+
+    if (num_digits == 0)
+    {
+        errno = ERANGE;
+        return 0.0;
+    }
+
+    // Correct for sign
+    if (negative) number = -number;
+
+    // Process an exponent string
+    if (toupper(*p) == toupper(sci))
+    {
+        // Handle optional sign
+        negative = 0;
+        switch (*++p)
+        {
+        case '-': negative = 1;   // Fall through to increment pos
+        case '+': p++;
+        }
+
+        // Process string of digits
+        n = 0;
+        while (isdigit(*p))
+        {
+            n = n * 10 + (*p - '0');
+            p++;
+        }
+
+        if (negative)
+            exponent -= n;
+        else
+            exponent += n;
+    }
+
+    if (exponent > 308)
+    {
+        errno = ERANGE;
+        return HUGE_VAL;
+    }
+    else if (exponent > 0)
+        number *= e[exponent];
+    else if (exponent < -308) // subnormal
+    {
+        if (exponent < -616) // prevent invalid array access
+            number = 0.;
+        number /= e[-308 - exponent];
+        number /= e[308];
+    }
+    else
+        number /= e[-exponent];
+
+    if (number == HUGE_VAL || number == -HUGE_VAL)
+        errno = ERANGE;
+
+    if (skip_trailing) {
+        // Skip trailing whitespace
+        while (isspace(*p)) p++;
+    }
+
+    if (endptr) *endptr = p;
+    return number;
+}
+
+void start_iteration(tokenizer_t *self, int col)
+{
+    // Begin looping over the column string with index col
+    self->iter_col = col;
+    // Start at the initial pointer position
+    self->curr_pos = self->output_cols[col];
+}
+
+char *next_field(tokenizer_t *self, int *size)
+{
+    char *tmp = self->curr_pos;
+
+    // pass through the entire field until reaching the delimiter
+    while (*self->curr_pos != '\x00')
+	++self->curr_pos;
+
+    ++self->curr_pos; // next field begins after the delimiter
+
+    if (*tmp == '\x01') // empty field; this is a hack
+    {
+        if (size)
+            *size = 0;
+        return self->buf;
+    }
+
+    else
+    {
+        if (size)
+            *size = self->curr_pos - tmp - 1;
+        return tmp;
+    }
+}
+
+char *get_line(char *ptr, int *len, int map_len)
+{
+    int pos = 0;
+
+    while (pos < map_len)
+    {
+        if (ptr[pos] == '\r')
+        {
+            *len = pos;
+            // Windows line break (\r\n)
+            if (pos != map_len - 1 && ptr[pos + 1] == '\n')
+                return ptr + pos + 2; // skip newline character
+            else // Carriage return line break
+                return ptr + pos + 1;
+        }
+
+        else if (ptr[pos] == '\n')
+        {
+            *len = pos;
+            return ptr + pos + 1;
+        }
+
+        ++pos;
+    }
+
+    // done with input
+    return 0;
+}
+
+void reset_comments(tokenizer_t *self)
+{
+    free(self->comment_lines);
+    self->comment_pos = 0;
+    self->comment_lines_len = INITIAL_COMMENT_LEN;
+    self->comment_lines = (char *) malloc(INITIAL_COMMENT_LEN);
+}
diff --git a/astropy/io/ascii/src/tokenizer.h b/astropy/io/ascii/src/tokenizer.h
new file mode 100644
index 0000000..8a356b7
--- /dev/null
+++ b/astropy/io/ascii/src/tokenizer.h
@@ -0,0 +1,97 @@
+// Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+#ifndef TOKENIZER_H
+#define TOKENIZER_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+typedef enum
+{
+    START_LINE = 0,
+    START_FIELD,
+    START_QUOTED_FIELD,
+    FIELD,
+    QUOTED_FIELD,
+    QUOTED_FIELD_NEWLINE,
+    COMMENT,
+    CARRIAGE_RETURN
+} tokenizer_state;
+
+typedef enum
+{
+    NO_ERROR,
+    INVALID_LINE,
+    TOO_MANY_COLS,
+    NOT_ENOUGH_COLS,
+    CONVERSION_ERROR,
+    OVERFLOW_ERROR
+} err_code;
+
+typedef struct
+{
+    char *source;          // single string containing all of the input
+    int source_len;        // length of the input
+    int source_pos;        // current index in source for tokenization
+    char delimiter;        // delimiter character
+    char comment;          // comment character
+    char quotechar;        // quote character
+    char **output_cols;    // array of output strings for each column
+    char **col_ptrs;       // array of pointers to current output position for each col
+    int *output_len;       // length of each output column string
+    int num_cols;          // number of table columns
+    int num_rows;          // number of table rows
+    int fill_extra_cols;   // represents whether or not to fill rows with too few values
+    tokenizer_state state; // current state of the tokenizer
+    err_code code;         // represents the latest error that has occurred
+    int iter_col;          // index of the column being iterated over
+    char *curr_pos;        // current iteration position
+    char *buf;             // buffer for empty data
+    int strip_whitespace_lines;  // whether to strip whitespace at the beginning and end of lines
+    int strip_whitespace_fields; // whether to strip whitespace at the beginning and end of fields
+    int use_fast_converter;      // whether to use the fast converter for floats
+    char *comment_lines;   // single null-delimited string containing comment lines
+    int comment_lines_len; // length of comment_lines in memory
+    int comment_pos;       // current index in comment_lines
+} tokenizer_t;
+
+/*
+Example input/output
+--------------------
+
+source: "A,B,C\n10,5.,6\n1,2,3"
+output_cols: ["A\x0010\x001", "B\x005.\x002", "C\x006\x003"]
+*/
+
+#define INITIAL_COL_SIZE 500
+#define INITIAL_COMMENT_LEN 50
+
+tokenizer_t *create_tokenizer(char delimiter, char comment, char quotechar, int fill_extra_cols,
+                              int strip_whitespace_lines, int strip_whitespace_fields,
+                              int use_fast_converter);
+void delete_tokenizer(tokenizer_t *tokenizer);
+void delete_data(tokenizer_t *tokenizer);
+void resize_col(tokenizer_t *self, int index);
+void resize_comments(tokenizer_t *self);
+int skip_lines(tokenizer_t *self, int offset, int header);
+int tokenize(tokenizer_t *self, int end, int header, int num_cols);
+long str_to_long(tokenizer_t *self, char *str);
+double str_to_double(tokenizer_t *self, char *str);
+double xstrtod(const char *str, char **endptr, char decimal,
+               char sci, char tsep, int skip_trailing);
+void start_iteration(tokenizer_t *self, int col);
+char *next_field(tokenizer_t *self, int *size);
+long file_len(FILE *fhandle);
+char *get_line(char *ptr, int *len, int map_len);
+void reset_comments(tokenizer_t *self);
+
+#endif
diff --git a/astropy/io/ascii/tests/t/fixed_width_2_line.txt b/astropy/io/ascii/tests/t/fixed_width_2_line.txt
new file mode 100644
index 0000000..2d78258
--- /dev/null
+++ b/astropy/io/ascii/tests/t/fixed_width_2_line.txt
@@ -0,0 +1,4 @@
+Col1      Col2 Col3 Col4
+---- --------- ---- ----
+ 1.2   "hello"    1    a
+ 2.4 's worlds    2    2
diff --git a/astropy/io/ascii/tests/test_c_reader.py b/astropy/io/ascii/tests/test_c_reader.py
new file mode 100644
index 0000000..bedfc37
--- /dev/null
+++ b/astropy/io/ascii/tests/test_c_reader.py
@@ -0,0 +1,764 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+try:
+    from cStringIO import StringIO
+except ImportError: # cStringIO doesn't exist in Python 3
+    from io import BytesIO
+    StringIO = lambda x: BytesIO(x.encode('ascii'))
+from tempfile import NamedTemporaryFile
+import os
+
+import numpy as np
+from numpy import ma
+
+from ....table import Table, MaskedColumn
+from ... import ascii
+from ...ascii.core import ParameterError, FastOptionsError
+from ...ascii.cparser import CParserError
+from ..fastbasic import FastBasic, FastCsv, FastTab, FastCommentedHeader, \
+    FastRdb, FastNoHeader
+from .common import assert_equal, assert_almost_equal, assert_true
+from ....tests.helper import pytest
+from ....extern import six
+
+TRAVIS = os.environ.get('TRAVIS', False)
+pytestmark = pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
+
+def assert_table_equal(t1, t2, check_meta=False):
+    assert_equal(len(t1), len(t2))
+    assert_equal(t1.colnames, t2.colnames)
+    if check_meta:
+        assert_equal(t1.meta, t2.meta)
+    for name in t1.colnames:
+        if len(t1) != 0:
+            assert_equal(t1[name].dtype.kind, t2[name].dtype.kind)
+        if not isinstance(t1[name], MaskedColumn):
+            for i, el in enumerate(t1[name]):
+                try:
+                    if not isinstance(el, six.string_types) and np.isnan(el):
+                        assert_true(not isinstance(t2[name][i], six.string_types) and np.isnan(t2[name][i]))
+                    elif isinstance(el, six.string_types):
+                        assert_equal(el, t2[name][i])
+                    else:
+                        assert_almost_equal(el, t2[name][i])
+                except (TypeError, NotImplementedError):
+                    pass # ignore for now
+
+def _read(table, Reader, format, parallel=False, check_meta=False, **kwargs):
+    # make sure we have a newline so table can't be misinterpreted as a filename
+    table += '\n'
+    reader = Reader(**kwargs)
+    t1 = reader.read(table)
+    t2 = reader.read(StringIO(table))
+    t3 = reader.read(table.splitlines())
+    t4 = ascii.read(table, format=format, guess=False, **kwargs)
+    t5 = ascii.read(table, format=format, guess=False, fast_reader=False, **kwargs)
+    assert_table_equal(t1, t2, check_meta=check_meta)
+    assert_table_equal(t2, t3, check_meta=check_meta)
+    assert_table_equal(t3, t4, check_meta=check_meta)
+    assert_table_equal(t4, t5, check_meta=check_meta)
+
+    if parallel:
+        if TRAVIS:
+            pytest.xfail("Multiprocessing can sometimes fail on Travis CI")
+        elif os.name == 'nt':
+            pytest.xfail("Multiprocessing is currently unsupported on Windows")
+        t6 = ascii.read(table, format=format, guess=False, fast_reader={
+            'parallel': True}, **kwargs)
+        assert_table_equal(t1, t6, check_meta=check_meta)
+
+    with NamedTemporaryFile() as f:
+        f.write(table.encode('ascii'))
+        f.flush()
+        t7 = ascii.read(f.name, format=format, guess=False, **kwargs)
+        if parallel:
+            t8 = ascii.read(f.name, format=format, guess=False, fast_reader={
+                'parallel': True}, **kwargs)
+
+    assert_table_equal(t1, t7, check_meta=check_meta)
+    if parallel:
+        assert_table_equal(t1, t8, check_meta=check_meta)
+    return t1
+
+def read_basic(table, **kwargs):
+    return _read(table, FastBasic, 'basic', **kwargs)
+
+def read_csv(table, **kwargs):
+    return _read(table, FastCsv, 'csv', **kwargs)
+
+def read_tab(table, **kwargs):
+    return _read(table, FastTab, 'tab', **kwargs)
+
+def read_commented_header(table, **kwargs):
+    return _read(table, FastCommentedHeader, 'commented_header', **kwargs)
+
+def read_rdb(table, **kwargs):
+    return _read(table, FastRdb, 'rdb', **kwargs)
+
+def read_no_header(table, **kwargs):
+    return _read(table, FastNoHeader, 'no_header', **kwargs)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_simple_data(parallel):
+    """
+    Make sure the fast reader works with basic input data.
+    """
+    table = read_basic("A B C\n1 2 3\n4 5 6", parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+def test_read_types():
+    """
+    Make sure that the read() function takes filenames,
+    strings, and lists of strings in addition to file-like objects.
+    """
+    t1 = ascii.read("a b c\n1 2 3\n4 5 6", format='fast_basic', guess=False)
+    #TODO: also read from file
+    t2 = ascii.read(StringIO("a b c\n1 2 3\n4 5 6"), format='fast_basic', guess=False)
+    t3 = ascii.read(["a b c", "1 2 3", "4 5 6"], format='fast_basic', guess=False)
+    assert_table_equal(t1, t2)
+    assert_table_equal(t2, t3)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_supplied_names(parallel):
+    """
+    If passed as a parameter, names should replace any
+    column names found in the header.
+    """
+    table = read_basic("A B C\n1 2 3\n4 5 6", names=('X', 'Y', 'Z'), parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('X', 'Y', 'Z'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_no_header(parallel):
+    """
+    The header should not be read when header_start=None. Unless names is
+    passed, the column names should be auto-generated.
+    """
+    t1 = read_basic("A B C\n1 2 3\n4 5 6", header_start=None, data_start=0, parallel=parallel)
+    t2 = read_no_header("A B C\n1 2 3\n4 5 6", parallel=parallel)
+    expected = Table([['A', '1', '4'], ['B', '2', '5'], ['C', '3', '6']], names=('col1', 'col2', 'col3'))
+    assert_table_equal(t1, expected)
+    assert_table_equal(t2, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_no_header_supplied_names(parallel):
+    """
+    If header_start=None and names is passed as a parameter, header
+    data should not be read and names should be used instead.
+    """
+    table = read_basic("A B C\n1 2 3\n4 5 6", header_start=None, data_start=0,
+                       names=('X', 'Y', 'Z'), parallel=parallel)
+    expected = Table([['A', '1', '4'], ['B', '2', '5'], ['C', '3', '6']], names=('X', 'Y', 'Z'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_comment(parallel):
+    """
+    Make sure that line comments are ignored by the C reader.
+    """
+    table = read_basic("# comment\nA B C\n # another comment\n1 2 3\n4 5 6", parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_empty_lines(parallel):
+    """
+    Make sure that empty lines are ignored by the C reader.
+    """
+    table = read_basic("\n\nA B C\n1 2 3\n\n\n4 5 6\n\n\n\n", parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_lstrip_whitespace(parallel):
+    """
+    Test to make sure the reader ignores whitespace at the beginning of fields.
+    """
+    text = """
+     1,  2,   \t3
+ A,\t\t B,  C
+  a, b,   c
+""" + '  \n'
+
+    table = read_basic(text, delimiter=',', parallel=parallel)
+    expected = Table([['A', 'a'], ['B', 'b'], ['C', 'c']], names=('1', '2', '3'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_rstrip_whitespace(parallel):
+    """
+    Test to make sure the reader ignores whitespace at the end of fields.
+    """
+    text = ' 1 ,2 \t,3  \nA\t,B ,C\t \t \n  \ta ,b , c \n'
+    table = read_basic(text, delimiter=',', parallel=parallel)
+    expected = Table([['A', 'a'], ['B', 'b'], ['C', 'c']], names=('1', '2', '3'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_conversion(parallel):
+    """
+    The reader should try to convert each column to ints. If this fails, the
+    reader should try to convert to floats. Failing this, it should fall back
+    to strings.
+    """
+    text = """
+A B C D E
+1 a 3 4 5
+2. 1 9 10 -5.3e4
+4 2 -12 .4 six
+"""
+    table = read_basic(text, parallel=parallel)
+    assert_equal(table['A'].dtype.kind, 'f')
+    assert table['B'].dtype.kind in ('S', 'U')
+    assert_equal(table['C'].dtype.kind, 'i')
+    assert_equal(table['D'].dtype.kind, 'f')
+    assert table['E'].dtype.kind in ('S', 'U')
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_delimiter(parallel):
+    """
+    Make sure that different delimiters work as expected.
+    """
+    text = """
+COL1 COL2 COL3
+1 A -1
+2 B -2
+"""
+    expected = Table([[1, 2], ['A', 'B'], [-1, -2]], names=('COL1', 'COL2', 'COL3'))
+
+    for sep in ' ,\t#;':
+        table = read_basic(text.replace(' ', sep), delimiter=sep, parallel=parallel)
+        assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_include_names(parallel):
+    """
+    If include_names is not None, the parser should read only those columns in include_names.
+    """
+    table = read_basic("A B C D\n1 2 3 4\n5 6 7 8", include_names=['A', 'D'], parallel=parallel)
+    expected = Table([[1, 5], [4, 8]], names=('A', 'D'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_exclude_names(parallel):
+    """
+    If exclude_names is not None, the parser should exclude the columns in exclude_names.
+    """
+    table = read_basic("A B C D\n1 2 3 4\n5 6 7 8", exclude_names=['A', 'D'], parallel=parallel)
+    expected = Table([[2, 6], [3, 7]], names=('B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_include_exclude_names(parallel):
+    """
+    Make sure that include_names is applied before exclude_names if both are specified.
+    """
+    text = """
+A B C D E F G H
+1 2 3 4 5 6 7 8
+9 10 11 12 13 14 15 16
+"""
+    table = read_basic(text, include_names=['A', 'B', 'D', 'F', 'H'],
+                       exclude_names=['B', 'F'], parallel=parallel)
+    expected = Table([[1, 9], [4, 12], [8, 16]], names=('A', 'D', 'H'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_quoted_fields(parallel):
+    """
+    The character quotechar (default '"') should denote the start of a field which can
+    contain the field delimiter and newlines.
+    """
+    if parallel:
+        pytest.xfail("Multiprocessing can fail with quoted fields")
+    text = """
+"A B" C D
+1.5 2.1 -37.1
+a b "   c
+ d"
+"""
+    table = read_basic(text, parallel=parallel)
+    expected = Table([['1.5', 'a'], ['2.1', 'b'], ['-37.1', 'cd']], names=('A B', 'C', 'D'))
+    assert_table_equal(table, expected)
+    table = read_basic(text.replace('"', "'"), quotechar="'", parallel=parallel)
+    assert_table_equal(table, expected)
+
+def test_invalid_parameters():
+    """
+    Make sure the C reader raises an error if passed parameters it can't handle.
+    """
+    int_converter = ascii.convert_numpy(np.uint)
+    converters = dict((i + 1, ascii.convert_numpy(np.uint)) for i in range(3))
+    invalid_params = {'delimiter': ',,', # multi-char delimiter
+                      'comment': '##', # multi-char comment
+                      'data_start': None, # data_start=None
+                      'quotechar': '##', # multi-char quote signifier
+                      'data_start': -1, # negative data_start
+                      'header_start': -1, # negative header_start
+                      'converters': converters, # passing converters
+                      'Inputter': ascii.ContinuationLinesInputter, # passing Inputter
+                      'header_Splitter': ascii.DefaultSplitter, # passing Splitter
+                      'data_Splitter': ascii.DefaultSplitter
+                      }
+    for key, val in invalid_params.items():
+        with pytest.raises(ParameterError):
+            print('Trying {0}={1} using constructor'.format(key, val))
+            table = FastBasic(**{key: val}).read('1 2 3\n4 5 6')
+        with pytest.raises(ParameterError):
+            print('Trying {0}={1} using ascii.read'.format(key, val))
+            table = ascii.read('1 2 3\n4 5 6', format='fast_basic', guess=False, **{key: val})
+
+    with pytest.raises(TypeError):
+        table = FastBasic(foo=7).read('1 2 3\n4 5 6') # unexpected argument
+    with pytest.raises(FastOptionsError): # don't fall back on the slow reader
+        table = ascii.read('1 2 3\n4 5 6', format='basic', fast_reader={'foo': 7})
+    with pytest.raises(ParameterError):
+        # Outputter cannot be specified in constructor
+        table = FastBasic(Outputter=ascii.TableOutputter).read('1 2 3\n4 5 6')
+
+def test_too_many_cols():
+    """
+    If a row contains too many columns, the C reader should raise an error.
+    """
+    text = """
+A B C
+1 2 3
+4 5 6
+7 8 9 10
+11 12 13
+"""
+    with pytest.raises(CParserError) as e:
+        table = FastBasic().read(text)
+    assert 'CParserError: an error occurred while parsing table data: too many ' \
+        'columns found in line 3 of data' in str(e)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_not_enough_cols(parallel):
+    """
+    If a row does not have enough columns, the FastCsv reader should add empty
+    fields while the FastBasic reader should raise an error.
+    """
+    text = """
+A,B,C
+1,2,3
+4,5
+6,7,8
+"""
+    table = read_csv(text, parallel=parallel)
+    assert table['B'][1] is not ma.masked
+    assert table['C'][1] is ma.masked
+
+    with pytest.raises(CParserError) as e:
+        table = FastBasic(delimiter=',').read(text)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_data_end(parallel):
+    """
+    The parameter data_end should specify where data reading ends.
+    """
+    text = """
+A B C
+1 2 3
+4 5 6
+7 8 9
+10 11 12
+"""
+    table = read_basic(text, data_end=3, parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    # data_end supports negative indexing
+    table = read_basic(text, data_end=-2, parallel=parallel)
+    assert_table_equal(table, expected)
+
+    text = """
+A\tB\tC
+N\tN\tS
+1\t2\ta
+3\t4\tb
+5\t6\tc
+"""
+    # make sure data_end works with RDB
+    table = read_rdb(text, data_end=-1, parallel=parallel)
+    expected = Table([[1, 3], [2, 4], ['a', 'b']], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    # positive index
+    table = read_rdb(text, data_end=3, parallel=parallel)
+    expected = Table([[1], [2], ['a']], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    # empty table if data_end is too small
+    table = read_rdb(text, data_end=1, parallel=parallel)
+    expected = Table([[], [], []], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_fill_values(parallel):
+    """
+    Make sure that the parameter fill_values works as intended. If fill_values
+    is not specified, the default behavior should be to convert '' to 0.
+    """
+    text = """
+A, B, C
+, 2, nan
+a, -999, -3.4
+nan, 5, -9999
+8, nan, 7.6e12
+"""
+    table = read_basic(text, delimiter=',', parallel=parallel)
+    # The empty value in row A should become a masked '0'
+    assert isinstance(table['A'], MaskedColumn)
+    assert table['A'][0] is ma.masked
+    # '0' rather than 0 because there is a string in the column
+    assert_equal(table['A'].data.data[0], '0')
+    assert table['A'][1] is not ma.masked
+
+    table = read_basic(text, delimiter=',', fill_values=('-999', '0'), parallel=parallel)
+    assert isinstance(table['B'], MaskedColumn)
+    assert table['A'][0] is not ma.masked # empty value unaffected
+    assert table['C'][2] is not ma.masked # -9999 is not an exact match
+    assert table['B'][1] is ma.masked
+    # Numeric because the rest of the column contains numeric data
+    assert_equal(table['B'].data.data[1], 0.0)
+    assert table['B'][0] is not ma.masked
+
+    table = read_basic(text, delimiter=',', fill_values=[], parallel=parallel)
+    # None of the columns should be masked
+    for name in 'ABC':
+        assert not isinstance(table[name], MaskedColumn)
+
+    table = read_basic(text, delimiter=',', fill_values=[('', '0', 'A'),
+                                ('nan', '999', 'A', 'C')], parallel=parallel)
+    assert np.isnan(table['B'][3]) # nan filling skips column B
+    assert table['B'][3] is not ma.masked # should skip masking as well as replacing nan
+    assert table['A'][0] is ma.masked
+    assert table['A'][2] is ma.masked
+    assert_equal(table['A'].data.data[0], '0')
+    assert_equal(table['A'].data.data[2], '999')
+    assert table['C'][0] is ma.masked
+    assert_almost_equal(table['C'].data.data[0], 999.0)
+    assert_almost_equal(table['C'][1], -3.4) # column is still of type float
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_fill_include_exclude_names(parallel):
+    """
+    fill_include_names and fill_exclude_names should filter missing/empty value handling
+    in the same way that include_names and exclude_names filter output columns.
+    """
+    text = """
+A, B, C
+, 1, 2
+3, , 4
+5, 5,
+"""
+    table = read_csv(text, fill_include_names=['A', 'B'], parallel=parallel)
+    assert table['A'][0] is ma.masked
+    assert table['B'][1] is ma.masked
+    assert table['C'][2] is not ma.masked # C not in fill_include_names
+
+    table = read_csv(text, fill_exclude_names=['A', 'B'], parallel=parallel)
+    assert table['C'][2] is ma.masked
+    assert table['A'][0] is not ma.masked
+    assert table['B'][1] is not ma.masked # A and B excluded from fill handling
+
+    table = read_csv(text, fill_include_names=['A', 'B'], fill_exclude_names=['B'], parallel=parallel)
+    assert table['A'][0] is ma.masked
+    assert table['B'][1] is not ma.masked # fill_exclude_names applies after fill_include_names
+    assert table['C'][2] is not ma.masked
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_many_rows(parallel):
+    """
+    Make sure memory reallocation works okay when the number of rows
+    is large (so that each column string is longer than INITIAL_COL_SIZE).
+    """
+    text = 'A B C\n'
+    for i in range(500): # create 500 rows
+        text += ' '.join([str(i) for i in range(3)])
+        text += '\n'
+
+    table = read_basic(text, parallel=parallel)
+    expected = Table([[0] * 500, [1] * 500, [2] * 500], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_many_columns(parallel):
+    """
+    Make sure memory reallocation works okay when the number of columns
+    is large (so that each hedaer string is longer than INITIAL_HEADER_SIZE).
+    """
+    # create a string with 500 columns and two data rows
+    text = ' '.join([str(i) for i in range(500)])
+    text += ('\n' + text + '\n' + text)
+    table = read_basic(text, parallel=parallel)
+    expected = Table([[i, i] for i in range(500)], names=[str(i) for i in range(500)])
+    assert_table_equal(table, expected)
+
+def test_fast_reader():
+    """
+    Make sure that ascii.read() works as expected by default and with
+    fast_reader specified.
+    """
+    text = 'a b c\n1 2 3\n4 5 6'
+    with pytest.raises(ParameterError): # C reader can't handle regex comment
+        ascii.read(text, format='fast_basic', guess=False, comment='##')
+
+    # Enable multiprocessing and the fast converter
+    ascii.read(text, format='basic', guess=False, fast_reader={'parallel': True,
+                                                    'use_fast_converter': True})
+    # Should raise an error if fast_reader has an invalid key
+    with pytest.raises(FastOptionsError):
+        ascii.read(text, format='fast_basic', guess=False, fast_reader={'foo': True})
+
+    # Use the slow reader instead
+    ascii.read(text, format='basic', guess=False, comment='##', fast_reader=False)
+    # Will try the slow reader afterwards by default
+    ascii.read(text, format='basic', guess=False, comment='##')
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_read_tab(parallel):
+    """
+    The fast reader for tab-separated values should not strip whitespace, unlike
+    the basic reader.
+    """
+    if parallel:
+        pytest.xfail("Multiprocessing can fail with quoted fields")
+    text = '1\t2\t3\n  a\t b \t\n c\t" d\n e"\t  '
+    table = read_tab(text, parallel=parallel)
+    assert_equal(table['1'][0], '  a')   # preserve line whitespace
+    assert_equal(table['2'][0], ' b ')   # preserve field whitespace
+    assert table['3'][0] is ma.masked    # empty value should be masked
+    assert_equal(table['2'][1], ' d e')  # preserve whitespace in quoted fields
+    assert_equal(table['3'][1], '  ')    # preserve end-of-line whitespace
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_default_data_start(parallel):
+    """
+    If data_start is not explicitly passed to read(), data processing should
+    beginning right after the header.
+    """
+    text = 'ignore this line\na b c\n1 2 3\n4 5 6'
+    table = read_basic(text, header_start=1, parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('a', 'b', 'c'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_commented_header(parallel):
+    """
+    The FastCommentedHeader reader should mimic the behavior of the
+    CommentedHeader by overriding the default header behavior of FastBasic.
+    """
+    text = """
+ # A B C
+ 1 2 3
+ 4 5 6
+"""
+    t1 = read_commented_header(text, parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C'))
+    assert_table_equal(t1, expected)
+
+    text = '# first commented line\n # second commented line\n\n' + text
+    t2 = read_commented_header(text, header_start=2, data_start=0, parallel=parallel)
+    assert_table_equal(t2, expected)
+    t3 = read_commented_header(text, header_start=-1, data_start=0, parallel=parallel) # negative indexing allowed
+    assert_table_equal(t3, expected)
+
+    text += '7 8 9'
+    t4 = read_commented_header(text, header_start=2, data_start=2, parallel=parallel)
+    expected = Table([[7], [8], [9]], names=('A', 'B', 'C'))
+    assert_table_equal(t4, expected)
+
+    with pytest.raises(ParameterError):
+        read_commented_header(text, header_start=-1, data_start=-1, parallel=parallel) # data_start cannot be negative
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_rdb(parallel):
+    """
+    Make sure the FastRdb reader works as expected.
+    """
+    text = """
+
+A\tB\tC
+1n\tS\t4N
+1\t 9\t4.3
+"""
+    table = read_rdb(text, parallel=parallel)
+    expected = Table([[1], [' 9'], [4.3]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+    assert_equal(table['A'].dtype.kind, 'i')
+    assert table['B'].dtype.kind in ('S', 'U')
+    assert_equal(table['C'].dtype.kind, 'f')
+
+    with pytest.raises(ValueError) as e:
+        text = 'A\tB\tC\nN\tS\tN\n4\tb\ta' # C column contains non-numeric data
+        read_rdb(text, parallel=parallel)
+    assert 'Column C failed to convert' in str(e)
+
+    with pytest.raises(ValueError) as e:
+        text = 'A\tB\tC\nN\tN\n1\t2\t3' # not enough types specified
+        read_rdb(text, parallel=parallel)
+    assert 'mismatch between number of column names and column types' in str(e)
+
+    with pytest.raises(ValueError) as e:
+        text = 'A\tB\tC\nN\tN\t5\n1\t2\t3' # invalid type for column C
+        read_rdb(text, parallel=parallel)
+    assert 'type definitions do not all match [num](N|S)' in str(e)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_data_start(parallel):
+    """
+    Make sure that data parsing begins at data_start (ignoring empty and
+    commented lines but not taking quoted values into account).
+    """
+    if parallel:
+        pytest.xfail("Multiprocessing can fail with quoted fields")
+    text = """
+A B C
+1 2 3
+4 5 6
+
+7 8 "9
+ \t1"
+# comment
+10 11 12
+"""
+    table = read_basic(text, data_start=2, parallel=parallel)
+    expected = Table([[4, 7, 10], [5, 8, 11], [6, 91, 12]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    table = read_basic(text, data_start=3, parallel=parallel)
+    # ignore empty line
+    expected = Table([[7, 10], [8, 11], [91, 12]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    with pytest.raises(CParserError) as e:
+        # tries to begin in the middle of quoted field
+        read_basic(text, data_start=4, parallel=parallel)
+    assert 'not enough columns found in line 1 of data' in str(e)
+
+    table = read_basic(text, data_start=5, parallel=parallel)
+    # ignore commented line
+    expected = Table([[10], [11], [12]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+    text = """
+A B C
+1 2 3
+4 5 6
+
+7 8 9
+# comment
+10 11 12
+"""
+    # make sure reading works as expected in parallel
+    table = read_basic(text, data_start=2, parallel=parallel)
+    expected = Table([[4, 7, 10], [5, 8, 11], [6, 9, 12]], names=('A', 'B', 'C'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_quoted_empty_values(parallel):
+    """
+    Quoted empty values spanning multiple lines should be treated correctly.
+    """
+    if parallel:
+        pytest.xfail("Multiprocessing can fail with quoted fields")
+    text = 'a b c\n1 2 " \n "'
+    table = read_basic(text, parallel=parallel)
+    assert table['c'][0] is ma.masked # empty value masked by default
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_csv_comment_default(parallel):
+    """
+    Unless the comment parameter is specified, the CSV reader should
+    not treat any lines as comments.
+    """
+    text = 'a,b,c\n#1,2,3\n4,5,6'
+    table = read_csv(text, parallel=parallel)
+    expected = Table([['#1', '4'], [2, 5], [3, 6]], names=('a', 'b', 'c'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_whitespace_before_comment(parallel):
+    """
+    Readers that don't strip whitespace from data (Tab, RDB)
+    should still treat lines with leading whitespace and then
+    the comment char as comment lines.
+    """
+    text = 'a\tb\tc\n # comment line\n1\t2\t3'
+    table = read_tab(text, parallel=parallel)
+    expected = Table([[1], [2], [3]], names=('a', 'b', 'c'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_strip_line_trailing_whitespace(parallel):
+    """
+    Readers that strip whitespace from lines should ignore
+    trailing whitespace after the last data value of each
+    row.
+    """
+    text = 'a b c\n1 2 \n3 4 5'
+    with pytest.raises(CParserError) as e:
+        ascii.read(StringIO(text), format='fast_basic', guess=False)
+    assert 'not enough columns found in line 1' in str(e)
+
+    text = 'a b c\n 1 2 3   \t \n 4 5 6 '
+    table = read_basic(text, parallel=parallel)
+    expected = Table([[1, 4], [2, 5], [3, 6]], names=('a', 'b', 'c'))
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_no_data(parallel):
+    """
+    As long as column names are supplied, the C reader
+    should return an empty table in the absence of data.
+    """
+    table = read_basic('a b c', parallel=parallel)
+    expected = Table([[], [], []], names=('a', 'b', 'c'))
+    assert_table_equal(table, expected)
+
+    table = read_basic('a b c\n1 2 3', data_start=2, parallel=parallel)
+    assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_line_endings(parallel):
+    """
+    Make sure the fast reader accepts CR and CR+LF
+    as newlines.
+    """
+    text = 'a b c\n1 2 3\n4 5 6\n7 8 9\n'
+    expected = Table([[1, 4, 7], [2, 5, 8], [3, 6, 9]], names=('a', 'b', 'c'))
+
+    for newline in ('\r\n', '\r'):
+        table = read_basic(text.replace('\n', newline), parallel=parallel)
+        assert_table_equal(table, expected)
+
+    # Make sure the splitlines() method of FileString
+    # works with CR/CR+LF line endings
+    text = '#' + text
+    for newline in ('\r\n', '\r'):
+        table = read_commented_header(text.replace('\n', newline), parallel=parallel)
+        assert_table_equal(table, expected)
+    text = 'a\tb\tc\nN\tN\tN\n1\t2\t3\n4\t5\t6\n7\t8\t9\n'
+    for newline in ('\r\n', '\r'):
+        table = read_rdb(text.replace('\n', newline), parallel=parallel)
+        assert_table_equal(table, expected)
+
+ at pytest.mark.parametrize("parallel", [True, False])
+def test_store_comments(parallel):
+    """
+    Make sure that the output Table produced by the fast
+    reader stores any comment lines in its meta attribute.
+    """
+    text = """
+# header comment
+a b c
+# comment 2
+# comment 3
+1 2 3
+4 5 6
+"""
+    table = read_basic(text, parallel=parallel, check_meta=True)
+    assert_equal(table.meta['comments'],
+                 ['header comment', 'comment 2', 'comment 3'])
diff --git a/astropy/io/ascii/tests/test_compressed.py b/astropy/io/ascii/tests/test_compressed.py
index 27724d6..b5442be 100644
--- a/astropy/io/ascii/tests/test_compressed.py
+++ b/astropy/io/ascii/tests/test_compressed.py
@@ -22,7 +22,7 @@ def test_gzip(filename):
     t_comp = read(os.path.join(ROOT, filename))
     t_uncomp = read(os.path.join(ROOT, filename.replace('.gz', '')))
     assert t_comp.dtype.names == t_uncomp.dtype.names
-    assert np.all(t_comp._data == t_uncomp._data)
+    assert np.all(t_comp.as_array() == t_uncomp.as_array())
 
 
 @pytest.mark.xfail('not HAS_BZ2')
@@ -31,4 +31,4 @@ def test_bzip2(filename):
     t_comp = read(os.path.join(ROOT, filename))
     t_uncomp = read(os.path.join(ROOT, filename.replace('.bz2', '')))
     assert t_comp.dtype.names == t_uncomp.dtype.names
-    assert np.all(t_comp._data == t_uncomp._data)
+    assert np.all(t_comp.as_array() == t_uncomp.as_array())
diff --git a/astropy/io/ascii/tests/test_connect.py b/astropy/io/ascii/tests/test_connect.py
index 23fad3c..22419d8 100644
--- a/astropy/io/ascii/tests/test_connect.py
+++ b/astropy/io/ascii/tests/test_connect.py
@@ -16,7 +16,7 @@ try:
     HAS_BEAUTIFUL_SOUP = True
 except ImportError:
     HAS_BEAUTIFUL_SOUP = False
-    
+
 if HAS_BEAUTIFUL_SOUP:
     files.append('t/html.html')
 
@@ -120,13 +120,20 @@ def test_write_rdb_noformat(tmpdir):
 
 
 def test_read_csv():
-    Table.read(os.path.join(ROOT, 't/simple_csv.csv'), format='ascii.csv')
+    '''If properly registered, filename should be sufficient to specify format
+
+    #3189
+    '''
+    Table.read(os.path.join(ROOT, 't/simple_csv.csv'))
 
 
 def test_write_csv(tmpdir):
+    '''If properly registered, filename should be sufficient to specify format
+
+    #3189
+    '''
     t = Table()
     t.add_column(Column(name='a', data=[1, 2, 3]))
     t.add_column(Column(name='b', data=['a', 'b', 'c']))
     path = str(tmpdir.join("data.csv"))
-    t.write(path, format='ascii.csv')
-
+    t.write(path)
diff --git a/astropy/io/ascii/tests/test_ecsv.py b/astropy/io/ascii/tests/test_ecsv.py
new file mode 100644
index 0000000..b120672
--- /dev/null
+++ b/astropy/io/ascii/tests/test_ecsv.py
@@ -0,0 +1,176 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+This module tests some of the methods related to the ``ECSV``
+reader/writer.
+
+Requires `pyyaml <http://pyyaml.org/>`_ to be installed.
+"""
+import os
+import copy
+
+import numpy as np
+
+from ....table import Table, Column
+from ....table.table_helpers import simple_table
+
+from ....tests.helper import pytest
+from ....extern.six.moves import StringIO
+from ..ecsv import DELIMITERS
+from ... import ascii
+
+try:
+    import yaml
+    HAS_YAML = True
+except ImportError:
+    HAS_YAML = False
+
+DTYPES = ['bool', 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32',
+          'uint64', 'float16', 'float32', 'float64', 'float128',
+          'str']
+if os.name == 'nt':
+    DTYPES.remove('float128')
+
+T_DTYPES = Table()
+
+for dtype in DTYPES:
+    if dtype == 'bool':
+        data = np.array([False, True, False])
+    elif dtype == 'str':
+        data = np.array(['ab 0', 'ab, 1', 'ab2'])
+    else:
+        data = np.arange(3, dtype=dtype)
+    c = Column(data, unit='m / s', description='descr_' + dtype,
+               meta={'meta ' + dtype: 1})
+    T_DTYPES[dtype] = c
+
+T_DTYPES.meta['comments'] = ['comment1', 'comment2']
+
+# Corresponds to simple_table()
+SIMPLE_LINES = ['# %ECSV 0.9',
+                '# ---',
+                '# datatype:',
+                '# - {name: a, datatype: int32}',
+                '# - {name: b, datatype: float32}',
+                '# - {name: c, datatype: string}',
+                'a b c',
+                '1 1.0 c',
+                '2 2.0 d',
+                '3 3.0 e']
+
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_write_simple():
+    """
+    Write a simple table with common types.  This shows the compact version
+    of serialization with one line per column.
+    """
+    t = simple_table()
+
+    out = StringIO()
+    t.write(out, format='ascii.ecsv')
+    assert out.getvalue().splitlines() == SIMPLE_LINES
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_write_full():
+    """
+    Write a full-featured table with common types and explicitly checkout output
+    """
+    t = T_DTYPES['bool', 'int64', 'float64', 'str']
+    lines = ['# %ECSV 0.9',
+             '# ---',
+             '# datatype:',
+             '# - name: bool',
+             '#   unit: m / s',
+             '#   datatype: bool',
+             '#   description: descr_bool',
+             '#   meta: {meta bool: 1}',
+             '# - name: int64',
+             '#   unit: m / s',
+             '#   datatype: int64',
+             '#   description: descr_int64',
+             '#   meta: {meta int64: 1}',
+             '# - name: float64',
+             '#   unit: m / s',
+             '#   datatype: float64',
+             '#   description: descr_float64',
+             '#   meta: {meta float64: 1}',
+             '# - name: str',
+             '#   unit: m / s',
+             '#   datatype: string',
+             '#   description: descr_str',
+             '#   meta: {meta str: 1}',
+             '# meta: !!omap',
+             '# - comments: [comment1, comment2]',
+             'bool int64 float64 str',
+             'False 0 0.0 "ab 0"',
+             'True 1 1.0 "ab, 1"',
+             'False 2 2.0 ab2']
+
+    out = StringIO()
+    t.write(out, format='ascii.ecsv')
+    assert out.getvalue().splitlines() == lines
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_write_read_roundtrip():
+    """
+    Write a full-featured table with all types and see that it round-trips on
+    readback.  Use both space and comma delimiters.
+    """
+    t = T_DTYPES
+    for delimiter in DELIMITERS:
+        out = StringIO()
+        t.write(out, format='ascii.ecsv', delimiter=delimiter)
+
+        t2s  = [Table.read(out.getvalue(), format='ascii.ecsv'),
+                Table.read(out.getvalue(), format='ascii'),
+                ascii.read(out.getvalue()),
+                ascii.read(out.getvalue(), format='ecsv', guess=False),
+                ascii.read(out.getvalue(), format='ecsv')]
+        for t2 in t2s:
+            assert t.meta == t2.meta
+            for name in t.colnames:
+                assert t[name].attrs_equal(t2[name])
+                assert np.all(t[name] == t2[name])
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_bad_delimiter():
+    """
+    Passing a delimiter other than space or comma gives an exception
+    """
+    out = StringIO()
+    with pytest.raises(ValueError) as err:
+        T_DTYPES.write(out, format='ascii.ecsv', delimiter='|')
+    assert 'only space and comma are allowed' in str(err.value)
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_bad_header_start():
+    """
+    Bad header without initial # %ECSV x.x
+    """
+    lines = copy.copy(SIMPLE_LINES)
+    lines[0]  = '# %ECV 0.9'
+    with pytest.raises(ascii.InconsistentTableError):
+        Table.read('\n'.join(lines), format='ascii.ecsv', guess=False)
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_bad_delimiter_input():
+    """
+    Illegal delimiter in input
+    """
+    lines = copy.copy(SIMPLE_LINES)
+    lines.insert(2, '# delimiter: |')
+    with pytest.raises(ValueError) as err:
+        Table.read('\n'.join(lines), format='ascii.ecsv', guess=False)
+    assert 'only space and comma are allowed' in str(err.value)
+
+ at pytest.mark.skipif('not HAS_YAML')
+def test_multidim_input():
+    """
+    Multi-dimensional column in input
+    """
+    t = Table([np.arange(4).reshape(2, 2)], names=['a'])
+    out = StringIO()
+    with pytest.raises(ValueError) as err:
+        t.write(out, format='ascii.ecsv')
+    assert 'ECSV format does not support multidimensional column' in str(err.value)
diff --git a/astropy/io/ascii/tests/test_fixedwidth.py b/astropy/io/ascii/tests/test_fixedwidth.py
index 5d3878c..a252458 100644
--- a/astropy/io/ascii/tests/test_fixedwidth.py
+++ b/astropy/io/ascii/tests/test_fixedwidth.py
@@ -8,8 +8,10 @@ except ImportError:
     from io import StringIO
 
 from ... import ascii
+from ..core import InconsistentTableError
 from .common import (assert_equal, assert_almost_equal,
                      setup_function, teardown_function)
+from ....tests.helper import pytest
 
 
 def assert_equal_splitlines(arg1, arg2):
@@ -384,6 +386,42 @@ def test_read_twoline_human():
     assert_equal(dat[1][1], "'s worlds")
 
 
+def test_read_twoline_fail():
+    """Test failure if too many different character are on position line.
+
+    The position line shall consist of only one character in addition to
+    the delimiter.
+    """
+    table = """
+| Col1 |   Col2   |
+|------|==========|
+|  1.2 | "hello"  |
+|  2.4 | 's worlds|
+"""
+    with pytest.raises(InconsistentTableError) as excinfo:
+        dat = ascii.read(table, Reader=ascii.FixedWidthTwoLine,
+                         delimiter='|', guess=False)
+    assert 'Position line should only contain delimiters and one other character' in str(excinfo.value)
+
+
+def test_read_twoline_wrong_marker():
+    '''Test failure when position line uses characters prone to ambiguity
+
+    Characters in position line must be part an allowed set because
+    normal letters or numbers will lead to ambiguous tables.
+    '''
+    table = """
+| Col1 |   Col2   |
+|aaaaaa|aaaaaaaaaa|
+|  1.2 | "hello"  |
+|  2.4 | 's worlds|
+"""
+    with pytest.raises(InconsistentTableError) as excinfo:
+        dat = ascii.read(table, Reader=ascii.FixedWidthTwoLine,
+                         delimiter='|', guess=False)
+    assert 'Characters in position line must be part' in str(excinfo.value)
+
+
 def test_write_twoline_normal():
     """Write a table as a normal fixed width table."""
     out = StringIO()
diff --git a/astropy/io/ascii/tests/test_html.py b/astropy/io/ascii/tests/test_html.py
index fd8b025..d398015 100644
--- a/astropy/io/ascii/tests/test_html.py
+++ b/astropy/io/ascii/tests/test_html.py
@@ -27,7 +27,7 @@ except ImportError:
 # Check to see if the BeautifulSoup dependency is present.
 
 try:
-    from bs4 import BeautifulSoup
+    from bs4 import BeautifulSoup, FeatureNotFound
     HAS_BEAUTIFUL_SOUP = True
 except ImportError:
     HAS_BEAUTIFUL_SOUP = False
@@ -37,19 +37,19 @@ def test_soupstring():
     """
     Test to make sure the class SoupString behaves properly.
     """
-    
-    soup = BeautifulSoup('<html><body><p>foo</p></body></html>')
+
+    soup = BeautifulSoup('<html><head></head><body><p>foo</p></body></html>')
     soup_str = html.SoupString(soup)
     assert isinstance(soup_str, str)
     assert isinstance(soup_str, html.SoupString)
-    assert soup_str == '<html><body><p>foo</p></body></html>'
+    assert soup_str == '<html><head></head><body><p>foo</p></body></html>'
     assert soup_str.soup is soup
 
 def test_listwriter():
     """
     Test to make sure the class ListWriter behaves properly.
     """
-    
+
     lst = []
     writer = html.ListWriter(lst)
 
@@ -174,6 +174,26 @@ def test_identify_table_fail():
     assert str(err).endswith("ERROR: HTML table number 3 not found")
 
 
+ at pytest.mark.skipif('not HAS_BEAUTIFUL_SOUP')
+def test_backend_parsers():
+    """
+    Make sure the user can specify which back-end parser to use
+    and that an error is raised if the parser is invalid.
+    """
+    for parser in ('lxml', 'xml', 'html.parser', 'html5lib'):
+        try:
+            table = Table.read('t/html2.html', format='ascii.html',
+                               htmldict={'parser': parser}, guess=False)
+        except FeatureNotFound:
+            if parser == 'html.parser':
+                raise
+            # otherwise ignore if the dependency isn't present
+
+    # reading should fail if the parser is invalid
+    with pytest.raises(FeatureNotFound):
+        Table.read('t/html2.html', format='ascii.html',
+                   htmldict={'parser': 'foo'}, guess=False)
+
 @pytest.mark.skipif('HAS_BEAUTIFUL_SOUP')
 def test_htmlinputter_no_bs4():
     """
@@ -184,7 +204,7 @@ def test_htmlinputter_no_bs4():
     inputter = html.HTMLInputter()
     with pytest.raises(core.OptionalTableImportError):
         inputter.process_lines([])
-    
+
 @pytest.mark.skipif('not HAS_BEAUTIFUL_SOUP')
 def test_htmlinputter():
     """
@@ -198,14 +218,14 @@ def test_htmlinputter():
 
     inputter = html.HTMLInputter()
     inputter.html = {}
-    
+
     # In absence of table_id, defaults to the first table
     expected = ['<tr><th>Column 1</th><th>Column 2</th><th>Column 3</th></tr>',
                 '<tr><td>1</td><td>a</td><td>1.05</td></tr>',
                 '<tr><td>2</td><td>b</td><td>2.75</td></tr>',
                 '<tr><td>3</td><td>c</td><td>-1.25</td></tr>']
     assert [str(x) for x in inputter.get_lines(table)] == expected
-    
+
     # Should raise an InconsistentTableError if the table is not found
     inputter.html = {'table_id': 4}
     with pytest.raises(core.InconsistentTableError):
@@ -237,8 +257,8 @@ def test_htmlsplitter():
 
     splitter = html.HTMLSplitter()
 
-    lines = [html.SoupString(BeautifulSoup('<tr><th>Col 1</th><th>Col 2</th></tr>').tr),
-            html.SoupString(BeautifulSoup('<tr><td>Data 1</td><td>Data 2</td></tr>').tr)]
+    lines = [html.SoupString(BeautifulSoup('<table><tr><th>Col 1</th><th>Col 2</th></tr></table>').tr),
+            html.SoupString(BeautifulSoup('<table><tr><td>Data 1</td><td>Data 2</td></tr></table>').tr)]
     expected_data = [['Col 1', 'Col 2'], ['Data 1', 'Data 2']]
     assert list(splitter(lines)) == expected_data
 
@@ -280,7 +300,7 @@ def test_htmlheader_start():
            '<tr><th>C1</th><th>C2</th><th>C3</th></tr>'
 
     # start_line should return None if no valid header is found
-    lines = [html.SoupString(BeautifulSoup('<tr><td>Data</td></tr>').tr),
+    lines = [html.SoupString(BeautifulSoup('<table><tr><td>Data</td></tr></table>').tr),
              html.SoupString(BeautifulSoup('<p>Text</p>').p)]
     assert header.start_line(lines) is None
 
@@ -318,16 +338,16 @@ def test_htmldata():
            '<tr><td>4</td><td>d</td><td>10.5</td></tr>'
     assert str(lines[data.end_line(lines) - 1]) == \
            '<tr><td>6</td><td>f</td><td>-12.5</td></tr>'
-    
+
     inputter.html['table_id'] = 3
     lines = inputter.get_lines(table)
     assert str(lines[data.start_line(lines)]) == \
            '<tr><td>7</td><td>g</td><td>105.0</td></tr>'
     assert str(lines[data.end_line(lines) - 1]) == \
            '<tr><td>9</td><td>i</td><td>-125.0</td></tr>'
-    
+
     # start_line should raise an error if no table data exists
-    lines = [html.SoupString(BeautifulSoup('<tr></tr>').tr),
+    lines = [html.SoupString(BeautifulSoup('<div></div>').div),
              html.SoupString(BeautifulSoup('<p>Text</p>').p)]
     with pytest.raises(core.InconsistentTableError):
         data.start_line(lines)
@@ -361,11 +381,13 @@ def test_multicolumn_write():
  </head>
  <body>
   <table>
-   <tr>
-    <th>C1</th>
-    <th colspan="2">C2</th>
-    <th colspan="3">C3</th>
-   </tr>
+   <thead>
+    <tr>
+     <th>C1</th>
+     <th colspan="2">C2</th>
+     <th colspan="3">C3</th>
+    </tr>
+   </thead>
    <tr>
     <td>1</td>
     <td>1.0</td>
@@ -415,11 +437,13 @@ def test_write_no_multicols():
  </head>
  <body>
   <table>
-   <tr>
-    <th>C1</th>
-    <th>C2</th>
-    <th>C3</th>
-   </tr>
+   <thead>
+    <tr>
+     <th>C1</th>
+     <th>C2</th>
+     <th>C3</th>
+    </tr>
+   </thead>
    <tr>
     <td>1</td>
     <td>1.0 .. 1.0</td>
diff --git a/astropy/io/ascii/tests/test_ipac_definitions.py b/astropy/io/ascii/tests/test_ipac_definitions.py
index b192c66..2e5a08c 100644
--- a/astropy/io/ascii/tests/test_ipac_definitions.py
+++ b/astropy/io/ascii/tests/test_ipac_definitions.py
@@ -2,13 +2,13 @@
 
 # TEST_UNICODE_LITERALS
 
-import os
-
 from ..ui import read
 from ..ipac import Ipac, IpacFormatError, IpacFormatErrorDBMS
 from ....tests.helper import pytest, catch_warnings
 from ... import ascii
 from ....table import Table
+from ..core import masked
+
 
 try:
     from cStringIO import StringIO
@@ -118,12 +118,16 @@ def test_too_long_comment():
 """
     assert out.getvalue().strip().splitlines() == expected_out.splitlines()
 
+
 def test_out_with_nonstring_null():
-    # unmasked tables don't have fill_values
+    '''Test a (non-string) fill value.
+
+    Even for an unmasked tables, the fill_value should show up in the
+    table header.
+    '''
     table = Table([[3]], masked=True)
-    table['col0'].fill_value = -99999
     out = StringIO()
-    ascii.write(table, out, Writer=Ipac)
+    ascii.write(table, out, Writer=Ipac, fill_values=[(masked, -99999)])
     expected_out = """\
 |  col0|
 |  long|
@@ -132,3 +136,18 @@ def test_out_with_nonstring_null():
       3
 """
     assert out.getvalue().strip().splitlines() == expected_out.splitlines()
+
+
+def test_include_exclude_names():
+    table = Table([[1], [2], [3]], names=('A', 'B', 'C'))
+    out = StringIO()
+    ascii.write(table, out, Writer=Ipac, include_names=('A', 'B'), exclude_names=('A',))
+    # column B should be the only included column in output
+    expected_out = """\
+|   B|
+|long|
+|    |
+|null|
+    2
+"""
+    assert out.getvalue().strip().splitlines() == expected_out.splitlines()
diff --git a/astropy/io/ascii/tests/test_read.py b/astropy/io/ascii/tests/test_read.py
index 7e3c95d..c9c7cf4 100644
--- a/astropy/io/ascii/tests/test_read.py
+++ b/astropy/io/ascii/tests/test_read.py
@@ -2,6 +2,7 @@
 
 # TEST_UNICODE_LITERALS
 
+import os
 import re
 
 import numpy as np
@@ -11,25 +12,22 @@ from ....tests.helper import pytest
 from ... import ascii
 from ....table import Table
 from ....units import Unit
-from distutils import version
 
 from .common import (raises, assert_equal, assert_almost_equal,
                      assert_true, setup_function, teardown_function)
-from ....tests.helper import pytest
+from .. import core
+
 
-_NUMPY_VERSION = version.LooseVersion(np.__version__)
 
-def test_convert_overflow():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_convert_overflow(fast_reader):
     """
     Test reading an extremely large integer, which falls through to
     string due to an overflow error (#2234).
     """
-    # Before Numpy 1.6 the exception from np.array(['1' * 10000], dtype=np.int)
-    # is exactly the same as np.array(['abc'], dtype=np.int).  In this case
-    # it falls through to float, so we just accept this as a known issue for
-    # numpy < 1.6.
-    expected_kind = ('f',) if _NUMPY_VERSION < version.LooseVersion('1.6') else ('S', 'U')
-    dat = ascii.read(['a', '1' * 10000], format='basic', guess=False)
+    expected_kind = ('S', 'U')
+    dat = ascii.read(['a', '1' * 10000], format='basic',
+                     fast_reader=fast_reader, guess=False)
     assert dat['a'].dtype.kind in expected_kind
 
 
@@ -89,15 +87,18 @@ def test_guess_with_format_arg():
     assert dat.colnames == ['a', 'b']
 
 
- at raises(ValueError)
-def test_read_with_names_arg():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_read_with_names_arg(fast_reader):
     """
     Test that a bad value of `names` raises an exception.
     """
-    dat = ascii.read(['c d', 'e f'], names=('a', ), guess=False)
+    with pytest.raises(ValueError):
+        dat = ascii.read(['c d', 'e f'], names=('a', ), guess=False, fast_reader=fast_reader)
 
 
-def test_read_all_files():
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_read_all_files(fast_reader):
     for testfile in get_testfiles():
         if testfile.get('skip'):
             print('\n\n******** SKIPPING %s' % testfile['name'])
@@ -107,13 +108,19 @@ def test_read_all_files():
             test_opts = testfile['opts'].copy()
             if 'guess' not in test_opts:
                 test_opts['guess'] = guess
+            if 'Reader' in test_opts and 'fast_{0}'.format(test_opts['Reader']._format_name) \
+                in core.FAST_CLASSES: # has fast version
+                if 'Inputter' not in test_opts: # fast reader doesn't allow this
+                    test_opts['fast_reader'] = fast_reader
             table = ascii.read(testfile['name'], **test_opts)
             assert_equal(table.dtype.names, testfile['cols'])
             for colname in table.dtype.names:
                 assert_equal(len(table[colname]), testfile['nrows'])
 
 
-def test_read_all_files_via_table():
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_read_all_files_via_table(fast_reader):
     for testfile in get_testfiles():
         if testfile.get('skip'):
             print('\n\n******** SKIPPING %s' % testfile['name'])
@@ -128,6 +135,8 @@ def test_read_all_files_via_table():
                 del test_opts['Reader']
             else:
                 format = 'ascii'
+            if 'fast_{0}'.format(format) in core.FAST_CLASSES:
+                test_opts['fast_reader'] = fast_reader
             table = Table.read(testfile['name'], format=format, **test_opts)
             assert_equal(table.dtype.names, testfile['cols'])
             for colname in table.dtype.names:
@@ -196,25 +205,30 @@ def test_daophot_multiple_aperture():
     assert np.all(table['RAPERT5'] == 23.3)  # assert all the 5th apertures are same 23.3
 
 
- at raises(ascii.InconsistentTableError)
-def test_empty_table_no_header():
-    table = ascii.read('t/no_data_without_header.dat', Reader=ascii.NoHeader,
-                            guess=False)
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_empty_table_no_header(fast_reader):
+    with pytest.raises(ascii.InconsistentTableError):
+        table = ascii.read('t/no_data_without_header.dat', Reader=ascii.NoHeader,
+                            guess=False, fast_reader=fast_reader)
 
 
- at raises(ascii.InconsistentTableError)
-def test_wrong_quote():
-    table = ascii.read('t/simple.txt', guess=False)
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_wrong_quote(fast_reader):
+    with pytest.raises(ascii.InconsistentTableError):
+        table = ascii.read('t/simple.txt', guess=False, fast_reader=fast_reader)
 
 
- at raises(ascii.InconsistentTableError)
-def test_extra_data_col():
-    table = ascii.read('t/bad.txt')
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_extra_data_col(fast_reader):
+    with pytest.raises(ascii.InconsistentTableError):
+        table = ascii.read('t/bad.txt', fast_reader=fast_reader)
 
 
- at raises(ascii.InconsistentTableError)
-def test_extra_data_col2():
-    table = ascii.read('t/simple5.txt', delimiter='|')
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_extra_data_col2(fast_reader):
+    with pytest.raises(ascii.InconsistentTableError):
+        table = ascii.read('t/simple5.txt', delimiter='|', fast_reader=fast_reader)
 
 
 @raises(IOError)
@@ -222,23 +236,28 @@ def test_missing_file():
     table = ascii.read('does_not_exist')
 
 
-def test_set_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_set_names(fast_reader):
     names = ('c1', 'c2', 'c3', 'c4', 'c5', 'c6')
-    data = ascii.read('t/simple3.txt', names=names, delimiter='|')
+    data = ascii.read('t/simple3.txt', names=names, delimiter='|',
+                      fast_reader=fast_reader)
     assert_equal(data.dtype.names, names)
 
 
-def test_set_include_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_set_include_names(fast_reader):
     names = ('c1', 'c2', 'c3', 'c4', 'c5', 'c6')
     include_names = ('c1', 'c3')
     data = ascii.read('t/simple3.txt', names=names, include_names=include_names,
-                           delimiter='|')
+                           delimiter='|', fast_reader=fast_reader)
     assert_equal(data.dtype.names, include_names)
 
 
-def test_set_exclude_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_set_exclude_names(fast_reader):
     exclude_names = ('Y', 'object')
-    data = ascii.read('t/simple3.txt', exclude_names=exclude_names, delimiter='|')
+    data = ascii.read('t/simple3.txt', exclude_names=exclude_names, delimiter='|',
+                      fast_reader=fast_reader)
     assert_equal(data.dtype.names, ('obsid', 'redshift', 'X', 'rad'))
 
 
@@ -311,31 +330,34 @@ def test_set_converters():
     assert_equal(data['p1.gamma'][0], '1.26764544642')
 
 
-def test_from_string():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_from_string(fast_reader):
     f = 't/simple.txt'
     with open(f) as fd:
         table = fd.read()
     testfile = get_testfiles(f)
-    data = ascii.read(table, **testfile['opts'])
+    data = ascii.read(table, fast_reader=fast_reader, **testfile['opts'])
     assert_equal(data.dtype.names, testfile['cols'])
     assert_equal(len(data), testfile['nrows'])
 
 
-def test_from_filelike():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_from_filelike(fast_reader):
     f = 't/simple.txt'
     testfile = get_testfiles(f)
     with open(f, 'rb') as fd:
-        data = ascii.read(fd, **testfile['opts'])
+        data = ascii.read(fd, fast_reader=fast_reader, **testfile['opts'])
     assert_equal(data.dtype.names, testfile['cols'])
     assert_equal(len(data), testfile['nrows'])
 
 
-def test_from_lines():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_from_lines(fast_reader):
     f = 't/simple.txt'
     with open(f) as fd:
         table = fd.readlines()
     testfile = get_testfiles(f)
-    data = ascii.read(table, **testfile['opts'])
+    data = ascii.read(table, fast_reader=fast_reader, **testfile['opts'])
     assert_equal(data.dtype.names, testfile['cols'])
     assert_equal(len(data), testfile['nrows'])
 
@@ -344,37 +366,44 @@ def test_comment_lines():
     table = ascii.get_reader(Reader=ascii.Rdb)
     data = table.read('t/apostrophe.rdb')
     assert_equal(table.comment_lines, ['# first comment', '  # second comment'])
+    assert_equal(data.meta['comments'], ['first comment', 'second comment'])
 
 
-def test_fill_values():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_fill_values(fast_reader):
     f = 't/fill_values.txt'
     testfile = get_testfiles(f)
-    data = ascii.read(f, fill_values=('a', '1'), **testfile['opts'])
+    data = ascii.read(f, fill_values=('a', '1'), fast_reader=fast_reader,
+                      **testfile['opts'])
     assert_true((data['a'].mask == [False, True]).all())
     assert_true((data['a'] == [1, 1]).all())
     assert_true((data['b'].mask == [False, True]).all())
     assert_true((data['b'] == [2, 1]).all())
 
 
-def test_fill_values_col():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_fill_values_col(fast_reader):
     f = 't/fill_values.txt'
     testfile = get_testfiles(f)
-    data = ascii.read(f, fill_values=('a', '1', 'b'), **testfile['opts'])
+    data = ascii.read(f, fill_values=('a', '1', 'b'), fast_reader=fast_reader,
+                      **testfile['opts'])
     check_fill_values(data)
 
 
-def test_fill_values_include_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_fill_values_include_names(fast_reader):
     f = 't/fill_values.txt'
     testfile = get_testfiles(f)
-    data = ascii.read(f, fill_values=('a', '1'),
+    data = ascii.read(f, fill_values=('a', '1'), fast_reader=fast_reader,
                            fill_include_names = ['b'], **testfile['opts'])
     check_fill_values(data)
 
 
-def test_fill_values_exclude_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_fill_values_exclude_names(fast_reader):
     f = 't/fill_values.txt'
     testfile = get_testfiles(f)
-    data = ascii.read(f, fill_values=('a', '1'),
+    data = ascii.read(f, fill_values=('a', '1'), fast_reader=fast_reader,
                            fill_exclude_names = ['a'], **testfile['opts'])
     check_fill_values(data)
 
@@ -390,11 +419,12 @@ def check_fill_values(data):
     assert_true((data['b'] == [2, 1]).all())
 
 
-def test_fill_values_list():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_fill_values_list(fast_reader):
     f = 't/fill_values.txt'
     testfile = get_testfiles(f)
     data = ascii.read(f, fill_values=[('a', '42'), ('1', '42', 'a')],
-                           **testfile['opts'])
+                      fast_reader=fast_reader, **testfile['opts'])
     data['a'].mask = False  # explicitly unmask for comparison
     assert_true((data['a'] == [42, 42]).all())
 
@@ -445,21 +475,23 @@ def test_set_guess_kwarg():
     assert(len(data) == 1)
 
 
- at raises(ascii.InconsistentTableError)
-def test_read_rdb_wrong_type():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_read_rdb_wrong_type(fast_reader):
     """Read RDB data with inconstent data type (except failure)"""
     table = """col1\tcol2
 N\tN
 1\tHello"""
-    ascii.read(table, Reader=ascii.Rdb)
+    with pytest.raises(ascii.InconsistentTableError):
+        ascii.read(table, Reader=ascii.Rdb, fast_reader=fast_reader)
 
 
-def test_default_missing():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_default_missing(fast_reader):
     """Read a table with empty values and ensure that corresponding entries are masked"""
     table = '\n'.join(['a,b,c,d',
                        '1,3,,',
                        '2, , 4.0 , ss '])
-    dat = ascii.read(table)
+    dat = ascii.read(table, fast_reader=fast_reader)
     assert dat.masked is True
     assert dat.pformat() == [' a   b   c   d ',
                              '--- --- --- ---',
@@ -468,7 +500,7 @@ def test_default_missing():
 
     # Single row table with a single missing element
     table = """ a \n "" """
-    dat = ascii.read(table)
+    dat = ascii.read(table, fast_reader=fast_reader)
     assert dat.pformat() == [' a ',
                              '---',
                              ' --']
@@ -552,7 +584,7 @@ def get_testfiles(name=None):
         {'cols': ('a', 'b', 'c'),
          'name': 't/commented_header2.dat',
          'nrows': 2,
-         'opts': {'Reader': ascii.CommentedHeader, 'header_start': -1, 'data_start': 0}},
+         'opts': {'Reader': ascii.CommentedHeader, 'header_start': -1}},
         {'cols': ('col1', 'col2', 'col3', 'col4', 'col5'),
          'name': 't/continuation.dat',
          'nrows': 2,
@@ -734,6 +766,10 @@ def get_testfiles(name=None):
          'name': 't/latex2.tex',
          'nrows': 3,
          'opts': {'Reader': ascii.AASTex}},
+        {'cols': ('Col1', 'Col2', 'Col3', 'Col4'),
+         'name': 't/fixed_width_2_line.txt',
+         'nrows': 2,
+         'opts': {'Reader': ascii.FixedWidthTwoLine}},
     ]
 
     try:
@@ -774,12 +810,13 @@ def test_csv_table_read():
     t = ascii.read(lines)
     assert t.colnames == ['a', 'b']
 
-def test_overlapping_names():
+ at pytest.mark.parametrize('fast_reader', [True, False, 'force'])
+def test_overlapping_names(fast_reader):
     """
     Check that the names argument list can overlap with the existing column names.
     This tests the issue in #1991.
     """
-    t = ascii.read(['a b', '1 2'], names=['b', 'a'])
+    t = ascii.read(['a b', '1 2'], names=['b', 'a'], fast_reader=fast_reader)
     assert t.colnames == ['b', 'a']
 
 def test_sextractor_units():
@@ -814,9 +851,82 @@ def test_list_with_newlines():
     assert t[0][0] == 123
     assert t[1][0] == 456
 
+def test_commented_csv():
+    """
+    Check that Csv reader does not have ignore lines with the # comment
+    character which is defined for most Basic readers.
+    """
+    t = ascii.read(['#a,b', '1,2', '#3,4'], format='csv')
+    assert t.colnames == ['#a', 'b']
+    assert len(t) == 2
+    assert t['#a'][1] == '#3'
+
+def test_meta_comments():
+    """
+    Make sure that line comments are included in the ``meta`` attribute
+    of the output Table.
+    """
+    t = ascii.read(['#comment1', '#   comment2 \t', 'a,b,c', '1,2,3'])
+    assert t.colnames == ['a', 'b', 'c']
+    assert t.meta['comments'] == ['comment1', 'comment2']
+
+def test_guess_fail():
+    """
+    Check the error message when guess fails
+    """
+    with pytest.raises(ascii.InconsistentTableError) as err:
+        ascii.read('asfdasdf\n1 2 3', format='html')
+
+    assert "** To figure out why the table did not read, use guess=False and" in str(err.value)
+
+
 def test_guessing_file_object():
     """
     Test guessing a file object.  Fixes #3013 and similar issue noted in #3019.
     """
     t = ascii.read(open('t/ipac.dat.bz2', 'rb'))
     assert t.colnames == ['ra','dec','sai','v2','sptype']
+
+
+def test_pformat_roundtrip():
+    """Check that the screen output of ``print tab`` can be read. See #3025."""
+    """Read a table with empty values and ensure that corresponding entries are masked"""
+    table = '\n'.join(['a,b,c,d',
+                       '1,3,1.11,1',
+                       '2, 2, 4.0 , ss '])
+    dat = ascii.read(table)
+    out = ascii.read(dat.pformat())
+    assert len(dat) == len(out)
+    assert dat.colnames == out.colnames
+    for c in dat.colnames:
+        assert np.all(dat[c] == out[c])
+
+
+def test_ipac_abbrev():
+    lines = ['| c1 | c2 | c3   |   c4 | c5| c6 | c7  | c8 | c9|c10|c11|c12|',
+             '| r  | rE | rea  | real | D | do | dou | f  | i | l | da| c |',
+             '  1    2    3       4     5   6    7     8    9   10  11  12 ']
+    dat = ascii.read(lines, format='ipac')
+    for name in dat.columns[0:8]:
+        assert dat[name].dtype.kind == 'f'
+    for name in dat.columns[8:10]:
+        assert dat[name].dtype.kind == 'i'
+    for name in dat.columns[10:12]:
+        assert dat[name].dtype.kind in ('U', 'S')
+
+
+def test_almost_but_not_quite_daophot():
+    '''Regression test for #3319.
+    This tables looks so close to a daophot table, that the daophot reader gets
+    quite far before it fails with an AttributeError.
+
+    Note that this table will actually be read as Commented Header table with
+    the columns ['some', 'header', 'info'].
+    '''
+    lines = ["# some header info",
+             "#F header info beginning with 'F'",
+             "1 2 3",
+             "4 5 6",
+             "7 8 9"]
+    dat = ascii.read(lines)
+    assert len(dat) == 3
diff --git a/astropy/io/ascii/tests/test_write.py b/astropy/io/ascii/tests/test_write.py
index dd56bb9..e2aaf56 100644
--- a/astropy/io/ascii/tests/test_write.py
+++ b/astropy/io/ascii/tests/test_write.py
@@ -2,6 +2,7 @@
 
 # TEST_UNICODE_LITERALS
 
+import os
 import copy
 
 try:
@@ -11,6 +12,8 @@ except ImportError:
 
 from ... import ascii
 from .... import table
+from ....tests.helper import pytest
+from .... import units
 
 from .common import setup_function, teardown_function
 
@@ -86,6 +89,7 @@ ID,XCENTER,YCENTER,MAG,MERR,MSKY,NITER,SHARPNESS,CHI,PIER,PERROR
 \\begin{table}
 \\begin{tabular}{ccccccccccc}
 ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PERROR \\\\
+ & pixels & pixels & magnitudes & magnitudes & counts &  &  &  &  & perrors \\\\
 14 & 138.538 & 256.405 & 15.461 & 0.003 & 34.85955 & 4 & -0.032 & 0.802 & 0 & No_error \\\\
 18 & 18.114 & 280.170 & 22.329 & 0.206 & 30.12784 & 4 & -2.544 & 1.104 & 0 & No_error \\\\
 \\end{tabular}
@@ -95,7 +99,7 @@ ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PE
     dict(kwargs=dict(Writer=ascii.AASTex),
          out="""\
 \\begin{deluxetable}{ccccccccccc}
-\\tablehead{\\colhead{ID} & \\colhead{XCENTER} & \\colhead{YCENTER} & \\colhead{MAG} & \\colhead{MERR} & \\colhead{MSKY} & \\colhead{NITER} & \\colhead{SHARPNESS} & \\colhead{CHI} & \\colhead{PIER} & \\colhead{PERROR}}
+\\tablehead{\\colhead{ID} & \\colhead{XCENTER} & \\colhead{YCENTER} & \\colhead{MAG} & \\colhead{MERR} & \\colhead{MSKY} & \\colhead{NITER} & \\colhead{SHARPNESS} & \\colhead{CHI} & \\colhead{PIER} & \\colhead{PERROR}\\\\ \\colhead{ } & \\colhead{pixels} & \\colhead{pixels} & \\colhead{magnitudes} & \\colhead{magnitudes} & \\colhead{counts} & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{perrors}}
 \\startdata
 14 & 138.538 & 256.405 & 15.461 & 0.003 & 34.85955 & 4 & -0.032 & 0.802 & 0 & No_error \\\\
 18 & 18.114 & 280.170 & 22.329 & 0.206 & 30.12784 & 4 & -2.544 & 1.104 & 0 & No_error \\\\
@@ -110,7 +114,7 @@ ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PE
         out="""\
 \\begin{deluxetable*}{ccccccccccc}[htpb]
 \\tablecaption{Mag values \\label{tab1}}
-\\tablehead{\\colhead{ID} & \\colhead{XCENTER} & \\colhead{YCENTER} & \\colhead{MAG} & \\colhead{MERR} & \\colhead{MSKY} & \\colhead{NITER} & \\colhead{SHARPNESS} & \\colhead{CHI} & \\colhead{PIER} & \\colhead{PERROR}\\\\ \\colhead{ } & \\colhead{[pixel]} & \\colhead{ } & \\colhead{[mag]} & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ }}
+\\tablehead{\\colhead{ID} & \\colhead{XCENTER} & \\colhead{YCENTER} & \\colhead{MAG} & \\colhead{MERR} & \\colhead{MSKY} & \\colhead{NITER} & \\colhead{SHARPNESS} & \\colhead{CHI} & \\colhead{PIER} & \\colhead{PERROR}\\\\ \\colhead{ } & \\colhead{[pixel]} & \\colhead{pixels} & \\colhead{[mag]} & \\colhead{magnitudes} & \\colhead{counts} & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{ } & \\colhead{perrors}}
 \\startdata
 14 & 138.538 & 256.405 & 15.461 & 0.003 & 34.85955 & 4 & -0.032 & 0.802 & 0 & No_error \\\\
 18 & 18.114 & 280.170 & 22.329 & 0.206 & 30.12784 & 4 & -2.544 & 1.104 & 0 & No_error \\\\
@@ -132,7 +136,7 @@ ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PE
 \\caption{Mag values \\label{tab1}}
 \\begin{tabular}{|lcccccccccc|}
 ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PERROR \\\\
- & [pixel] &  & [mag] &  &  &  &  &  &  &  \\\\
+ & [pixel] & pixels & [mag] & magnitudes & counts &  &  &  &  & perrors \\\\
 14 & 138.538 & 256.405 & 15.461 & 0.003 & 34.85955 & 4 & -0.032 & 0.802 & 0 & No_error \\\\
 18 & 18.114 & 280.170 & 22.329 & 0.206 & 30.12784 & 4 & -2.544 & 1.104 & 0 & No_error \\\\
 \\hline
@@ -150,7 +154,7 @@ preamble
 \\begin{tabular}{col_align}
 header_start
 ID & XCENTER & YCENTER & MAG & MERR & MSKY & NITER & SHARPNESS & CHI & PIER & PERROR \\\\
- &  &  &  &  &  &  &  &  &  &  \\\\
+ & pixels & pixels & magnitudes & magnitudes & counts &  &  &  &  & perrors \\\\
 header_end
 data_start
 14 & 138.538 & 256.405 & 15.461 & 0.003 & 34.85955 & 4 & -0.032 & 0.802 & 0 & No_error \\\\
@@ -172,19 +176,21 @@ table,th,td{border:1px solid black;  </style>
  </head>
  <body>
   <table>
-   <tr>
-    <th>ID</th>
-    <th>XCENTER</th>
-    <th>YCENTER</th>
-    <th>MAG</th>
-    <th>MERR</th>
-    <th>MSKY</th>
-    <th>NITER</th>
-    <th>SHARPNESS</th>
-    <th>CHI</th>
-    <th>PIER</th>
-    <th>PERROR</th>
-   </tr>
+   <thead>
+    <tr>
+     <th>ID</th>
+     <th>XCENTER</th>
+     <th>YCENTER</th>
+     <th>MAG</th>
+     <th>MERR</th>
+     <th>MSKY</th>
+     <th>NITER</th>
+     <th>SHARPNESS</th>
+     <th>CHI</th>
+     <th>PIER</th>
+     <th>PERROR</th>
+    </tr>
+   </thead>
    <tr>
     <td>14</td>
     <td>138.538</td>
@@ -369,16 +375,21 @@ a,b,c
 ]
 
 
-def check_write_table(test_def, table):
+def check_write_table(test_def, table, fast_writer):
     out = StringIO()
-    ascii.write(table, out, **test_def['kwargs'])
+    try:
+        ascii.write(table, out, fast_writer=fast_writer, **test_def['kwargs'])
+    except ValueError as e: # if format doesn't have a fast writer, ignore
+        if not 'not in the list of formats with fast writers' in str(e):
+            raise e
+        return
     print('Expected:\n%s' % test_def['out'])
     print('Actual:\n%s' % out.getvalue())
     assert [x.strip() for x in out.getvalue().strip().splitlines()] == [
         x.strip() for x in test_def['out'].strip().splitlines()]
 
 
-def check_write_table_via_table(test_def, table):
+def check_write_table_via_table(test_def, table, fast_writer):
     out = StringIO()
 
     test_def = copy.deepcopy(test_def)
@@ -388,30 +399,38 @@ def check_write_table_via_table(test_def, table):
     else:
         format = 'ascii'
 
-    table.write(out, format=format, **test_def['kwargs'])
+    try:
+        table.write(out, format=format,  fast_writer=fast_writer, **test_def['kwargs'])
+    except ValueError as e: # if format doesn't have a fast writer, ignore
+        if not 'not in the list of formats with fast writers' in str(e):
+            raise e
+        return
     print('Expected:\n%s' % test_def['out'])
     print('Actual:\n%s' % out.getvalue())
     assert [x.strip() for x in out.getvalue().strip().splitlines()] == [
         x.strip() for x in test_def['out'].strip().splitlines()]
 
 
-def test_write_table():
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_write_table(fast_writer):
     table = ascii.get_reader(Reader=ascii.Daophot)
     data = table.read('t/daophot.dat')
 
     for test_def in test_defs:
-        check_write_table(test_def, data)
-        check_write_table_via_table(test_def, data)
+        check_write_table(test_def, data, fast_writer)
+        check_write_table_via_table(test_def, data, fast_writer)
 
 
-def test_write_fill_values():
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_write_fill_values(fast_writer):
     data = ascii.read(tab_to_fill)
 
     for test_def in test_defs_fill_value:
-        check_write_table(test_def, data)
+        check_write_table(test_def, data, fast_writer)
 
 
-def test_write_fill_masked_different():
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_write_fill_masked_different(fast_writer):
     '''see discussion in #2255'''
     data = ascii.read(tab_to_fill)
     data = table.Table(data, masked=True)
@@ -419,14 +438,78 @@ def test_write_fill_masked_different():
     data['c'].mask = [False, True]
 
     for test_def in test_def_masked_fill_value:
-        check_write_table(test_def, data)
+        check_write_table(test_def, data, fast_writer)
 
 
-def test_write_no_data_ipac():
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_write_no_data_ipac(fast_writer):
     """Write an IPAC table that contains no data."""
     table = ascii.get_reader(Reader=ascii.Ipac)
     data = table.read('t/no_data_ipac.dat')
 
     for test_def in test_defs_no_data:
-        check_write_table(test_def, data)
-        check_write_table_via_table(test_def, data)
+        check_write_table(test_def, data, fast_writer)
+        check_write_table_via_table(test_def, data, fast_writer)
+
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_write_comments(fast_writer):
+    """Write comments in output originally read by io.ascii."""
+    data = ascii.read('#c1\n  # c2\t\na,b,c\n#  c3\n1,2,3')
+    out = StringIO()
+    ascii.write(data, out, format='basic', fast_writer=fast_writer)
+    expected = ['# c1', '# c2', '# c3', 'a b c', '1 2 3']
+    assert out.getvalue().splitlines() == expected
+
+    # header comes before comments for commented-header
+    out = StringIO()
+    ascii.write(data, out, format='commented_header', fast_writer=fast_writer)
+    expected = ['# a b c', '# c1', '# c2', '# c3', '1 2 3']
+    assert out.getvalue().splitlines() == expected
+
+    # setting comment=False should disable comment writing
+    out = StringIO()
+    ascii.write(data, out, format='basic', comment=False, fast_writer=fast_writer)
+    expected = ['a b c', '1 2 3']
+    assert out.getvalue().splitlines() == expected
+
+ at pytest.mark.parametrize("fast_writer", [True, False])
+def test_strip_names(fast_writer):
+    """Names should be stripped of whitespace by default."""
+    data = table.Table([[1], [2], [3]], names=(' A', 'B ', ' C '))
+    out = StringIO()
+    ascii.write(data, out, format='csv', fast_writer=fast_writer)
+    assert out.getvalue().splitlines()[0] == 'A,B,C'
+
+
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
+def test_latex_units():
+    """
+    Check to make sure that Latex and AASTex writers attempt to fall
+    back on the **unit** attribute of **Column** if the supplied
+    **latexdict** does not specify units.
+    """
+    t = table.Table([table.Column(name='date', data=['a','b']),
+               table.Column(name='NUV exp.time', data=[1,2])])
+    latexdict = copy.deepcopy(ascii.latexdicts['AA'])
+    latexdict['units'] = {'NUV exp.time':'s'}
+    out = StringIO()
+    expected = '''\
+\\begin{table}{cc}
+\\tablehead{\\colhead{date} & \\colhead{NUV exp.time}\\\\ \\colhead{ } & \\colhead{s}}
+\\startdata
+a & 1 \\\\
+b & 2 \\\\
+\\enddata
+\\end{table}
+'''
+    ascii.write(t, out, format='aastex', latexdict=latexdict)
+    assert out.getvalue() == expected
+    # use unit attribute instead
+    t['NUV exp.time'].unit = units.s
+    t['date'].unit = units.yr
+    out = StringIO()
+    ascii.write(t, out, format='aastex', latexdict=ascii.latexdicts['AA'])
+    assert out.getvalue() == expected.replace(
+        'colhead{s}', 'colhead{$\mathrm{s}$}').replace(
+        'colhead{ }', 'colhead{$\mathrm{yr}$}')
+
diff --git a/astropy/io/ascii/ui.py b/astropy/io/ascii/ui.py
index 607cd8a..3445bfa 100644
--- a/astropy/io/ascii/ui.py
+++ b/astropy/io/ascii/ui.py
@@ -18,14 +18,24 @@ from . import core
 from . import basic
 from . import cds
 from . import daophot
+from . import ecsv
 from . import sextractor
 from . import ipac
 from . import latex
 from . import html
+from . import fastbasic
+from . import cparser
+from . import fixedwidth
 
 from ...table import Table
 from ...utils.data import get_readable_fileobj
 
+try:
+    import yaml
+    HAS_YAML = True
+except ImportError:
+    HAS_YAML = False
+
 # Default setting for guess parameter in read()
 _GUESS = True
 
@@ -56,11 +66,11 @@ def get_reader(Reader=None, Inputter=None, Outputter=None, **kwargs):
     :param data_Splitter: Splitter class to split data columns
     :param header_Splitter: Splitter class to split header columns
     :param names: list of names corresponding to each data column
-    :param include_names: list of names to include in output (default=None selects all names)
-    :param exclude_names: list of names to exlude from output (applied after ``include_names``)
+    :param include_names: list of names to include in output (default= ``None`` selects all names)
+    :param exclude_names: list of names to exclude from output (applied after ``include_names``)
     :param fill_values: specification of fill values for bad or missing table values
-    :param fill_include_names: list of names to include in fill_values (default=None selects all names)
-    :param fill_exclude_names: list of names to exlude from fill_values (applied after ``fill_include_names``)
+    :param fill_include_names: list of names to include in fill_values (default= ``None`` selects all names)
+    :param fill_exclude_names: list of names to exclude from fill_values (applied after ``fill_include_names``)
     """
     # This function is a light wrapper around core._get_reader to provide a public interface
     # with a default Reader.
@@ -89,10 +99,10 @@ def read(table, guess=None, **kwargs):
     class.
 
     :param table: input table (file name, file-like object, list of strings, or single newline-separated string)
-    :param guess: try to guess the table format (default=True)
+    :param guess: try to guess the table format (default= ``True``)
     :param format: input table format
     :param Inputter: Inputter class
-    :param Outputter: Outputter class (default=TableOutputter)
+    :param Outputter: Outputter class (default= :class:`TableOutputter`)
     :param delimiter: column delimiter string
     :param comment: regular expression defining a comment line in table
     :param quotechar: one-character string to quote fields containing special characters
@@ -103,12 +113,13 @@ def read(table, guess=None, **kwargs):
     :param data_Splitter: Splitter class to split data columns
     :param header_Splitter: Splitter class to split header columns
     :param names: list of names corresponding to each data column
-    :param include_names: list of names to include in output (default=None selects all names)
-    :param exclude_names: list of names to exlude from output (applied after ``include_names``)
-    :param fill_values: specification of fill values for bad or missing table values (default=('', '0'))
+    :param include_names: list of names to include in output (default= ``None`` selects all names)
+    :param exclude_names: list of names to exclude from output (applied after ``include_names``)
+    :param fill_values: specification of fill values for bad or missing table values (default= ``('', '0')``)
     :param fill_include_names: list of names to include in fill_values (default=None selects all names)
-    :param fill_exclude_names: list of names to exlude from fill_values (applied after ``fill_include_names``)
-    :param Reader: Reader class (DEPRECATED) (default=``ascii.Basic``)
+    :param fill_exclude_names: list of names to exclude from fill_values (applied after ``fill_include_names``)
+    :param fast_reader: whether to use the C engine, can also be a dict with options which default to False (default= ``True``)
+    :param Reader: Reader class (DEPRECATED) (default= :class:`Basic`)
     """
 
     if 'fill_values' not in kwargs:
@@ -116,13 +127,18 @@ def read(table, guess=None, **kwargs):
 
     # If an Outputter is supplied in kwargs that will take precedence.
     new_kwargs = {}
-    new_kwargs['Outputter'] = core.TableOutputter
+    fast_reader_param = kwargs.get('fast_reader', True)
+    if 'Outputter' in kwargs: # user specified Outputter, not supported for fast reading
+        fast_reader_param = False
+    format = kwargs.get('format')
     new_kwargs.update(kwargs)
 
     # Get the Reader class based on possible format and Reader kwarg inputs.
-    Reader = _get_format_class(kwargs.get('format'), kwargs.get('Reader'), 'Reader')
+    Reader = _get_format_class(format, kwargs.get('Reader'), 'Reader')
     if Reader is not None:
         new_kwargs['Reader'] = Reader
+        format = Reader._format_name
+
     # Remove format keyword if there, this is only allowed in read() not get_reader()
     if 'format' in new_kwargs:
         del new_kwargs['format']
@@ -130,15 +146,29 @@ def read(table, guess=None, **kwargs):
     if guess is None:
         guess = _GUESS
     if guess:
-        dat = _guess(table, new_kwargs)
+        dat = _guess(table, new_kwargs, format, fast_reader_param)
     else:
         reader = get_reader(**new_kwargs)
-        dat = reader.read(table)
+        # Try the fast reader first if applicable
+        if fast_reader_param and format is not None and 'fast_{0}'.format(format) \
+                                                        in core.FAST_CLASSES:
+            new_kwargs['Reader'] = core.FAST_CLASSES['fast_{0}'.format(format)]
+            fast_reader = get_reader(**new_kwargs)
+            try:
+                return fast_reader.read(table)
+            except (core.ParameterError, cparser.CParserError) as e:
+                # special testing value to avoid falling back on the slow reader
+                if fast_reader_param == 'force':
+                    raise e
+                # If the fast reader doesn't work, try the slow version
+                dat = reader.read(table)
+        else:
+            dat = reader.read(table)
 
     return dat
 
 
-def _guess(table, read_kwargs):
+def _guess(table, read_kwargs, format, fast_reader):
     """Try to read the table using various sets of keyword args. First try the
     original args supplied in the read() call. Then try the standard guess
     keyword args. For each key/val pair specified explicitly in the read()
@@ -159,16 +189,26 @@ def _guess(table, read_kwargs):
 
     # Keep a trace of all failed guesses kwarg
     failed_kwargs = []
+    full_list_guess = _get_guess_kwargs_list(read_kwargs)
+
+    if fast_reader and format is not None and 'fast_{0}'.format(format) in \
+                                                         core.FAST_CLASSES:
+        # If a fast version of the reader is available, try that before the slow version
+        fast_kwargs = read_kwargs.copy()
+        fast_kwargs['Reader'] = core.FAST_CLASSES['fast_{0}'.format(format)]
+        full_list_guess = [fast_kwargs] + full_list_guess
+    else:
+        fast_kwargs = None
 
     # First try guessing
-    for guess_kwargs in [read_kwargs.copy()] + _get_guess_kwargs_list():
+    for guess_kwargs in full_list_guess:
         guess_kwargs_ok = True  # guess_kwargs are consistent with user_kwargs?
         for key, val in read_kwargs.items():
             # Do guess_kwargs.update(read_kwargs) except that if guess_args has
             # a conflicting key/val pair then skip this guess entirely.
             if key not in guess_kwargs:
                 guess_kwargs[key] = val
-            elif val != guess_kwargs[key]:
+            elif val != guess_kwargs[key] and guess_kwargs != fast_kwargs:
                 guess_kwargs_ok = False
                 break
 
@@ -177,24 +217,17 @@ def _guess(table, read_kwargs):
             # user supplies delimiter="|" but the guess wants to try delimiter=" ",
             # so skip the guess entirely.
             continue
-
         try:
             # If guessing will try all Readers then use strict req'ts on column names
             if 'Reader' not in read_kwargs:
                 guess_kwargs['strict_names'] = True
 
             reader = get_reader(**guess_kwargs)
-            dat = reader.read(table)
-
-            # When guessing require at least two columns
-            if len(dat.colnames) <= 1:
-                del dat
-                raise ValueError
-
-            return dat
+            reader.guessing = True
+            return reader.read(table)
 
-        except (core.InconsistentTableError, ValueError, TypeError,
-                core.OptionalTableImportError):
+        except (core.InconsistentTableError, ValueError, TypeError, AttributeError,
+                core.OptionalTableImportError, core.ParameterError, cparser.CParserError):
             failed_kwargs.append(guess_kwargs)
     else:
         # failed all guesses, try the original read_kwargs without column requirements
@@ -202,7 +235,7 @@ def _guess(table, read_kwargs):
             reader = get_reader(**read_kwargs)
             return reader.read(table)
         except (core.InconsistentTableError, ValueError, ImportError,
-                                            core.OptionalTableImportError):
+                core.OptionalTableImportError, core.ParameterError, cparser.CParserError):
             failed_kwargs.append(read_kwargs)
             lines = ['\nERROR: Unable to guess table format with the guesses listed below:']
             for kwargs in failed_kwargs:
@@ -213,24 +246,54 @@ def _guess(table, read_kwargs):
                 kwargs_sorted = ((key, kwargs[key]) for key in sorted_keys)
                 keys_vals.extend(['%s: %s' % (key, repr(val)) for key, val in kwargs_sorted])
                 lines.append(' '.join(keys_vals))
-            lines.append('ERROR: Unable to guess table format with the guesses listed above.')
-            lines.append('Check the table and try with guess=False '
-                         'and appropriate arguments to read()')
-            raise core.InconsistentTableError('\n'.join(lines))
 
+            msg = ['',
+                   '************************************************************************',
+                   '** ERROR: Unable to guess table format with the guesses listed above. **',
+                   '**                                                                    **',
+                   '** To figure out why the table did not read, use guess=False and      **',
+                   '** appropriate arguments to read().  In particular specify the format **',
+                   '** and any known attributes like the delimiter.                       **',
+                   '************************************************************************']
+            lines.extend(msg)
+            raise core.InconsistentTableError('\n'.join(lines))
 
-def _get_guess_kwargs_list():
-    guess_kwargs_list = [dict(Reader=basic.Rdb),
-                         dict(Reader=basic.Tab),
-                         dict(Reader=cds.Cds),
-                         dict(Reader=daophot.Daophot),
-                         dict(Reader=sextractor.SExtractor),
-                         dict(Reader=ipac.Ipac),
-                         dict(Reader=latex.Latex),
-                         dict(Reader=latex.AASTex),
-                         dict(Reader=html.HTML)
-                         ]
-    for Reader in (basic.CommentedHeader, basic.Basic, basic.NoHeader):
+def _get_guess_kwargs_list(read_kwargs):
+    guess_kwargs_list = []
+
+    # Start with ECSV because an ECSV file will be read by Basic.  This format
+    # has very specific header requirements and fails out quickly.
+    if HAS_YAML:
+        guess_kwargs_list.append(dict(Reader=ecsv.Ecsv))
+
+    # Now try readers that accept the common arguments with the input arguments
+    # (Unless there are not arguments - we try that in the next step anyway.)
+    # FixedWidthTwoLine would also be read by Basic, so it needs to come first.
+    if len(read_kwargs) > 0:
+        for reader in [fixedwidth.FixedWidthTwoLine,
+                       basic.Basic]:
+            first_kwargs = read_kwargs.copy()
+            first_kwargs.update(dict(Reader=reader))
+            guess_kwargs_list.append(first_kwargs)
+
+    # Then try a list of readers with default arguments
+    guess_kwargs_list.extend([dict(Reader=fixedwidth.FixedWidthTwoLine),
+                              dict(Reader=fastbasic.FastBasic),
+                              dict(Reader=basic.Basic),
+                              dict(Reader=basic.Rdb),
+                              dict(Reader=fastbasic.FastTab),
+                              dict(Reader=basic.Tab),
+                              dict(Reader=cds.Cds),
+                              dict(Reader=daophot.Daophot),
+                              dict(Reader=sextractor.SExtractor),
+                              dict(Reader=ipac.Ipac),
+                              dict(Reader=latex.Latex),
+                              dict(Reader=latex.AASTex),
+                              dict(Reader=html.HTML)
+                              ])
+
+    for Reader in (basic.CommentedHeader, fastbasic.FastBasic, basic.Basic,
+                   fastbasic.FastNoHeader, basic.NoHeader):
         for delimiter in ("|", ",", " ", "\s"):
             for quotechar in ('"', "'"):
                 guess_kwargs_list.append(dict(
@@ -241,52 +304,61 @@ extra_writer_pars = ('delimiter', 'comment', 'quotechar', 'formats',
                      'names', 'include_names', 'exclude_names', 'strip_whitespace')
 
 
-def get_writer(Writer=None, **kwargs):
+def get_writer(Writer=None, fast_writer=True, **kwargs):
     """Initialize a table writer allowing for common customizations.  Most of the
     default behavior for various parameters is determined by the Writer class.
 
-    :param Writer: Writer class (DEPRECATED) (default=``ascii.Basic``)
+    :param Writer: Writer class (DEPRECATED) (default= :class:`Basic`)
     :param delimiter: column delimiter string
     :param write_comment: string defining a comment line in table
     :param quotechar: one-character string to quote fields containing special characters
     :param formats: dict of format specifiers or formatting functions
-    :param strip_whitespace: strip surrounding whitespace from column values (default=True)
+    :param strip_whitespace: strip surrounding whitespace from column values (default= ``True``)
     :param names: list of names corresponding to each data column
-    :param include_names: list of names to include in output (default=None selects all names)
-    :param exclude_names: list of names to exlude from output (applied after ``include_names``)
+    :param include_names: list of names to include in output (default= ``None`` selects all names)
+    :param exclude_names: list of names to exclude from output (applied after ``include_names``)
+    :param fast_writer: whether to use the fast Cython writer (default= ``True``)
     """
     if Writer is None:
         Writer = basic.Basic
     if 'strip_whitespace' not in kwargs:
         kwargs['strip_whitespace'] = True
-    writer = core._get_writer(Writer, **kwargs)
+    writer = core._get_writer(Writer, fast_writer, **kwargs)
     return writer
 
 
-def write(table, output=None,  format=None, Writer=None, **kwargs):
+def write(table, output=None,  format=None, Writer=None, fast_writer=True, **kwargs):
     """Write the input ``table`` to ``filename``.  Most of the default behavior
     for various parameters is determined by the Writer class.
 
     :param table: input table (Reader object, NumPy struct array, list of lists, etc)
-    :param output: output [filename, file-like object] (default = sys.stdout)
-    :param format: output format (default=``basic``)
+    :param output: output [filename, file-like object] (default = ``sys.stdout``)
+    :param format: output format (default= ``basic``)
     :param delimiter: column delimiter string
     :param write_comment: string defining a comment line in table
     :param quotechar: one-character string to quote fields containing special characters
     :param formats: dict of format specifiers or formatting functions
-    :param strip_whitespace: strip surrounding whitespace from column values (default=True)
+    :param strip_whitespace: strip surrounding whitespace from column values (default= ``True``)
     :param names: list of names corresponding to each data column
-    :param include_names: list of names to include in output (default=None selects all names)
-    :param exclude_names: list of names to exlude from output (applied after ``include_names``)
-    :param Writer: Writer class (DEPRECATED) (default=``ascii.Basic``)
+    :param include_names: list of names to include in output (default= ``None`` selects all names)
+    :param exclude_names: list of names to exclude from output (applied after ``include_names``)
+    :param fast_writer: whether to use the fast Cython writer (default= ``True``)
+    :param Writer: Writer class (DEPRECATED) (default= :class:`Basic`)
     """
     if output is None:
         output = sys.stdout
 
     table = Table(table, names=kwargs.get('names'))
 
+    if table.has_mixin_columns:
+        fast_writer = False
+
     Writer = _get_format_class(format, Writer, 'Writer')
-    writer = get_writer(Writer=Writer, **kwargs)
+    writer = get_writer(Writer=Writer, fast_writer=fast_writer, **kwargs)
+    if writer._format_name in core.FAST_CLASSES:
+        writer.write(table, output)
+        return
+
     lines = writer.write(table)
 
     # Write the lines to output
diff --git a/astropy/io/fits/card.py b/astropy/io/fits/card.py
index 40623e7..05e6f8e 100644
--- a/astropy/io/fits/card.py
+++ b/astropy/io/fits/card.py
@@ -11,7 +11,6 @@ from .verify import _Verify, _ErrList, VerifyError, VerifyWarning
 
 from . import conf
 from ...extern.six import string_types, integer_types, text_type, binary_type
-from ...extern.six.moves import xrange
 from ...utils import deprecated
 from ...utils.exceptions import AstropyUserWarning, AstropyDeprecationWarning
 
@@ -501,7 +500,7 @@ class Card(_Verify):
             elif self._keywd_hierarch_RE.match(keyword):
                 # In prior versions of PyFITS HIERARCH cards would only be
                 # created if the user-supplied keyword explicitly started with
-                # 'HIERARCH '.  Now we will create them automtically for long
+                # 'HIERARCH '.  Now we will create them automatically for long
                 # keywords, but we still want to support the old behavior too;
                 # the old behavior makes it possible to create HEIRARCH cards
                 # that would otherwise be recognized as RVKCs
@@ -855,7 +854,7 @@ class Card(_Verify):
         If one argument is given, that argument is treated as a full card image
         and parsed as such.  If two arguments are given, the first is treated
         as the card keyword (including the field-specifier if the card is
-        intened as a RVKC), and the second as the card value OR the first value
+        intended as a RVKC), and the second as the card value OR the first value
         can be the base keyword, and the second value the 'field-specifier:
         value' string.
 
@@ -901,7 +900,7 @@ class Card(_Verify):
     def _check_if_rvkc_image(self, *args):
         """
         Implements `Card._check_if_rvkc` for the case of an unparsed card
-        image.  If given one argment this is the full intact image.  If given
+        image.  If given one argument this is the full intact image.  If given
         two arguments the card has already been split between keyword and
         value+comment at the standard value indicator '= '.
         """
@@ -1268,7 +1267,6 @@ class Card(_Verify):
         output = []
 
         # do the value string
-        value_format = "'%-s&'"
         value = self._value.replace("'", "''")
         words = _words_group(value, value_length)
         for idx, word in enumerate(words):
@@ -1276,15 +1274,29 @@ class Card(_Verify):
                 headstr = '%-*s= ' % (KEYWORD_LENGTH, self.keyword)
             else:
                 headstr = 'CONTINUE  '
+
+            # If this is the final CONTINUE remove the '&'
+            if not self.comment and idx == len(words) - 1:
+                value_format = "'%-s'"
+            else:
+                value_format = "'%-s&'"
+
             value = value_format % word
+
             output.append('%-80s' % (headstr + value))
 
         # do the comment string
         comment_format = "%-s"
         if self.comment:
             words = _words_group(self.comment, comment_length)
-            for word in words:
-                comment = "CONTINUE  '&' / " + comment_format % word
+            for idx, word in enumerate(words):
+                # If this is the final CONTINUE remove the '&'
+                if idx == len(words) - 1:
+                    headstr = "CONTINUE  '' / "
+                else:
+                    headstr = "CONTINUE  '&' / "
+
+                comment = headstr + comment_format % word
                 output.append('%-80s' % comment)
 
         return ''.join(output)
@@ -1339,7 +1351,7 @@ class Card(_Verify):
                 # keywords can only occur if they came from the wild
                 keyword = self._split()[0]
                 if keyword != keyword.upper():
-                # Keyword should be uppercase unless it's a HIERARCH card
+                    # Keyword should be uppercase unless it's a HIERARCH card
                     errs.append(self.run_option(
                         option,
                         err_text='Card keyword %r is not upper case.' %
diff --git a/astropy/io/fits/column.py b/astropy/io/fits/column.py
index 00bb0f0..22cde67 100644
--- a/astropy/io/fits/column.py
+++ b/astropy/io/fits/column.py
@@ -67,7 +67,7 @@ ASCII2NUMPY = {'A': 'a', 'I': 'i4', 'J': 'i8', 'F': 'f4', 'E': 'f4',
 ASCII2STR = {'A': 's', 'I': 'd', 'J': 'd', 'F': 'f', 'E': 'E', 'D': 'E'}
 
 # For each ASCII table format code, provides a default width (and decimal
-# precision) for when one isn't given explicity in the column format
+# precision) for when one isn't given explicitly in the column format
 ASCII_DEFAULT_WIDTHS= {'A': (1, 0), 'I': (10, 0), 'J': (15, 0),
                        'E': (15, 7), 'F': (16, 7), 'D': (25, 17)}
 
@@ -102,8 +102,9 @@ TDEF_RE = re.compile(r'(?P<label>^T[A-Z]*)(?P<num>[1-9][0-9 ]*$)')
 # table dimension keyword regular expression (fairly flexible with whitespace)
 TDIM_RE = re.compile(r'\(\s*(?P<dims>(?:\d+,\s*)+\s*\d+)\s*\)\s*')
 
-ASCIITNULL = 0          # value for ASCII table cell with value = TNULL
-                        # this can be reset by user.
+# value for ASCII table cell with value = TNULL
+# this can be reset by user.
+ASCIITNULL = 0
 
 # The default placeholder to use for NULL values in ASCII tables when
 # converting from binary to ASCII tables
@@ -394,7 +395,7 @@ class Column(object):
 
         array : iterable, optional
             a `list`, `numpy.ndarray` (or other iterable that can be used to
-            initialize an ndarray) providing intial data for this column.
+            initialize an ndarray) providing initial data for this column.
             The array will be automatically converted, if possible, to the data
             format of the column.  In the case were non-trivial ``bscale``
             and/or ``bzero`` arguments are given, the values in the array must
@@ -740,7 +741,7 @@ class Column(object):
         BINARY tables.
         """
 
-        # If the given format string is unabiguously a Numpy dtype or one of
+        # If the given format string is unambiguously a Numpy dtype or one of
         # the Numpy record format type specifiers supported by PyFITS then that
         # should take priority--otherwise assume it is a FITS format
         if isinstance(format, np.dtype):
@@ -797,7 +798,7 @@ class Column(object):
         except VerifyError:
             # For whatever reason our guess was wrong (for example if we got
             # just 'F' that's not a valid binary format, but it an ASCII format
-            # code albeit with the width/precision ommitted
+            # code albeit with the width/precision omitted
             guess_format = (_AsciiColumnFormat
                             if guess_format is _ColumnFormat
                             else _ColumnFormat)
@@ -890,7 +891,7 @@ class ColDefs(object):
         else:
             tbtype = 'BinTableHDU'  # The old default
 
-        # Backards-compat support
+        # Backwards-compat support
         # TODO: Remove once the tbtype argument is removed entirely
         if tbtype == 'BinTableHDU':
             klass = cls
@@ -1083,7 +1084,7 @@ class ColDefs(object):
 
         # Handle a few special cases of column format options that are not
         # compatible between ASCII an binary tables
-        # TODO: This is sort of hacked in right now; we really neet
+        # TODO: This is sort of hacked in right now; we really need
         # separate classes for ASCII and Binary table Columns, and they
         # should handle formatting issues like these
         if not isinstance(new_column.format, _AsciiColumnFormat):
@@ -1831,7 +1832,7 @@ def _convert_fits2record(format):
     if dtype in FITS2NUMPY:
         if dtype == 'A':
             output_format = FITS2NUMPY[dtype] + str(repeat)
-            # to accomodate both the ASCII table and binary table column
+            # to accommodate both the ASCII table and binary table column
             # format spec, i.e. A7 in ASCII table is the same as 7A in
             # binary table, so both will produce 'a7'.
             # Technically the FITS standard does not allow this but it's a very
@@ -1948,7 +1949,7 @@ def _convert_ascii_format(format, reverse=False):
             return 'A1'
         elif kind == 'i':
             # Use for the width the maximum required to represent integers
-            # of that byte size plus 1 for signs, but use a minumum of the
+            # of that byte size plus 1 for signs, but use a minimum of the
             # default width (to keep with existing behavior)
             width = 1 + len(str(2 ** (itemsize * 8)))
             width = max(width, ASCII_DEFAULT_WIDTHS['I'][0])
diff --git a/astropy/io/fits/connect.py b/astropy/io/fits/connect.py
index 129d658..a1a2349 100644
--- a/astropy/io/fits/connect.py
+++ b/astropy/io/fits/connect.py
@@ -9,7 +9,6 @@ import warnings
 import numpy as np
 
 from .. import registry as io_registry
-from ... import log
 from ... import units as u
 from ...extern import six
 from ...extern.six import string_types
@@ -210,6 +209,13 @@ def write_table_fits(input, output, overwrite=False):
         Whether to overwrite any existing file without warning.
     """
 
+    # Tables with mixin columns are not supported
+    if input.has_mixin_columns:
+        mixin_names = [name for name, col in input.columns.items()
+                       if not isinstance(col, input.ColumnClass)]
+        raise ValueError('cannot write table with mixin column(s) {0} to FITS'
+                         .format(mixin_names))
+
     # Check if output file already exists
     if isinstance(output, string_types) and os.path.exists(output):
         if overwrite:
diff --git a/astropy/io/fits/convenience.py b/astropy/io/fits/convenience.py
index 03e8806..a3fb2f5 100644
--- a/astropy/io/fits/convenience.py
+++ b/astropy/io/fits/convenience.py
@@ -51,7 +51,7 @@ explanation of all the different formats.
     multiple argument formats that were used in past versions of PyFITS.
     Unfortunately, it is not possible to support all formats without
     introducing some ambiguity.  A future Astropy release may standardize
-    around a single format and offically deprecate the other formats.
+    around a single format and officially deprecate the other formats.
 """
 
 
@@ -65,8 +65,7 @@ from .hdu.hdulist import fitsopen
 from .hdu.image import PrimaryHDU, ImageHDU
 from .hdu.table import BinTableHDU
 from .header import Header
-from .util import (fileobj_closed, fileobj_name, fileobj_mode,
-                   fileobj_closed, _is_int)
+from .util import fileobj_closed, fileobj_name, fileobj_mode, _is_int
 from ...extern.six import string_types
 from ...utils import deprecated
 
@@ -511,7 +510,7 @@ def update(filename, data, *args, **kwargs):
         `astropy.io.fits.open`.
     """
 
-    # The arguments to this function are a bit tricker to deal with than others
+    # The arguments to this function are a bit trickier to deal with than others
     # in this module, since the documentation has promised that the header
     # argument can be an optional positional argument.
     if args and isinstance(args[0], Header):
diff --git a/astropy/io/fits/diff.py b/astropy/io/fits/diff.py
index 46ea2d4..7023e60 100644
--- a/astropy/io/fits/diff.py
+++ b/astropy/io/fits/diff.py
@@ -14,6 +14,7 @@ import glob
 import inspect
 import io
 import textwrap
+import os.path
 
 from collections import defaultdict
 from itertools import islice
@@ -28,7 +29,7 @@ from ...utils import indent
 from .card import Card, BLANK_CARD
 from .header import Header
 # HDUList is used in one of the doctests
-from .hdu.hdulist import fitsopen, HDUList  # pylint: disable=W0611
+from .hdu.hdulist import fitsopen  # pylint: disable=W0611
 from .hdu.table import _TableLikeHDU
 
 
@@ -92,16 +93,17 @@ class _BaseDiff(object):
     @classmethod
     def fromdiff(cls, other, a, b):
         """
-        Returns a new Diff object of a specfic subclass from an existing diff
+        Returns a new Diff object of a specific subclass from an existing diff
         object, passing on the values for any arguments they share in common
         (such as ignore_keywords).
 
         For example::
 
-            >>> hdul1, hdul2 = HDUList(), HDUList()
-            >>> headera, headerb = Header(), Header()
-            >>> fd = FITSDiff(hdul1, hdul2, ignore_keywords=['*'])
-            >>> hd = HeaderDiff.fromdiff(fd, headera, headerb)
+            >>> from astropy.io import fits
+            >>> hdul1, hdul2 = fits.HDUList(), fits.HDUList()
+            >>> headera, headerb = fits.Header(), fits.Header()
+            >>> fd = fits.FITSDiff(hdul1, hdul2, ignore_keywords=['*'])
+            >>> hd = fits.HeaderDiff.fromdiff(fd, headera, headerb)
             >>> list(hd.ignore_keywords)
             ['*']
         """
@@ -129,7 +131,7 @@ class _BaseDiff(object):
         return not any(getattr(self, attr) for attr in self.__dict__
                        if attr.startswith('diff_'))
 
-    def report(self, fileobj=None, indent=0):
+    def report(self, fileobj=None, indent=0, clobber=False):
         """
         Generates a text report on the differences (if any) between two
         objects, and either returns it as a string or writes it to a file-like
@@ -137,28 +139,46 @@ class _BaseDiff(object):
 
         Parameters
         ----------
-        fileobj : file-like object or None, optional
+        fileobj : file-like object, string, or None (optional)
             If `None`, this method returns the report as a string. Otherwise it
             returns `None` and writes the report to the given file-like object
-            (which must have a ``.write()`` method at a minimum).
+            (which must have a ``.write()`` method at a minimum), or to a new
+            file at the path specified.
 
         indent : int
             The number of 4 space tabs to indent the report.
 
+        clobber : bool
+            Whether the report output should overwrite an existing file, when
+            fileobj is specified as a path.
+
         Returns
         -------
         report : str or None
         """
 
         return_string = False
-        if fileobj is None:
+        filepath = None
+
+        if isinstance(fileobj, string_types):
+            if os.path.exists(fileobj) and not clobber:
+                raise IOError("File {0} exists, aborting (pass in "
+                              "clobber=True to overwrite)".format(fileobj))
+            else:
+                filepath = fileobj
+                fileobj = open(filepath, 'w')
+        elif fileobj is None:
             fileobj = io.StringIO()
             return_string = True
 
         self._fileobj = fileobj
         self._indent = indent  # This is used internally by _writeln
 
-        self._report()
+        try:
+            self._report()
+        finally:
+            if filepath:
+                fileobj.close()
 
         if return_string:
             return fileobj.getvalue()
@@ -218,7 +238,7 @@ class FITSDiff(_BaseDiff):
             differences.  Though the count of differences is the same either
             way, this allows controlling the number of different values that
             are kept in memory or output.  If a negative value is given, then
-            numdifs is treated as unlimited (default: 10).
+            numdiffs is treated as unlimited (default: 10).
 
         tolerance : float, optional
             The relative difference to allow when comparing two float values
@@ -928,7 +948,7 @@ class TableDataDiff(_BaseDiff):
       objects.
 
     - ``diff_column_attributes``: Lists columns that are in both tables but
-      have different secondard attributes, such as TUNIT or TDISP.  The format
+      have different secondary attributes, such as TUNIT or TDISP.  The format
       is a list of 2-tuples: The first a tuple of the column name and the
       attribute, the second a tuple of the different values.
 
diff --git a/astropy/io/fits/file.py b/astropy/io/fits/file.py
index 68a4029..83c03f2 100644
--- a/astropy/io/fits/file.py
+++ b/astropy/io/fits/file.py
@@ -3,6 +3,7 @@
 from __future__ import division, with_statement
 
 from ...utils.compat import gzip as _astropy_gzip
+from ...utils.data import download_file, _is_url
 import gzip as _system_gzip
 import mmap
 import os
@@ -17,7 +18,7 @@ from numpy import memmap as Memmap
 
 from .util import (isreadable, iswritable, isfile, fileobj_open, fileobj_name,
                    fileobj_closed, fileobj_mode, _array_from_file,
-                   _array_to_file, _write_string, encode_ascii)
+                   _array_to_file, _write_string)
 from ...extern.six import b, string_types
 from ...extern.six.moves import urllib
 from ...utils.exceptions import AstropyUserWarning
@@ -81,7 +82,11 @@ class _File(object):
     # See self._test_mmap
     _mmap_available = None
 
-    def __init__(self, fileobj=None, mode=None, memmap=False, clobber=False):
+    def __init__(self, fileobj=None, mode=None, memmap=None, clobber=False,
+                 cache=True):
+        self.strict_memmap = bool(memmap)
+        memmap = True if memmap is None else memmap
+
         if fileobj is None:
             self.__file = None
             self.closed = False
@@ -109,25 +114,9 @@ class _File(object):
             raise ValueError("Mode '%s' not recognized" % mode)
 
         if (isinstance(fileobj, string_types) and
-                mode not in ('ostream', 'append') and
-                not os.path.exists(fileobj)):
-
-            # Not writing file and file does not exist on local machine and
-            # name does not begin with a drive letter (Windows), try to get it
-            # over the web.
-            try:
-                if not os.path.splitdrive(fileobj)[0]:
-                    # Basically if the filename (on Windows anyways) doesn't
-                    # have a drive letter try to open it as a URL
-                    self.name, _ = urllib.request.urlretrieve(fileobj)
-                else:
-                    # Otherwise the file was already not found so just raise
-                    # a ValueError
-                    raise ValueError("File not found")
-            except (TypeError, ValueError, IOError):
-                # A couple different exceptions can occur here when passing a
-                # filename into urlretrieve in Python 3
-                raise IOError('File does not exist: {0!r}'.format(fileobj))
+            mode not in ('ostream', 'append') and
+            _is_url(fileobj)): # This is an URL.
+                self.name = download_file(fileobj, cache=cache)
         else:
             self.name = fileobj_name(fileobj)
 
@@ -342,13 +331,9 @@ class _File(object):
         """
 
         # The file will be overwritten...
-        if ((self.file_like and
-                (hasattr(fileobj, 'len') and fileobj.len > 0)) or
-                (os.path.exists(self.name) and
-                 os.path.getsize(self.name) != 0)):
+        if ((self.file_like and hasattr(fileobj, 'len') and fileobj.len > 0) or
+            (os.path.exists(self.name) and os.path.getsize(self.name) != 0)):
             if clobber:
-                warnings.warn("Overwriting existing file %r." % self.name,
-                              AstropyUserWarning)
                 if self.file_like and hasattr(fileobj, 'truncate'):
                     fileobj.truncate(0)
                 else:
diff --git a/astropy/io/fits/fitsrec.py b/astropy/io/fits/fitsrec.py
index f1d3303..611ec5f 100644
--- a/astropy/io/fits/fitsrec.py
+++ b/astropy/io/fits/fitsrec.py
@@ -13,10 +13,10 @@ from numpy import char as chararray
 
 from .column import (ASCIITNULL, FITS2NUMPY, ASCII2NUMPY, ASCII2STR, ColDefs,
                      _AsciiColDefs, _FormatX, _FormatP, _VLF, _get_index,
-                     _wrapx, _unwrapx, _makep, _convert_ascii_format, Delayed)
+                     _wrapx, _unwrapx, _makep, Delayed)
 from .util import decode_ascii, encode_ascii
 from ...extern.six import string_types
-from ...extern.six.moves import xrange, map
+from ...extern.six.moves import xrange
 from ...utils import lazyproperty
 from ...utils.compat import ignored
 from ...utils.exceptions import AstropyDeprecationWarning, AstropyUserWarning
@@ -564,18 +564,9 @@ class FITS_rec(np.recarray):
         attributes (including ``._convert``!).  So we need to make a deep copy
         of all those attributes so that the two arrays truly do not share any
         data.
-
-        Note: The ``order`` argument is unsupported in Numpy 1.5 and will be
-        ignored when used with that version.
         """
 
-        try:
-            new = super(FITS_rec, self).copy(order=order)
-        except TypeError:
-            # This will probably occur if the order argument is not supported,
-            # such as on Numpy 1.5; in other words we're just going to ask
-            # forgiveness rather than check the Numpy version explicitly.
-            new = super(FITS_rec, self).copy()
+        new = super(FITS_rec, self).copy(order=order)
 
         new.__dict__ = copy.deepcopy(self.__dict__)
         return new
diff --git a/astropy/io/fits/hdu/base.py b/astropy/io/fits/hdu/base.py
index 10b5fa6..c0b86d5 100644
--- a/astropy/io/fits/hdu/base.py
+++ b/astropy/io/fits/hdu/base.py
@@ -11,15 +11,14 @@ import warnings
 import numpy as np
 
 from .. import conf
-from ..card import Card
 from ..file import _File
-from ..header import Header, HEADER_END_RE, _pad_length
+from ..header import Header, _pad_length
 from ..util import (_is_int, _is_pseudo_unsigned, _unsigned_zero,
-                    itersubclasses, encode_ascii, decode_ascii,
+                    itersubclasses, decode_ascii,
                     _get_array_mmap, _array_to_file, first)
 from ..verify import _Verify, _ErrList
 
-from ....extern.six import string_types, next
+from ....extern.six import string_types
 from ....utils import lazyproperty, deprecated
 from ....utils.compat import ignored
 from ....utils.exceptions import AstropyUserWarning
@@ -320,7 +319,7 @@ class _BaseHDU(object):
         Parameters
         ----------
         data : str, bytearray, memoryview, ndarray
-           A byte string contining the HDU's header and data.
+           A byte string containing the HDU's header and data.
 
         checksum : bool, optional
            Check the HDU's checksum and/or datasum.
@@ -757,9 +756,9 @@ class _BaseHDU(object):
         self._data_size = datsize
         self._data_replaced = False
 
-_AllHDU = _BaseHDU  # For backwards-compatibility, though nobody should have
-                    # been using this directly
-
+# For backwards-compatibility, though nobody should have
+# been using this directly:
+_AllHDU = _BaseHDU
 
 # For convenience...
 # TODO: register_hdu could be made into a class decorator which would be pretty
@@ -1232,7 +1231,7 @@ class _ValidHDU(_BaseHDU, _Verify):
             err_text = "'%s' card does not exist." % keyword
             fix_text = "Fixed by inserting a new '%s' card." % keyword
             if fixable:
-                # use repr to accomodate both string and non-string types
+                # use repr to accommodate both string and non-string types
                 # Boolean is also OK in this constructor
                 card = (keyword, fix_value)
 
@@ -1383,7 +1382,7 @@ class _ValidHDU(_BaseHDU, _Verify):
         Verify that the value in the ``DATASUM`` keyword matches the value
         calculated for the ``DATASUM`` of the current HDU data.
 
-        blocking: str, optional
+        blocking : str, optional
             "standard" or "nonstandard", compute sum 2880 bytes at a time, or
             not
 
@@ -1413,7 +1412,7 @@ class _ValidHDU(_BaseHDU, _Verify):
         Verify that the value in the ``CHECKSUM`` keyword matches the
         value calculated for the current HDU CHECKSUM.
 
-        blocking: str, optional
+        blocking : str, optional
             "standard" or "nonstandard", compute sum 2880 bytes at a time, or
             not
 
@@ -1724,7 +1723,7 @@ class ExtensionHDU(_ValidHDU):
                        1, option, errs)
 
         return errs
-# For backwards compatilibity, though this needs to be deprecated
+# For backwards compatibility, though this needs to be deprecated
 # TODO: Mark this as deprecated
 _ExtensionHDU = ExtensionHDU
 
diff --git a/astropy/io/fits/hdu/compressed.py b/astropy/io/fits/hdu/compressed.py
index d8f8b49..0f1e0d7 100644
--- a/astropy/io/fits/hdu/compressed.py
+++ b/astropy/io/fits/hdu/compressed.py
@@ -12,14 +12,13 @@ from .base import DELAYED, ExtensionHDU
 from .image import _ImageBaseHDU, ImageHDU
 from .table import BinTableHDU
 from ..card import Card
-from ..column import Column, ColDefs, _FormatP, TDEF_RE
+from ..column import Column, ColDefs, TDEF_RE
 from ..column import KEYWORD_NAMES as TABLE_KEYWORD_NAMES
 from ..fitsrec import FITS_rec
 from ..header import Header
 from ..util import _is_pseudo_unsigned, _unsigned_zero, _is_int
 
 from ....extern.six import string_types, iteritems
-from ....extern.six.moves import xrange, filter
 from ....utils import lazyproperty, deprecated
 from ....utils.compat import ignored
 from ....utils.exceptions import (AstropyPendingDeprecationWarning,
@@ -460,7 +459,7 @@ class CompImageHDU(BinTableHDU):
                convention are described at the `FITS Support Office web site
                <http://fits.gsfc.nasa.gov/registry/tilecompression.html>`_.
                Basically, the compressed image tiles are stored in rows of a
-               variable length arrray column in a FITS binary table.  The
+               variable length array column in a FITS binary table.  The
                astropy.io.fits recognizes that this binary table extension
                contains an image and treats it as if it were an image
                extension.  Under this tile-compression format, FITS header
@@ -508,7 +507,7 @@ class CompImageHDU(BinTableHDU):
         range -2 to -100).
 
         Very high compression factors (of 100 or more) can be achieved by using
-        large ``hcomp_scale`` values, however, this can produce undesireable
+        large ``hcomp_scale`` values, however, this can produce undesirable
         'blocky' artifacts in the compressed image.  A variation of the
         HCOMPRESS algorithm (called HSCOMPRESS) can be used in this case to
         apply a small amount of smoothing of the image when it is uncompressed
@@ -526,9 +525,9 @@ class CompImageHDU(BinTableHDU):
         GZIP, RICE, or HCOMPRESS).  This technique produces much higher
         compression factors than simply using the GZIP utility to externally
         compress the whole FITS file, but it also means that the original
-        floating point value pixel values are not exactly perserved.  When done
+        floating point value pixel values are not exactly preserved.  When done
         properly, this integer scaling technique will only discard the
-        insignificant noise while still preserving all the real imformation in
+        insignificant noise while still preserving all the real information in
         the image.  The amount of precision that is retained in the pixel
         values is controlled by the ``quantize_level`` parameter.  Larger
         values will result in compressed images whose pixels more closely match
@@ -548,7 +547,7 @@ class CompImageHDU(BinTableHDU):
         between adjacent scaled integer pixel values will equal 2.0 by default.
         Note that the RMS noise is independently calculated for each tile of
         the image, so the resulting integer scaling factor may fluctuate
-        slightly for each tile.  In some cases, it may be desireable to specify
+        slightly for each tile.  In some cases, it may be desirable to specify
         the exact quantization level to be used, instead of specifying it
         relative to the calculated noise value.  This may be done by specifying
         the negative of desired quantization level for the value of
@@ -1457,7 +1456,7 @@ class CompImageHDU(BinTableHDU):
         # The header attribute is the header for the image data.  It
         # is not actually stored in the object dictionary.  Instead,
         # the _image_header is stored.  If the _image_header attribute
-        # has already been defined we just return it.  If not, we nust
+        # has already been defined we just return it.  If not, we must
         # create it from the table header (the _header attribute).
         if hasattr(self, '_image_header'):
             return self._image_header
@@ -1764,7 +1763,7 @@ class CompImageHDU(BinTableHDU):
         self._bitpix = _ImageBaseHDU.ImgCode[self.data.dtype.name]
         self._bzero = self.header.get('BZERO', 0)
         self._bscale = self.header.get('BSCALE', 1)
-        # Update BITPIX for the image header specificially
+        # Update BITPIX for the image header specifically
         # TODO: Make this more clear by using self._image_header, but only once
         # this has been fixed so that the _image_header attribute is guaranteed
         # to be valid
@@ -1810,7 +1809,7 @@ class CompImageHDU(BinTableHDU):
 
             # Now we need to perform an ugly hack to set the compressed data as
             # the .data attribute on the HDU so that the call to _writedata
-            # handles it propertly
+            # handles it properly
             self.__dict__['data'] = self.compressed_data
 
         return super(CompImageHDU, self)._prewriteto(checksum=checksum,
@@ -1910,7 +1909,7 @@ class CompImageHDU(BinTableHDU):
             # indices of slices (starting from 0)
             first_tile = self.data[tuple(slice(d) for d in tile_dims)]
 
-            # The checksum agorithm used is literally just the sum of the bytes
+            # The checksum algorithm used is literally just the sum of the bytes
             # of the tile data (not its actual floating point values).  Integer
             # overflow is irrelevant.
             csum = first_tile.view(dtype='uint8').sum()
diff --git a/astropy/io/fits/hdu/groups.py b/astropy/io/fits/hdu/groups.py
index a24a70c..5e3d8df 100644
--- a/astropy/io/fits/hdu/groups.py
+++ b/astropy/io/fits/hdu/groups.py
@@ -142,8 +142,8 @@ class GroupData(FITS_rec):
                 parnames = ['PAR%d' % (idx + 1) for idx in range(npars)]
 
             if len(parnames) != npars:
-                raise ValueError('The number of paramater data arrays does '
-                                 'not match the number of paramaters.')
+                raise ValueError('The number of parameter data arrays does '
+                                 'not match the number of parameters.')
 
             unique_parnames = _unique_parnames(parnames + ['DATA'])
 
@@ -252,7 +252,7 @@ class GroupsHDU(PrimaryHDU, _TableLikeHDU):
         super(GroupsHDU, self).__init__(data=data, header=header)
 
         # The name of the table record array field that will contain the group
-        # data for each group; 'data' by default, but may be precdeded by any
+        # data for each group; 'data' by default, but may be preceded by any
         # number of underscores if 'data' is already a parameter name
         self._data_field = 'DATA'
 
@@ -527,7 +527,7 @@ class GroupsHDU(PrimaryHDU, _TableLikeHDU):
             # This is the case where the data has not been read from the file
             # yet.  We can handle that in a generic manner so we do it in the
             # base class.  The other possibility is that there is no data at
-            # all.  This can also be handled in a gereric manner.
+            # all.  This can also be handled in a generic manner.
             return super(GroupsHDU, self)._calculate_datasum(blocking=blocking)
 
     def _summary(self):
diff --git a/astropy/io/fits/hdu/hdulist.py b/astropy/io/fits/hdu/hdulist.py
index ca0d394..6933b71 100644
--- a/astropy/io/fits/hdu/hdulist.py
+++ b/astropy/io/fits/hdu/hdulist.py
@@ -22,7 +22,8 @@ from ....utils import indent
 from ....utils.exceptions import AstropyUserWarning
 
 
-def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
+def fitsopen(name, mode='readonly', memmap=None, save_backup=False,
+             cache=True, **kwargs):
     """Factory function to open a FITS file and return an `HDUList` object.
 
     Parameters
@@ -30,7 +31,7 @@ def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
     name : file path, file object or file-like object
         File to be opened.
 
-    mode : str
+    mode : str, optional
         Open mode, 'readonly' (default), 'update', 'append', 'denywrite', or
         'ostream'.
 
@@ -38,17 +39,22 @@ def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
         match the mode the file was opened with, readonly (rb), update (rb+),
         append (ab+), ostream (w), denywrite (rb)).
 
-    memmap : bool
+    memmap : bool, optional
         Is memory mapping to be used?
 
-    save_backup : bool
+    save_backup : bool, optional
         If the file was opened in update or append mode, this ensures that a
         backup of the original file is saved before any changes are flushed.
         The backup has the same name as the original file with ".bak" appended.
         If "file.bak" already exists then "file.bak.1" is used, and so on.
 
-    kwargs : dict
-        optional keyword arguments, possible values are:
+    cache : bool, optional
+        If the file name is a URL, `~astropy.utils.data.download_file` is used
+        to open the file.  This specifies whether or not to save the file
+        locally in Astropy's download cache (default: `True`).
+
+    kwargs : dict, optional
+        additional optional keyword arguments, possible values are:
 
         - **uint** : bool
 
@@ -78,7 +84,7 @@ def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
 
         - **disable_image_compression** : bool
 
-            If `True`, treates compressed image HDU's like normal
+            If `True`, treats compressed image HDU's like normal
             binary table HDU's.
 
         - **do_not_scale_image_data** : bool
@@ -107,7 +113,11 @@ def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
 
     if memmap is None:
         from .. import conf
-        memmap = conf.use_memmap
+        # distinguish between True (kwarg explicitly set)
+        # and None (preference for memmap in config, might be ignored)
+        memmap = None if conf.use_memmap else False
+    else:
+        memmap = bool(memmap)
 
     if 'uint16' in kwargs and 'uint' not in kwargs:
         kwargs['uint'] = kwargs['uint16']
@@ -116,7 +126,7 @@ def fitsopen(name, mode='readonly', memmap=None, save_backup=False, **kwargs):
     if not name:
         raise ValueError('Empty filename: %s' % repr(name))
 
-    return HDUList.fromfile(name, mode, memmap, save_backup, **kwargs)
+    return HDUList.fromfile(name, mode, memmap, save_backup, cache, **kwargs)
 
 
 class HDUList(list, _Verify):
@@ -247,8 +257,8 @@ class HDUList(list, _Verify):
         self.close()
 
     @classmethod
-    def fromfile(cls, fileobj, mode=None, memmap=False,
-                 save_backup=False, **kwargs):
+    def fromfile(cls, fileobj, mode=None, memmap=None,
+                 save_backup=False, cache=True, **kwargs):
         """
         Creates an `HDUList` instance from a file-like object.
 
@@ -258,7 +268,7 @@ class HDUList(list, _Verify):
         """
 
         return cls._readfrom(fileobj=fileobj, mode=mode, memmap=memmap,
-                             save_backup=save_backup, **kwargs)
+                             save_backup=save_backup, cache=cache, **kwargs)
 
     @classmethod
     def fromstring(cls, data, **kwargs):
@@ -765,7 +775,7 @@ class HDUList(list, _Verify):
 
     @classmethod
     def _readfrom(cls, fileobj=None, data=None, mode=None,
-                  memmap=False, save_backup=False, **kwargs):
+                  memmap=None, save_backup=False, cache=True, **kwargs):
         """
         Provides the implementations from HDUList.fromfile and
         HDUList.fromstring, both of which wrap this method, as their
@@ -775,7 +785,7 @@ class HDUList(list, _Verify):
         if fileobj is not None:
             if not isinstance(fileobj, _File):
                 # instantiate a FITS file object (ffo)
-                ffo = _File(fileobj, mode=mode, memmap=memmap)
+                ffo = _File(fileobj, mode=mode, memmap=memmap, cache=cache)
             else:
                 ffo = fileobj
             # The pyfits mode is determined by the _File initializer if the
@@ -942,7 +952,7 @@ class HDUList(list, _Verify):
 
         if not self.__file.file_like:
             old_mode = os.stat(old_name).st_mode
-            # The underlying file is an acutal file object.  The HDUList is
+            # The underlying file is an actual file object.  The HDUList is
             # resized, so we need to write it to a tmp file, delete the
             # original file, and rename the tmp file to the original file.
             if self.__file.compression == 'gzip':
diff --git a/astropy/io/fits/hdu/image.py b/astropy/io/fits/hdu/image.py
index 3cfb4bf..0c580ec 100644
--- a/astropy/io/fits/hdu/image.py
+++ b/astropy/io/fits/hdu/image.py
@@ -7,13 +7,11 @@ import numpy as np
 
 from .base import DELAYED, _ValidHDU, ExtensionHDU
 from ..header import Header
-from ..util import (_is_pseudo_unsigned, _unsigned_zero, _is_int,
-                    _normalize_slice)
+from ..util import _is_pseudo_unsigned, _unsigned_zero, _is_int
 from ..verify import VerifyWarning
 
 from ....extern.six import string_types
-from ....extern.six.moves import xrange
-from ....utils import lazyproperty
+from ....utils import isiterable, lazyproperty
 
 
 class _ImageBaseHDU(_ValidHDU):
@@ -321,7 +319,7 @@ class _ImageBaseHDU(_ValidHDU):
                          after='BITPIX')
 
         # TODO: This routine is repeated in several different classes--it
-        # should probably be made available as a methond on all standard HDU
+        # should probably be made available as a method on all standard HDU
         # types
         # add NAXISi if it does not exist
         for idx, axis in enumerate(self._axes):
@@ -592,6 +590,14 @@ class _ImageBaseHDU(_ValidHDU):
             # No further conversion of the data is necessary
             return raw_data
 
+        try:
+            if self._file.strict_memmap:
+                raise ValueError("Cannot load a memory-mapped image: "
+                                 "BZERO/BSCALE/BLANK header keywords present. "
+                                 "Set memmap=False.")
+        except AttributeError:  # strict_memmap not set
+            pass
+
         data = None
         if not (self._orig_bzero == 0 and self._orig_bscale == 1):
             data = self._convert_pseudo_unsigned(raw_data)
@@ -703,7 +709,7 @@ class _ImageBaseHDU(_ValidHDU):
             # This is the case where the data has not been read from the file
             # yet.  We can handle that in a generic manner so we do it in the
             # base class.  The other possibility is that there is no data at
-            # all.  This can also be handled in a gereric manner.
+            # all.  This can also be handled in a generic manner.
             return super(_ImageBaseHDU, self)._calculate_datasum(
                 blocking=blocking)
 
@@ -726,109 +732,80 @@ class Section(object):
         self.hdu = hdu
 
     def __getitem__(self, key):
-        dims = []
         if not isinstance(key, tuple):
             key = (key,)
         naxis = len(self.hdu.shape)
-        if naxis < len(key):
-            raise IndexError('too many indices')
-        elif naxis > len(key):
-            key = key + (slice(None),) * (naxis - len(key))
+        return_scalar = (all(isinstance(k, (int, np.integer)) for k in key)
+                         and len(key) == naxis)
+        if not any(k is Ellipsis for k in key):
+            # We can always add a ... at the end, after making note of whether
+            # to return a scalar.
+            key += Ellipsis,
+        ellipsis_count = len([k for k in key if k is Ellipsis])
+        if len(key) - ellipsis_count > naxis or ellipsis_count > 1:
+            raise IndexError('too many indices for array')
+        # Insert extra dimensions as needed.
+        idx = next(i for i, k in enumerate(key + (Ellipsis,)) if k is Ellipsis)
+        key = key[:idx] + (slice(None),) * (naxis - len(key) + 1) + key[idx+1:]
+        return_0dim = (all(isinstance(k, (int, np.integer)) for k in key)
+                       and len(key) == naxis)
 
+        dims = []
         offset = 0
-
-        # Declare outside of loop scope for use below--don't abuse for loop
-        # scope leak defect
-        idx = 0
+        # Find all leading axes for which a single point is used.
         for idx in range(naxis):
             axis = self.hdu.shape[idx]
-            indx = _iswholeline(key[idx], axis)
+            indx = _IndexInfo(key[idx], axis)
             offset = offset * axis + indx.offset
-
-            # all elements after the first WholeLine must be WholeLine or
-            # OnePointAxis
-            if isinstance(indx, (_WholeLine, _LineSlice)):
+            if not _is_int(key[idx]):
                 dims.append(indx.npts)
                 break
-            elif isinstance(indx, _SteppedSlice):
-                raise IndexError('Stepped Slice not supported')
-
-        contiguousSubsection = True
 
+        is_contiguous = indx.contiguous
         for jdx in range(idx + 1, naxis):
             axis = self.hdu.shape[jdx]
-            indx = _iswholeline(key[jdx], axis)
+            indx = _IndexInfo(key[jdx], axis)
             dims.append(indx.npts)
-            if not isinstance(indx, _WholeLine):
-                contiguousSubsection = False
-
-            # the offset needs to multiply the length of all remaining axes
-            else:
+            if indx.npts == axis and indx.contiguous:
+                # The offset needs to multiply the length of all remaining axes
                 offset *= axis
+            else:
+                is_contiguous = False
 
-        if contiguousSubsection:
-            if not dims:
-                dims = [1]
-
-            dims = tuple(dims)
+        if is_contiguous:
+            dims = tuple(dims) or (1,)
             bitpix = self.hdu._orig_bitpix
-            offset = self.hdu._data_offset + (offset * abs(bitpix) // 8)
+            offset = self.hdu._data_offset + offset * abs(bitpix) // 8
             data = self.hdu._get_scaled_image_data(offset, dims)
         else:
             data = self._getdata(key)
 
+        if return_scalar:
+            data = data.item()
+        elif return_0dim:
+            data = data.squeeze()
         return data
 
     def _getdata(self, keys):
-        out = []
-
-        # Determine the number of slices in the set of input keys.
-        # If there is only one slice then the result is a one dimensional
-        # array, otherwise the result will be a multidimensional array.
-        n_slices = 0
-        for idx, key in enumerate(keys):
-            if isinstance(key, slice):
-                n_slices = n_slices + 1
-
-        for idx, key in enumerate(keys):
+        for idx, (key, axis) in enumerate(zip(keys, self.hdu.shape)):
             if isinstance(key, slice):
-                # OK, this element is a slice so see if we can get the data for
-                # each element of the slice.
-                axis = self.hdu.shape[idx]
-                ns = _normalize_slice(key, axis)
-
-                for k in range(ns.start, ns.stop):
-                    key1 = list(keys)
-                    key1[idx] = k
-                    key1 = tuple(key1)
-
-                    if n_slices > 1:
-                        # This is not the only slice in the list of keys so
-                        # we simply get the data for this section and append
-                        # it to the list that is output.  The out variable will
-                        # be a list of arrays.  When we are done we will pack
-                        # the list into a single multidimensional array.
-                        out.append(self[key1])
-                    else:
-                        # This is the only slice in the list of keys so if this
-                        # is the first element of the slice just set the output
-                        # to the array that is the data for the first slice.
-                        # If this is not the first element of the slice then
-                        # append the output for this slice element to the array
-                        # that is to be output.  The out variable is a single
-                        # dimensional array.
-                        if k == ns.start:
-                            out = self[key1]
-                        else:
-                            out = np.append(out, self[key1])
-
-                # We have the data so break out of the loop.
+                ks = range(*key.indices(axis))
                 break
+            elif isiterable(key):
+                # Handle both integer and boolean arrays.
+                ks = np.arange(axis, dtype=int)[key]
+                break
+            # This should always break at some point if _getdata is called.
 
-        if isinstance(out, list):
-            out = np.array(out)
+        data = [self[keys[:idx] + (k,) + keys[idx + 1:]] for k in ks]
 
-        return out
+        if any(isinstance(key, slice) or isiterable(key)
+               for key in keys[idx + 1:]):
+            # data contains multidimensional arrays; combine them.
+            return np.array(data)
+        else:
+            # Only singleton dimensions remain; concatenate in a 1D array.
+            return np.concatenate([np.atleast_1d(array) for array in data])
 
 
 class PrimaryHDU(_ImageBaseHDU):
@@ -987,7 +964,7 @@ class ImageHDU(_ImageBaseHDU, ExtensionHDU):
 
         errs = super(ImageHDU, self)._verify(option=option)
         naxis = self._header.get('NAXIS', 0)
-        # PCOUNT must == 0, GCOUNT must == 1; the former is verifed in
+        # PCOUNT must == 0, GCOUNT must == 1; the former is verified in
         # ExtensionHDU._verify, however ExtensionHDU._verify allows PCOUNT
         # to be >= 0, so we need to check it here
         self.req_cards('PCOUNT', naxis + 3, lambda v: (_is_int(v) and v == 0),
@@ -995,50 +972,23 @@ class ImageHDU(_ImageBaseHDU, ExtensionHDU):
         return errs
 
 
-def _iswholeline(indx, naxis):
-    if _is_int(indx):
-        if indx >= 0 and indx < naxis:
-            if naxis > 1:
-                return _SinglePoint(1, indx)
-            elif naxis == 1:
-                return _OnePointAxis(1, 0)
-        else:
-            raise IndexError('Index %s out of range.' % indx)
-    elif isinstance(indx, slice):
-        indx = _normalize_slice(indx, naxis)
-        if (indx.start == 0) and (indx.stop == naxis) and (indx.step == 1):
-            return _WholeLine(naxis, 0)
-        else:
-            if indx.step == 1:
-                return _LineSlice(indx.stop - indx.start, indx.start)
+class _IndexInfo(object):
+    def __init__(self, indx, naxis):
+        if _is_int(indx):
+            if 0 <= indx < naxis:
+                self.npts = 1
+                self.offset = indx
+                self.contiguous = True
             else:
-                return _SteppedSlice((indx.stop - indx.start) // indx.step,
-                                     indx.start)
-    else:
-        raise IndexError('Illegal index %s' % indx)
-
-
-class _KeyType(object):
-    def __init__(self, npts, offset):
-        self.npts = npts
-        self.offset = offset
-
-
-class _WholeLine(_KeyType):
-    pass
-
-
-class _SinglePoint(_KeyType):
-    pass
-
-
-class _OnePointAxis(_KeyType):
-    pass
-
-
-class _LineSlice(_KeyType):
-    pass
-
-
-class _SteppedSlice(_KeyType):
-    pass
+                raise IndexError('Index %s out of range.' % indx)
+        elif isinstance(indx, slice):
+            start, stop, step = indx.indices(naxis)
+            self.npts = (stop - start) // step
+            self.offset = start
+            self.contiguous = step == 1
+        elif isiterable(indx):
+            self.npts = len(indx)
+            self.offset = 0
+            self.contiguous = False
+        else:
+            raise IndexError('Illegal index %s' % indx)
diff --git a/astropy/io/fits/hdu/streaming.py b/astropy/io/fits/hdu/streaming.py
index 3da6312..fb90243 100644
--- a/astropy/io/fits/hdu/streaming.py
+++ b/astropy/io/fits/hdu/streaming.py
@@ -68,12 +68,12 @@ class StreamingHDU(object):
 
         # handle a file object instead of a file name
         filename = fileobj_name(name) or ''
-#
-#       Check if the file already exists.  If it does not, check to see
-#       if we were provided with a Primary Header.  If not we will need
-#       to prepend a default PrimaryHDU to the file before writing the
-#       given header.
-#
+
+        # Check if the file already exists.  If it does not, check to see
+        # if we were provided with a Primary Header.  If not we will need
+        # to prepend a default PrimaryHDU to the file before writing the
+        # given header.
+
         newfile = False
 
         if filename:
@@ -87,11 +87,11 @@ class StreamingHDU(object):
                 hdulist = HDUList([PrimaryHDU()])
                 hdulist.writeto(name, 'exception')
         else:
-#
-#               This will not be the first extension in the file so we
-#               must change the Primary header provided into an image
-#               extension header.
-#
+
+            # This will not be the first extension in the file so we
+            # must change the Primary header provided into an image
+            # extension header.
+
             if 'SIMPLE' in self._header:
                 self._header.set('XTENSION', 'IMAGE', 'Image extension',
                                  after='SIMPLE')
@@ -176,9 +176,7 @@ class StreamingHDU(object):
                             'in the header.')
 
         if data.dtype.str[0] != '>':
-#
-#           byteswap little endian arrays before writing
-#
+            # byteswap little endian arrays before writing
             output = data.byteswap()
         else:
             output = data
@@ -186,9 +184,7 @@ class StreamingHDU(object):
         self._ffo.writearray(output)
 
         if self._ffo.tell() - self._data_offset == self._size:
-#
-#           the stream is full so pad the data to the next FITS block
-#
+            # the stream is full so pad the data to the next FITS block
             self._ffo.write(_pad_length(self._size) * '\0')
             self.writecomplete = True
 
diff --git a/astropy/io/fits/hdu/table.py b/astropy/io/fits/hdu/table.py
index 55335e5..95d4586 100644
--- a/astropy/io/fits/hdu/table.py
+++ b/astropy/io/fits/hdu/table.py
@@ -18,7 +18,7 @@ from .base import DELAYED, _ValidHDU, ExtensionHDU
 # utilities in pyfits.column
 from ..column import (FITS2NUMPY, KEYWORD_NAMES, KEYWORD_ATTRIBUTES, TDEF_RE,
                       Column, ColDefs, _AsciiColDefs, _FormatP, _FormatQ,
-                      _makep, _VLF, _parse_tformat, _scalar_to_format,
+                      _makep, _parse_tformat, _scalar_to_format,
                       _convert_format, _cmp_recformats, _get_index)
 from ..fitsrec import FITS_rec
 from ..header import Header, _pad_length
@@ -46,7 +46,7 @@ class _TableLikeHDU(_ValidHDU):
     """
     A class for HDUs that have table-like data.  This is used for both
     Binary/ASCII tables as well as Random Access Group HDUs (which are
-    otherwise too dissimlary for tables to use _TableBaseHDU directly).
+    otherwise too dissimilar for tables to use _TableBaseHDU directly).
     """
 
     _data_type = FITS_rec
@@ -302,9 +302,9 @@ class _TableBaseHDU(ExtensionHDU, _TableLikeHDU):
                 self.update()
 
                 with ignored(TypeError, AttributeError):
-                   # Make the ndarrays in the Column objects of the ColDefs
-                   # object of the HDU reference the same ndarray as the HDU's
-                   # FITS_rec object.
+                    # Make the ndarrays in the Column objects of the ColDefs
+                    # object of the HDU reference the same ndarray as the HDU's
+                    # FITS_rec object.
                     for idx in range(len(self.columns)):
                         self.columns[idx].array = self.data.field(idx)
 
@@ -392,9 +392,9 @@ class _TableBaseHDU(ExtensionHDU, _TableLikeHDU):
             self.update()
 
             with ignored(TypeError, AttributeError):
-               # Make the ndarrays in the Column objects of the ColDefs
-               # object of the HDU reference the same ndarray as the HDU's
-               # FITS_rec object.
+                # Make the ndarrays in the Column objects of the ColDefs
+                # object of the HDU reference the same ndarray as the HDU's
+                # FITS_rec object.
                 for idx in range(len(self.columns)):
                     self.columns[idx].array = self.data.field(idx)
 
@@ -623,7 +623,7 @@ class TableHDU(_TableBaseHDU):
             # This is the case where the data has not been read from the file
             # yet.  We can handle that in a generic manner so we do it in the
             # base class.  The other possibility is that there is no data at
-            # all.  This can also be handled in a gereric manner.
+            # all.  This can also be handled in a generic manner.
             return super(TableHDU, self)._calculate_datasum(blocking)
 
     def _verify(self, option='warn'):
@@ -1032,8 +1032,9 @@ class BinTableHDU(_TableBaseHDU):
 
             # Process each column of the row.
             for column in self.columns:
-                vla_format = None   # format of data in a variable length array
-                                    # where None means it is not a VLA
+                # format of data in a variable length array
+                # where None means it is not a VLA:
+                vla_format = None
                 format = _convert_format(column.format)
 
                 if isinstance(format, _FormatP):
diff --git a/astropy/io/fits/header.py b/astropy/io/fits/header.py
index 92c2ac1..9c024d9 100644
--- a/astropy/io/fits/header.py
+++ b/astropy/io/fits/header.py
@@ -10,8 +10,6 @@ import re
 import sys
 import warnings
 
-from collections import defaultdict
-
 from .card import Card, CardList, _pad, KEYWORD_LENGTH
 from .file import _File
 from .util import (encode_ascii, decode_ascii, fileobj_closed,
@@ -126,7 +124,7 @@ class Header(object):
         if keyword in self._keyword_indices or keyword in self._rvkc_indices:
             # For the most common case (single, standard form keyword lookup)
             # this will work and is an O(1) check.  If it fails that doesn't
-            # guarantee absense, just that we have to perform the full set of
+            # guarantee absence, just that we have to perform the full set of
             # checks in self._cardindex
             return True
         try:
@@ -565,11 +563,11 @@ class Header(object):
     @classmethod
     def _find_end_card(cls, block, card_len):
         """
-        Utitility method to search a header block for the END card and handle
+        Utility method to search a header block for the END card and handle
         invalid END cards.
 
         This method can also returned a modified copy of the input header block
-        in case an invalid end card needs to be sanitized
+        in case an invalid end card needs to be sanitized.
         """
 
         for mo in HEADER_END_RE.finditer(block):
@@ -1335,7 +1333,7 @@ class Header(object):
         # We don't immediately modify the header, because first we need to sift
         # out any duplicates in the new header prior to adding them to the
         # existing header, but while *allowing* duplicates from the header
-        # being exteded from (see ticket #156)
+        # being extended from (see ticket #156)
         extend_cards = []
 
         for idx, card in enumerate(temp.cards):
@@ -1660,7 +1658,7 @@ class Header(object):
             existing_card = self._cards[idx]
             existing_card.value = value
             if comment is not None:
-                # '' should be used to explictly blank a comment
+                # '' should be used to explicitly blank a comment
                 existing_card.comment = comment
             if existing_card._modified:
                 self._modified = True
diff --git a/astropy/io/fits/py3compat.py b/astropy/io/fits/py3compat.py
index b095413..d703a61 100644
--- a/astropy/io/fits/py3compat.py
+++ b/astropy/io/fits/py3compat.py
@@ -63,7 +63,6 @@ if six.PY3:
     # TODO: Maybe do a version check on numpy for this?  (Note: the fix for
     # this hasn't been accepted in Numpy yet, so a version number check would
     # not be helpful yet...)
-    from . import file
 
     _chararray = numpy.char.chararray
 
@@ -79,74 +78,3 @@ if six.PY3:
             return val
     for m in [numpy.char, numpy.core.defchararray, numpy.core.records]:
         m.chararray = chararray
-
-    # Fix recarrays with sub-array fields.  See
-    # http://projects.scipy.org/numpy/ticket/1766
-    # TODO: Same as above, though the fix to this problem hasn't made it into
-    # any Numpy release yet either, so we'll have to hold off on a version
-    # check
-    def _fix_dtype(dtype):
-        """
-        Numpy has a bug (in Python3 only) that causes a segfault when
-        accessing the data of arrays containing nested arrays.  Specifically,
-        this happens if the shape of the subarray is not given as a tuple.
-        See http://projects.scipy.org/numpy/ticket/1766.
-        """
-
-        if not hasattr(dtype, 'fields') or dtype.fields is None:
-            return dtype
-
-        formats = []
-        offsets = []
-        titles = []
-        for name in dtype.names:
-            field = dtype.fields[name]
-            shape = field[0].shape
-            if not isinstance(shape, tuple):
-                shape = (shape,)
-            formats.append((field[0].base, shape))
-            offsets.append(field[1])
-
-            # There seems to be no obvious way to extract the titles from
-            # a dtype, so this just searches for duplicate fields
-            title = None
-            for key, dup in dtype.fields.items():
-                if key != name and dup == field:
-                    title = key
-                    break
-            titles.append(title)
-
-        return numpy.dtype({'names': dtype.names, 'formats': formats,
-                            'offsets': offsets, 'titles': titles})
-
-    _recarray = numpy.recarray
-
-    class recarray(_recarray):
-        def __new__(subtype, shape, dtype=None, buf=None, offset=0,
-                    strides=None, formats=None, names=None, titles=None,
-                    byteorder=None, aligned=False, order='C'):
-            if dtype is not None:
-                dtype = _fix_dtype(dtype)
-
-            if 'order' in _recarray.__new__.__code__.co_varnames:
-                return _recarray.__new__(
-                    subtype, shape, dtype, buf, offset, strides, formats,
-                    names, titles, byteorder, aligned, order)
-            else:
-                return _recarray.__new__(
-                    subtype, shape, dtype, buf, offset, strides, formats,
-                    names, titles, byteorder, aligned)
-    numpy.recarray = numpy.core.records.recarray = recarray
-
-    # We also need to patch astropy.io.fits.file._File which can also be
-    # affected by the #1766 bug
-    old_File = file._File
-
-    class _File(old_File):
-        def readarray(self, size=None, offset=0, dtype=numpy.uint8,
-                      shape=None):
-            if isinstance(dtype, numpy.dtype):
-                dtype = _fix_dtype(dtype)
-            return old_File.readarray(self, size, offset, dtype, shape)
-        readarray.__doc__ = old_File.readarray.__doc__
-    file._File = _File
diff --git a/astropy/io/fits/scripts/__init__.py b/astropy/io/fits/scripts/__init__.py
index c72f2d5..903a7f0 100644
--- a/astropy/io/fits/scripts/__init__.py
+++ b/astropy/io/fits/scripts/__init__.py
@@ -3,10 +3,6 @@
 This subpackage contains implementations of command-line scripts that are
 included with Astropy.
 
-It lives under the astropy.io.fits package primarily for Python 3 support--2to3
-does not convert these scripts unless they are actually found in the packages
-(as opposed to the top-level scripts/ directory.
-
 The actual scripts that are installed in bin/ are simple wrappers for these
 modules that will run in any Python version.
 """
diff --git a/astropy/io/fits/scripts/fitsdiff.py b/astropy/io/fits/scripts/fitsdiff.py
index 3db900f..9b029eb 100644
--- a/astropy/io/fits/scripts/fitsdiff.py
+++ b/astropy/io/fits/scripts/fitsdiff.py
@@ -22,7 +22,7 @@ data.
 where filename1 filename2 are the two files to be compared.  They may also be
 wild cards, in such cases, they must be enclosed by double or single quotes, or
 they may be directory names.  If both are directory names, all files in each of
-the directories will be included; if only one is directory name, then the
+the directories will be included; if only one is a directory name, then the
 directory name will be prefixed to the file name(s) specified by the other
 argument.  for example::
 
@@ -49,10 +49,11 @@ different pixels values per extension, only report data values larger than
 1.e-6 relative to each other, and will neglect the different values of keywords
 FILENAME and FILTNAM1 (or their very existence).
 
-fitsdiff commandline arguments can also be set using the environment variable
+fitsdiff command-line arguments can also be set using the environment variable
 FITSDIFF_SETTINGS.  If the FITSDIFF_SETTINGS environment variable is present,
 each argument present will override the corresponding argument on the
-commandline.  This environment variable exists to make it easier to change the
+command-line unless the --exact option is specified.  The FITSDIFF_SETTINGS
+environment variable exists to make it easier to change the
 behavior of fitsdiff on a global level, such as in a set of regression tests.
 """.strip()
 
@@ -106,20 +107,26 @@ def handle_options(argv=None):
              'in headers (default %default).')
 
     parser.add_option(
-        '-b', '--no-ignore-blanks', action='store_false', dest='ignore_blanks',
-        default=True,
+        '-b', '--no-ignore-blanks', action='store_false',
+        dest='ignore_blanks', default=True,
         help="Don't ignore trailing blanks (whitespace) in string values.  "
              "Otherwise trailing blanks both in header keywords/values and in "
-             "table column values) are not treated as significant i.e. "
-             "without this option 'ABC   ' and 'ABC' are considered "
-             "equivalent.")
+             "table column values) are not treated as significant i.e., "
+             "without this option 'ABCDEF   ' and 'ABCDEF' are considered "
+             "equivalent. ")
 
     parser.add_option(
         '--no-ignore-blank-cards', action='store_false',
         dest='ignore_blank_cards', default=True,
-        help="Don't ignore entirey blank cards in headers.  Normally fitsdiff "
+        help="Don't ignore entirely blank cards in headers.  Normally fitsdiff "
              "does not consider blank cards when comparing headers, but this "
-             "will ensure that even blank cards match up.")
+             "will ensure that even blank cards match up. ")
+
+    parser.add_option(
+        '--exact', action='store_true',
+        dest='exact_comparisons', default=False,
+        help="Report ALL differences, "
+             "overriding command-line options and FITSDIFF_SETTINGS. ")
 
     parser.add_option(
         '-o', '--output-file', metavar='FILE',
@@ -135,7 +142,7 @@ def handle_options(argv=None):
         help='Comma-separated list of keywords not to be compared.  Keywords '
              'may contain wildcard patterns.  To exclude all keywords, use '
              '"*"; make sure to have double or single quotes around the '
-             'asterisk.')
+             'asterisk on the command-line.')
 
     group.add_option(
         '-c', '--ignore-comments', action='callback', callback=store_list,
@@ -239,6 +246,15 @@ def main():
 
     opts, args = handle_options(argv)
 
+    if opts.exact_comparisons:
+        # override the options so that each is the most restrictive
+        opts.ignore_keywords = []
+        opts.ignore_comments = []
+        opts.ignore_fields = []
+        opts.tolerance = 0.0
+        opts.ignore_blanks = False
+        opts.ignore_blank_cards = False
+
     if not opts.quiet:
         setup_logging(opts.output_file)
     files = match_files(args)
@@ -255,12 +271,15 @@ def main():
     identical = []
     try:
         for a, b in files:
-            # TODO: pass in any additonal arguments here too
+            # TODO: pass in any additional arguments here too
             diff = fits.diff.FITSDiff(
-                a, b, ignore_keywords=opts.ignore_keywords,
+                a, b,
+                ignore_keywords=opts.ignore_keywords,
                 ignore_comments=opts.ignore_comments,
-                ignore_fields=opts.ignore_fields, numdiffs=opts.numdiffs,
-                tolerance=opts.tolerance, ignore_blanks=opts.ignore_blanks,
+                ignore_fields=opts.ignore_fields,
+                numdiffs=opts.numdiffs,
+                tolerance=opts.tolerance,
+                ignore_blanks=opts.ignore_blanks,
                 ignore_blank_cards=opts.ignore_blank_cards)
             diff.report(fileobj=out_file)
             identical.append(diff.identical)
diff --git a/astropy/io/fits/scripts/fitsheader.py b/astropy/io/fits/scripts/fitsheader.py
index 3294788..0e189f9 100644
--- a/astropy/io/fits/scripts/fitsheader.py
+++ b/astropy/io/fits/scripts/fitsheader.py
@@ -10,18 +10,27 @@ Example uses of fitsheader:
 
     $ fitsheader filename.fits
 
-2. Print the header of the third HDU extension::
+2. Print the header of the third and fifth HDU extension::
 
-    $ fitsheader --ext 3 filename.fits
+    $ fitsheader --extension 3 --extension 5 filename.fits
 
-3. Print the header of a named extension, e.g. to select the HDU with header
+3. Print the header of a named extension, e.g. select the HDU containing
    keywords EXTNAME='SCI' and EXTVER='2'::
 
-    $ fitsheader --ext "SCI,2" filename.fits
+    $ fitsheader --extension "SCI,2" filename.fits
 
-4. Print the headers of all fits files in a directory::
+4. Print only specific keywords::
 
-    $ fitsheader *.fits
+    $ fitsheader --keyword BITPIX --keyword NAXIS filename.fits
+
+5. Print keywords NAXIS, NAXIS1, NAXIS2, etc using a wildcard::
+
+    $ fitsheader --keyword NAXIS* filename.fits
+
+6. Dump the header keywords of all the files in the current directory into a
+   machine-readable csv file::
+
+    $ fitsheader --table ascii.csv *.fits > keywords.csv
 
 Note that compressed images (HDUs of type
 :class:`~astropy.io.fits.CompImageHDU`) really have two headers: a real
@@ -36,124 +45,287 @@ documentation.
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
+import sys
+
 from ... import fits
+from .... import table
 from .... import log
 
 
-class FormattingException(Exception):
+class ExtensionNotFoundException(Exception):
+    """Raised if an HDU extension requested by the user does not exist."""
     pass
 
 
 class HeaderFormatter(object):
-    """
-    Base class to format the header(s) of a FITS file for terminal display.
+    """Class to format the header(s) of a FITS file for display by the
+    `fitsheader` tool; essentially a wrapper around a `HDUList` object.
+
+    Example usage:
+    fmt = HeaderFormatter('/path/to/file.fits')
+    print(fmt.parse(extensions=[0, 3], keywords=['NAXIS', 'BITPIX']))
 
     Parameters
     ----------
     filename : str
-        Path to the FITS file.
+        Path to a single FITS file.
 
-    compressed : boolean, optional
-        show the header describing the compression (for CompImageHDU's only)
+    Raises
+    ------
+    IOError
+        If `filename` does not exist or cannot be read.
     """
-    def __init__(self, filename, compressed=False):
-        try:
-            self.hdulist = fits.open(filename)
-        except IOError as e:
-            raise FormattingException(str(e))
-        self.compressed = compressed
+    def __init__(self, filename):
+        self.filename = filename
+        self._hdulist = fits.open(filename)
 
-    def parse(self, extension=None):
+    def parse(self, extensions=None, keywords=None, compressed=False):
         """Returns the FITS file header(s) in a readable format.
 
         Parameters
         ----------
-        extension : int or str, optional
-            Format only a specific HDU, identified by its number or its name.
-            The name is the "EXTNAME" or "EXTNAME,EXTVER" string.
+        extensions : list of int or str, optional
+            Format only specific HDU(s), identified by number or name.
+            The name can be composed of the "EXTNAME" or "EXTNAME,EXTVER"
+            keywords.
+
+        keywords : list of str, optional
+            Keywords for which the value(s) should be returned.
+            If not specified, then the entire header is returned.
+
+        compressed : boolean, optional
+            If True, shows the header describing the compression, rather than
+            the header obtained after decompression. (Affects FITS files
+            containing `CompImageHDU` extensions only.)
 
         Returns
         -------
-        formatted_header : str
-            Nicely formatted header information.
+        formatted_header : str or astropy.table.Table
+            Traditional 80-char wide format in the case of `HeaderFormatter`;
+            an Astropy Table object in the case of `TableHeaderFormatter`.
         """
         # `hdukeys` will hold the keys of the HDUList items to display
-        if extension is None:
-            hdukeys = range(len(self.hdulist))  # Display all by default
+        if extensions is None:
+            hdukeys = range(len(self._hdulist))  # Display all by default
         else:
+            hdukeys = []
+            for ext in extensions:
+                try:
+                    # HDU may be specified by number
+                    hdukeys.append(int(ext))
+                except ValueError:
+                    # The user can specify "EXTNAME" or "EXTNAME,EXTVER"
+                    parts = ext.split(',')
+                    if len(parts) > 1:
+                        extname = ','.join(parts[0:-1])
+                        extver = int(parts[-1])
+                        hdukeys.append((extname, extver))
+                    else:
+                        hdukeys.append(ext)
+
+        # Having established which HDUs the user wants, we now format these:
+        return self._parse_internal(hdukeys, keywords, compressed)
+
+    def _parse_internal(self, hdukeys, keywords, compressed):
+        """The meat of the formatting; in a separate method to allow overriding.
+        """
+        result = []
+        for idx, hdu in enumerate(hdukeys):
             try:
-                hdukeys = [int(extension)]  # HDU may be specified by number
-            except ValueError:
-                # The user can specify "EXTNAME" or "EXTNAME,EXTVER" as well
-                parts = extension.split(',')
-                if len(parts) > 1:
-                    # We use str() below to avoid issue #2184
-                    extname = ','.join(parts[0:-1])
-                    extver = int(parts[-1])
-                    hdukeys = [(extname, extver)]
-                else:
-                    hdukeys = [extension]
-
-        # Having established which HDUs are wanted, we can now format these
-        return self._format_hdulist(hdukeys)
-
-    def _get_header(self, hdukey):
-        """Returns the `astropy.io.fits.header.Header` object for the HDU."""
+                cards = self._get_cards(hdu, keywords, compressed)
+
+                if idx > 0:  # Separate HDUs by a blank line
+                    result.append('\n')
+                result.append('# HDU {hdu} in {filename}:\n'.format(
+                              filename=self.filename,
+                              hdu=hdu
+                              ))
+                result.append('{0}\n'.format('\n'.join([str(c)
+                                                        for c in cards])))
+            except ExtensionNotFoundException:
+                pass
+        return ''.join(result)
+
+    def _get_cards(self, hdukey, keywords, compressed):
+        """Returns a list of `astropy.io.fits.card.Card` objects.
+
+        This function will return the desired header cards, taking into
+        account the user's preference to see the compressed or uncompressed
+        version.
+
+        Parameters
+        ----------
+        hdukey : int or str
+            Key of a single HDU in the HDUList.
+
+        keywords : list of str, optional
+            Keywords for which the cards should be returned.
+
+        compressed : boolean, optional
+            If True, shows the header describing the compression.
+
+        Raises
+        ------
+        ExtensionNotFoundException
+            If the hdukey does not correspond to an extension.
+        """
+        # First we obtain the desired header
         try:
-            if self.compressed:
+            if compressed:
                 # In the case of a compressed image, return the header before
                 # decompression (not the default behavior)
-                return self.hdulist[hdukey]._header
-            else:
-                return self.hdulist[hdukey].header
-        except IndexError:
-            raise FormattingException('{0}: Extension #{1} not found.'.
-                                      format(self.hdulist.filename(), hdukey))
-        except KeyError as e:
-            raise FormattingException('{0}: {1}'.format(
-                                      self.hdulist.filename(), str(e)))
-
-    def _format_hdulist(self, hdukeys):
-        """Returns the formatted version of the header; the important bit."""
-        text = []
-        for i, key in enumerate(hdukeys):
-            if i > 0:
-                prefix = '\n\n'  # Separate HDUs by a blank line
+                header = self._hdulist[hdukey]._header
             else:
-                prefix = ''
-            text.append('{prefix}# HDU {key} in {filename}:\n{header}'.format(
-                        prefix=prefix,
-                        key=key,
-                        filename=self.hdulist.filename(),
-                        header=self._get_header(key).tostring(sep='\n',
-                                                              padding=False)))
-        return ''.join(text)
+                header = self._hdulist[hdukey].header
+        except (IndexError, KeyError):
+            message = '{0}: Extension {1} not found.'.format(self.filename,
+                                                             hdukey)
+            log.warning(message)
+            raise ExtensionNotFoundException(message)
+
+        if not keywords:  # return all cards
+            cards = header.cards
+        else:  # specific keywords are requested
+            cards = []
+            for kw in keywords:
+                try:
+                    crd = header.cards[kw]
+                    if isinstance(crd, fits.card.Card):  # Single card
+                        cards.append(crd)
+                    else:  # Allow for wildcard access
+                        cards.extend(crd)
+                except KeyError as e:  # Keyword does not exist
+                    log.warning('{filename} (HDU {hdukey}): '
+                                'Keyword {kw} not found.'.format(
+                                    filename=self.filename,
+                                    hdukey=hdukey,
+                                    kw=kw))
+        return cards
+
+
+class TableHeaderFormatter(HeaderFormatter):
+    """Class to convert the header(s) of a FITS file into a Table object.
+    The table returned by the `parse` method will contain four columns:
+    filename, hdu, keyword, and value.
+
+    Subclassed from HeaderFormatter, which contains the meat of the formatting.
+    """
+    def _parse_internal(self, hdukeys, keywords, compressed):
+        """Method called by the parse method in the parent class."""
+        tablerows = []
+        for hdu in hdukeys:
+            try:
+                for card in self._get_cards(hdu, keywords, compressed):
+                    tablerows.append({'filename': self.filename,
+                                      'hdu': hdu,
+                                      'keyword': card.keyword,
+                                      'value': str(card.value)})
+            except ExtensionNotFoundException:
+                pass
+
+        if tablerows:
+            return table.Table(tablerows)
+        return None
+
+
+def print_headers_traditional(args):
+    """Prints FITS header(s) using the traditional 80-char format.
+
+    Parameters
+    ----------
+    args : argparse.Namespace
+        Arguments passed from the command-line as defined below.
+    """
+    for idx, filename in enumerate(args.filename):  # support wildcards
+        if idx > 0 and not args.keywords:
+            print()  # print a newline between different files
+        try:
+            formatter = HeaderFormatter(filename)
+            print(formatter.parse(args.extensions,
+                                  args.keywords,
+                                  args.compressed), end='')
+        except IOError as e:
+            log.error(str(e))
+
+
+def print_headers_as_table(args):
+    """Prints FITS header(s) in a machine-readable table format.
+
+    Parameters
+    ----------
+    args : argparse.Namespace
+        Arguments passed from the command-line as defined below.
+    """
+    tables = []
+    # Create a Table object for each file
+    for filename in args.filename:  # Support wildcards
+        try:
+            formatter = TableHeaderFormatter(filename)
+            tbl = formatter.parse(args.extensions,
+                                  args.keywords,
+                                  args.compressed)
+            if tbl:
+                tables.append(tbl)
+        except IOError as e:
+            log.error(str(e))  # file not found or unreadable
+    # Concatenate the tables
+    if len(tables) == 0:
+        return False
+    elif len(tables) == 1:
+        resulting_table = tables[0]
+    else:
+        resulting_table = table.vstack(tables)
+    # Print the string representation of the concatenated table
+    resulting_table.write(sys.stdout, format=args.table)
 
 
 def main(args=None):
+    """This is the main function called by the `fitsheader` script."""
     from astropy.utils.compat import argparse
 
     parser = argparse.ArgumentParser(
         description=('Print the header(s) of a FITS file. '
-                     'All HDU extensions are shown by default. '
-                     'In the case of a compressed image, '
-                     'the decompressed header is shown.'))
-    parser.add_argument('-e', '--ext', metavar='hdu',
-                        help='specify the HDU extension number or name')
+                     'Optional arguments allow the desired extension(s), '
+                     'keyword(s), and output format to be specified. '
+                     'Note that in the case of a compressed image, '
+                     'the decompressed header is shown by default.'))
+    parser.add_argument('-e', '--extension', metavar='HDU',
+                        action='append', dest='extensions',
+                        help='specify the extension by name or number; '
+                             'this argument can be repeated '
+                             'to select multiple extensions')
+    parser.add_argument('-k', '--keyword', metavar='KEYWORD',
+                        action='append', dest='keywords',
+                        help='specify a keyword; this argument can be '
+                             'repeated to select multiple keywords; '
+                             'also supports wildcards')
+    parser.add_argument('-t', '--table',
+                        nargs='?', default=False, metavar='FORMAT',
+                        help='print the header(s) in machine-readable table '
+                             'format; the default format is '
+                             '"ascii.fixed_width" (can be "ascii.csv", '
+                             '"ascii.html", "ascii.latex", "fits", etc)')
     parser.add_argument('-c', '--compressed', action='store_true',
                         help='for compressed image data, '
                              'show the true header which describes '
                              'the compression rather than the data')
     parser.add_argument('filename', nargs='+',
-                        help='path to one or more FITS files to display')
+                        help='path to one or more files; '
+                             'wildcards are supported')
     args = parser.parse_args(args)
 
+    # If `--table` was used but no format specified,
+    # then use ascii.fixed_width by default
+    if args.table is None:
+        args.table = 'ascii.fixed_width'
+
+    # Now print the desired headers
     try:
-        for filename in args.filename:
-            print(HeaderFormatter(filename, args.compressed).parse(args.ext))
-    except FormattingException as e:
-        log.error(e)
+        if args.table:
+            print_headers_as_table(args)
+        else:
+            print_headers_traditional(args)
     except IOError as e:
         # A 'Broken pipe' IOError may occur when stdout is closed prematurely,
-        # eg when using `fitsheader file.fits | head`. We let this pass.
+        # eg. when calling `fitsheader file.fits | head`. We let this pass.
         pass
diff --git a/astropy/io/fits/tests/test_core.py b/astropy/io/fits/tests/test_core.py
index b0adb1c..48a109a 100644
--- a/astropy/io/fits/tests/test_core.py
+++ b/astropy/io/fits/tests/test_core.py
@@ -572,7 +572,7 @@ class TestFileFunctions(FitsTestCase):
         try:
             fits.open(self.temp('foobar.fits'))
         except IOError as e:
-            assert 'File does not exist' in str(e)
+            assert 'No such file or directory' in str(e)
         except:
             raise
 
@@ -947,6 +947,23 @@ class TestFileFunctions(FitsTestCase):
 
         self._test_write_string_bytes_io(io.BytesIO())
 
+    @pytest.mark.skipif(str('sys.platform.startswith("win32")'))
+    def test_filename_with_colon(self):
+        """
+        Test reading and writing a file with a colon in the filename.
+
+        Regression test for https://github.com/astropy/astropy/issues/3122
+        """
+
+        # Skip on Windows since colons in filenames makes NTFS sad.
+
+        filename = 'APEXHET.2014-04-01T15:18:01.000.fits'
+        hdu = fits.PrimaryHDU(data=np.arange(10))
+        hdu.writeto(self.temp(filename))
+
+        with fits.open(self.temp(filename)) as hdul:
+            assert np.all(hdul[0].data == hdu.data)
+
     def _test_write_string_bytes_io(self, fileobj):
         """
         Implemented for both test_write_stringio and test_write_bytesio.
@@ -1059,3 +1076,8 @@ class TestStreamingFunctions(FitsTestCase):
 
         with fits.open(self.data('blank.fits'), ignore_blank=True) as f:
             assert f[0].data.flat[0] == 2
+
+    def test_error_if_memmap_impossible(self):
+        pth = self.data('blank.fits')
+        with pytest.raises(ValueError):
+            fits.open(pth, memmap=True)[0].data
diff --git a/astropy/io/fits/tests/test_diff.py b/astropy/io/fits/tests/test_diff.py
index 3a842eb..ebef851 100644
--- a/astropy/io/fits/tests/test_diff.py
+++ b/astropy/io/fits/tests/test_diff.py
@@ -1,6 +1,7 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
 import io
+import pytest
 
 import numpy as np
 
@@ -595,3 +596,36 @@ class TestDiff(FitsTestCase):
         # did show a difference in their text representations
         assert 'a>' in out
         assert 'b>' in out
+
+    def test_file_output_from_path_string(self):
+        outpath = self.temp('diff_output.txt')
+        ha = Header([('A', 1), ('B', 2), ('C', 3)])
+        hb = ha.copy()
+        hb['C'] = 4
+        diffobj = HeaderDiff(ha, hb)
+        diffobj.report(fileobj=outpath)
+        report_as_string = diffobj.report()
+        assert open(outpath).read() == report_as_string
+
+    def test_file_output_clobber_safety(self):
+        outpath = self.temp('diff_output.txt')
+        ha = Header([('A', 1), ('B', 2), ('C', 3)])
+        hb = ha.copy()
+        hb['C'] = 4
+        diffobj = HeaderDiff(ha, hb)
+        diffobj.report(fileobj=outpath)
+
+        with pytest.raises(IOError):
+            diffobj.report(fileobj=outpath)
+
+    def test_file_output_clobber_success(self):
+        outpath = self.temp('diff_output.txt')
+        ha = Header([('A', 1), ('B', 2), ('C', 3)])
+        hb = ha.copy()
+        hb['C'] = 4
+        diffobj = HeaderDiff(ha, hb)
+        diffobj.report(fileobj=outpath)
+        report_as_string = diffobj.report()
+        diffobj.report(fileobj=outpath, clobber=True)
+        assert open(outpath).read() == report_as_string, ("clobbered output "
+            "file is not identical to report string")
diff --git a/astropy/io/fits/tests/test_header.py b/astropy/io/fits/tests/test_header.py
index 5e2c9e9..4215782 100644
--- a/astropy/io/fits/tests/test_header.py
+++ b/astropy/io/fits/tests/test_header.py
@@ -442,7 +442,7 @@ class TestHeaderFunctions(FitsTestCase):
             "CONTINUE  'string value long string value long string value &'                  "
             "CONTINUE  '&' / long comment long comment long comment long comment long        "
             "CONTINUE  '&' / comment long comment long comment long comment long comment     "
-            "CONTINUE  '&' / long comment                                                    ")
+            "CONTINUE  '' / long comment                                                     ")
 
     def test_long_unicode_string(self):
         """Regression test for
@@ -481,7 +481,7 @@ class TestHeaderFunctions(FitsTestCase):
              "CONTINUE  'string value long string value long string value &'                  ",
              "CONTINUE  '&' / long comment long comment long comment long comment long        ",
              "CONTINUE  '&' / comment long comment long comment long comment long comment     ",
-             "CONTINUE  '&' / long comment                                                    ",
+             "CONTINUE  '' / long comment                                                     ",
              str(fits.Card('TEST3', 'Regular value', 'Regular comment'))])
 
     def test_blank_keyword_long_value(self):
@@ -520,7 +520,7 @@ class TestHeaderFunctions(FitsTestCase):
             "CONTINUE  'string value long string value long string value &'                  "
             "CONTINUE  '&' / long comment long comment long comment long comment long        "
             "CONTINUE  '&' / comment long comment long comment long comment long comment     "
-            "CONTINUE  '&' / long comment                                                    ")
+            "CONTINUE  '' / long comment                                                     ")
 
     def test_word_in_long_string_too_long(self):
         # if a word in a long string is too long, it will be cut in the middle
@@ -530,7 +530,7 @@ class TestHeaderFunctions(FitsTestCase):
             "CONTINUE  'ingvaluelongstringvaluelongstringvaluelongstringvaluelongstringvalu&'"
             "CONTINUE  'elongstringvalue&'                                                   "
             "CONTINUE  '&' / longcommentlongcommentlongcommentlongcommentlongcommentlongcomme"
-            "CONTINUE  '&' / ntlongcommentlongcommentlongcommentlongcomment                  ")
+            "CONTINUE  '' / ntlongcommentlongcommentlongcommentlongcomment                   ")
 
     def test_long_string_value_via_fromstring(self, capsys):
         # long string value via fromstring() method
@@ -544,7 +544,7 @@ class TestHeaderFunctions(FitsTestCase):
         assert (str(c) ==
                 "ABC     = 'longstring''s testing  continue with long string but without the &'  "
                  "CONTINUE  'ampersand at the endcontinue must have string value (with quotes)&'  "
-                 "CONTINUE  '&' / comments in line 1 comments with ''.                            ")
+                 "CONTINUE  '' / comments in line 1 comments with ''.                             ")
 
     def test_continue_card_with_equals_in_value(self):
         """
@@ -562,6 +562,28 @@ class TestHeaderFunctions(FitsTestCase):
                 '* 5.87359e-12 * MWAvg(Av=0.12)')
         assert c.comment == 'pysyn expression'
 
+    def test_final_continue_card_lacks_ampersand(self):
+        """
+        Regression test for https://github.com/astropy/astropy/issues/3282
+        """
+
+        h = fits.Header()
+        h['SVALUE'] = 'A' * 69
+        assert repr(h).splitlines()[-1] == _pad("CONTINUE  'AA'")
+
+    def test_final_continue_card_ampersand_removal_on_long_comments(self):
+        """
+        Regression test for https://github.com/astropy/astropy/issues/3282
+        """
+
+        c = fits.Card('TEST', 'long value' * 10, 'long comment &' * 10)
+        assert (str(c) ==
+            "TEST    = 'long valuelong valuelong valuelong valuelong valuelong valuelong &'  "
+            "CONTINUE  'valuelong valuelong valuelong value&'                                "
+            "CONTINUE  '&' / long comment &long comment &long comment &long comment &long    "
+            "CONTINUE  '&' / comment &long comment &long comment &long comment &long comment "
+            "CONTINUE  '' / &long comment &                                                  ")
+
     def test_hierarch_card_creation(self):
         # Test automatic upgrade to hierarch card
         with catch_warnings() as w:
@@ -2583,20 +2605,80 @@ class TestRecordValuedKeywordCards(FitsTestCase):
         pytest.raises(KeyError, lambda: h['FOO.'])
 
     def test_fitsheader_script(self):
-        """
-        Checks the basic functionality of the fitsheader script
-        """
+        """Tests the basic functionality of the `fitsheader` script."""
         from ....io.fits.scripts import fitsheader
+
         # Can an extension by specified by the EXTNAME keyword?
         hf = fitsheader.HeaderFormatter(self.data('zerowidth.fits'))
-        assert "EXTNAME = 'AIPS FQ" in hf.parse('AIPS FQ')
+        output = hf.parse(extensions=['AIPS FQ'])
+        assert "EXTNAME = 'AIPS FQ" in output
+        assert "BITPIX" in output
+
+        # Can we limit the display to one specific keyword?
+        output = hf.parse(extensions=['AIPS FQ'], keywords=['EXTNAME'])
+        assert "EXTNAME = 'AIPS FQ" in output
+        assert "BITPIX  =" not in output
+        assert len(output.split('\n')) == 3
+
+        # Can we limit the display to two specific keywords?
+        output = hf.parse(extensions=[1],
+                          keywords=['EXTNAME', 'BITPIX'])
+        assert "EXTNAME =" in output
+        assert "BITPIX  =" in output
+        assert len(output.split('\n')) == 4
+
+        # Can we use wildcards for keywords?
+        output = hf.parse(extensions=[1], keywords=['NAXIS*'])
+        assert "NAXIS   =" in output
+        assert "NAXIS1  =" in output
+        assert "NAXIS2  =" in output
 
         # Can an extension by specified by the EXTNAME+EXTVER keywords?
         hf = fitsheader.HeaderFormatter(self.data('test0.fits'))
-        assert "EXTNAME = 'SCI" in hf.parse('SCI,2')
-        # fitsheader should only print the compressed header when asked
+        assert "EXTNAME = 'SCI" in hf.parse(extensions=['SCI,2'])
+
+        # Can we print the original header before decompression?
         hf = fitsheader.HeaderFormatter(self.data('comp.fits'))
-        assert "XTENSION= 'IMAGE" in hf.parse(1)  # decompressed
-        hf = fitsheader.HeaderFormatter(self.data('comp.fits'),
-                                        compressed=True)
-        assert "XTENSION= 'BINTABLE" in hf.parse(1)  # compressed
+        assert "XTENSION= 'IMAGE" in hf.parse(extensions=[1],
+                                              compressed=False)
+        assert "XTENSION= 'BINTABLE" in hf.parse(extensions=[1],
+                                                 compressed=True)
+
+    def test_fitsheader_table_feature(self):
+        """Tests the `--table` feature of the `fitsheader` script."""
+        from ....io import fits
+        from ....io.fits.scripts import fitsheader
+        test_filename = self.data('zerowidth.fits')
+        fitsobj = fits.open(test_filename)
+        formatter = fitsheader.TableHeaderFormatter(test_filename)
+
+        # Does the table contain the expected number of rows?
+        mytable = formatter.parse([0])
+        assert len(mytable) == len(fitsobj[0].header)
+        # Repeat the above test when multiple HDUs are requested
+        mytable = formatter.parse(extensions=['AIPS FQ', 2, "4"])
+        assert len(mytable) == (len(fitsobj['AIPS FQ'].header)
+                                + len(fitsobj[2].header)
+                                + len(fitsobj[4].header))
+
+        # Can we recover the filename and extension name from the table?
+        mytable = formatter.parse(extensions=['AIPS FQ'])
+        assert np.all(mytable['filename'] == test_filename)
+        assert np.all(mytable['hdu'] == 'AIPS FQ')
+        assert mytable['value'][mytable['keyword'] == "EXTNAME"] == "AIPS FQ"
+
+        # Can we specify a single extension/keyword?
+        mytable = formatter.parse(extensions=['AIPS FQ'],
+                                  keywords=['EXTNAME'])
+        assert len(mytable) == 1
+        assert mytable['hdu'][0] == "AIPS FQ"
+        assert mytable['keyword'][0] == "EXTNAME"
+        assert mytable['value'][0] == "AIPS FQ"
+
+        # Is an incorrect extension dealt with gracefully?
+        mytable = formatter.parse(extensions=['DOES_NOT_EXIST'])
+        assert mytable is None
+        # Is an incorrect keyword dealt with gracefully?
+        mytable = formatter.parse(extensions=['AIPS FQ'],
+                                  keywords=['DOES_NOT_EXIST'])
+        assert mytable is None
diff --git a/astropy/io/fits/tests/test_image.py b/astropy/io/fits/tests/test_image.py
index 7983b80..2462558 100644
--- a/astropy/io/fits/tests/test_image.py
+++ b/astropy/io/fits/tests/test_image.py
@@ -151,10 +151,10 @@ class TestImageFunctions(FitsTestCase):
             r[0].header.rename_key('fname', 'filename')
 
             # get a subsection of data
-            assert (r[2].data[:3, :3] ==
-                    np.array([[349, 349, 348],
-                              [349, 349, 347],
-                              [347, 350, 349]], dtype=np.int16)).all()
+            assert np.array_equal(r[2].data[:3, :3],
+                                  np.array([[349, 349, 348],
+                                            [349, 349, 347],
+                                            [347, 350, 349]], dtype=np.int16))
 
             # We can create a new FITS file by opening a new file with "append"
             # mode.
@@ -240,11 +240,11 @@ class TestImageFunctions(FitsTestCase):
         # create an HDU with data only
         data = np.ones((3, 5), dtype=np.float32)
         hdu = fits.ImageHDU(data=data, name='SCI')
-        assert (hdu.data ==
-                np.array([[1.,  1.,  1.,  1.,  1.],
-                          [1.,  1.,  1.,  1.,  1.],
-                          [1.,  1.,  1.,  1.,  1.]],
-                         dtype=np.float32)).all()
+        assert np.array_equal(hdu.data,
+                              np.array([[1.,  1.,  1.,  1.,  1.],
+                                        [1.,  1.,  1.,  1.,  1.],
+                                        [1.,  1.,  1.,  1.,  1.]],
+                                       dtype=np.float32))
 
         # create an HDU with header and data
         # notice that the header has the right NAXIS's since it is constructed
@@ -284,56 +284,80 @@ class TestImageFunctions(FitsTestCase):
     def test_section(self):
         # section testing
         fs = fits.open(self.data('arange.fits'))
-        assert (fs[0].section[3, 2, 5] == np.array([357])).all()
-        assert (fs[0].section[3, 2, :] ==
-                np.array([352, 353, 354, 355, 356, 357, 358, 359, 360, 361,
-                          362])).all()
-        assert (fs[0].section[3, 2, 4:] ==
-                np.array([356, 357, 358, 359, 360, 361, 362])).all()
-        assert (fs[0].section[3, 2, :8] ==
-                np.array([352, 353, 354, 355, 356, 357, 358, 359])).all()
-        assert (fs[0].section[3, 2, -8:8] ==
-                np.array([355, 356, 357, 358, 359])).all()
-        assert (fs[0].section[3, 2:5, :] ==
-                np.array([[352, 353, 354, 355, 356, 357, 358, 359, 360, 361,
-                           362],
-                          [363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
-                           373],
-                          [374, 375, 376, 377, 378, 379, 380, 381, 382, 383,
-                           384]])).all()
-
-        assert (fs[0].section[3, :, :][:3, :3] ==
-                np.array([[330, 331, 332],
-                          [341, 342, 343],
-                          [352, 353, 354]])).all()
+        assert np.array_equal(fs[0].section[3, 2, 5], 357)
+        assert np.array_equal(
+            fs[0].section[3, 2, :],
+            np.array([352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362]))
+        assert np.array_equal(fs[0].section[3, 2, 4:],
+                              np.array([356, 357, 358, 359, 360, 361, 362]))
+        assert np.array_equal(fs[0].section[3, 2, :8],
+                              np.array([352, 353, 354, 355, 356, 357, 358, 359]))
+        assert np.array_equal(fs[0].section[3, 2, -8:8],
+                              np.array([355, 356, 357, 358, 359]))
+        assert np.array_equal(
+            fs[0].section[3, 2:5, :],
+            np.array([[352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362],
+                      [363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373],
+                      [374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384]]))
+
+        assert np.array_equal(fs[0].section[3, :, :][:3, :3],
+                              np.array([[330, 331, 332],
+                                        [341, 342, 343],
+                                        [352, 353, 354]]))
 
         dat = fs[0].data
-        assert (fs[0].section[3, 2:5, :8] == dat[3, 2:5, :8]).all()
-        assert (fs[0].section[3, 2:5, 3] == dat[3, 2:5, 3]).all()
-
-        assert (fs[0].section[3:6, :, :][:3, :3, :3] ==
-                np.array([[[330, 331, 332],
-                           [341, 342, 343],
-                           [352, 353, 354]],
-                          [[440, 441, 442],
-                           [451, 452, 453],
-                           [462, 463, 464]],
-                          [[550, 551, 552],
-                           [561, 562, 563],
-                           [572, 573, 574]]])).all()
-
-        assert (fs[0].section[:, :, :][:3, :2, :2] ==
-                np.array([[[0,   1],
-                           [11,  12]],
-                          [[110, 111],
-                           [121, 122]],
-                          [[220, 221],
-                           [231, 232]]])).all()
-
-        assert (fs[0].section[:, 2, :] == dat[:, 2, :]).all()
-        assert (fs[0].section[:, 2:5, :] == dat[:, 2:5, :]).all()
-        assert (fs[0].section[3:6, 3, :] == dat[3:6, 3, :]).all()
-        assert (fs[0].section[3:6, 3:7, :] == dat[3:6, 3:7, :]).all()
+        assert np.array_equal(fs[0].section[3, 2:5, :8], dat[3, 2:5, :8])
+        assert np.array_equal(fs[0].section[3, 2:5, 3], dat[3, 2:5, 3])
+
+        assert np.array_equal(fs[0].section[3:6, :, :][:3, :3, :3],
+                              np.array([[[330, 331, 332],
+                                         [341, 342, 343],
+                                         [352, 353, 354]],
+                                        [[440, 441, 442],
+                                         [451, 452, 453],
+                                         [462, 463, 464]],
+                                        [[550, 551, 552],
+                                         [561, 562, 563],
+                                         [572, 573, 574]]]))
+
+        assert np.array_equal(fs[0].section[:, :, :][:3, :2, :2],
+                              np.array([[[0,   1],
+                                         [11,  12]],
+                                        [[110, 111],
+                                         [121, 122]],
+                                        [[220, 221],
+                                         [231, 232]]]))
+
+        assert np.array_equal(fs[0].section[:, 2, :], dat[:, 2, :])
+        assert np.array_equal(fs[0].section[:, 2:5, :], dat[:, 2:5, :])
+        assert np.array_equal(fs[0].section[3:6, 3, :], dat[3:6, 3, :])
+        assert np.array_equal(fs[0].section[3:6, 3:7, :], dat[3:6, 3:7, :])
+
+        assert np.array_equal(fs[0].section[:, ::2], dat[:, ::2])
+        assert np.array_equal(fs[0].section[:, [1, 2, 4], 3],
+                              dat[:, [1, 2, 4], 3])
+        assert np.array_equal(
+            fs[0].section[:, np.array([True, False, True]), :],
+            dat[:, np.array([True, False, True]), :])
+
+        assert np.array_equal(
+            fs[0].section[3:6, 3, :, ...], dat[3:6, 3, :, ...])
+        assert np.array_equal(fs[0].section[..., ::2], dat[..., ::2])
+        assert np.array_equal(fs[0].section[..., [1, 2, 4], 3],
+                              dat[..., [1, 2, 4], 3])
+
+    def test_section_data_single(self):
+        a = np.array([1])
+        hdu = fits.PrimaryHDU(a)
+        hdu.writeto(self.temp('test_new.fits'))
+
+        hdul = fits.open(self.temp('test_new.fits'))
+        sec = hdul[0].section
+        dat = hdul[0].data
+        assert np.array_equal(sec[0], dat[0])
+        assert np.array_equal(sec[...], dat[...])
+        assert np.array_equal(sec[..., 0], dat[..., 0])
+        assert np.array_equal(sec[0, ...], dat[0, ...])
 
     def test_section_data_square(self):
         a = np.arange(4).reshape((2, 2))
diff --git a/astropy/io/fits/tests/test_uint.py b/astropy/io/fits/tests/test_uint.py
index e96f157..6beb717 100644
--- a/astropy/io/fits/tests/test_uint.py
+++ b/astropy/io/fits/tests/test_uint.py
@@ -1,5 +1,6 @@
 # Licensed under a 3-clause BSD style license - see PYFITS.rst
 
+import os
 import platform
 
 import numpy as np
@@ -23,6 +24,7 @@ class TestUintFunctions(FitsTestCase):
     @pytest.mark.parametrize(('utype','compressed'),
         [('u2', False), ('u4', False), ('u8', False), ('u2', True),
          ('u4',True)]) #,('u8',True)])
+    @pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
     def test_uint(self, utype, compressed):
         bits = 8*int(utype[1])
         if platform.architecture()[0] == '64bit' or bits != 64:
diff --git a/astropy/io/fits/util.py b/astropy/io/fits/util.py
index 91ca38b..5442d08 100644
--- a/astropy/io/fits/util.py
+++ b/astropy/io/fits/util.py
@@ -2,7 +2,6 @@
 
 from __future__ import division
 
-import functools
 import gzip
 import itertools
 import io
@@ -32,6 +31,7 @@ from ...extern import six
 from ...extern.six import (string_types, integer_types, text_type,
                            binary_type, next)
 from ...extern.six.moves import zip
+from ...utils import wraps
 from ...utils.exceptions import AstropyUserWarning
 
 
@@ -103,10 +103,10 @@ def ignore_sigint(func):
     until the wrapped function is completed.
     """
 
-    @functools.wraps(func)
+    @wraps(func)
     def wrapped(*args, **kwargs):
         # Get the name of the current thread and determine if this is a single
-        # treaded application
+        # threaded application
         curr_thread = threading.currentThread()
         single_thread = (threading.activeCount() == 1 and
                          curr_thread.getName() == 'MainThread')
@@ -621,7 +621,7 @@ def _array_from_file(infile, dtype, count, sep):
     else:
         # treat as file-like object with "read" method; this includes gzip file
         # objects, because numpy.fromfile just reads the compressed bytes from
-        # their underlying file object, instead of the decompresed bytes
+        # their underlying file object, instead of the decompressed bytes
         read_size = np.dtype(dtype).itemsize * count
         s = infile.read(read_size)
         return np.fromstring(s, dtype=dtype, count=count, sep=sep)
@@ -655,7 +655,7 @@ def _array_to_file(arr, outfile):
 
     # Implements a workaround for a bug deep in OSX's stdlib file writing
     # functions; on 64-bit OSX it is not possible to correctly write a number
-    # of bytes greater than 2 ** 32 and divisble by 4096 (or possibly 8192--
+    # of bytes greater than 2 ** 32 and divisible by 4096 (or possibly 8192--
     # whatever the default blocksize for the filesystem is).
     # This issue should have a workaround in Numpy too, but hasn't been
     # implemented there yet: https://github.com/astropy/astropy/issues/839
@@ -689,9 +689,9 @@ def _array_to_file_like(arr, fileobj):
     """
 
     if arr.flags.contiguous:
-        # It sufficies to just pass the underlying buffer directly to the
+        # It suffices to just pass the underlying buffer directly to the
         # fileobj's write (assuming it supports the buffer interface, which
-        # unforunately there's no simple way to check)
+        # unfortunately there's no simple way to check)
         fileobj.write(arr.data)
     elif hasattr(np, 'nditer'):
         # nditer version for non-contiguous arrays
@@ -779,52 +779,6 @@ def _str_to_num(val):
     return num
 
 
-def _normalize_slice(input, naxis):
-    """
-    Set the slice's start/stop in the regular range.
-    """
-
-    def _normalize(indx, npts):
-        if indx < -npts:
-            indx = 0
-        elif indx < 0:
-            indx += npts
-        elif indx > npts:
-            indx = npts
-        return indx
-
-    _start = input.start
-    if _start is None:
-        _start = 0
-    elif _is_int(_start):
-        _start = _normalize(_start, naxis)
-    else:
-        raise IndexError('Illegal slice %s; start must be integer.' % input)
-
-    _stop = input.stop
-    if _stop is None:
-        _stop = naxis
-    elif _is_int(_stop):
-        _stop = _normalize(_stop, naxis)
-    else:
-        raise IndexError('Illegal slice %s; stop must be integer.' % input)
-
-    if _stop < _start:
-        raise IndexError('Illegal slice %s; stop < start.' % input)
-
-    _step = input.step
-    if _step is None:
-        _step = 1
-    elif _is_int(_step):
-        if _step <= 0:
-            raise IndexError('Illegal slice %s; step must be positive.'
-                             % input)
-    else:
-        raise IndexError('Illegal slice %s; step must be integer.' % input)
-
-    return slice(_start, _stop, _step)
-
-
 def _words_group(input, strlen):
     """
     Split a long string into parts where each part is no longer
diff --git a/astropy/io/misc/hdf5.py b/astropy/io/misc/hdf5.py
index d96fc1a..b454a72 100644
--- a/astropy/io/misc/hdf5.py
+++ b/astropy/io/misc/hdf5.py
@@ -22,7 +22,7 @@ __all__ = ['read_table_hdf5', 'write_table_hdf5']
 
 def _find_all_structured_arrays(handle):
     """
-    Find all sturctured arrays in an HDF5 file
+    Find all structured arrays in an HDF5 file
     """
     import h5py
     structured_arrays = []
@@ -179,6 +179,13 @@ def write_table_hdf5(table, output, path=None, compression=False,
     except ImportError:
         raise Exception("h5py is required to read and write HDF5 files")
 
+    # Tables with mixin columns are not supported
+    if table.has_mixin_columns:
+        mixin_names = [name for name, col in table.columns.items()
+                       if not isinstance(col, table.ColumnClass)]
+        raise ValueError('cannot write table with mixin column(s) {0} to HDF5'
+                         .format(mixin_names))
+
     if path is None:
         raise ValueError("table path should be set via the path= argument")
     elif path.endswith('/'):
@@ -235,10 +242,10 @@ def write_table_hdf5(table, output, path=None, compression=False,
     if compression:
         if compression is True:
             compression = 'gzip'
-        dset = output_group.create_dataset(name, data=table._data,
+        dset = output_group.create_dataset(name, data=table.as_array(),
                                            compression=compression)
     else:
-        dset = output_group.create_dataset(name, data=table._data)
+        dset = output_group.create_dataset(name, data=table.as_array())
 
     # Write the meta-data to the file
     for key in table.meta:
diff --git a/astropy/io/misc/pickle_helpers.py b/astropy/io/misc/pickle_helpers.py
index 8c64e98..d8e5b39 100644
--- a/astropy/io/misc/pickle_helpers.py
+++ b/astropy/io/misc/pickle_helpers.py
@@ -7,8 +7,6 @@ part of a larger framework or standard.
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-import sys
-
 from ...extern import six
 
 
diff --git a/astropy/io/misc/tests/test_hdf5.py b/astropy/io/misc/tests/test_hdf5.py
index befd215..7534c10 100644
--- a/astropy/io/misc/tests/test_hdf5.py
+++ b/astropy/io/misc/tests/test_hdf5.py
@@ -2,6 +2,8 @@
 
 from __future__ import print_function
 
+import os
+
 import numpy as np
 
 from ....tests.helper import pytest, catch_warnings
@@ -118,6 +120,7 @@ def test_read_write_simple(tmpdir):
 
 
 @pytest.mark.skipif('not HAS_H5PY')
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
 def test_read_write_existing_table(tmpdir):
     test_file = str(tmpdir.join('test.hdf5'))
     t1 = Table()
@@ -190,6 +193,7 @@ def test_read_write_existing_append_groups(tmpdir):
 
 
 @pytest.mark.skipif('not HAS_H5PY')
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'), reason="fails on AppVeyor")
 def test_read_write_existing_append_overwrite(tmpdir):
     test_file = str(tmpdir.join('test.hdf5'))
     t1 = Table()
diff --git a/astropy/io/registry.py b/astropy/io/registry.py
index 03a7bf3..bcb3091 100644
--- a/astropy/io/registry.py
+++ b/astropy/io/registry.py
@@ -57,11 +57,7 @@ def get_formats(data_class=None):
         # of the full 'ascii.rdb'.
         ascii_format_class = ('ascii.' + format_class[0], format_class[1])
 
-        # In the following, we use '   ' instead of '' because if the first
-        # format that is added is not deprecated, the data type for this
-        # element would be U0, which Numpy 1.5.x in Python 3 doesn't support,
-        # so we have to give it a non-zero length.
-        deprecated = 'Yes' if ascii_format_class in format_classes else '   '
+        deprecated = 'Yes' if ascii_format_class in format_classes else ''
 
         rows.append((format_class[1].__name__, format_class[0], has_read, has_write,
                      has_identify, deprecated))
@@ -332,7 +328,7 @@ def read(cls, *args, **kwargs):
         if not isinstance(data, cls):
             if issubclass(cls, data.__class__):
                 # User has read with a subclass where only the parent class is
-                # registered.  This returns the parent class, so try coercing to 
+                # registered.  This returns the parent class, so try coercing to
                 # desired subclass.
                 try:
                     data = cls(data)
diff --git a/astropy/io/votable/connect.py b/astropy/io/votable/connect.py
index 372f686..633cd57 100644
--- a/astropy/io/votable/connect.py
+++ b/astropy/io/votable/connect.py
@@ -139,6 +139,13 @@ def write_table_votable(input, output, table_id=None, overwrite=False,
         ``tabledata``.  See :ref:`votable-serialization`.
     """
 
+    # Tables with mixin columns are not supported
+    if input.has_mixin_columns:
+        mixin_names = [name for name, col in input.columns.items()
+                       if not isinstance(col, input.ColumnClass)]
+        raise ValueError('cannot write table with mixin column(s) {0} to VOTable'
+                         .format(mixin_names))
+
     # Check if output file already exists
     if isinstance(output, six.string_types) and os.path.exists(output):
         if overwrite:
diff --git a/astropy/io/votable/exceptions.py b/astropy/io/votable/exceptions.py
index 2e71168..fb510a0 100644
--- a/astropy/io/votable/exceptions.py
+++ b/astropy/io/votable/exceptions.py
@@ -342,7 +342,7 @@ class W03(VOTableChangeWarning):
     <http://www.ivoa.net/Documents/VOTable/20091130/REC-VOTable-1.2.html#sec:name>`__
     """
 
-    message_template = "Implictly generating an ID from a name '%s' -> '%s'"
+    message_template = "Implicitly generating an ID from a name '%s' -> '%s'"
     default_args = ('x', 'y')
 
 
@@ -515,6 +515,11 @@ class W13(VOTableSpecWarning):
        int64         -> long
        float32       -> float
        float64       -> double
+       unsignedInt   -> long
+       unsignedShort -> int
+
+    To add more datatype mappings during parsing, use the
+    ``datatype_mapping`` keyword to `astropy.io.votable.parse`.
 
     **References**: `1.1
     <http://www.ivoa.net/Documents/VOTable/20040811/REC-VOTable-1.1-20040811.html#sec:datatypes>`__,
@@ -1161,6 +1166,11 @@ class E06(VOWarning, ValueError):
         int64         -> long
         float32       -> float
         float64       -> double
+        unsignedInt   -> long
+        unsignedShort -> int
+
+    To add more datatype mappings during parsing, use the
+    ``datatype_mapping`` keyword to `astropy.io.votable.parse`.
 
     **References**: `1.1
     <http://www.ivoa.net/Documents/VOTable/20040811/REC-VOTable-1.1-20040811.html#sec:datatypes>`__,
diff --git a/astropy/io/votable/setup_package.py b/astropy/io/votable/setup_package.py
index d33e51c..cdde2a7 100755
--- a/astropy/io/votable/setup_package.py
+++ b/astropy/io/votable/setup_package.py
@@ -4,8 +4,6 @@ from __future__ import absolute_import
 from distutils.core import Extension
 from os.path import join
 
-from astropy_helpers import setup_helpers
-
 
 def get_extensions(build_type='release'):
     VO_DIR = 'astropy/io/votable/src'
diff --git a/astropy/io/votable/table.py b/astropy/io/votable/table.py
index c5b648b..53f5672 100644
--- a/astropy/io/votable/table.py
+++ b/astropy/io/votable/table.py
@@ -37,7 +37,7 @@ PEDANTIC = ConfigAlias(
 def parse(source, columns=None, invalid='exception', pedantic=None,
           chunk_size=tree.DEFAULT_CHUNK_SIZE, table_number=None,
           table_id=None, filename=None, unit_format=None,
-          _debug_python_based_parser=False):
+          datatype_mapping=None, _debug_python_based_parser=False):
     """
     Parses a VOTABLE_ xml file (or file-like object), and returns a
     `~astropy.io.votable.tree.VOTableFile` object.
@@ -100,6 +100,12 @@ def parse(source, columns=None, invalid='exception', pedantic=None,
         VOTable, and (probably) ``vounit`` in future versions of the
         spec).
 
+    datatype_mapping : dict of str to str, optional
+        A mapping of datatype names to valid VOTable datatype names.
+        For example, if the file being read contains the datatype
+        "unsignedInt" (an invalid datatype in VOTable), include the
+        mapping ``{"unsignedInt": "long"}``.
+
     Returns
     -------
     votable : `~astropy.io.votable.tree.VOTableFile` object
@@ -116,14 +122,19 @@ def parse(source, columns=None, invalid='exception', pedantic=None,
     if pedantic is None:
         pedantic = conf.pedantic
 
+    if datatype_mapping is None:
+        datatype_mapping = {}
+
     config = {
-        'columns'      :      columns,
-        'invalid'      :      invalid,
-        'pedantic'     :     pedantic,
-        'chunk_size'   :   chunk_size,
-        'table_number' : table_number,
-        'filename'     :     filename,
-        'unit_format'  :  unit_format}
+        'columns'          : columns,
+        'invalid'          : invalid,
+        'pedantic'         : pedantic,
+        'chunk_size'       : chunk_size,
+        'table_number'     : table_number,
+        'filename'         : filename,
+        'unit_format'      : unit_format,
+        'datatype_mapping' : datatype_mapping
+    }
 
     if filename is None and isinstance(source, six.string_types):
         config['filename'] = source
diff --git a/astropy/io/votable/tests/data/custom_datatype.xml b/astropy/io/votable/tests/data/custom_datatype.xml
new file mode 100644
index 0000000..17e2217
--- /dev/null
+++ b/astropy/io/votable/tests/data/custom_datatype.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VOTABLE version="1.1"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:noNamespaceSchemaLocation="xmlns:http://www.ivoa.net/xml/VOTable/VOTable-1.1.xsd"
+xmlns="http://www.ivoa.net/xml/VOTable/v1.1">
+  <RESOURCE>
+    <TABLE>
+      <FIELD name="foo" datatype="bar"/>
+      <DATA>
+        <TABLEDATA>
+          <TR>
+            <TD>42</TD>
+          </TR>
+        </TABLEDATA>
+      </DATA>
+    </TABLE>
+  </RESOURCE>
+</VOTABLE>
diff --git a/astropy/io/votable/tests/vo_test.py b/astropy/io/votable/tests/vo_test.py
index 9ec698d..364d839 100644
--- a/astropy/io/votable/tests/vo_test.py
+++ b/astropy/io/votable/tests/vo_test.py
@@ -13,7 +13,6 @@ from ....extern.six.moves import xrange
 
 # STDLIB
 import difflib
-from distutils import version
 import io
 import os
 import shutil
@@ -725,6 +724,8 @@ def test_open_files():
         parse(filename, pedantic=False)
 
     for filename in get_pkg_data_filenames('data', '*.xml'):
+        if filename.endswith('custom_datatype.xml'):
+            continue
         yield test_file, filename
 
 
@@ -992,3 +993,14 @@ def test_instantiate_vowarning():
     # This used to raise a deprecation exception on Python 2.6.
     # See https://github.com/astropy/astroquery/pull/276
     VOWarning(())
+
+
+def test_custom_datatype():
+    votable = parse(
+        get_pkg_data_filename('data/custom_datatype.xml'),
+        pedantic=False,
+        datatype_mapping={'bar': 'int'}
+    )
+
+    table = votable.get_first_table()
+    assert table.array.dtype['foo'] == np.int32
diff --git a/astropy/io/votable/tree.py b/astropy/io/votable/tree.py
index 7fbd057..a02e955 100644
--- a/astropy/io/votable/tree.py
+++ b/astropy/io/votable/tree.py
@@ -1189,7 +1189,13 @@ class Field(SimpleElement, _IDProperty, _NameProperty, _XtypeProperty,
             'int32'         : 'int',
             'int64'         : 'long',
             'float32'       : 'float',
-            'float64'       : 'double'}
+            'float64'       : 'double',
+            # The following appear in some Vizier tables
+            'unsignedInt'   : 'long',
+            'unsignedShort' : 'int'
+        }
+
+        datatype_mapping.update(config.get('datatype_mapping', {}))
 
         if datatype in datatype_mapping:
             warn_or_raise(W13, W13, (datatype, datatype_mapping[datatype]),
@@ -1778,7 +1784,7 @@ class ParamRef(SimpleElement, _UtypeProperty, _UcdProperty):
 
     It contains the following publicly-accessible members:
 
-      *ref*: An XML ID refering to a <PARAM> element.
+      *ref*: An XML ID referring to a <PARAM> element.
     """
     _attr_list_11 = ['ref']
     _attr_list_12 = _attr_list_11 + ['ucd', 'utype']
@@ -2888,7 +2894,8 @@ class Table(Element, _IDProperty, _NameProperty, _UcdProperty,
         if table.mask is None:
             new_table.array = ma.array(np.asarray(table))
         else:
-            new_table.array = ma.array(np.asarray(table), mask=table.mask)
+            new_table.array = ma.array(np.asarray(table),
+                                       mask=np.asarray(table.mask))
 
         return new_table
 
diff --git a/astropy/logger.py b/astropy/logger.py
index 42ab9dd..29290c3 100644
--- a/astropy/logger.py
+++ b/astropy/logger.py
@@ -3,6 +3,7 @@
 
 from __future__ import print_function
 
+import inspect
 import os
 import sys
 import logging
@@ -11,9 +12,9 @@ from contextlib import contextmanager
 
 from . import config as _config
 from . import conf as _conf
-from .utils.compat import inspect_getmodule
+from .extern.six import PY3
+from .utils import find_current_module
 from .utils.console import color_print
-from .utils.misc import find_current_module
 from .utils.exceptions import AstropyWarning, AstropyUserWarning
 
 __all__ = ['Conf', 'conf', 'log', 'AstropyLogger', 'LoggingError']
@@ -162,14 +163,13 @@ class AstropyLogger(Logger):
                 extra['origin'] = current_module.__name__
             else:
                 extra['origin'] = 'unknown'
-        if sys.version_info[0] < 3 or \
-           (sys.version_info[0] == 3 and sys.version_info[1] < 2):
-            return Logger.makeRecord(self, name, level, pathname, lineno, msg,
-                                     args, exc_info, func=func, extra=extra)
-        else:
+        if PY3:
             return Logger.makeRecord(self, name, level, pathname, lineno, msg,
                                      args, exc_info, func=func, extra=extra,
                                      sinfo=sinfo)
+        else:
+            return Logger.makeRecord(self, name, level, pathname, lineno, msg,
+                                     args, exc_info, func=func, extra=extra)
 
     _showwarning_orig = None
 
@@ -198,22 +198,22 @@ class AstropyLogger(Logger):
         # module.__file__ is the original source file name, so things
         # are more direct.
         mod_name = None
-        if sys.version_info[0] < 3:  # pragma: py2
-            for name, mod in sys.modules.items():
+        if PY3:
+            mod_path, ext = os.path.splitext(mod_path)
+            for name, mod in list(sys.modules.items()):
                 try:
                     # Believe it or not this can fail in some cases:
                     # https://github.com/astropy/astropy/issues/2671
-                    if getattr(mod, '__file__', '') == mod_path:
-                        mod_name = mod.__name__
-                        break
+                    path = os.path.splitext(getattr(mod, '__file__', ''))[0]
                 except:
                     continue
-        else:  # pragma: py3
-            mod_path, ext = os.path.splitext(mod_path)
-            for name, mod in sys.modules.items():
+                if path == mod_path:
+                    mod_name = mod.__name__
+                    break
+        else:  # pragma: py2
+            for name, mod in list(sys.modules.items()):
                 try:
-                    path = os.path.splitext(getattr(mod, '__file__', ''))[0]
-                    if path == mod_path:
+                    if getattr(mod, '__file__', '') == mod_path:
                         mod_name = mod.__name__
                         break
                 except:
@@ -270,7 +270,7 @@ class AstropyLogger(Logger):
             tb = traceback
             while tb.tb_next is not None:
                 tb = tb.tb_next
-            mod = inspect_getmodule(tb)
+            mod = inspect.getmodule(tb)
 
         # include the the error type in the message.
         if len(value.args) > 0:
diff --git a/astropy/modeling/__init__.py b/astropy/modeling/__init__.py
index 6d21ff3..399fe80 100644
--- a/astropy/modeling/__init__.py
+++ b/astropy/modeling/__init__.py
@@ -11,3 +11,4 @@ from . import fitting
 from . import models
 from .core import *
 from .parameters import *
+from ._compound_deprecated import *
diff --git a/astropy/modeling/_compound_deprecated.py b/astropy/modeling/_compound_deprecated.py
new file mode 100644
index 0000000..9f0acc9
--- /dev/null
+++ b/astropy/modeling/_compound_deprecated.py
@@ -0,0 +1,420 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+This module contains implementations of the old compound model interfaces that
+are now deprecated.
+
+The classes exported by this module should be imported from `astropy.modeling`
+rather than from `astropy.modeling.core` or from this module directly.
+"""
+
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import functools
+import operator
+import warnings
+
+import numpy as np
+
+from ..utils import deprecated, indent
+from ..utils.compat.odict import OrderedDict
+from ..utils.exceptions import AstropyDeprecationWarning
+from .core import Model
+
+
+__all__ = ['LabeledInput', 'SerialCompositeModel', 'SummedCompositeModel']
+
+
+ at deprecated('1.0', alternative=':ref:`compound-models` as described in the '
+                               'Astropy documentation')
+class LabeledInput(OrderedDict):
+    """
+    Used by `SerialCompositeModel` and `SummedCompositeModel` to choose input
+    data using labels.
+
+    This is a container assigning labels (names) to all input data arrays to a
+    composite model.
+
+    Parameters
+    ----------
+    data : list
+        List of all input data
+    labels : list of strings
+        names matching each coordinate in data
+
+    Examples
+    --------
+    >>> y, x = np.mgrid[:5, :5]
+    >>> l = np.arange(10)
+    >>> labeled_input = LabeledInput([x, y, l], ['x', 'y', 'pixel'])
+    >>> labeled_input.x
+    array([[0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4]])
+    >>> labeled_input['x']
+    array([[0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4],
+           [0, 1, 2, 3, 4]])
+    """
+
+    def __init__(self, data, labels):
+        if len(labels) != len(data):
+            raise TypeError("Number of labels and data doesn't match")
+
+        super(LabeledInput, self).__init__(zip(labels, data))
+
+    def __getattr__(self, label):
+        try:
+            return self[label]
+        except KeyError:
+            raise AttributeError(label)
+
+    def __setattr__(self, label, data):
+        if label.startswith('_'):
+            super(LabeledInput, self).__setattr__(label, data)
+        else:
+            self[label] = data
+
+    def __delattr__(self, label):
+        try:
+            del self[label]
+        except KeyError:
+            raise AttributeError(label)
+
+    @property
+    def labels(self):
+        return tuple(self.keys())
+
+    def add(self, label=None, value=None, **kw):
+        """
+        Add input data to a LabeledInput object
+
+        Parameters
+        --------------
+        label : str
+            coordinate label
+        value : numerical type
+            coordinate value
+        kw : dictionary
+            if given this is a dictionary of ``{label: value}`` pairs
+        """
+
+        if ((label is None and value is not None) or
+                (label is not None and value is None)):
+            raise TypeError("Expected label and value to be defined")
+
+        kw[label] = value
+
+        self.update(kw)
+
+    def copy(self):
+        return LabeledInput(self.values(), self.labels)
+
+
+class _LabeledInputMapping(Model):
+    def __init__(self, labeled_input, inmap, outmap):
+        self._labeled_input = labeled_input
+        self._inmap = tuple(inmap)
+        self._outmap = tuple(outmap)
+        super(_LabeledInputMapping, self).__init__()
+
+    def __repr__(self):
+        return '<{0}>'.format(self.name)
+
+    @property
+    def inputs(self):
+        return self._outmap
+
+    @property
+    def outputs(self):
+        return self._inmap
+
+    @property
+    def name(self):
+        return '{0}({1} -> {2})'.format(self.__class__.__name__,
+                                        self._outmap, self._inmap)
+
+    def evaluate(self, *inputs):
+        for idx, label in enumerate(self._outmap):
+            self._labeled_input[label] = inputs[idx]
+
+        result = tuple(self._labeled_input[label] for label in self._inmap)
+
+        if len(result) == 1:
+            return result[0]
+        else:
+            return result
+
+
+class _CompositeModel(Model):
+    """Base class for all composite models."""
+
+    _operator = None
+    fittable = False
+
+    def __init__(self, transforms, n_inputs, n_outputs, inmap=None,
+                 outmap=None):
+        self._transforms = transforms
+        param_names = []
+        for tr in self._transforms:
+            param_names.extend(tr.param_names)
+        super(_CompositeModel, self).__init__()
+        self.param_names = param_names
+        self._n_inputs = n_inputs
+        self._n_outputs = n_outputs
+        self._basic_transform = None
+
+        self._inmap = inmap
+        self._outmap = outmap
+
+    def __repr__(self):
+        return '<{0}([\n{1}\n])>'.format(
+            self.__class__.__name__,
+            indent(',\n'.join(repr(tr) for tr in self._transforms),
+                   width=4))
+
+    def __str__(self):
+        parts = ['Model: {0}'.format(self.__class__.__name__)]
+        for tr in self._transforms:
+            parts.append(indent(str(tr), width=4))
+        return '\n'.join(parts)
+
+    @property
+    def inputs(self):
+        return self._transforms[0].inputs
+
+    @property
+    def outputs(self):
+        return self._transforms[-1].outputs
+
+    @property
+    def n_inputs(self):
+        return self._n_inputs
+
+    @n_inputs.setter
+    def n_inputs(self, val):
+        warnings.warn(
+            'Setting n_inputs on {0} objects is undefined and should not '
+            'be used.'.format(self.__class__.__name__),
+            AstropyDeprecationWarning)
+        self._n_inputs = val
+
+    @property
+    def n_outputs(self):
+        return self._n_outputs
+
+    @n_outputs.setter
+    def n_outputs(self, val):
+        warnings.warn(
+            'Setting n_outputs on {0} objects is undefined and should not '
+            'be used.'.format(self.__class__.__name__),
+            AstropyDeprecationWarning)
+        self._n_outputs = val
+
+    def invert(self):
+        raise NotImplementedError("Subclasses should implement this")
+
+    @property
+    def parameters(self):
+        raise NotImplementedError(
+            "Composite models do not currently support the .parameters "
+            "array.")
+
+    def evaluate(self, *inputs):
+        """
+        Specialized `Model.evaluate` implementation that allows `LabeledInput`
+        inputs to be handled when calling this model.
+
+        This ignores any passed in parameter values, as _CompositeModels can't
+        be fitted anyways.
+        """
+
+        # Drop parameter arguments
+        inputs = inputs[:self.n_inputs]
+
+        if len(inputs) == 1 and isinstance(inputs[0], LabeledInput):
+            labeled_input = inputs[0].copy()
+            transform = self._make_labeled_transform(labeled_input)
+            inputs = [labeled_input[label] for label in self._inmap[0]]
+            result = transform(*inputs)
+
+            if self._transforms[-1].n_outputs == 1:
+                labeled_input[self._outmap[-1][0]] = result
+            else:
+                for label, output in zip(self._outmap[-1], result):
+                    labeled_input[label] = output
+
+            return labeled_input
+        else:
+            if self._basic_transform is None:
+                transform = self._transforms[0]
+                for t in self._transforms[1:]:
+                    transform = self._operator(transform, t)
+
+                self._basic_transform = transform
+
+            return self._basic_transform(*inputs)
+
+    def __call__(self, *inputs):
+        """
+        Specialized `Model.__call__` implementation that allows
+        `LabeledInput` inputs to be handled when calling this model.
+        """
+
+        return self.evaluate(*inputs)
+
+    def _param_sets(self, raw=False):
+        all_params = tuple(m._param_sets(raw=raw) for m in self._transforms)
+        return np.vstack(all_params)
+
+    def _make_labeled_transform(self, labeled_input):
+        """
+        Build up a transformation graph that incorporates the instructions
+        encoded in the `LabeledInput` object.
+
+        This requires use of the ``_inmap`` and ``_outmap`` attributes set
+        when instantiating this `_CompositeModel`.
+        """
+
+        if self._inmap is None:
+            raise TypeError("Parameter 'inmap' must be provided when "
+                            "input is a labeled object.")
+        if self._outmap is None:
+            raise TypeError("Parameter 'outmap' must be provided when "
+                            "input is a labeled object")
+
+        transforms = [self._transforms[0]]
+        previous_outmap = self._outmap[0]
+        for model, inmap, outmap in zip(self._transforms[1:], self._inmap[1:],
+                                        self._outmap[1:]):
+            mapping = _LabeledInputMapping(labeled_input, inmap,
+                                           previous_outmap)
+            transforms.append(mapping | model)
+            previous_outmap = outmap
+
+        return functools.reduce(self._operator, transforms)
+
+
+ at deprecated('1.0', alternative=':ref:`compound-models` as described in the '
+                               'Astropy documentation')
+class SerialCompositeModel(_CompositeModel):
+    """
+    Composite model that evaluates models in series.
+
+    Parameters
+    ----------
+    transforms : list
+        a list of transforms in the order to be executed
+    inmap : list of lists or None
+        labels in an input instance of LabeledInput
+        if None, the number of input coordinates is exactly what
+        the transforms expect
+    outmap : list or None
+        labels in an input instance of LabeledInput
+        if None, the number of output coordinates is exactly what
+        the transforms expect
+    n_inputs : int
+        dimension of input space (e.g. 2 for a spatial model)
+    n_outputs : int
+        dimension of output
+
+    Notes
+    -----
+    Output values of one model are used as input values of another.
+    Obviously the order of the models matters.
+
+    Examples
+    --------
+    Apply a 2D rotation followed by a shift in x and y::
+
+        >>> import numpy as np
+        >>> from astropy.modeling import models, LabeledInput, SerialCompositeModel
+        >>> y, x = np.mgrid[:5, :5]
+        >>> rotation = models.Rotation2D(angle=23.5)
+        >>> offset_x = models.Shift(-4.23)
+        >>> offset_y = models.Shift(2)
+        >>> labeled_input = LabeledInput([x, y], ["x", "y"])
+        >>> transform = SerialCompositeModel([rotation, offset_x, offset_y],
+        ...                                  inmap=[['x', 'y'], ['x'], ['y']],
+        ...                                  outmap=[['x', 'y'], ['x'], ['y']])
+        >>> result = transform(labeled_input)
+    """
+
+    _operator = operator.or_
+
+    def __init__(self, transforms, inmap=None, outmap=None, n_inputs=None,
+                 n_outputs=None):
+        if n_inputs is None:
+            n_inputs = max([tr.n_inputs for tr in transforms])
+            # the output dimension is equal to the output dim of the last
+            # transform
+            n_outputs = transforms[-1].n_outputs
+        else:
+            if n_outputs is None:
+                raise TypeError("Expected n_inputs and n_outputs")
+
+        if transforms and inmap and outmap:
+            if not (len(transforms) == len(inmap) == len(outmap)):
+                raise ValueError("Expected sequences of transform, "
+                                 "inmap and outmap to have the same length")
+
+        super(SerialCompositeModel, self).__init__(
+                transforms, n_inputs, n_outputs, inmap=inmap, outmap=outmap)
+
+    def inverse(self):
+        try:
+            transforms = []
+            for transform in self._transforms[::-1]:
+                transforms.append(transform.inverse)
+        except NotImplementedError:
+            raise NotImplementedError(
+                "An analytical inverse has not been implemented for "
+                "{0} models.".format(transform.__class__.__name__))
+        if self._inmap is not None:
+            inmap = self._inmap[::-1]
+            outmap = self._outmap[::-1]
+        else:
+            inmap = None
+            outmap = None
+        return SerialCompositeModel(transforms, inmap, outmap)
+
+
+ at deprecated('1.0', alternative=':ref:`compound-models` as described in the '
+                               'Astropy documentation')
+class SummedCompositeModel(_CompositeModel):
+    """
+    Composite model that evaluates models in parallel.
+
+    Parameters
+    --------------
+    transforms : list
+        transforms to be executed in parallel
+    inmap : list or None
+        labels in an input instance of LabeledInput
+        if None, the number of input coordinates is exactly what the
+        transforms expect
+    outmap : list or None
+
+    Notes
+    -----
+    Evaluate each model separately and add the results to the input_data.
+    """
+
+    _operator = operator.add
+
+    def __init__(self, transforms, inmap=None, outmap=None):
+        n_inputs = transforms[0].n_inputs
+        n_outputs = n_inputs
+        for transform in transforms:
+            if not (transform.n_inputs == transform.n_outputs == n_inputs):
+                raise ValueError("A SummedCompositeModel expects n_inputs = "
+                                 "n_outputs for all transforms")
+
+        super(SummedCompositeModel, self).__init__(transforms, n_inputs,
+                                                   n_outputs, inmap=inmap,
+                                                   outmap=outmap)
diff --git a/astropy/modeling/core.py b/astropy/modeling/core.py
index 100b2e4..51439a1 100644
--- a/astropy/modeling/core.py
+++ b/astropy/modeling/core.py
@@ -18,105 +18,171 @@ from __future__ import (absolute_import, unicode_literals, division,
 
 import abc
 import copy
-import functools
 import inspect
+import functools
+import operator
 import warnings
 
+from collections import defaultdict
+from itertools import chain, islice
+
 import numpy as np
 
-from ..utils import indent, isiterable
+from ..utils import indent, isiterable, isinstancemethod, metadata
 from ..extern import six
-from ..extern.six.moves import zip as izip
-from ..extern.six.moves import range
 from ..table import Table
-from ..utils import deprecated
+from ..utils import (deprecated, sharedmethod, find_current_module,
+                     InheritDocstrings)
+from ..utils.codegen import make_function_with_signature
 from ..utils.exceptions import AstropyDeprecationWarning
-from .utils import array_repr_oneline, check_broadcast, IncompatibleShapeError
+from .utils import (array_repr_oneline, check_broadcast, combine_labels,
+                    make_binary_operator_eval, ExpressionTree,
+                    IncompatibleShapeError)
 
 from .parameters import Parameter, InputParameterError
 
-__all__ = ['Model', 'FittableModel', 'SummedCompositeModel',
-           'SerialCompositeModel', 'LabeledInput', 'FittableModel',
-           'Fittable1DModel', 'Fittable2DModel', 'ModelDefinitionError',
-           'format_input']
-
 
-__doctest_skip__ = ['.']
+__all__ = ['Model', 'FittableModel', 'Fittable1DModel', 'Fittable2DModel',
+           'custom_model', 'ModelDefinitionError']
 
 
-class ModelDefinitionError(Exception):
+class ModelDefinitionError(TypeError):
     """Used for incorrect models definitions"""
 
 
-def format_input(func):
+def _model_oper(oper, **kwargs):
     """
-    Wraps a model's ``__call__`` method so that the input arrays are converted
-    into the appropriate shape given the model's parameter dimensions.
+    Returns a function that evaluates a given Python arithmetic operator
+    between two models.  The operator should be given as a string, like ``'+'``
+    or ``'**'``.
 
-    Wraps the result to match the shape of the last input array.
+    Any additional keyword arguments passed in are passed to
+    `_CompoundModelMeta._from_operator`.
     """
 
-    argspec = inspect.getargspec(func)
+    # Note: Originally this used functools.partial, but that won't work when
+    # used in the class definition of _CompoundModelMeta since
+    # _CompoundModelMeta has not been defined yet.
 
-    @functools.wraps(func)
-    def wrapped_call(self, *inputs, **kwargs):
-        model_set_axis = kwargs.pop('model_set_axis', None)
+    # Perform an arithmetic operation on two models.
+    return lambda left, right: _CompoundModelMeta._from_operator(oper,
+            left, right, **kwargs)
 
-        if model_set_axis is None:
-            # By default the model_set_axis for the input is assumed to be the
-            # same as that for the parameters the model was defined with
-            # TODO: Ensure that negative model_set_axis arguments are respected
-            model_set_axis = self.model_set_axis
 
-        n_models = len(self)
+class _ModelMeta(InheritDocstrings, abc.ABCMeta):
+    """
+    Metaclass for Model.
 
-        params = [getattr(self, name) for name in self.param_names]
-        inputs = [np.asanyarray(_input, dtype=float) for _input in inputs]
+    Currently just handles auto-generating the param_names list based on
+    Parameter descriptors declared at the class-level of Model subclasses.
+    """
 
-        scalar_params = all(not param.shape for param in params)
-        scalar_inputs = all(not np.shape(_input) for _input in inputs)
+    registry = set()
+    """
+    A registry of all known concrete (non-abstract) Model subclasses.
+    """
 
-        if n_models == 1 and scalar_params and scalar_inputs:
-            # Simplest case is either a parameterless models (currently I don't
-            # think we have any but they could exist in principle) or a single
-            # model (not a model set) with all scalar paramaters and all scalar
-            # inputs
-            outputs = func(self, *inputs, **kwargs)
+    def __new__(mcls, name, bases, members):
+        parameters = mcls._handle_parameters(name, members)
+        mcls._create_inverse_property(members)
+        mcls._handle_backwards_compat(name, members)
 
-            if self.n_outputs == 1:
-                return np.asscalar(outputs)
-            else:
-                return tuple(np.asscalar(output) for output in outputs)
+        cls = super(_ModelMeta, mcls).__new__(mcls, name, bases, members)
 
-        input_names = argspec.args[1:1 + len(inputs)]
+        mcls._handle_special_methods(members, cls, parameters)
 
-        _validate_input_shapes(inputs, input_names, n_models,
-                               model_set_axis, self.standard_broadcasting)
+        if not inspect.isabstract(cls) and not name.startswith('_'):
+            mcls.registry.add(cls)
 
-        # The input formatting required for single models versus a multiple
-        # model set are different enough that they've been split into separate
-        # subroutines
-        if n_models == 1:
-            return _format_single_model_input(func, self, params, inputs,
-                                              input_names, **kwargs)
-        else:
-            return _format_model_set_input(func, self, params, inputs,
-                                           input_names, n_models,
-                                           model_set_axis, **kwargs)
+        return cls
 
-    return wrapped_call
+    def __repr__(cls):
+        """
+        Custom repr for Model subclasses.
+        """
 
+        return cls._format_cls_repr()
 
-class _ModelMeta(abc.ABCMeta):
-    """
-    Metaclass for Model.
+    def _repr_pretty_(cls, p, cycle):
+        """
+        Repr for IPython's pretty printer.
 
-    Currently just handles auto-generating the param_names list based on
-    Parameter descriptors declared at the class-level of Model subclasses.
-    """
+        By default IPython "pretty prints" classes, so we need to implement
+        this so that IPython displays the custom repr for Models.
+        """
 
-    def __new__(mcls, name, bases, members):
-        param_names = members.get('param_names', [])
+        p.text(repr(cls))
+
+    @property
+    def name(cls):
+        """
+        The name of this model class--equivalent to ``cls.__name__``.
+
+        This attribute is provided for symmetry with the `Model.name` attribute
+        of model instances.
+        """
+
+        return cls.__name__
+
+    @property
+    def n_inputs(cls):
+        return len(cls.inputs)
+
+    @property
+    def n_outputs(cls):
+        return len(cls.outputs)
+
+    def rename(cls, name):
+        """
+        Creates a copy of this model class with a new name.
+
+        The new class is technically a subclass of the original class, so that
+        instance and type checks will still work.  For example::
+
+            >>> from astropy.modeling.models import Rotation2D
+            >>> SkyRotation = Rotation2D.rename('SkyRotation')
+            >>> SkyRotation
+            <class '__main__.SkyRotation'>
+            Name: SkyRotation (Rotation2D)
+            Inputs: ('x', 'y')
+            Outputs: ('x', 'y')
+            Fittable parameters: ('angle',)
+            >>> issubclass(SkyRotation, Rotation2D)
+            True
+            >>> r = SkyRotation(90)
+            >>> isinstance(r, Rotation2D)
+            True
+        """
+
+        if six.PY2 and isinstance(name, six.text_type):
+            # Unicode names are not allowed in Python 2, so just convert to
+            # ASCII.  As such, for cross-compatibility all model names should
+            # just be ASCII for now.
+            name = name.encode('ascii')
+
+        mod = find_current_module(2)
+        if mod:
+            modname = mod.__name__
+        else:
+            modname = '__main__'
+
+        new_cls = type(name, (cls,), {})
+        # On Python 2 __module__ must be a str, not unicode
+        new_cls.__module__ = str(modname)
+
+        if hasattr(cls, '__qualname__'):
+            if new_cls.__module__ == '__main__':
+                # __main__ is not added to a class's qualified name
+                new_cls.__qualname__ = name
+            else:
+                new_cls.__qualname__ = '{0}.{1}'.format(modname, name)
+
+        return new_cls
+
+    @classmethod
+    def _handle_parameters(mcls, name, members):
+        # Handle parameters
+        param_names = members.get('param_names', ())
         parameters = {}
         for key, value in members.items():
             if not isinstance(value, Parameter):
@@ -138,9 +204,13 @@ class _ModelMeta(abc.ABCMeta):
         # If no parameters were defined get out early--this is especially
         # important for PolynomialModels which take a different approach to
         # parameters, since they can have a variable number of them
-        if not parameters:
-            return super(_ModelMeta, mcls).__new__(mcls, name, bases, members)
+        if parameters:
+            mcls._check_parameters(name, members, param_names, parameters)
+
+        return parameters
 
+    @staticmethod
+    def _check_parameters(name, members, param_names, parameters):
         # If param_names was declared explicitly we use only the parameters
         # listed manually in param_names, but still check that all listed
         # parameters were declared
@@ -151,14 +221,185 @@ class _ModelMeta(abc.ABCMeta):
                         "Parameter {0!r} listed in {1}.param_names was not "
                         "declared in the class body.".format(param_name, name))
         else:
-            param_names = [param.name for param in
-                           sorted(parameters.values(),
-                                  key=lambda p: p._order)]
+            param_names = tuple(param.name for param in
+                                sorted(parameters.values(),
+                                       key=lambda p: p._order))
             members['param_names'] = param_names
             members['_param_orders'] = \
                     dict((name, idx) for idx, name in enumerate(param_names))
 
-        return super(_ModelMeta, mcls).__new__(mcls, name, bases, members)
+    @staticmethod
+    def _create_inverse_property(members):
+        inverse = members.get('inverse', None)
+        if inverse is None:
+            return
+
+        if isinstance(inverse, property):
+            fget = inverse.fget
+        else:
+            # We allow the @property decorator to be omitted entirely from
+            # the class definition, though its use should be encouraged for
+            # clarity
+            fget = inverse
+
+        def wrapped_fget(self):
+            if self._custom_inverse is not None:
+                return self._custom_inverse
+
+            return fget(self)
+
+        def fset(self, value):
+            if not isinstance(value, (Model, type(None))):
+                raise ValueError(
+                    "The ``inverse`` attribute may be assigned a `Model` "
+                    "instance or `None` (where `None` restores the default "
+                    "inverse for this model if one is defined.")
+
+            self._custom_inverse = value
+
+        members['inverse'] = property(wrapped_fget, fset,
+                                      doc=inverse.__doc__)
+
+    @classmethod
+    def _handle_backwards_compat(mcls, name, members):
+        # Backwards compatibility check for 'eval' -> 'evaluate'
+        # TODO: Remove sometime after Astropy 1.0 release.
+        if 'eval' in members and 'evaluate' not in members:
+            warnings.warn(
+                "Use of an 'eval' method when defining subclasses of "
+                "FittableModel is deprecated; please rename this method to "
+                "'evaluate'.  Otherwise its semantics remain the same.",
+                AstropyDeprecationWarning)
+            members['evaluate'] = members['eval']
+        elif ('evaluate' in members and callable(members['evaluate']) and
+                not getattr(members['evaluate'], '__isabstractmethod__',
+                            False)):
+            # Don't bother making a deprecated eval() except for concrete
+            # implementations of evaluate, so that we don't end up with an eval
+            # abstractmethod as well
+            alt = '.'.join((name, 'evaluate'))
+            deprecate = deprecated('1.0', alternative=alt, name='eval')
+            members['eval'] = deprecate(members['evaluate'])
+
+    @classmethod
+    def _handle_special_methods(mcls, members, cls, parameters):
+        # Handle init creation from inputs
+        def update_wrapper(wrapper, cls):
+            # Set up the new __call__'s metadata attributes as though it were
+            # manually defined in the class definition
+            # A bit like functools.update_wrapper but uses the class instead of
+            # the wrapped function
+            wrapper.__module__ = cls.__module__
+            wrapper.__doc__ = getattr(cls, wrapper.__name__).__doc__
+            if hasattr(cls, '__qualname__'):
+                wrapper.__qualname__ = '{0}.{1}'.format(
+                        cls.__qualname__, wrapper.__name__)
+
+        if ('__call__' not in members and 'inputs' in members and
+                isinstance(members['inputs'], tuple)):
+            inputs = members['inputs']
+            # Done create a custom __call__ for classes that already have one
+            # explicitly defined (this includes the Model base class, and any
+            # other classes that manually override __call__
+            def __call__(self, *inputs, **kwargs):
+                """Evaluate this model on the supplied inputs."""
+
+                return super(cls, self).__call__(*inputs, **kwargs)
+
+            args = ('self',) + inputs
+            new_call = make_function_with_signature(
+                    __call__, args, [('model_set_axis', None)])
+            update_wrapper(new_call, cls)
+            cls.__call__ = new_call
+
+        if ('__init__' not in members and not inspect.isabstract(cls) and
+                parameters):
+            # If *all* the parameters have default values we can make them
+            # keyword arguments; otherwise they must all be positional
+            # arguments
+            if all(p.default is not None
+                   for p in six.itervalues(parameters)):
+                args = ('self',)
+                kwargs = [(name, parameters[name].default)
+                          for name in cls.param_names]
+            else:
+                args = ('self',) + cls.param_names
+                kwargs = {}
+
+            def __init__(self, *params, **kwargs):
+                return super(cls, self).__init__(*params, **kwargs)
+
+            new_init = make_function_with_signature(
+                    __init__, args, kwargs, varkwargs='kwargs')
+            update_wrapper(new_init, cls)
+            cls.__init__ = new_init
+
+    # *** Arithmetic operators for creating compound models ***
+    __add__ =     _model_oper('+')
+    __sub__ =     _model_oper('-')
+    __mul__ =     _model_oper('*')
+    __truediv__ = _model_oper('/')
+    __pow__ =     _model_oper('**')
+    __or__ =      _model_oper('|')
+    __and__ =     _model_oper('&')
+
+    if not six.PY3:
+        # The classic __div__ operator need only be implemented for Python 2
+        # without from __future__ import division
+        __div__ = _model_oper('/')
+
+    # *** Other utilities ***
+
+    def _format_cls_repr(cls, keywords=[]):
+        """
+        Internal implementation of ``__repr__``.
+
+        This is separated out for ease of use by subclasses that wish to
+        override the default ``__repr__`` while keeping the same basic
+        formatting.
+        """
+
+        # For the sake of familiarity start the output with the standard class
+        # __repr__
+        parts = [super(_ModelMeta, cls).__repr__()]
+
+        if cls.__name__.startswith('_') or inspect.isabstract(cls):
+            return parts[0]
+
+        def format_inheritance(cls):
+            bases = []
+            for base in cls.mro()[1:]:
+                if not issubclass(base, Model):
+                    continue
+                elif (inspect.isabstract(base) or
+                        base.__name__.startswith('_')):
+                    break
+                bases.append(base.name)
+            if bases:
+                return '{0} ({1})'.format(cls.name, ' -> '.join(bases))
+            else:
+                return cls.name
+
+        try:
+            default_keywords = [
+                ('Name', format_inheritance(cls)),
+                ('Inputs', cls.inputs),
+                ('Outputs', cls.outputs),
+            ]
+
+            if cls.param_names:
+                default_keywords.append(('Fittable parameters',
+                                         cls.param_names))
+
+            for keyword, value in default_keywords + keywords:
+                if value is not None:
+                    parts.append('{0}: {1}'.format(keyword, value))
+
+            return '\n'.join(parts)
+        except:
+            # If any of the above formatting fails fall back on the basic repr
+            # (this is particularly useful in debugging)
+            return parts[0]
 
 
 @six.add_metaclass(_ModelMeta)
@@ -173,9 +414,12 @@ class Model(object):
 
     Parameters
     ----------
-    param_dim : int
-        Number of parameter sets
-    fixed : dict
+    name : str, optional
+        A human-friendly name associated with this model instance
+        (particularly useful for identifying the individual components of a
+        compound model).
+
+    fixed : dict, optional
         Dictionary ``{parameter_name: bool}`` setting the fixed constraint
         for one or more parameters.  `True` means the parameter is held fixed
         during fitting and is prevented from updates once an instance of the
@@ -183,7 +427,8 @@ class Model(object):
 
         Alternatively the `~astropy.modeling.Parameter.fixed` property of a
         parameter may be used to lock or unlock individual parameters.
-    tied : dict
+
+    tied : dict, optional
         Dictionary ``{parameter_name: callable}`` of parameters which are
         linked to some other parameter. The dictionary values are callables
         providing the linking relationship.
@@ -191,7 +436,8 @@ class Model(object):
         Alternatively the `~astropy.modeling.Parameter.tied` property of a
         parameter may be used to set the ``tied`` constraint on individual
         parameters.
-    bounds : dict
+
+    bounds : dict, optional
         Dictionary ``{parameter_name: value}`` of lower and upper bounds of
         parameters. Keys are parameter names. Values are a list of length 2
         giving the desired range for the parameter.
@@ -200,10 +446,12 @@ class Model(object):
         `~astropy.modeling.Parameter.max` or
         ~astropy.modeling.Parameter.bounds` properties of a parameter may be
         used to set bounds on individual parameters.
-    eqcons : list
+
+    eqcons : list, optional
         List of functions of length n such that ``eqcons[j](x0, *args) == 0.0``
         in a successfully optimized problem.
-    ineqcons : list
+
+    ineqcons : list, optional
         List of functions of length n such that ``ieqcons[j](x0, *args) >=
         0.0`` is a successfully optimized problem.
 
@@ -246,27 +494,62 @@ class Model(object):
     True
     """
 
-    parameter_constraints = ['fixed', 'tied', 'bounds']
-    model_constraints = ['eqcons', 'ineqcons']
+    parameter_constraints = ('fixed', 'tied', 'bounds')
+    """
+    Primarily for informational purposes, these are the types of constraints
+    that can be set on a model's parameters.
+    """
+    model_constraints = ('eqcons', 'ineqcons')
+    """
+    Primarily for informational purposes, these are the types of constraints
+    that constrain model evaluation.
+    """
 
-    param_names = []
+    param_names = ()
     """
-    List of names of the parameters that describe models of this type.
+    Names of the parameters that describe models of this type.
 
-    The parameters in this list are in the same order they should be passed in
+    The parameters in this tuple are in the same order they should be passed in
     when initializing a model of a specific type.  Some types of models, such
     as polynomial models, have a different number of parameters depending on
     some other property of the model, such as the degree.
+
+    When defining a custom model class the value of this attribute is
+    automatically set by the `~astropy.modeling.Parameter` attributes defined
+    in the class body.
     """
 
-    n_inputs = 1
-    n_outputs = 1
+    inputs = ()
+    """The name(s) of the input variable(s) on which a model is evaluated."""
+    outputs = ()
+    """The name(s) of the output(s) of the model."""
+
     standard_broadcasting = True
     fittable = False
     linear = True
 
+    meta = metadata.MetaData()
+    """A dict-like object to store optional information."""
+
+    # By default models either use their own inverse property or have no
+    # inverse at all, but users my also assign a custom inverse to a model,
+    # optionally; in that case it is of course up to the user to determine
+    # whether their inverse is *actually* an inverse to the model they assign
+    # it to.
+    _custom_inverse = None
+
+    # Default n_models attribute, so that __len__ is still defined even when a
+    # model hasn't completed initialization yet
+    _n_models = 1
+
     def __init__(self, *args, **kwargs):
         super(Model, self).__init__()
+        meta = kwargs.pop('meta', None)
+        if meta is not None:
+            self.meta = meta
+
+        self._name = kwargs.pop('name', None)
+
         self._initialize_constraints(kwargs)
         # Remaining keyword args are either parameter values or invalid
         # Parameter values must be passed in as keyword arguments in order to
@@ -282,9 +565,40 @@ class Model(object):
     def __len__(self):
         return self._n_models
 
-    @abc.abstractmethod
-    def __call__(self, *args, **kwargs):
-        """Evaluate the model on some input variables."""
+    def __call__(self, *inputs, **kwargs):
+        """
+        Evaluate this model using the given input(s) and the parameter values
+        that were specified when the model was instantiated.
+        """
+
+        inputs, format_info = self.prepare_inputs(*inputs, **kwargs)
+        parameters = self._param_sets(raw=True)
+
+        outputs = self.evaluate(*chain(inputs, parameters))
+
+        if self.n_outputs == 1:
+            outputs = (outputs,)
+
+        return self.prepare_outputs(format_info, *outputs, **kwargs)
+
+    # *** Arithmetic operators for creating compound models ***
+    __add__ =     _model_oper('+')
+    __sub__ =     _model_oper('-')
+    __mul__ =     _model_oper('*')
+    __truediv__ = _model_oper('/')
+    __pow__ =     _model_oper('**')
+    __or__ =      _model_oper('|')
+    __and__ =     _model_oper('&')
+
+    if not six.PY3:
+        __div__ = _model_oper('/')
+
+    # *** Properties ***
+    @property
+    def name(self):
+        """User-provided name for this model instance."""
+
+        return self._name
 
     @property
     @deprecated('0.4', alternative='len(model)')
@@ -292,45 +606,49 @@ class Model(object):
         return self._n_models
 
     @property
-    def model_set_axis(self):
-        return self._model_set_axis
+    def n_inputs(self):
+        """
+        The number of inputs to this model.
+
+        Equivalent to ``len(model.inputs)``.
+        """
+
+        return len(self.inputs)
 
     @property
-    def param_sets(self):
+    def n_outputs(self):
         """
-        Return parameters as a pset.
+        The number of outputs from this model.
 
-        This is an array where each column represents one parameter set.
+        Equivalent to ``len(model.outputs)``.
         """
+        return len(self.outputs)
 
-        values = [getattr(self, name).value for name in self.param_names]
+    @property
+    def model_set_axis(self):
+        """
+        The index of the model set axis--that is the axis of a parameter array
+        that pertains to which model a parameter value pertains to--as
+        specified when the model was initialized.
 
-        # Ensure parameter values are broadcastable
-        for name, shape in six.iteritems(self._param_broadcast_shapes):
-            idx = self._param_orders[name]
-            values[idx] = values[idx].reshape(shape)
+        See the documentation on `Model Sets
+        <http://docs.astropy.org/en/stable/modeling/models.html#model-sets>`_
+        for more details.
+        """
 
-        shapes = [np.shape(value) for value in values]
+        return self._model_set_axis
 
-        if len(self) == 1:
-            # Add a single param set axis to the parameter's value (thus
-            # converting scalars to shape (1,) array values) for consistency
-            values = [np.array([value]) for value in values]
+    @property
+    def param_sets(self):
+        """
+        Return parameters as a pset.
 
-        if len(set(shapes)) != 1:
-            # If the parameters are not all the same shape, converting to an
-            # array is going to produce an object array
-            # However the way Numpy creates object arrays is tricky in that it
-            # will recurse into array objects in the list and break them up
-            # into separate objects.  Doing things this way ensures a 1-D
-            # object array the elements of which are the individual parameter
-            # arrays.  There's not much reason to do this over returning a list
-            # except for consistency
-            psets = np.empty(len(values), dtype=object)
-            psets[:] = values
-            return psets
+        This is a list with one item per parameter set, which is an array of
+        that parameter's values across all parameter sets, with the last axis
+        associated with the parameter set.
+        """
 
-        return np.array(values)
+        return self._param_sets()
 
     @property
     def parameters(self):
@@ -340,7 +658,18 @@ class Model(object):
         Fittable parameters maintain this list and fitters modify it.
         """
 
-        return self._parameters
+        # Currently the sequence of a model's parameters must be contiguous
+        # within the _parameters array (which may be a view of a larger array,
+        # for example when taking a sub-expression of a compound model), so
+        # the assumption here is reliable:
+        if not self.param_names:
+            # Trivial, but not unheard of
+            return self._parameters
+
+        start = self._param_metrics[self.param_names[0]]['slice'].start
+        stop = self._param_metrics[self.param_names[-1]]['slice'].stop
+
+        return self._parameters[start:stop]
 
     @parameters.setter
     def parameters(self, value):
@@ -349,15 +678,20 @@ class Model(object):
         replacing it.
         """
 
+        if not self.param_names:
+            return
+
+        start = self._param_metrics[self.param_names[0]]['slice'].start
+        stop = self._param_metrics[self.param_names[-1]]['slice'].stop
+
         try:
-            value = np.array(value).reshape(self._parameters.shape)
+            value = np.array(value).flatten()
+            self._parameters[start:stop] = value
         except ValueError as e:
             raise InputParameterError(
                 "Input parameter values not compatible with the model "
                 "parameters array: {0}".format(e))
 
-        self._parameters[:] = value
-
     @property
     def fixed(self):
         """
@@ -395,17 +729,76 @@ class Model(object):
 
         return self._constraints['ineqcons']
 
+    # *** Public methods ***
+
+    @property
     def inverse(self):
-        """Returns a callable object which performs the inverse transform."""
+        """
+        Returns a new `Model` instance which performs the inverse
+        transform, if an analytic inverse is defined for this model.
+
+        Even on models that don't have an inverse defined, this property can be
+        set with a manually-defined inverse, such a pre-computed or
+        experimentally determined inverse (often given as a
+        `~astropy.modeling.polynomial.PolynomialModel`, but not by
+        requirement).
+
+        Note to authors of `Model` subclasses:  To define an inverse for a
+        model simply override this property to return the appropriate model
+        representing the inverse.  The machinery that will make the inverse
+        manually-overridable is added automatically by the base class.
+        """
 
         raise NotImplementedError("An analytical inverse transform has not "
                                   "been implemented for this model.")
 
-    def invert(self):
-        """Invert coordinates iteratively if possible."""
+    @abc.abstractmethod
+    def evaluate(self, *args, **kwargs):
+        """Evaluate the model on some input variables."""
+
+    def prepare_inputs(self, *inputs, **kwargs):
+        """
+        This method is used in `~astropy.modeling.Model.__call__` to ensure
+        that all the inputs to the model can be broadcast into compatible
+        shapes (if one or both of them are input as arrays), particularly if
+        there are more than one parameter sets.
+        """
+
+        model_set_axis = kwargs.pop('model_set_axis', None)
+
+        if model_set_axis is None:
+            # By default the model_set_axis for the input is assumed to be the
+            # same as that for the parameters the model was defined with
+            # TODO: Ensure that negative model_set_axis arguments are respected
+            model_set_axis = self.model_set_axis
+
+        n_models = len(self)
 
-        raise NotImplementedError("Subclasses should implement this")
+        params = [getattr(self, name) for name in self.param_names]
+        inputs = [np.asanyarray(_input, dtype=float) for _input in inputs]
 
+        _validate_input_shapes(inputs, self.inputs, n_models,
+                               model_set_axis, self.standard_broadcasting)
+
+        # The input formatting required for single models versus a multiple
+        # model set are different enough that they've been split into separate
+        # subroutines
+        if n_models == 1:
+            return _prepare_inputs_single_model(self, params, inputs,
+                                                **kwargs)
+        else:
+            return _prepare_inputs_model_set(self, params, inputs, n_models,
+                                             model_set_axis, **kwargs)
+
+    def prepare_outputs(self, format_info, *outputs, **kwargs):
+        if len(self) == 1:
+            return _prepare_outputs_single_model(self, outputs, format_info)
+        else:
+            return _prepare_outputs_model_set(self, outputs, format_info)
+
+    @deprecated('1.0',
+                alternative='Use Model operators (TODO: link to compound '
+                            'model docs')
     def add_model(self, model, mode):
         """
         Create a CompositeModel by chaining the current model with the new one
@@ -425,6 +818,9 @@ class Model(object):
             an instance of CompositeModel
         """
 
+        from ._compound_deprecated import (SummedCompositeModel,
+                                           SerialCompositeModel)
+
         if mode in ['parallel', 'p']:
             return SummedCompositeModel([self, model])
         elif mode in ['serial', 's']:
@@ -442,12 +838,70 @@ class Model(object):
 
         return copy.deepcopy(self)
 
+    @sharedmethod
+    def rename(self, name):
+        """
+        Return a copy of this model with a new name.
+        """
+
+        new_model = self.copy()
+        new_model._name = name
+        return new_model
+
+    # *** Internal methods ***
+    @sharedmethod
+    def _from_existing(self, existing, param_names):
+        """
+        Creates a new instance of ``cls`` that shares its underlying parameter
+        values with an existing model instance given by ``existing``.
+
+        This is used primarily by compound models to return a view of an
+        individual component of a compound model.  ``param_names`` should be
+        the names of the parameters in the *existing* model to use as the
+        parameters in this new model.  Its length should equal the number of
+        parameters this model takes, so that it can map parameters on the
+        existing model to parameters on this model one-to-one.
+        """
+
+        # Basically this is an alternative __init__
+        # TODO: Support constraints properly
+        if isinstance(self, type):
+            # self is a class, not an instance
+            needs_initialization = True
+            dummy_args = (0,) * len(param_names)
+            self = self.__new__(self, *dummy_args)
+        else:
+            needs_initialization = False
+            self = self.copy()
+
+        self._initialize_constraints({})
+        self._n_models = existing._n_models
+        self._model_set_axis = existing._model_set_axis
+        self._parameters = existing._parameters
+
+        self._param_metrics = defaultdict(dict)
+        for param_a, param_b in zip(self.param_names, param_names):
+            # Take the param metrics info for the giving parameters in the
+            # existing model, and hand them to the appropriate parameters in
+            # the new model
+            self._param_metrics[param_a] = existing._param_metrics[param_b]
+
+        if needs_initialization:
+            self.__init__(*dummy_args)
+
+        return self
+
     def _initialize_constraints(self, kwargs):
         """
         Pop parameter constraint values off the keyword arguments passed to
         `Model.__init__` and store them in private instance attributes.
         """
 
+        if hasattr(self, '_constraints'):
+            # Skip constraint initialization if it has already been handled via
+            # an alternate initialization
+            return
+
         self._constraints = {}
         # Pop any constraints off the keyword arguments
         for constraint in self.parameter_constraints:
@@ -475,6 +929,11 @@ class Model(object):
         slices of this array.
         """
 
+        if hasattr(self, '_parameters'):
+            # Skip parameter initialization if it has already been handled via
+            # an alternate initialization
+            return
+
         n_models = None
         # Pop off param_dim and handle backwards compatibility
         if 'param_dim' in kwargs:
@@ -556,6 +1015,9 @@ class Model(object):
                     '{0}.__init__() got an unrecognized parameter '
                     '{1!r}'.format(self.__class__.__name__, kwarg))
 
+        self._model_set_axis = model_set_axis
+        self._param_metrics = defaultdict(dict)
+
         # Determine the number of model sets: If the model_set_axis is
         # None then there is just one parameter set; otherwise it is determined
         # by the size of that axis on the first parameter--if the other
@@ -590,21 +1052,20 @@ class Model(object):
                         "same for all input parameter values".format(
                         name, n_models, model_set_axis))
 
-            self._param_broadcast_shapes = self._check_param_broadcast(
-                    params, max_ndim, model_set_axis)
+            self._check_param_broadcast(params, max_ndim)
         else:
             if n_models is None:
                 n_models = 1
 
-            self._param_broadcast_shapes = self._check_param_broadcast(
-                    params, None, None)
+            self._check_param_broadcast(params, None)
 
-        # First we need to determine how much array space is needed by all the
-        # parameters based on the number of parameters, the shape each input
-        # parameter, and the param_dim
         self._n_models = n_models
-        self._model_set_axis = model_set_axis
-        self._param_metrics = {}
+        self._initialize_parameter_values(params)
+
+    def _initialize_parameter_values(self, params):
+        # self._param_metrics should have been initialized in
+        # self._initialize_parameters
+        param_metrics = self._param_metrics
         total_size = 0
 
         for name in self.param_names:
@@ -627,19 +1088,22 @@ class Model(object):
             param_shape = np.shape(value)
 
             param_slice = slice(total_size, total_size + param_size)
-            self._param_metrics[name] = (param_slice, param_shape)
+
+            param_metrics[name]['slice'] = param_slice
+            param_metrics[name]['shape'] = param_shape
             total_size += param_size
 
+        self._param_metrics = param_metrics
         self._parameters = np.empty(total_size, dtype=np.float64)
         # Now set the parameter values (this will also fill
         # self._parameters)
         for name, value in params.items():
             setattr(self, name, value)
 
-    def _check_param_broadcast(self, params, max_ndim, model_set_axis):
+    def _check_param_broadcast(self, params, max_ndim):
         """
         This subroutine checks that all parameter arrays can be broadcast
-        against each other, and determimes the shapes parameters must have in
+        against each other, and determines the shapes parameters must have in
         order to broadcast correctly.
 
         If model_set_axis is None this merely checks that the parameters
@@ -647,9 +1111,9 @@ class Model(object):
         single model sets.
         """
 
-        broadcast_shapes = {}
         all_shapes = []
         param_names = []
+        model_set_axis = self._model_set_axis
 
         for name in self.param_names:
             # Previously this just used iteritems(params), but we loop over all
@@ -685,7 +1149,7 @@ class Model(object):
                     broadcast_shape = (param_shape[:model_set_axis + 1] +
                                        new_axes +
                                        param_shape[model_set_axis + 1:])
-                broadcast_shapes[name] = broadcast_shape
+                self._param_metrics[name]['broadcast_shape'] = broadcast_shape
                 all_shapes.append(broadcast_shape)
             else:
                 all_shapes.append(param_shape)
@@ -705,7 +1169,55 @@ class Model(object):
                 "to the broadcasting rules.".format(param_a, shape_a,
                                                     param_b, shape_b))
 
-        return broadcast_shapes
+    def _param_sets(self, raw=False):
+        """
+        Implementation of the Model.param_sets property.
+
+        This internal implementation has a ``raw`` argument which controls
+        whether or not to return the raw parameter values (i.e. the values that
+        are actually stored in the ._parameters array, as opposed to the values
+        displayed to users.  In most cases these are one in the same but there
+        are currently a few exceptions.
+
+        Note: This is notably an overcomplicated device and may be removed
+        entirely in the near future.
+        """
+
+        param_metrics = self._param_metrics
+        values = []
+        for name in self.param_names:
+            if raw:
+                value = getattr(self, name)._raw_value
+            else:
+                value = getattr(self, name).value
+
+            broadcast_shape = param_metrics[name].get('broadcast_shape')
+            if broadcast_shape is not None:
+                value = value.reshape(broadcast_shape)
+
+            values.append(value)
+
+        shapes = [np.shape(value) for value in values]
+
+        if len(self) == 1:
+            # Add a single param set axis to the parameter's value (thus
+            # converting scalars to shape (1,) array values) for consistency
+            values = [np.array([value]) for value in values]
+
+        if len(set(shapes)) != 1:
+            # If the parameters are not all the same shape, converting to an
+            # array is going to produce an object array
+            # However the way Numpy creates object arrays is tricky in that it
+            # will recurse into array objects in the list and break them up
+            # into separate objects.  Doing things this way ensures a 1-D
+            # object array the elements of which are the individual parameter
+            # arrays.  There's not much reason to do this over returning a list
+            # except for consistency
+            psets = np.empty(len(values), dtype=object)
+            psets[:] = values
+            return psets
+
+        return np.array(values)
 
     def _format_repr(self, args=[], kwargs={}, defaults={}):
         """
@@ -718,29 +1230,25 @@ class Model(object):
 
         # TODO: I think this could be reworked to preset model sets better
 
-        parts = ['<{0}('.format(self.__class__.__name__)]
-
-        parts.append(', '.join(repr(a) for a in args))
+        parts = [repr(a) for a in args]
 
-        if args:
-            parts.append(', ')
+        parts.extend(
+            "{0}={1}".format(name,
+                             array_repr_oneline(getattr(self, name).value))
+            for name in self.param_names)
 
-        parts.append(', '.join(
-            "{0}={1}".format(
-                name, array_repr_oneline(getattr(self, name).value))
-            for name in self.param_names))
+        if self.name is not None:
+            parts.append('name={0!r}'.format(self.name))
 
         for kwarg, value in kwargs.items():
-            if kwarg  in defaults and defaults[kwarg] != value:
+            if kwarg in defaults and defaults[kwarg] != value:
                 continue
-            parts.append(', {0}={1!r}'.format(kwarg, value))
+            parts.append('{0}={1!r}'.format(kwarg, value))
 
         if len(self) > 1:
-            parts.append(", n_models={0}".format(len(self)))
+            parts.append("n_models={0}".format(len(self)))
 
-        parts.append(')>')
-
-        return ''.join(parts)
+        return '<{0}({1})>'.format(self.__class__.__name__, ', '.join(parts))
 
     def _format_str(self, keywords=[]):
         """
@@ -753,13 +1261,15 @@ class Model(object):
 
         default_keywords = [
             ('Model', self.__class__.__name__),
-            ('Inputs', self.n_inputs),
-            ('Outputs', self.n_outputs),
+            ('Name', self.name),
+            ('Inputs', self.inputs),
+            ('Outputs', self.outputs),
             ('Model set size', len(self))
         ]
 
         parts = ['{0}: {1}'.format(keyword, value)
-                 for keyword, value in default_keywords + keywords]
+                 for keyword, value in default_keywords + keywords
+                 if value is not None]
 
         parts.append('Parameters:')
 
@@ -787,8 +1297,10 @@ class FittableModel(Model):
     # derivative with respect to parameters
     fit_deriv = None
     """
-    Function (similar to the model's ``eval``) to compute the derivatives of
-    the model with respect to its parameters, for use by fitting algorithms.
+    Function (similar to the model's `~Model.evaluate`) to compute the
+    derivatives of the model with respect to its parameters, for use by fitting
+    algorithms.  In other words, this computes the Jacobian matrix with respect
+    to the model's parameters.
     """
     # Flag that indicates if the model derivatives with respect to parameters
     # are given in columns or rows
@@ -796,461 +1308,866 @@ class FittableModel(Model):
     fittable = True
 
 
-class LabeledInput(dict):
+class Fittable1DModel(FittableModel):
     """
-    Used by `SerialCompositeModel` and `SummedCompositeModel` to choose input
-    data using labels.
+    Base class for one-dimensional fittable models.
 
-    This is a container assigning labels (names) to all input data arrays to a
-    composite model.
+    This class provides an easier interface to defining new models.
+    Examples can be found in `astropy.modeling.functional_models`.
+    """
 
-    Parameters
-    ----------
-    data : list
-        List of all input data
-    labels : list of strings
-        names matching each coordinate in data
+    inputs = ('x',)
+    outputs = ('y',)
 
-    Examples
-    --------
-    >>> y, x = np.mgrid[:5, :5]
-    >>> l = np.arange(10)
-    >>> labeled_input = LabeledInput([x, y, l], ['x', 'y', 'pixel'])
-    >>> labeled_input.x
-    array([[0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4]])
-    >>> labeled_input['x']
-    array([[0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4],
-           [0, 1, 2, 3, 4]])
-    """
 
-    def __init__(self, data, labels):
-        dict.__init__(self)
-        if len(labels) != len(data):
-            raise TypeError("Number of labels and data doesn't match")
-        self.labels = [l.strip() for l in labels]
-        for coord, label in zip(data, labels):
-            self[label] = coord
-            setattr(self, '_' + label, coord)
-        self._set_properties(self.labels)
+class Fittable2DModel(FittableModel):
+    """
+    Base class for two-dimensional fittable models.
 
-    def _getlabel(self, name):
-        par = getattr(self, '_' + name)
-        return par
+    This class provides an easier interface to defining new models.
+    Examples can be found in `astropy.modeling.functional_models`.
+    """
 
-    def _setlabel(self, name, val):
-        setattr(self, '_' + name, val)
-        self[name] = val
+    inputs = ('x', 'y')
+    outputs = ('z',)
+
+
+def _make_arithmetic_operator(oper):
+    # We don't bother with tuple unpacking here for efficiency's sake, but for
+    # documentation purposes:
+    #
+    #     f_eval, f_n_inputs, f_n_outputs = f
+    #
+    # and similarly for g
+    def op(f, g):
+        return (make_binary_operator_eval(oper, f[0], g[0]), f[1], f[2])
+
+    return op
+
+
+def _composition_operator(f, g):
+    # We don't bother with tuple unpacking here for efficiency's sake, but for
+    # documentation purposes:
+    #
+    #     f_eval, f_n_inputs, f_n_outputs = f
+    #
+    # and similarly for g
+    return (lambda inputs, params: g[0](f[0](inputs, params), params),
+            f[1], g[2])
+
+
+def _join_operator(f, g):
+    # We don't bother with tuple unpacking here for efficiency's sake, but for
+    # documentation purposes:
+    #
+    #     f_eval, f_n_inputs, f_n_outputs = f
+    #
+    # and similarly for g
+    return (lambda inputs, params: (f[0](inputs[:f[1]], params) +
+                                    g[0](inputs[f[1]:], params)),
+            f[1] + g[1], f[2] + g[2])
+
+
+# TODO: Support a couple unary operators--at least negation?
+BINARY_OPERATORS = {
+    '+': _make_arithmetic_operator(operator.add),
+    '-': _make_arithmetic_operator(operator.sub),
+    '*': _make_arithmetic_operator(operator.mul),
+    '/': _make_arithmetic_operator(operator.truediv),
+    '**': _make_arithmetic_operator(operator.pow),
+    '|': _composition_operator,
+    '&': _join_operator
+}
+
+
+_ORDER_OF_OPERATORS = [('|',), ('&',), ('+', '-'), ('*', '/'), ('**',)]
+OPERATOR_PRECEDENCE = {}
+for idx, ops in enumerate(_ORDER_OF_OPERATORS):
+    for op in ops:
+        OPERATOR_PRECEDENCE[op] = idx
+del idx, op, ops
+
+
+class _CompoundModelMeta(_ModelMeta):
+    _tree = None
+    _submodels = None
+    _submodel_names = None
+    _nextid = 0
+
+    _param_names = None
+    # _param_map is a mapping of the compound model's generated param names to
+    # the parameters of submodels they are associated with.  The values in this
+    # mapping are (idx, name) tuples were idx is the index of the submodel this
+    # parameter is associated with, and name is the same parameter's name on
+    # the submodel
+    # In principle this will allow compound models to give entirely new names
+    # to parameters that don't have to be the same as their original names on
+    # the submodels, but right now that isn't taken advantage of
+    _param_map = None
+
+    _slice_offset = 0
+    # When taking slices of a compound model, this keeps track of how offset
+    # the first model in the slice is from the first model in the original
+    # compound model it was taken from
+
+    # This just inverts _param_map, swapping keys with values.  This is also
+    # useful to have.
+    _param_map_inverse = None
+    _fittable = None
+
+    _evaluate = None
+
+    def __getitem__(cls, index):
+        index = cls._normalize_index(index)
+
+        if isinstance(index, int):
+            return cls._get_submodels()[index]
+        else:
+            return cls._get_slice(index.start, index.stop)
+
+    def __getattr__(cls, attr):
+        # Make sure the _tree attribute is set; otherwise we are not looking up
+        # an attribute on a concrete compound model class and should just raise
+        # the AttributeError
+        if cls._tree is not None and attr in cls.param_names:
+            cls._init_param_descriptors()
+            return getattr(cls, attr)
+
+        raise AttributeError(attr)
+
+    def __repr__(cls):
+        if cls._tree is None:
+            # This case is mostly for debugging purposes
+            return cls._format_cls_repr()
+
+        expression = cls._format_expression()
+        components = '\n\n'.join('[{0}]: {1!r}'.format(idx, m)
+                                 for idx, m in enumerate(cls._get_submodels()))
+        keywords = [
+            ('Expression', expression),
+            ('Components', '\n' + indent(components))
+        ]
 
-    def _dellabel(self, name):
-        delattr(self, '_' + name)
-        del self[name]
+        return cls._format_cls_repr(keywords=keywords)
 
-    def add(self, label=None, value=None, **kw):
+    def __dir__(cls, *args):
+        """
+        Returns a list of attributes defined on a compound model, including
+        all of its parameters.
         """
-        Add input data to a LabeledInput object
-
-        Parameters
-        --------------
-        label : str
-            coordinate label
-        value : numerical type
-            coordinate value
-        kw : dictionary
-            if given this is a dictionary of ``{label: value}`` pairs
-        """
-
-        if kw:
-            if label is None or value is None:
-                self.update(kw)
-            else:
-                kw[label] = value
-                self.update(kw)
-        else:
-            kw = dict({label: value})
-            if label is None or value is None:
-                raise TypeError("Expected label and value to be defined")
-            self[label] = value
-
-        for key in kw:
-            self.__setattr__('_' + key, kw[key])
-        self._set_properties(kw.keys())
-
-    def _set_properties(self, attributes):
-        for attr in attributes:
-            setattr(self.__class__, attr, property(lambda self, attr=attr:
-                                                   self._getlabel(attr),
-                    lambda self, value, attr=attr:
-                                                   self._setlabel(attr, value),
-                    lambda self, attr=attr:
-                                                   self._dellabel(attr)
-                                                   )
-                    )
 
-    def copy(self):
-        data = [self[label] for label in self.labels]
-        return LabeledInput(data, self.labels)
+        # The *args is to address a bug (?) on Python 2.6 where the dir()
+        # builtin calls __dir__ with an additional (unused) argument
 
+        try:
+            # Annoyingly, this will only work for Python 3.3+
+            basedir = super(_CompoundModelMeta, cls).__dir__()
+        except AttributeError:
+            basedir = list(set((dir(type(cls)) + list(cls.__dict__))))
 
-class _CompositeModel(Model):
-    def __init__(self, transforms, n_inputs, n_outputs):
-        """Base class for all composite models."""
+        if cls._tree is not None:
+            for name in cls.param_names:
+                basedir.append(name)
 
-        self._transforms = transforms
-        param_names = []
-        for tr in self._transforms:
-            param_names.extend(tr.param_names)
-        super(_CompositeModel, self).__init__()
-        self.param_names = param_names
-        self.n_inputs = n_inputs
-        self.n_outputs = n_outputs
-        self.fittable = False
+            basedir.sort()
 
-    def __repr__(self):
-        return '<{0}([\n{1}\n])>'.format(
-            self.__class__.__name__,
-            indent(',\n'.join(repr(tr) for tr in self._transforms),
-                   width=4))
+        return basedir
 
-    def __str__(self):
-        parts = ['Model: {0}'.format(self.__class__.__name__)]
-        for tr in self._transforms:
-            parts.append(indent(str(tr), width=4))
-        return '\n'.join(parts)
+    @property
+    def submodel_names(cls):
+        if cls._submodel_names is not None:
+            return cls._submodel_names
+
+        by_name = defaultdict(list)
+
+        for idx, submodel in enumerate(cls._get_submodels()):
+            # Keep track of the original sort order of the submodels
+            by_name[submodel.name].append(idx)
+
+        names = []
+        for basename, indices in six.iteritems(by_name):
+            if len(indices) == 1:
+                # There is only one model with this name, so it doesn't need an
+                # index appended to its name
+                names.append((basename, indices[0]))
+            else:
+                for idx in indices:
+                    names.append(('{0}_{1}'.format(basename, idx), idx))
 
-    def add_model(self, transf, inmap, outmap):
-        self[transf] = [inmap, outmap]
+        # Sort according to the models' original sort orders
+        names.sort(key=lambda k: k[1])
 
-    def invert(self):
-        raise NotImplementedError("Subclasses should implement this")
+        names = tuple(k[0] for k in names)
 
-    def __call__(self):
-        # implemented by subclasses
-        raise NotImplementedError("Subclasses should implement this")
+        cls._submodels_names = names
+        return names
 
     @property
-    def param_sets(self):
-        raise NotImplementedError(
-            "Composite models do not currently support multiple "
-            "parameter sets.")
+    def param_names(cls):
+        if cls._param_names is None:
+            cls._init_param_names()
+
+        return cls._param_names
 
     @property
-    def parameters(self):
-        raise NotImplementedError(
-            "Composite models do not currently support the .parameters "
-            "array.")
+    def fittable(cls):
+        if cls._fittable is None:
+            cls._fittable = all(m.fittable for m in cls._get_submodels())
+
+        return cls._fittable
+
+    # TODO: Maybe we could use make_function_with_signature for evaluate, but
+    # it's probably not worth it (and I'm not sure what the limit is on number
+    # of function arguments/local variables but we could break that limit for
+    # complicated compound models...
+    def evaluate(cls, *args):
+        if cls._evaluate is None:
+            func = cls._tree.evaluate(BINARY_OPERATORS,
+                                      getter=cls._model_evaluate_getter)[0]
+            # Making this a staticmethod isn't strictly necessary for Python 3,
+            # but it is necessary on Python 2 since looking up cls._evaluate
+            # will return an unbound method otherwise
+            cls._evaluate = staticmethod(func)
+
+        inputs = args[:cls.n_inputs]
+        params = iter(args[cls.n_inputs:])
+        result = cls._evaluate(inputs, params)
+
+        if cls.n_outputs == 1:
+            return result[0]
+        else:
+            return result
 
+    # TODO: This supports creating a new compound model from two existing
+    # compound models (or normal models) and a single operator.  However, it
+    # ought also to be possible to create a new model from an *entire*
+    # expression, represented as a sequence of operators and their operands (or
+    # an exiting ExpressionTree) and build that into a compound model without
+    # creating an intermediate _CompoundModel class for every single operator
+    # in the expression.  This will prove to be a useful optimization in many
+    # cases
+    @classmethod
+    def _from_operator(mcls, operator, left, right, additional_members={}):
+        """
+        Given a Python operator (represented by a string, such as ``'+'``
+        or ``'*'``, and two model classes or instances, return a new compound
+        model that evaluates the given operator on the outputs of the left and
+        right input models.
+
+        If either of the input models are a model *class* (i.e. a subclass of
+        `~astropy.modeling.Model`) then the returned model is a new subclass of
+        `~astropy.modeling.Model` that may be instantiated with any parameter
+        values.  If both input models are *instances* of a model, a new class
+        is still created, but this method returns an *instance* of that class,
+        taking the parameter values from the parameters of the input model
+        instances.
+
+        If given, the ``additional_members`` `dict` may provide additional
+        class members that should be added to the generated
+        `~astropy.modeling.Model` subclass.  Some members that are generated by
+        this method should not be provided by ``additional_members``.  These
+        include ``_tree``, ``inputs``, ``outputs``, ``linear``,
+        ``standard_broadcasting``, and ``__module__`.  This is currently for
+        internal use only.
+        """
 
-class SerialCompositeModel(_CompositeModel):
-    """
-    Composite model that evaluates models in series.
+        # Note, currently this only supports binary operators, but could be
+        # easily extended to support unary operators (namely '-') if/when
+        # needed
+        children = []
+        for child in (left, right):
+            if isinstance(child, (_CompoundModelMeta, _CompoundModel)):
+                children.append(child._tree)
+            else:
+                children.append(ExpressionTree(child))
 
-    Parameters
-    ----------
-    transforms : list
-        a list of transforms in the order to be executed
-    inmap : list of lists or None
-        labels in an input instance of LabeledInput
-        if None, the number of input coordinates is exactly what
-        the transforms expect
-    outmap : list or None
-        labels in an input instance of LabeledInput
-        if None, the number of output coordinates is exactly what
-        the transforms expect
-    n_inputs : int
-        dimension of input space (e.g. 2 for a spatial model)
-    n_outputs : int
-        dimension of output
-
-    Notes
-    -----
-    Output values of one model are used as input values of another.
-    Obviously the order of the models matters.
+        tree = ExpressionTree(operator, left=children[0], right=children[1])
 
-    Examples
-    --------
-    Apply a 2D rotation followed by a shift in x and y::
+        name = str('CompoundModel{0}'.format(_CompoundModelMeta._nextid))
+        _CompoundModelMeta._nextid += 1
 
-        >>> import numpy as np
-        >>> from astropy.modeling import models, LabeledInput, SerialCompositeModel
-        >>> y, x = np.mgrid[:5, :5]
-        >>> rotation = models.Rotation2D(angle=23.5)
-        >>> offset_x = models.Shift(-4.23)
-        >>> offset_y = models.Shift(2)
-        >>> labeled_input = LabeledInput([x, y], ["x", "y"])
-        >>> transform = SerialCompositeModel([rotation, offset_x, offset_y],
-        ...                                  inmap=[['x', 'y'], ['x'], ['y']],
-        ...                                  outmap=[['x', 'y'], ['x'], ['y']])
-        >>> result = transform(labeled_input)
-    """
+        mod = find_current_module(3)
+        if mod:
+            modname = mod.__name__
+        else:
+            modname = '__main__'
 
-    def __init__(self, transforms, inmap=None, outmap=None, n_inputs=None,
-                 n_outputs=None):
-        if n_inputs is None:
-            n_inputs = max([tr.n_inputs for tr in transforms])
-            # the output dimension is equal to the output dim of the last
-            # transform
-            n_outputs = transforms[-1].n_outputs
+        # TODO: These aren't the full rules for handling inputs and outputs, but
+        # this will handle most basic cases correctly
+        if operator == '|':
+            inputs = left.inputs
+            outputs = right.outputs
+
+            if left.n_outputs != right.n_inputs:
+                raise ModelDefinitionError(
+                    "Unsupported operands for |: {0} (n_inputs={1}, "
+                    "n_outputs={2}) and {3} (n_inputs={4}, n_outputs={5}); "
+                    "n_outputs for the left-hand model must match n_inputs "
+                    "for the right-hand model.".format(
+                        left.name, left.n_inputs, left.n_outputs, right.name,
+                        right.n_inputs, right.n_outputs))
+        elif operator == '&':
+            inputs = combine_labels(left.inputs, right.inputs)
+            outputs = combine_labels(left.outputs, right.outputs)
         else:
-            if n_outputs is None:
-                raise TypeError("Expected n_inputs and n_outputs")
+            # Without loss of generality
+            inputs = left.inputs
+            outputs = left.outputs
 
-        super(SerialCompositeModel, self).__init__(transforms, n_inputs,
-                                                   n_outputs)
+            if (left.n_inputs != right.n_inputs or
+                    left.n_outputs != right.n_outputs):
+                raise ModelDefinitionError(
+                    "Unsupported operands for {0}: {1} (n_inputs={2}, "
+                    "n_outputs={3}) and {4} (n_inputs={5}, n_outputs={6}); "
+                    "models must have the same n_inputs and the same "
+                    "n_outputs for this operator".format(
+                        operator, left.name, left.n_inputs, left.n_outputs,
+                        right.name, right.n_inputs, right.n_outputs))
+
+        if operator in ('|', '+', '-'):
+            linear = left.linear and right.linear
+        else:
+            # Which is not to say it is *definitely* not linear but it would be
+            # trickier to determine
+            linear = False
+
+        standard_broadcasting = \
+                left.standard_broadcasting and right.standard_broadcasting
+
+        # Note: If any other members are added here, make sure to mention them
+        # in the docstring of this method.
+        members = additional_members
+        members.update({
+            '_tree': tree,
+            # TODO: These are temporary until we implement the full rules
+            # for handling inputs/outputs
+            'inputs': inputs,
+            'outputs': outputs,
+            'linear': linear,
+            'standard_broadcasting': standard_broadcasting,
+            '__module__': str(modname)})
+
+        new_cls = mcls(name, (_CompoundModel,), members)
+
+        if isinstance(left, Model) and isinstance(right, Model):
+            # Both models used in the operator were already instantiated models,
+            # not model *classes*.  As such it's not particularly useful to return
+            # the class itself, but to instead produce a new instance:
+            return new_cls()
+
+        # Otherwise return the new uninstantiated class itself
+        return new_cls
+
+    @classmethod
+    def _handle_backwards_compat(mcls, name, members):
+        # Override _handle_backwards_compat from _ModelMeta to be a no-op; it
+        # is not needed since compound models did not exist before version 1.0
+        # anyways.
+
+        # TODO: Remove this at the same time as removing
+        # _ModelMeta._handle_backwards_compat
+        return
 
-        if transforms and inmap and outmap:
-            if not (len(transforms) == len(inmap) == len(outmap)):
-                raise ValueError("Expected sequences of transform, "
-                                 "inmap and outmap to have the same length")
+    # TODO: Perhaps, just perhaps, the post-order (or ???-order) ordering of
+    # leaf nodes is something the ExpressionTree class itself could just know
+    def _get_submodels(cls):
+        # Would make this a lazyproperty but those don't currently work with
+        # type objects
+        if cls._submodels is not None:
+            return cls._submodels
 
-        if inmap is None:
-            inmap = [None] * len(transforms)
+        submodels = [c.value for c in cls._tree.traverse_postorder()
+                     if c.isleaf]
+        cls._submodels = submodels
+        return submodels
 
-        if outmap is None:
-            outmap = [None] * len(transforms)
+    def _init_param_descriptors(cls):
+        """
+        This routine sets up the names for all the parameters on a compound
+        model, including figuring out unique names for those parameters and
+        also mapping them back to their associated parameters of the underlying
+        submodels.
+
+        Setting this all up is costly, and only necessary for compound models
+        that a user will directly interact with.  For example when building an
+        expression like::
+
+            >>> M = (Model1 + Model2) * Model3  # doctest: +SKIP
+
+        the user will generally never interact directly with the temporary
+        result of the subexpression ``(Model1 + Model2)``.  So there's no need
+        to setup all the parameters for that temporary throwaway.  Only once
+        the full expression is built and the user initializes or introspects
+        ``M`` is it necessary to determine its full parameterization.
+        """
 
-        self._inmap = inmap
-        self._outmap = outmap
+        # Accessing cls.param_names will implicitly call _init_param_names if
+        # needed and thus also set up the _param_map; I'm not crazy about that
+        # design but it stands for now
+        for param_name in cls.param_names:
+            submodel_idx, submodel_param = cls._param_map[param_name]
+            submodel = cls[submodel_idx]
+
+            orig_param = getattr(submodel, submodel_param, None)
+            if not isinstance(orig_param, Parameter):
+                # This is just a pathological case that is only really needed
+                # to support the deprecated _CompositeModel--composite models
+                # claim to have some parameters, but don't actually implement
+                # the parameter descriptors, so we just make one up basically,
+                # with a default value of zero.  This value will just be thrown
+                # away, basically.
+                # TODO: Remove this special case once the legacy interfaces
+                # have been removed (basically this entire if statement--keep
+                # only the parts in the else: clause.
+                new_param = Parameter(name=param_name, default=0)
+            else:
+                if isinstance(submodel, Model):
+                    # Take the parameter's default from the model's value for that
+                    # parameter
+                    default = orig_param.value
+                else:
+                    default = orig_param.default
 
-    def inverse(self):
-        try:
-            transforms = []
-            for transform in self._transforms[::-1]:
-                transforms.append(transform.inverse())
-        except NotImplementedError:
-            raise NotImplementedError(
-                "An analytical inverse has not been implemented for "
-                "{0} models.".format(transform.__class__.__name__))
-        if self._inmap is not None:
-            inmap = self._inmap[::-1]
-            outmap = self._outmap[::-1]
-        else:
-            inmap = None
-            outmap = None
-        return SerialCompositeModel(transforms, inmap, outmap)
-
-    def __call__(self, *data):
-        """Transforms data using this model."""
-
-        if len(data) == 1:
-            if not isinstance(data[0], LabeledInput):
-                if self._transforms[0].n_inputs != 1:
-                    raise TypeError("First transform expects {0} inputs, 1 "
-                                    "given".format(self._transforms[0].n_inputs))
-
-                result = data[0]
-                for tr in self._transforms:
-                    result = tr(result)
-                return result
+                # Note: Parameter.copy() returns a new unbound Parameter, never
+                # a bound Parameter even if submodel is a Model instance (as
+                # opposed to a Model subclass)
+                new_param = orig_param.copy(name=param_name, default=default)
+
+            setattr(cls, param_name, new_param)
+
+    def _init_param_names(cls):
+        """
+        This subroutine is solely for setting up the ``param_names`` attribute
+        itself.
+
+        See ``_init_param_descriptors`` for the full parameter setup.
+        """
+
+        # Currently this skips over Model *instances* in the expression tree;
+        # basically these are treated as constants and do not add
+        # fittable/tunable parameters to the compound model.
+        # TODO: I'm not 100% happy with this design, and maybe we need some
+        # interface for distinguishing fittable/settable parameters with
+        # *constant* parameters (which would be distinct from parameters with
+        # fixed constraints since they're permanently locked in place). But I'm
+        # not sure if this is really the best way to treat the issue.
+
+        names = []
+        param_map = {}
+
+        # Start counting the suffix indices to put on parameter names from the
+        # slice_offset.  Usually this will just be zero, but for compound
+        # models that were sliced from another compound model this may be > 0
+        param_suffix = cls._slice_offset
+
+        for idx, model in enumerate(cls._get_submodels()):
+            if not model.param_names:
+                # Skip models that don't have parameters in the numbering
+                # TODO: Reevaluate this if it turns out to be confusing, though
+                # parameter-less models are not very common in practice (there
+                # are a few projections that don't take parameters)
+                continue
+
+            for param_name in model.param_names:
+                # This is sort of heuristic, but we want to check that
+                # model.param_name *actually* returns a Parameter descriptor,
+                # and that the model isn't some inconsistent type that happens
+                # to have a param_names attribute but does not actually
+                # implement settable parameters.
+                # In the future we can probably remove this check, but this is
+                # here specifically to support the legacy compat
+                # _CompositeModel which can be considered a pathological case
+                # in the context of the new framework
+                #if not isinstance(getattr(model, param_name, None),
+                #                  Parameter):
+                #    break
+                name = '{0}_{1}'.format(param_name, param_suffix + idx)
+                names.append(name)
+                param_map[name] = (idx, param_name)
+
+        cls._param_names = tuple(names)
+        cls._param_map = param_map
+        cls._param_map_inverse = dict((v, k) for k, v in param_map.items())
+
+    def _format_expression(cls):
+        # TODO: At some point might be useful to make a public version of this,
+        # albeit with more formatting options
+        return cls._tree.format_expression(OPERATOR_PRECEDENCE)
+
+    def _normalize_index(cls, index):
+        """
+        Converts an index given to __getitem__ to either an integer, or
+        a slice with integer start and stop values.
+
+        If the length of the slice is exactly 1 this converts the index to a
+        simple integer lookup.
+
+        Negative integers are converted to positive integers.
+        """
+
+        def get_index_from_name(name):
+            try:
+                return cls.submodel_names.index(name)
+            except ValueError:
+                raise IndexError(
+                    'Compound model {0} does not have a component named '
+                    '{1}'.format(cls.name, name))
+
+        def check_for_negative_index(index):
+            if index < 0:
+                new_index = len(cls.submodel_names) + index
+                if new_index < 0:
+                    # If still < 0 then this is an invalid index
+                    raise IndexError(
+                            "Model index {0} out of range.".format(index))
+                else:
+                    index = new_index
+
+            return index
+
+        if isinstance(index, six.string_types):
+            return get_index_from_name(index)
+        elif isinstance(index, slice):
+            if index.step not in (1, None):
+                # In principle it could be but I can scarcely imagine a case
+                # where it would be useful.  If someone can think of one then
+                # we can enable it.
+                raise ValueError(
+                    "Step not supported for compound model slicing.")
+            start = index.start if index.start is not None else 0
+            stop = (index.stop
+                    if index.stop is not None else len(cls.submodel_names))
+            if isinstance(start, int):
+                start = check_for_negative_index(start)
+            if isinstance(stop, int):
+                stop = check_for_negative_index(stop)
+            if isinstance(start, six.string_types):
+                start = get_index_from_name(start)
+            if isinstance(stop, six.string_types):
+                stop = get_index_from_name(stop) + 1
+            length = stop - start
+
+            if length == 1:
+                return start
+            elif length <= 0:
+                raise ValueError("Empty slice of a compound model.")
+
+            return slice(start, stop)
+        elif isinstance(index, int):
+            if index >= len(cls.submodel_names):
+                raise IndexError(
+                        "Model index {0} out of range.".format(index))
+
+            return check_for_negative_index(index)
+
+        raise TypeError(
+            'Submodels can be indexed either by their integer order or '
+            'their name (got {0!r}).'.format(index))
+
+    def _get_slice(cls, start, stop):
+        """
+        Return a new model build from a sub-expression of the expression
+        represented by this model.
+
+        Right now this is highly inefficient, as it creates a new temporary
+        model for each operator that appears in the sub-expression.  It would
+        be better if this just built a new expression tree, and the new model
+        instantiated directly from that tree.
+
+        Once tree -> model instantiation is possible this should be fixed to
+        use that instead.
+        """
+
+        members = {'_slice_offset': cls._slice_offset + start}
+        operators = dict((oper, _model_oper(oper, additional_members=members))
+                         for oper in BINARY_OPERATORS)
+
+        return cls._tree.evaluate(operators, start=start, stop=stop)
+
+    @staticmethod
+    def _model_evaluate_getter(idx, model):
+        n_params = len(model.param_names)
+        n_inputs = model.n_inputs
+        n_outputs = model.n_outputs
+
+        # There is currently an unfortunate inconsistency in some models, which
+        # requires them to be instantiated for their evaluate to work.  I think
+        # that needs to be reconsidered and fixed somehow, but in the meantime
+        # we need to check for that case
+        if (not isinstance(model, Model) and
+                isinstancemethod(model, model.evaluate)):
+            if n_outputs == 1:
+                # Where previously model was a class, now make an instance
+                def f(inputs, params):
+                    param_values = tuple(islice(params, n_params))
+                    return (model(*param_values).evaluate(
+                        *chain(inputs, param_values)),)
             else:
-                labeled_input = data[0].copy()
-                # we want to return the entire labeled object because some
-                # parts of it may be used in another transform of which this
-                # one is a component
-                if self._inmap is None:
-                    raise TypeError("Parameter 'inmap' must be provided when "
-                                    "input is a labeled object.")
-                if self._outmap is None:
-                    raise TypeError("Parameter 'outmap' must be provided when "
-                                    "input is a labeled object")
-
-                for transform, incoo, outcoo in izip(self._transforms,
-                                                     self._inmap,
-                                                     self._outmap):
-                    inlist = [labeled_input[label] for label in incoo]
-                    result = transform(*inlist)
-                    if len(outcoo) == 1:
-                        result = [result]
-                    for label, res in zip(outcoo, result):
-
-                        if label not in labeled_input.labels:
-                            labeled_input[label] = res
-                        setattr(labeled_input, label, res)
-                return labeled_input
+                def f(inputs, params):
+                    param_values = tuple(islice(params, n_params))
+                    return model(*param_values).evaluate(
+                        *chain(inputs, param_values))
         else:
-            if self.n_inputs != len(data):
-                raise TypeError("This transform expects {0} inputs".
-                                format(self._n_inputs))
+            evaluate = model.evaluate
+            if n_outputs == 1:
+                f = lambda inputs, params: \
+                    (evaluate(*chain(inputs, islice(params, n_params))),)
+            else:
+                f = lambda inputs, params: \
+                    evaluate(*chain(inputs, islice(params, n_params)))
 
-            result = self._transforms[0](*data)
-            for transform in self._transforms[1:]:
-                result = transform(*result)
-        return result
+        return (f, n_inputs, n_outputs)
 
 
-class SummedCompositeModel(_CompositeModel):
-    """
-    Composite model that evaluates models in parallel.
+ at six.add_metaclass(_CompoundModelMeta)
+class _CompoundModel(Model):
+    fit_deriv = None
+    col_fit_deriv = False
 
-    Parameters
-    --------------
-    transforms : list
-        transforms to be executed in parallel
-    inmap : list or None
-        labels in an input instance of LabeledInput
-        if None, the number of input coordinates is exactly what the
-        transforms expect
-    outmap : list or None
-
-    Notes
-    -----
-    Evaluate each model separately and add the results to the input_data.
-    """
+    _submodels = None
 
-    def __init__(self, transforms, inmap=None, outmap=None):
-        self._transforms = transforms
-        n_inputs = self._transforms[0].n_inputs
-        n_outputs = n_inputs
-        for transform in self._transforms:
-            if not (transform.n_inputs == transform.n_outputs == n_inputs):
-                raise ValueError("A SummedCompositeModel expects n_inputs = "
-                                 "n_outputs for all transforms")
-
-        super(SummedCompositeModel, self).__init__(transforms, n_inputs,
-                                                   n_outputs)
-
-        self._inmap = inmap
-        self._outmap = outmap
-
-    def __call__(self, *data):
-        """Transforms data using this model."""
-
-        if len(data) == 1:
-            if not isinstance(data[0], LabeledInput):
-                x = data[0]
-                deltas = sum(tr(x) for tr in self._transforms)
-                return deltas
-            else:
-                if self._inmap is None:
-                    raise TypeError("Parameter 'inmap' must be provided when "
-                                    "input is a labeled object.")
-                if self._outmap is None:
-                    raise TypeError("Parameter 'outmap' must be provided when "
-                                    "input is a labeled object")
-                labeled_input = data[0].copy()
-                # create a list of inputs to be passed to the transforms
-                inlist = [getattr(labeled_input, label)
-                          for label in self._inmap]
-                sum_of_deltas = [np.zeros_like(x) for x in inlist]
-                for transform in self._transforms:
-                    delta = [transform(*inlist)]
-                    for i in range(len(sum_of_deltas)):
-                        sum_of_deltas[i] += delta[i]
-
-                for outcoo, delta in izip(self._outmap, sum_of_deltas):
-                    setattr(labeled_input, outcoo, delta)
-                # always return the entire labeled object, not just the result
-                # since this may be part of another composite transform
-                return labeled_input
+    def __getattr__(self, attr):
+        return getattr(self.__class__, attr)
+
+    def __getitem__(self, index):
+        index = self.__class__._normalize_index(index)
+        model = self.__class__[index]
+
+        if isinstance(index, slice):
+            param_names = model.param_names
         else:
-            result = self._transforms[0](*data)
-            if self.n_inputs != self.n_outputs:
-                raise ValueError("Expected equal number of inputs and outputs")
-            for tr in self._transforms[1:]:
-                result += tr(*data)
-            return result
+            param_map = self.__class__._param_map_inverse
+            param_names = tuple(param_map[index, name]
+                                for name in model.param_names)
 
+        return model._from_existing(self, param_names)
 
-class Fittable1DModel(FittableModel):
-    """
-    Base class for one-dimensional fittable models.
+    @property
+    def submodel_names(self):
+        return self.__class__.submodel_names
 
-    This class provides an easier interface to defining new models.
-    Examples can be found in `astropy.modeling.functional_models`.
+    @property
+    def param_names(self):
+        return self.__class__.param_names
+
+    @property
+    def fittable(self):
+        return self.__class__.fittable
+
+    @sharedmethod
+    def evaluate(self, *args):
+        return self.__class__.evaluate(*args)
+
+    # TODO: The way this works is highly inefficient--the inverse is created by
+    # making a new model for each operator in the compound model, which could
+    # potentially mean creating a large number of temporary throwaway model
+    # classes.  This can definitely be optimized in the future by implementing
+    # a way to construct a single model class from an existing tree
+    @property
+    def inverse(self):
+        def _not_implemented(oper):
+            def _raise(x, y):
+                raise NotImplementedError(
+                    "The inverse is not currently defined for compound "
+                    "models created using the {0} operator.".format(oper))
+            return _raise
+
+        operators = dict((oper, _not_implemented(oper))
+                         for oper in ('+', '-', '*', '/', '**'))
+        operators['&'] = operator.and_
+        # Reverse the order of compositions
+        operators['|'] = lambda x, y: operator.or_(y, x)
+
+        leaf_idx = -1
+
+        def getter(idx, model):
+            try:
+                # By indexing on self[] this will return an instance of the
+                # model, with all the appropriate parameters set, which is
+                # currently required to return an inverse
+                return self[idx].inverse
+            except NotImplementedError:
+                raise NotImplementedError(
+                    "All models in a composite model must have an inverse "
+                    "defined in order for the composite model to have an "
+                    "inverse.  {0!r} does not have an inverse.".format(model))
+
+
+        return self._tree.evaluate(operators, getter=getter)
+
+    @sharedmethod
+    def _get_submodels(self):
+        return self.__class__._get_submodels()
+
+
+def custom_model(*args, **kwargs):
     """
+    Create a model from a user defined function. The inputs and parameters of
+    the model will be inferred from the arguments of the function.
 
-    @abc.abstractmethod
-    def eval(self):
-        """
-        A method, `classmethod`, or `staticmethod` that implements evaluation
-        of the function represented by this model.
+    This can be used either as a function or as a decorator.  See below for
+    examples of both usages.
 
-        It must take arguments of the function's independent variables,
-        followed by the function's parameters given in the same order they are
-        listed by `Model.param_names`.
-        """
+    .. note::
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
+        All model parameters have to be defined as keyword arguments with
+        default values in the model function.  Use `None` as a default argument
+        value if you do not want to have a default value for that parameter.
 
-        Parameters
-        ----------
-        x : array-like or numeric value
-            Input coordinate values.
+    Parameters
+    ----------
+    func : function
+        Function which defines the model.  It should take N positional
+        arguments where ``N`` is dimensions of the model (the number of
+        independent variable in the model), and any number of keyword arguments
+        (the parameters).  It must return the value of the model (typically as
+        an array, but can also be a scalar for scalar inputs).  This
+        corresponds to the `~astropy.modeling.Model.evaluate` method.
+    fit_deriv : function, optional
+        Function which defines the Jacobian derivative of the model. I.e., the
+        derivative with respect to the *parameters* of the model.  It should
+        have the same argument signature as ``func``, but should return a
+        sequence where each element of the sequence is the derivative
+        with respect to the corresponding argument. This corresponds to the
+        :meth:`~astropy.modeling.FittableModel.fit_deriv` method.
 
-        model_set_axis : `int` or `False`, optional
-            For `Model` instances representing a multiple-model set, this picks
-            out which axis of the input array is used to map inputs to specific
-            models in the set.  If `False`, this indicates that the input array
-            has no such axis, and instead the same input should be broadcast to
-            all models in the set.
-        """
+    Examples
+    --------
+    Define a sinusoidal model function as a custom 1D model::
 
-        return self.eval(x, *self.param_sets)
+        >>> from astropy.modeling.models import custom_model
+        >>> import numpy as np
+        >>> def sine_model(x, amplitude=1., frequency=1.):
+        ...     return amplitude * np.sin(2 * np.pi * frequency * x)
+        >>> def sine_deriv(x, amplitude=1., frequency=1.):
+        ...     return 2 * np.pi * amplitude * np.cos(2 * np.pi * frequency * x)
+        >>> SineModel = custom_model(sine_model, fit_deriv=sine_deriv)
+
+    Create an instance of the custom model and evaluate it::
+
+        >>> model = SineModel()
+        >>> model(0.25)
+        1.0
+
+    This model instance can now be used like a usual astropy model.
+
+    The next example demonstrates a 2D Moffat function model, and also
+    demonstrates the support for docstrings (this example could also include
+    a derivative, but it has been omitted for simplicity)::
+
+        >>> @custom_model
+        ... def Moffat2D(x, y, amplitude=1.0, x_0=0.0, y_0=0.0, gamma=1.0,
+        ...            alpha=1.0):
+        ...     \"\"\"Two dimensional Moffat function.\"\"\"
+        ...     rr_gg = ((x - x_0) ** 2 + (y - y_0) ** 2) / gamma ** 2
+        ...     return amplitude * (1 + rr_gg) ** (-alpha)
+        ...
+        >>> print(Moffat2D.__doc__)
+        Two dimensional Moffat function.
+        >>> model = Moffat2D()
+        >>> model(1, 1)  # doctest: +FLOAT_CMP
+        0.3333333333333333
+    """
 
+    fit_deriv = kwargs.get('fit_deriv', None)
 
-class Fittable2DModel(FittableModel):
+    if len(args) == 1 and six.callable(args[0]):
+        return _custom_model_wrapper(args[0], fit_deriv=fit_deriv)
+    elif not args:
+        return functools.partial(_custom_model_wrapper, fit_deriv=fit_deriv)
+    else:
+        raise TypeError(
+            "{0} takes at most one positional argument (the callable/"
+            "function to be turned into a model.  When used as a decorator "
+            "it should be passed keyword arguments only (if "
+            "any).".format(__name__))
+
+
+def _custom_model_wrapper(func, fit_deriv=None):
     """
-    Base class for one-dimensional fittable models.
+    Internal implementation `custom_model`.
 
-    This class provides an easier interface to defining new models.
-    Examples can be found in `astropy.modeling.functional_models`.
+    When `custom_model` is called as a function its arguments are passed to
+    this function, and the result of this function is returned.
+
+    When `custom_model` is used as a decorator a partial evaluation of this
+    function is returned by `custom_model`.
     """
 
-    n_inputs = 2
-    n_outputs = 1
+    if not six.callable(func):
+        raise ModelDefinitionError(
+            "func is not callable; it must be a function or other callable "
+            "object")
 
-    @abc.abstractmethod
-    def eval(self):
-        """
-        A method, `classmethod`, or `staticmethod` that implements evaluation
-        of the function represented by this model.
+    if fit_deriv is not None and not six.callable(fit_deriv):
+        raise ModelDefinitionError(
+            "fit_deriv not callable; it must be a function or other "
+            "callable object")
 
-        It must take arguments of the function's independent variables,
-        followed by the function's parameters given in the same order they are
-        listed by `Model.param_names`.
-        """
+    model_name = func.__name__
+    argspec = inspect.getargspec(func)
+    param_values = argspec.defaults or ()
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        """
-        Transforms data using this model.
+    nparams = len(param_values)
+    param_names = argspec.args[-nparams:]
 
-        Parameters
-        ----------
-        x : array-like or numeric value
-            First input coordinate values.
+    if (fit_deriv is not None and
+            len(six.get_function_defaults(fit_deriv)) != nparams):
+        raise ModelDefinitionError("derivative function should accept "
+                                   "same number of parameters as func.")
 
-        y : array-like or numeric value
-            Second input coordinate values.
+    if nparams:
+        input_names = argspec.args[:-nparams]
+    else:
+        input_names = argspec.args
 
-        model_set_axis : `int` or `False`, optional
-            For `Model` instances representing a multiple-model set, this picks
-            out which axis of the input array is used to map inputs to specific
-            models in the set.  If `False`, this indicates that the input array
-            has no such axis, and instead the same input should be broadcast to
-            all models in the set.
-        """
+    # TODO: Maybe have a clever scheme for default output name?
+    if input_names:
+        output_names = (input_names[0],)
+    else:
+        output_names = ('x',)
+
+    params = dict((name, Parameter(name, default=default))
+                  for name, default in zip(param_names, param_values))
+
+    mod = find_current_module(2)
+    if mod:
+        modname = mod.__name__
+    else:
+        modname = '__main__'
 
-        return self.eval(x, y, *self.param_sets)
+    members = {
+        '__module__': str(modname),
+        '__doc__': func.__doc__,
+        'inputs': tuple(input_names),
+        'outputs': output_names,
+        'evaluate': staticmethod(func),
+    }
 
+    if fit_deriv is not None:
+        members['fit_deriv'] = staticmethod(fit_deriv)
 
-def _format_single_model_input(func, model, params, inputs, input_names,
-                               **kwargs):
+    members.update(params)
+
+    return type(model_name, (FittableModel,), members)
+
+
+def _prepare_inputs_single_model(model, params, inputs, **kwargs):
     broadcasts = []
 
     for idx, _input in enumerate(inputs):
-        _input = np.asanyarray(_input, dtype=np.float)
         input_shape = _input.shape
-        max_broadcast = ()
+
+        # Ensure that array scalars are always upgrade to 1-D arrays for the
+        # sake of consistency with how parameters work.  They will be cast back
+        # to scalars at the end
+        if not input_shape:
+            inputs[idx] = _input.reshape((1,))
+
+        if not params:
+            max_broadcast = input_shape
+        else:
+            max_broadcast = ()
 
         for param in params:
             try:
@@ -1262,7 +2179,7 @@ def _format_single_model_input(func, model, params, inputs, input_names,
                 raise ValueError(
                     "Model input argument {0!r} of shape {1!r} cannot be "
                     "broadcast with parameter {2!r} of shape "
-                    "{3!r}.".format(input_names[idx], input_shape,
+                    "{3!r}.".format(model.inputs[idx], input_shape,
                                     param.name, param.shape))
 
             if len(broadcast) > len(max_broadcast):
@@ -1272,8 +2189,6 @@ def _format_single_model_input(func, model, params, inputs, input_names,
 
         broadcasts.append(max_broadcast)
 
-    outputs = func(model, *inputs, **kwargs)
-
     if model.n_outputs > model.n_inputs:
         if len(set(broadcasts)) > 1:
             raise ValueError(
@@ -1288,14 +2203,22 @@ def _format_single_model_input(func, model, params, inputs, input_names,
             extra_outputs = model.n_outputs - model.n_inputs
             broadcasts.extend([broadcasts[0]] * extra_outputs)
 
-    if model.n_outputs == 1:
-        outputs = [outputs]
-    else:
-        outputs = list(outputs)
+    return inputs, (broadcasts,)
+
+
+def _prepare_outputs_single_model(model, outputs, format_info):
+    broadcasts = format_info[0]
+
+    outputs = list(outputs)
 
     for idx, output in enumerate(outputs):
-        if broadcasts[idx]:
-            outputs[idx] = output.reshape(broadcasts[idx])
+        broadcast_shape = broadcasts[idx]
+        if broadcast_shape is not None:
+            if not broadcast_shape:
+                # Shape is (), i.e. a scalar should be returned
+                outputs[idx] = np.asscalar(output)
+            else:
+                outputs[idx] = output.reshape(broadcast_shape)
 
     if model.n_outputs == 1:
         return outputs[0]
@@ -1303,14 +2226,12 @@ def _format_single_model_input(func, model, params, inputs, input_names,
         return tuple(outputs)
 
 
-def _format_model_set_input(func, model, params, inputs, input_names,
-                            n_models, model_set_axis, **kwargs):
+def _prepare_inputs_model_set(model, params, inputs, n_models, model_set_axis,
+                              **kwargs):
     reshaped = []
     pivots = []
 
     for idx, _input in enumerate(inputs):
-        _input = np.asanyarray(_input, dtype=np.float)
-
         max_param_shape = ()
 
         if n_models > 1 and model_set_axis is not False:
@@ -1327,7 +2248,7 @@ def _format_model_set_input(func, model, params, inputs, input_names,
                 raise ValueError(
                     "Model input argument {0!r} of shape {1!r} cannot be "
                     "broadcast with parameter {2!r} of shape "
-                    "{3!r}.".format(input_names[idx], input_shape,
+                    "{3!r}.".format(model.inputs[idx], input_shape,
                                     param.name, param.shape))
 
             if len(param.shape) > len(max_param_shape):
@@ -1364,12 +2285,13 @@ def _format_model_set_input(func, model, params, inputs, input_names,
         pivots.append(pivot)
         reshaped.append(new_input)
 
-    outputs = func(model, *reshaped, **kwargs)
+    return reshaped, (pivots,)
 
-    if model.n_outputs == 1:
-        outputs = [outputs]
-    else:
-        outputs = list(outputs)
+
+def _prepare_outputs_model_set(model, outputs, format_info):
+    pivots = format_info[0]
+
+    outputs = list(outputs)
 
     for idx, output in enumerate(outputs):
         pivot = pivots[idx]
diff --git a/astropy/modeling/fitting.py b/astropy/modeling/fitting.py
index a72b8d6..7be75a4 100644
--- a/astropy/modeling/fitting.py
+++ b/astropy/modeling/fitting.py
@@ -2,7 +2,7 @@
 
 """
 This module implements classes (called Fitters) which combine optimization
-algorithms (typically from `scipy.optimize`) with statistic functions to perfom
+algorithms (typically from `scipy.optimize`) with statistic functions to perform
 fitting. Fitters are implemented as callable classes. In addition to the data
 to fit, the ``__call__`` method takes an instance of
 `~astropy.modeling.core.FittableModel` as input, and returns a copy of the
@@ -35,7 +35,6 @@ import numpy as np
 
 from .utils import poly_map_domain
 from ..utils.exceptions import AstropyUserWarning
-from .core import _CompositeModel
 from ..extern import six
 from .optimizers import (SLSQP, Simplex)
 from .statistic import (leastsquare)
@@ -69,7 +68,23 @@ class UnsupportedConstraintError(ModelsError, ValueError):
     """
 
 
- at six.add_metaclass(abc.ABCMeta)
+class _FitterMeta(abc.ABCMeta):
+    """
+    Currently just provides a registry for all Fitter classes.
+    """
+
+    registry = set()
+
+    def __new__(mcls, name, bases, members):
+        cls = super(_FitterMeta, mcls).__new__(mcls, name, bases, members)
+
+        if not inspect.isabstract(cls) and not name.startswith('_'):
+            mcls.registry.add(cls)
+
+        return cls
+
+
+ at six.add_metaclass(_FitterMeta)
 class Fitter(object):
     """
     Base class for all fitters.
@@ -77,7 +92,7 @@ class Fitter(object):
     Parameters
     ----------
     optimizer : callable
-        A callble implementing an optimization algorithm
+        A callable implementing an optimization algorithm
     statistic : callable
         Statistic function
     """
@@ -116,7 +131,7 @@ class Fitter(object):
         -----
         The list of arguments (args) is set in the `__call__` method.
         Fitters may overwrite this method, e.g. when statistic functions
-        require other aguments.
+        require other arguments.
 
         """
         model = args[0]
@@ -137,6 +152,10 @@ class Fitter(object):
         raise NotImplementedError("Subclasses should implement this method.")
 
 
+# TODO: I have ongoing branch elsewhere that's refactoring this module so that
+# all the fitter classes in here are Fitter subclasses.  In the meantime we
+# need to specify that _FitterMeta is its metaclass.
+ at six.add_metaclass(_FitterMeta)
 class LinearLSQFitter(object):
     """
     A class performing a linear least square fitting.
@@ -322,6 +341,7 @@ class LinearLSQFitter(object):
         return model_copy
 
 
+ at six.add_metaclass(_FitterMeta)
 class LevMarLSQFitter(object):
     """
     Levenberg-Marquardt algorithm and least squares statistic.
@@ -350,7 +370,7 @@ class LevMarLSQFitter(object):
 
     supported_constraints = ['fixed', 'tied', 'bounds']
     """
-    The constaint types supported by this fitter type.
+    The constraint types supported by this fitter type.
     """
 
     def __init__(self):
@@ -403,7 +423,7 @@ class LevMarLSQFitter(object):
            input coordinates
         z : array (optional)
            input coordinates
-        weights : array (optional
+        weights : array (optional)
            weights
         maxiter : int
             maximum number of iterations
@@ -467,7 +487,7 @@ class LevMarLSQFitter(object):
         for model constraints.
 
         `scipy.optimize.leastsq` expects the function derivative to have the
-        above signature (parlist, (argtuple)). In order to accomodate model
+        above signature (parlist, (argtuple)). In order to accommodate model
         constraints, instead of using p directly, we set the parameter list in
         this function.
         """
@@ -629,6 +649,7 @@ class SimplexLSQFitter(Fitter):
         return model_copy
 
 
+ at six.add_metaclass(_FitterMeta)
 class JointFitter(object):
     """
     Fit models which share a parameter.
@@ -664,9 +685,10 @@ class JointFitter(object):
         for model in self.models:
             params = [p.flatten() for p in model.parameters]
             joint_params = self.jointparams[model]
+            param_metrics = model._param_metrics
             for param_name in joint_params:
-                slc = model._param_metrics[param_name][0]
-                del params[slc]
+                slice_ = param_metrics[param_name]['slice']
+                del params[slice_]
             fparams.extend(params)
         return fparams
 
@@ -703,6 +725,7 @@ class JointFitter(object):
             del fitparams[:numfp]
             # recreate the model parameters
             mparams = []
+            param_metrics = model._param_metrics
             for param_name in model.param_names:
                 if param_name in joint_params:
                     index = joint_params.index(param_name)
@@ -710,11 +733,11 @@ class JointFitter(object):
                     # parameter is not a number
                     mparams.extend([jointfitparams[index]])
                 else:
-                    slc = model._param_metrics[param_name][0]
-                    plen = slc.stop - slc.start
+                    slice_ = param_metrics[param_name]['slice']
+                    plen = slice_.stop - slice_.start
                     mparams.extend(mfparams[:plen])
                     del mfparams[:plen]
-            modelfit = model.eval(margs[:-1], *mparams)
+            modelfit = model.evaluate(margs[:-1], *mparams)
             fitted.extend(modelfit - margs[-1])
         return np.ravel(fitted)
 
@@ -732,7 +755,7 @@ class JointFitter(object):
 
     def __call__(self, *args):
         """
-        Fit data to these models keeping some of the pramaters common to the
+        Fit data to these models keeping some of the parameters common to the
         two models.
         """
 
@@ -761,6 +784,7 @@ class JointFitter(object):
             del fparams[:numfp]
             # recreate the model parameters
             mparams = []
+            param_metrics = model._param_metrics
             for param_name in model.param_names:
                 if param_name in joint_params:
                     index = joint_params.index(param_name)
@@ -768,8 +792,8 @@ class JointFitter(object):
                     # is not a number
                     mparams.extend([jointfitparams[index]])
                 else:
-                    slc = model._param_metrics[param_name][0]
-                    plen = slc.stop - slc.start
+                    slice_ = param_metrics[param_name]['slice']
+                    plen = slice_.stop - slice_.start
                     mparams.extend(mfparams[:plen])
                     del mfparams[:plen]
             model.parameters = np.array(mparams)
@@ -842,11 +866,13 @@ def _fitter_to_model_params(model, fps):
 
     fit_param_indices = set(fit_param_indices)
     offset = 0
+    param_metrics = model._param_metrics
     for idx, name in enumerate(model.param_names):
         if idx not in fit_param_indices:
             continue
 
-        slice_, shape = model._param_metrics[name]
+        slice_ = param_metrics[name]['slice']
+        shape = param_metrics[name]['shape']
         # This is determining which range of fps (the fitted parameters) maps
         # to parameters of the model
         size = reduce(operator.mul, shape, 1)
@@ -872,7 +898,7 @@ def _fitter_to_model_params(model, fps):
         for idx, name in enumerate(model.param_names):
             if model.tied[name] != False:
                 value = model.tied[name](model)
-                slice_ = model._param_metrics[name][0]
+                slice_ = param_metrics[name]['slice']
                 model.parameters[slice_] = value
 
 
@@ -890,10 +916,11 @@ def _model_to_fit_params(model):
     fitparam_indices = list(range(len(model.param_names)))
     if any(model.fixed.values()) or any(model.tied.values()):
         params = list(model.parameters)
+        param_metrics = model._param_metrics
         for idx, name in list(enumerate(model.param_names))[::-1]:
             if model.fixed[name] or model.tied[name]:
-                sl = model._param_metrics[name][0]
-                del params[sl]
+                slice_ = param_metrics[name]['slice']
+                del params[slice_]
                 del fitparam_indices[idx]
         return (np.array(params), fitparam_indices)
     else:
diff --git a/astropy/modeling/functional_models.py b/astropy/modeling/functional_models.py
index db806d5..02f64df 100644
--- a/astropy/modeling/functional_models.py
+++ b/astropy/modeling/functional_models.py
@@ -5,21 +5,19 @@
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
-import collections
-
-from textwrap import dedent
+import inspect
 
 import numpy as np
 
-from .core import (Fittable1DModel, Fittable2DModel,
-                   Model, format_input, ModelDefinitionError)
+from .core import (Fittable1DModel, Fittable2DModel, Model,
+                   ModelDefinitionError, custom_model)
 from .parameters import Parameter, InputParameterError
-from ..utils import find_current_module
+from ..utils import deprecated
 from ..extern import six
 
 __all__ = sorted([
-    'AiryDisk2D', 'Beta1D', 'Beta2D', 'Box1D',
-    'Box2D', 'Const1D', 'Const2D', 'Disk2D',
+    'AiryDisk2D', 'Moffat1D', 'Moffat2D', 'Box1D',
+    'Box2D', 'Const1D', 'Const2D', 'Ellipse2D', 'Disk2D',
     'Gaussian1D', 'GaussianAbsorption1D', 'Gaussian2D', 'Linear1D',
     'Lorentz1D', 'MexicanHat1D', 'MexicanHat2D', 'Scale', 'Redshift', 'Shift',
     'Sine1D', 'Trapezoid1D', 'TrapezoidDisk2D', 'Ring2D',
@@ -87,19 +85,15 @@ class Gaussian1D(Fittable1DModel):
 
     See Also
     --------
-    Gaussian2D, Box1D, Beta1D, Lorentz1D
+    Gaussian2D, Box1D, Moffat1D, Lorentz1D
     """
 
-    amplitude = Parameter()
-    mean = Parameter()
-    stddev = Parameter()
-
-    def __init__(self, amplitude, mean, stddev, **kwargs):
-        super(Gaussian1D, self).__init__(
-            amplitude=amplitude, mean=mean, stddev=stddev, **kwargs)
+    amplitude = Parameter(default=1)
+    mean = Parameter(default=0)
+    stddev = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, mean, stddev):
+    def evaluate(x, amplitude, mean, stddev):
         """
         Gaussian1D model function.
         """
@@ -142,20 +136,16 @@ class GaussianAbsorption1D(Fittable1DModel):
     Gaussian1D
     """
 
-    amplitude = Parameter()
-    mean = Parameter()
-    stddev = Parameter()
-
-    def __init__(self, amplitude, mean, stddev, **kwargs):
-        super(GaussianAbsorption1D, self).__init__(
-            amplitude=amplitude, mean=mean, stddev=stddev, **kwargs)
+    amplitude = Parameter(default=1)
+    mean = Parameter(default=0)
+    stddev = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, mean, stddev):
+    def evaluate(x, amplitude, mean, stddev):
         """
         GaussianAbsorption1D model function.
         """
-        return 1.0 - Gaussian1D.eval(x, amplitude, mean, stddev)
+        return 1.0 - Gaussian1D.evaluate(x, amplitude, mean, stddev)
 
     @staticmethod
     def fit_deriv(x, amplitude, mean, stddev):
@@ -237,21 +227,23 @@ class Gaussian2D(Fittable2DModel):
 
     See Also
     --------
-    Gaussian1D, Box2D, Beta2D
+    Gaussian1D, Box2D, Moffat2D
 
     References
     ----------
     .. [1] http://en.wikipedia.org/wiki/Gaussian_function
     """
 
-    amplitude = Parameter()
-    x_mean = Parameter()
-    y_mean = Parameter()
-    x_stddev = Parameter()
-    y_stddev = Parameter()
-    theta = Parameter()
+    amplitude = Parameter(default=1)
+    x_mean = Parameter(default=0)
+    y_mean = Parameter(default=0)
+    x_stddev = Parameter(default=1)
+    y_stddev = Parameter(default=1)
+    theta = Parameter(default=0)
+
 
-    def __init__(self, amplitude, x_mean, y_mean, x_stddev=None, y_stddev=None,
+    def __init__(self, amplitude=amplitude.default, x_mean=x_mean.default,
+                 y_mean=y_mean.default, x_stddev=None, y_stddev=None,
                  theta=0.0, cov_matrix=None, **kwargs):
         if y_stddev is None and cov_matrix is None:
             raise InputParameterError(
@@ -268,9 +260,19 @@ class Gaussian2D(Fittable2DModel):
 
         # Compute principle coordinate system transformation
         elif cov_matrix is not None:
+            if (x_stddev is not None or y_stddev is not None):
+                raise InputParameterError(
+                    "Cannot specify both cov_matrix and x/y_stddev")
+            # Compute principle coordinate system transformation
             cov_matrix = np.array(cov_matrix)
+
             if cov_matrix.shape != (2, 2):
+                # TODO: Maybe it should be possible for the covariance matrix
+                # to be some (x, y, ..., z, 2, 2) array to be broadcast with
+                # other paramters of shape (x, y, ..., z)
+                # But that's maybe a special case to work out if/when needed
                 raise ValueError("Covariance matrix must be 2x2")
+
             eig_vals, eig_vecs = np.linalg.eig(cov_matrix)
             x_stddev, y_stddev = np.sqrt(eig_vals)
             y_vec = eig_vecs[:, 0]
@@ -281,7 +283,7 @@ class Gaussian2D(Fittable2DModel):
             x_stddev=x_stddev, y_stddev=y_stddev, theta=theta, **kwargs)
 
     @staticmethod
-    def eval(x, y, amplitude, x_mean, y_mean, x_stddev, y_stddev, theta):
+    def evaluate(x, y, amplitude, x_mean, y_mean, x_stddev, y_stddev, theta):
         """Two dimensional Gaussian function"""
 
         cost2 = np.cos(theta) ** 2
@@ -351,37 +353,24 @@ class Shift(Model):
 
     Parameters
     ----------
-    offsets : float or a list of floats
-        offsets to be applied to a coordinate
-        if a list - each value in the list is an offset to be applied to a
-        column in the input coordinate array
+    offset : float
+        Offset to add to a coordinate.
     """
 
-    offsets = Parameter()
+    inputs = ('x',)
+    outputs = ('x',)
 
-    def __init__(self, offsets, **kwargs):
-        super(Shift, self).__init__(offsets, **kwargs)
+    offset = Parameter(default=0)
 
-    # TODO: Might need to do some work to ensure that cases like this work
-    # consistently.  Should iterating over self.offsets mean iterating over its
-    # parameter sets?  Maybe something like this should just work seamlessly
+    @property
     def inverse(self):
         inv = self.copy()
-        inv.offsets *= -1
+        inv.offset *= -1
         return inv
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
-
-        Parameters
-        ----------
-        x : array like or a number
-            input
-        """
-
-        return self.offsets + x
+    @staticmethod
+    def evaluate(x, offset):
+        return x + offset
 
 
 class Scale(Model):
@@ -390,33 +379,25 @@ class Scale(Model):
 
     Parameters
     ----------
-    factors : float or a list of floats
-        scale for a coordinate
+    factor : float
+        Factor by which to scale a coordinate.
     """
 
-    factors = Parameter()
-    linear = True
+    inputs = ('x',)
+    outputs = ('x',)
 
-    def __init__(self, factors, **kwargs):
-        super(Scale, self).__init__(factors, **kwargs)
+    factor = Parameter(default=1)
+    linear = True
 
+    @property
     def inverse(self):
         inv = self.copy()
-        inv.factors = 1 / self.factors
+        inv.factor = 1 / self.factor
         return inv
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
-
-        Parameters
-        ----------
-        x : array like or a number
-            input
-        """
-
-        return self.factors * x
+    @staticmethod
+    def evaluate(x, factor):
+        return factor * x
 
 
 class Redshift(Fittable1DModel):
@@ -435,14 +416,13 @@ class Redshift(Fittable1DModel):
         .. math:: \\lambda_{obs} = (1 + z) \\lambda_{rest}
 
     """
-    z = Parameter(description='redshift')
 
-    def __init__(self, z, **kwargs):
-        super(Redshift, self).__init__(z=z, **kwargs)
+    z = Parameter(description='redshift', default=0)
 
     @staticmethod
-    def eval(x, z):
+    def evaluate(x, z):
         """One dimensional Redshift model function"""
+
         return (1 + z) * x
 
     @staticmethod
@@ -451,6 +431,7 @@ class Redshift(Fittable1DModel):
         d_z = x
         return [d_z]
 
+    @property
     def inverse(self):
         """Inverse Redshift model"""
 
@@ -482,15 +463,11 @@ class Sine1D(Fittable1DModel):
         .. math:: f(x) = A \\sin(2 \\pi f x)
     """
 
-    amplitude = Parameter()
-    frequency = Parameter()
-
-    def __init__(self, amplitude, frequency, **kwargs):
-        super(Sine1D, self).__init__(
-            amplitude=amplitude, frequency=frequency, **kwargs)
+    amplitude = Parameter(default=1)
+    frequency = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, frequency):
+    def evaluate(x, amplitude, frequency):
         """One dimensional Sine model function"""
 
         return amplitude * np.sin(2 * np.pi * frequency * x)
@@ -528,16 +505,12 @@ class Linear1D(Fittable1DModel):
         .. math:: f(x) = a x + b
     """
 
-    slope = Parameter()
-    intercept = Parameter()
+    slope = Parameter(default=1)
+    intercept = Parameter(default=0)
     linear = True
 
-    def __init__(self, slope, intercept, **kwargs):
-        super(Linear1D, self).__init__(
-            slope=slope, intercept=intercept, **kwargs)
-
     @staticmethod
-    def eval(x, slope, intercept):
+    def evaluate(x, slope, intercept):
         """One dimensional Line model function"""
 
         return slope * x + intercept
@@ -577,16 +550,12 @@ class Lorentz1D(Fittable1DModel):
         f(x) = \\frac{A \\gamma^{2}}{\\gamma^{2} + \\left(x - x_{0}\\right)^{2}}
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    fwhm = Parameter()
-
-    def __init__(self, amplitude, x_0, fwhm, **kwargs):
-        super(Lorentz1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, fwhm=fwhm, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    fwhm = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, fwhm):
+    def evaluate(x, amplitude, x_0, fwhm):
         """One dimensional Lorentzian model function"""
 
         return (amplitude * ((fwhm / 2.) ** 2) / ((x - x_0) ** 2 +
@@ -594,7 +563,7 @@ class Lorentz1D(Fittable1DModel):
 
     @staticmethod
     def fit_deriv(x, amplitude, x_0, fwhm):
-        """One dimensional Lorentzian model derivative wiht respect to parameters"""
+        """One dimensional Lorentzian model derivative with respect to parameters"""
 
         d_amplitude = fwhm ** 2 / (fwhm ** 2 + (x - x_0) ** 2)
         d_x_0 = (amplitude * d_amplitude * (2 * x - 2 * x_0) /
@@ -623,18 +592,15 @@ class Const1D(Fittable1DModel):
         .. math:: f(x) = A
     """
 
-    amplitude = Parameter()
+    amplitude = Parameter(default=1)
     linear = True
 
-    def __init__(self, amplitude, **kwargs):
-        super(Const1D, self).__init__(amplitude=amplitude, **kwargs)
-
     @staticmethod
-    def eval(x, amplitude):
+    def evaluate(x, amplitude):
         """One dimensional Constant model function"""
 
         if amplitude.size == 1:
-            # This is slighly faster than using ones_like and multiplying
+            # This is slightly faster than using ones_like and multiplying
             x = np.empty_like(x)
             x.fill(amplitude.item())
         else:
@@ -672,18 +638,15 @@ class Const2D(Fittable2DModel):
         .. math:: f(x, y) = A
     """
 
-    amplitude = Parameter()
+    amplitude = Parameter(default=1)
     linear = True
 
-    def __init__(self, amplitude, **kwargs):
-        super(Const2D, self).__init__(amplitude=amplitude, **kwargs)
-
     @staticmethod
-    def eval(x, y, amplitude):
+    def evaluate(x, y, amplitude):
         """Two dimensional Constant model function"""
 
         if amplitude.size == 1:
-            # This is slighly faster than using ones_like and multiplying
+            # This is slightly faster than using ones_like and multiplying
             x = np.empty_like(x)
             x.fill(amplitude.item())
         else:
@@ -694,6 +657,97 @@ class Const2D(Fittable2DModel):
         return x
 
 
+class Ellipse2D(Fittable2DModel):
+    """
+    A 2D Ellipse model.
+
+    Parameters
+    ----------
+    amplitude : float
+        Value of the ellipse.
+
+    x_0 : float
+        x position of the center of the disk.
+
+    y_0 : float
+        y position of the center of the disk.
+
+    a : float
+        The length of the semimajor axis.
+
+    b : float
+        The length of the semiminor axis.
+
+    theta : float, optional
+        The rotation angle in radians of the semimajor axis.  The
+        rotation angle increases counterclockwise from the positive x
+        axis.
+
+    See Also
+    --------
+    Disk2D, Box2D
+
+    Notes
+    -----
+    Model formula:
+
+    .. math::
+
+        f(x, y) = \\left \\{
+                    \\begin{array}{ll}
+                      \\mathrm{amplitude} & : \\left[\\frac{(x - x_0) \\cos
+                        \\theta + (y - y_0) \\sin \\theta}{a}\\right]^2 +
+                        \\left[\\frac{-(x - x_0) \\sin \\theta + (y - y_0)
+                        \\cos \\theta}{b}\\right]^2  \\leq 1 \\\\
+                      0 & : \\mathrm{otherwise}
+                    \\end{array}
+                  \\right.
+
+    Examples
+    --------
+    .. plot::
+        :include-source:
+
+        import numpy as np
+        from astropy.modeling.models import Ellipse2D
+        from astropy.coordinates import Angle
+        import matplotlib.pyplot as plt
+        import matplotlib.patches as mpatches
+        x0, y0 = 25, 25
+        a, b = 20, 10
+        theta = Angle(30, 'deg')
+        e = Ellipse2D(amplitude=100., x_0=x0, y_0=y0, a=a, b=b,
+                      theta=theta.radian)
+        y, x = np.mgrid[0:50, 0:50]
+        fig, ax = plt.subplots(1, 1)
+        ax.imshow(e(x, y), origin='lower', cmap='Greys_r')
+        e2 = mpatches.Ellipse((x0, y0), 2*a, 2*b, theta.degree,
+                              edgecolor='red', facecolor='none')
+        ax.add_patch(e2)
+        plt.show()
+    """
+
+    amplitude = Parameter()
+    x_0 = Parameter()
+    y_0 = Parameter()
+    a = Parameter()
+    b = Parameter()
+    theta = Parameter()
+
+    @staticmethod
+    def evaluate(x, y, amplitude, x_0, y_0, a, b, theta):
+        """Two dimensional Ellipse model function."""
+
+        xx = x - x_0
+        yy = y - y_0
+        cost = np.cos(theta)
+        sint = np.sin(theta)
+        numerator1 = (xx * cost) + (yy * sint)
+        numerator2 = -(xx * sint) + (yy * cost)
+        in_ellipse = (((numerator1 / a) ** 2 + (numerator2 / b) ** 2) < 1.)
+        return np.select([in_ellipse], [amplitude])
+
+
 class Disk2D(Fittable2DModel):
     """
     Two dimensional radial symmetric Disk model.
@@ -727,17 +781,13 @@ class Disk2D(Fittable2DModel):
                    \\right.
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    R_0 = Parameter()
-
-    def __init__(self, amplitude, x_0, y_0, R_0, **kwargs):
-        super(Disk2D, self).__init__(
-            amplitude=amplitude, x_0=x_0, y_0=y_0, R_0=R_0, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    R_0 = Parameter(default=1)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, R_0):
+    def evaluate(x, y, amplitude, x_0, y_0, R_0):
         """Two dimensional Disk model function"""
 
         rr = (x - x_0) ** 2 + (y - y_0) ** 2
@@ -784,25 +834,29 @@ class Ring2D(Fittable2DModel):
     Where :math:`r_{out} = r_{in} + r_{width}`.
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    r_in = Parameter()
-    width = Parameter()
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    r_in = Parameter(default=1)
+    width = Parameter(default=1)
 
-    def __init__(self, amplitude, x_0, y_0, r_in, width=None, r_out=None,
-                 **kwargs):
+    def __init__(self, amplitude=amplitude.default, x_0=x_0.default,
+                 y_0=y_0.default, r_in=r_in.default, width=width.default,
+                 r_out=None, **kwargs):
         if r_out is not None:
+            if width is not None:
+                raise InputParameterError(
+                    "Cannot specify both width and outer radius separately.")
             width = r_out - r_in
-        if r_out is None and width is None:
-            raise ModelDefinitionError("Either specify width or r_out.")
+        elif width is None:
+            width = self.width.default
 
         super(Ring2D, self).__init__(
             amplitude=amplitude, x_0=x_0, y_0=y_0, r_in=r_in, width=width,
             **kwargs)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, r_in, width):
+    def evaluate(x, y, amplitude, x_0, y_0, r_in, width):
         """Two dimensional Ring model function."""
 
         rr = (x - x_0) ** 2 + (y - y_0) ** 2
@@ -855,16 +909,12 @@ class Box1D(Fittable1DModel):
                    \\right.
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    width = Parameter()
-
-    def __init__(self, amplitude, x_0, width, **kwargs):
-        super(Box1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, width=width, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    width = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, width):
+    def evaluate(x, amplitude, x_0, width):
         """One dimensional Box model function"""
 
         return np.select([np.logical_and(x >= x_0 - width / 2.,
@@ -875,7 +925,7 @@ class Box1D(Fittable1DModel):
     def fit_deriv(cls, x, amplitude, x_0, width):
         """One dimensional Box model derivative with respect to parameters"""
 
-        d_amplitude = cls.eval(x, 1, x_0, width)
+        d_amplitude = cls.evaluate(x, 1, x_0, width)
         d_x_0 = np.zeros_like(x)
         d_width = np.zeros_like(x)
         return [d_amplitude, d_x_0, d_width]
@@ -900,7 +950,7 @@ class Box2D(Fittable2DModel):
 
     See Also
     --------
-    Box1D, Gaussian2D, Beta2D
+    Box1D, Gaussian2D, Moffat2D
 
     Notes
     -----
@@ -918,20 +968,16 @@ class Box2D(Fittable2DModel):
 
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    x_width = Parameter()
-    y_width = Parameter()
-
-    def __init__(self, amplitude, x_0, y_0, x_width, y_width, **kwargs):
-        super(Box2D, self).__init__(
-            amplitude=amplitude, x_0=x_0, y_0=y_0, x_width=x_width,
-            y_width=y_width, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    x_width = Parameter(default=1)
+    y_width = Parameter(default=1)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, x_width, y_width):
+    def evaluate(x, y, amplitude, x_0, y_0, x_width, y_width):
         """Two dimensional Box model function"""
+
         x_range = np.logical_and(x >= x_0 - x_width / 2.,
                                  x <= x_0 + x_width / 2.)
         y_range = np.logical_and(y >= y_0 - y_width / 2.,
@@ -956,21 +1002,18 @@ class Trapezoid1D(Fittable1DModel):
 
     See Also
     --------
-    Box1D, Gaussian1D, Beta1D
+    Box1D, Gaussian1D, Moffat1D
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    width = Parameter()
-    slope = Parameter()
-
-    def __init__(self, amplitude, x_0, width, slope, **kwargs):
-        super(Trapezoid1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, width=width, slope=slope, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    width = Parameter(default=1)
+    slope = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, width, slope):
+    def evaluate(x, amplitude, x_0, width, slope):
         """One dimensional Trapezoid model function"""
+
         # Compute the four points where the trapezoid changes slope
         # x1 <= x2 <= x3 <= x4
         x2 = x_0 - width / 2.
@@ -1010,19 +1053,14 @@ class TrapezoidDisk2D(Fittable2DModel):
     Disk2D, Box2D
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    R_0 = Parameter()
-    slope = Parameter()
-
-    def __init__(self, amplitude, x_0, y_0, R_0, slope, **kwargs):
-        super(TrapezoidDisk2D, self).__init__(
-            amplitude=amplitude, x_0=x_0, y_0=y_0, R_0=R_0, slope=slope,
-            **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    R_0 = Parameter(default=1)
+    slope = Parameter(default=1)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, R_0, slope):
+    def evaluate(x, y, amplitude, x_0, y_0, R_0, slope):
         """Two dimensional Trapezoid Disk model function"""
 
         r = np.sqrt((x - x_0) ** 2 + (y - y_0) ** 2)
@@ -1061,16 +1099,12 @@ class MexicanHat1D(Fittable1DModel):
 
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    sigma = Parameter()
-
-    def __init__(self, amplitude, x_0, sigma, **kwargs):
-        super(MexicanHat1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, sigma=sigma, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    sigma = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, sigma):
+    def evaluate(x, amplitude, x_0, sigma):
         """One dimensional Mexican Hat model function"""
 
         xx_ww = (x - x_0) ** 2 / (2 * sigma ** 2)
@@ -1108,17 +1142,13 @@ class MexicanHat2D(Fittable2DModel):
         - \\left(y - y_{0}\\right)^{2}}{2 \\sigma^{2}}}
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    sigma = Parameter()
-
-    def __init__(self, amplitude, x_0, y_0, sigma, **kwargs):
-        super(MexicanHat2D, self).__init__(
-            amplitude=amplitude, x_0=x_0, y_0=y_0, sigma=sigma, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    sigma = Parameter(default=1)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, sigma):
+    def evaluate(x, y, amplitude, x_0, y_0, sigma):
         """Two dimensional Mexican Hat model function"""
 
         rr_ww = ((x - x_0) ** 2 + (y - y_0) ** 2) / (2 * sigma ** 2)
@@ -1168,13 +1198,14 @@ class AiryDisk2D(Fittable2DModel):
     .. [1] http://en.wikipedia.org/wiki/Airy_disk
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    radius = Parameter()
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    radius = Parameter(default=1)
     _j1 = None
 
-    def __init__(self, amplitude, x_0, y_0, radius, **kwargs):
+    def __init__(self, amplitude=amplitude.default, x_0=x_0.default,
+                 y_0=y_0.default, radius=radius.default, **kwargs):
         if self._j1 is None:
             try:
                 from scipy.special import j1, jn_zeros
@@ -1187,6 +1218,9 @@ class AiryDisk2D(Fittable2DModel):
         super(AiryDisk2D, self).__init__(
             amplitude=amplitude, x_0=x_0, y_0=y_0, radius=radius, **kwargs)
 
+    # TODO: Why does this particular model have its own special __deepcopy__
+    # and __copy__?  If it has anything to do with the use of the j_1 function
+    # that should be reworked.
     def __deepcopy__(self, memo):
         new_model = self.__class__(self.amplitude.value, self.x_0.value,
                                    self.y_0.value, self.radius.value)
@@ -1198,7 +1232,7 @@ class AiryDisk2D(Fittable2DModel):
         return new_model
 
     @classmethod
-    def eval(cls, x, y, amplitude, x_0, y_0, radius):
+    def evaluate(cls, x, y, amplitude, x_0, y_0, radius):
         """Two dimensional Airy model function"""
 
         r = np.sqrt((x - x_0) ** 2 + (y - y_0) ** 2) / (radius / cls._rz)
@@ -1211,20 +1245,20 @@ class AiryDisk2D(Fittable2DModel):
         return z
 
 
-class Beta1D(Fittable1DModel):
+class Moffat1D(Fittable1DModel):
     """
-    One dimensional Beta model.
+    One dimensional Moffat model.
 
     Parameters
     ----------
     amplitude : float
         Amplitude of the model.
     x_0 : float
-        x position of the maximum of the Beta model.
+        x position of the maximum of the Moffat model.
     gamma : float
-        Core width of the Beta model.
+        Core width of the Moffat model.
     alpha : float
-        Power index of the beta model.
+        Power index of the Moffat model.
 
     See Also
     --------
@@ -1239,24 +1273,20 @@ class Beta1D(Fittable1DModel):
         f(x) = A \\left(1 + \\frac{\\left(x - x_{0}\\right)^{2}}{\\gamma^{2}}\\right)^{- \\alpha}
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    gamma = Parameter()
-    alpha = Parameter()
-
-    def __init__(self, amplitude, x_0, gamma, alpha, **kwargs):
-        super(Beta1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, gamma=gamma, alpha=alpha, **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    gamma = Parameter(default=1)
+    alpha = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, gamma, alpha):
-        """One dimensional Beta model function"""
+    def evaluate(x, amplitude, x_0, gamma, alpha):
+        """One dimensional Moffat model function"""
 
         return amplitude * (1 + ((x - x_0) / gamma) ** 2) ** (-alpha)
 
     @staticmethod
     def fit_deriv(x, amplitude, x_0, gamma, alpha):
-        """One dimensional Beta model derivative with respect to parameters"""
+        """One dimensional Moffat model derivative with respect to parameters"""
 
         d_A = (1 + (x - x_0) ** 2 / gamma ** 2) ** (-alpha)
         d_x_0 = (-amplitude * alpha * d_A * (-2 * x + 2 * x_0) /
@@ -1267,22 +1297,22 @@ class Beta1D(Fittable1DModel):
         return [d_A, d_x_0, d_gamma, d_alpha]
 
 
-class Beta2D(Fittable2DModel):
+class Moffat2D(Fittable2DModel):
     """
-    Two dimensional Beta model.
+    Two dimensional Moffat model.
 
     Parameters
     ----------
     amplitude : float
         Amplitude of the model.
     x_0 : float
-        x position of the maximum of the Beta model.
+        x position of the maximum of the Moffat model.
     y_0 : float
-        y position of the maximum of the Beta model.
+        y position of the maximum of the Moffat model.
     gamma : float
-        Core width of the Beta model.
+        Core width of the Moffat model.
     alpha : float
-        Power index of the beta model.
+        Power index of the Moffat model.
 
     See Also
     --------
@@ -1298,27 +1328,22 @@ class Beta2D(Fittable2DModel):
         \\left(y - y_{0}\\right)^{2}}{\\gamma^{2}}\\right)^{- \\alpha}
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    y_0 = Parameter()
-    gamma = Parameter()
-    alpha = Parameter()
-
-    def __init__(self, amplitude, x_0, y_0, gamma, alpha, **kwargs):
-        super(Beta2D, self).__init__(
-            amplitude=amplitude, x_0=x_0, y_0=y_0, gamma=gamma, alpha=alpha,
-            **kwargs)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=0)
+    y_0 = Parameter(default=0)
+    gamma = Parameter(default=1)
+    alpha = Parameter(default=1)
 
     @staticmethod
-    def eval(x, y, amplitude, x_0, y_0, gamma, alpha):
-        """Two dimensional Beta model function"""
+    def evaluate(x, y, amplitude, x_0, y_0, gamma, alpha):
+        """Two dimensional Moffat model function"""
 
         rr_gg = ((x - x_0) ** 2 + (y - y_0) ** 2) / gamma ** 2
         return amplitude * (1 + rr_gg) ** (-alpha)
 
     @staticmethod
     def fit_deriv(x, y, amplitude, x_0, y_0, gamma, alpha):
-        """Two dimensional Beta model derivative with respect to parameters"""
+        """Two dimensional Moffat model derivative with respect to parameters"""
 
         rr_gg = ((x - x_0) ** 2 + (y - y_0) ** 2) / gamma ** 2
         d_A = (1 + rr_gg) ** (-alpha)
@@ -1331,118 +1356,17 @@ class Beta2D(Fittable2DModel):
         return [d_A, d_x_0, d_y_0, d_gamma, d_alpha]
 
 
+ at deprecated('1.0', alternative='astropy.modeling.models.custom_model',
+            pending=True)
 def custom_model_1d(func, func_fit_deriv=None):
-    """
-    Create a one dimensional model from a user defined function. The
-    parameters of the model will be inferred from the arguments of
-    the function.
-
-    .. note::
-
-        All model parameters have to be defined as keyword arguments
-        with default values in the model function.
-
-    If you want to use parameter sets in the model, the parameters should be
-    treated as lists or arrays.
-
-    Parameters
-    ----------
-    func : function
-        Function which defines the model.  It should take one positional
-        argument (the independent variable in the model), and any number of
-        keyword arguments (the parameters).  It must return the value of the
-        model (typically as an array, but can also be a scalar for scalar
-        inputs).  This corresponds to the
-        `~astropy.modeling.Fittable1DModel.eval` method.
-    func_fit_deriv : function, optional
-        Function which defines the Jacobian derivative of the model. I.e., the
-        derivive with respect to the *parameters* of the model.  It should
-        have the same argument signature as ``func``, but should return a
-        sequence where each element of the sequence is the derivative
-        with respect to the correseponding argument. This corresponds to the
-        :meth:`~astropy.modeling.FittableModel.fit_deriv` method.
-
-
-    Examples
-    --------
-    Define a sinusoidal model function as a custom 1D model:
-
-        >>> from astropy.modeling.models import custom_model_1d
-        >>> import numpy as np
-        >>> def sine_model(x, amplitude=1., frequency=1.):
-        ...     return amplitude * np.sin(2 * np.pi * frequency * x)
-        >>> def sine_deriv(x, amplitude=1., frequency=1.):
-        ...     return 2 * np.pi * amplitude * np.cos(2 * np.pi * frequency * x)
-        >>> SineModel = custom_model_1d(sine_model, func_fit_deriv=sine_deriv)
-
-    Create an instance of the custom model and evaluate it:
-
-        >>> model = SineModel()
-        >>> model(0.25)
-        1.0
-
-    This model instance can now be used like a usual astropy model.
-    """
-
-    if not six.callable(func):
-        raise ModelDefinitionError("Not callable. Must be function")
-
-    if func_fit_deriv is not None and not six.callable(func_fit_deriv):
-        raise ModelDefinitionError(
-                "func_fit_deriv not callable. Must be function")
-
-    model_name = func.__name__
-    param_values = six.get_function_defaults(func)
-
-    # Check if all parameters are keyword arguments
+    argspec = inspect.getargspec(func)
+    param_values = argspec.defaults
     nparams = len(param_values)
 
-    if (func_fit_deriv is not None and
-            len(six.get_function_defaults(func_fit_deriv)) != nparams):
-        raise ModelDefinitionError("derivative function should accept "
-                                   "same number of parameters as func.")
-
-    func_code = six.get_function_code(func)
-    if func_code.co_argcount == nparams + 1:
-        param_names = func_code.co_varnames[1:nparams + 1]
+    if len(argspec.args) == nparams + 1:
+        param_names = argspec.args[-nparams:]
     else:
         raise ModelDefinitionError(
             "All parameters must be keyword arguments")
 
-    params = dict((name, Parameter(name, default=default))
-                  for name, default in zip(param_names, param_values))
-
-    arg_signature_1 = ', '.join('{0}=None'.format(name)
-                                for name in param_names)
-    arg_signature_2 = ', '.join('{0}={0}'.format(name)
-                                for name in param_names)
-
-    mod = find_current_module(2)
-    if mod:
-        filename = mod.__file__
-        modname = mod.__name__
-    else:
-        filename = '<string>'
-        modname = '__main__'
-
-    members = {'eval': staticmethod(func)}
-
-    eval_globals = {}
-
-    init_code_string = dedent("""
-        def __init__(self, {0}, **kwargs):
-            super(self.__class__, self).__init__({1}, **kwargs)
-    """).format(arg_signature_1, arg_signature_2)
-
-    eval(compile(init_code_string, filename, 'single'), eval_globals)
-
-    if func_fit_deriv is not None:
-        members['fit_deriv'] = staticmethod(func_fit_deriv)
-
-    members['__init__'] = eval_globals['__init__']
-    members.update(params)
-
-    cls = type(model_name, (Fittable1DModel,), members)
-    cls.__module__ = modname
-
-    return cls
+    return custom_model(func, fit_deriv=func_fit_deriv)
diff --git a/astropy/modeling/mappings.py b/astropy/modeling/mappings.py
new file mode 100644
index 0000000..3bf50e9
--- /dev/null
+++ b/astropy/modeling/mappings.py
@@ -0,0 +1,175 @@
+"""
+Special models useful for complex compound models where control is needed over
+which outputs from a source model are mapped to which inputs of a target model.
+"""
+
+from .core import Model
+
+
+__all__ = ['Mapping', 'Identity']
+
+
+class Mapping(Model):
+    """
+    Allows inputs to be reordered, duplicated or dropped.
+
+    Parameters
+    ----------
+    mapping : tuple
+        A tuple of integers representing indices of the inputs to this model
+        to return and in what order to return them.  See
+        :ref:`compound-model-mappings` for more details.
+    n_inputs : int
+        Number of inputs; if `None` (default) then ``max(mapping) + 1`` is
+        used (i.e. the highest input index used in the mapping).
+    name : str, optional
+        A human-friendly name associated with this model instance
+        (particularly useful for identifying the individual components of a
+        compound model).
+    meta : dict-like
+        Free-form metadata to associate with this model.
+
+    Raises
+    ------
+    TypeError
+        Raised when number of inputs is less that ``max(mapping)``.
+
+    Examples
+    --------
+
+    >>> from astropy.modeling.models import Polynomial2D, Shift, Mapping
+    >>> poly1 = Polynomial2D(1, c0_0=1, c1_0=2, c0_1=3)
+    >>> poly2 = Polynomial2D(1, c0_0=1, c1_0=2.4, c0_1=2.1)
+    >>> model = (Shift(1) & Shift(2)) | Mapping((0, 1, 0, 1)) | (poly1 & poly2)
+    >>> model(1, 2)  # doctest: +FLOAT_CMP
+    (17.0, 14.2)
+    """
+
+    def __init__(self, mapping, n_inputs=None, name=None, meta=None):
+        if n_inputs is None:
+            self._inputs = tuple('x' + str(idx)
+                                 for idx in range(max(mapping) + 1))
+        else:
+            self._inputs = tuple('x' + str(idx)
+                                 for idx in range(n_inputs))
+        self._outputs = tuple('x' + str(idx) for idx in range(len(mapping)))
+        self._mapping = mapping
+        super(Mapping, self).__init__(name=name, meta=meta)
+
+    @property
+    def inputs(self):
+        """
+        The name(s) of the input variable(s) on which a model is evaluated.
+        """
+
+        return self._inputs
+
+    @property
+    def outputs(self):
+        """The name(s) of the output(s) of the model."""
+
+        return self._outputs
+
+    @property
+    def mapping(self):
+        """Integers representing indices of the inputs."""
+
+        return self._mapping
+
+    def __repr__(self):
+        if self.name is None:
+            return '<Mapping({0})>'.format(self.mapping)
+        else:
+            return '<Mapping({0}, name={1})>'.format(self.mapping, self.name)
+
+    def evaluate(self, *args):
+        if len(args) != self.n_inputs:
+            name = self.name if self.name is not None else "Mapping"
+
+            raise TypeError('{0} expects {1} inputs; got {2}'.format(
+                name, self.n_inputs, len(args)))
+
+        result = tuple(args[idx] for idx in self._mapping)
+
+        if self.n_outputs == 1:
+            return result[0]
+
+        return result
+
+    @property
+    def inverse(self):
+        """
+        A `Mapping` representing the inverse of the current mapping.
+
+        Raises
+        ------
+        `NotImplementedError`
+            An inverse does no exist on mappings that drop some of its inputs
+            (there is then no way to reconstruct the inputs that were dropped).
+        """
+
+        try:
+            mapping = tuple(self.mapping.index(idx)
+                            for idx in range(self.n_inputs))
+        except ValueError:
+            raise NotImplementedError(
+                "Mappings such as {0} that drop one or more of their inputs "
+                "are not invertible at this time.".format(self.mapping))
+
+        inv = self.__class__(mapping)
+        inv._inputs = self._outputs
+        inv._outputs = self._inputs
+        return inv
+
+
+class Identity(Mapping):
+    """
+    Returns inputs unchanged.
+
+    This class is useful in compound models when some of the inputs must be
+    passed unchanged to the next model.
+
+    Parameters
+    ----------
+    n_inputs : int
+        Specifies the number of inputs this identity model accepts.
+    name : str, optional
+        A human-friendly name associated with this model instance
+        (particularly useful for identifying the individual components of a
+        compound model).
+    meta : dict-like
+        Free-form metadata to associate with this model.
+
+    Examples
+    --------
+
+    Transform ``(x, y)`` by a shift in x, followed by scaling the two inputs::
+
+        >>> from astropy.modeling.models import (Polynomial1D, Shift, Scale,
+        ...                                      Identity)
+        >>> model = (Shift(1) & Identity(1)) | Scale(1.2) & Scale(2)
+        >>> model(1,1)  # doctest: +FLOAT_CMP
+        (2.4, 2.0)
+        >>> model.inverse(2.4, 2) # doctest: +FLOAT_CMP
+        (1.0, 1.0)
+    """
+
+    def __init__(self, n_inputs, name=None, meta=None):
+        mapping = tuple(range(n_inputs))
+        super(Identity, self).__init__(mapping, name=name, meta=meta)
+
+    def __repr__(self):
+        if self.name is None:
+            return '<Identity({0})>'.format(self.n_inputs)
+        else:
+            return '<Identity({0}, name={1})>'.format(self.n_inputs, self.name)
+
+    @property
+    def inverse(self):
+        """
+        The inverse transformation.
+
+        In this case of `Identity`, ``self.inverse is self``.
+        """
+
+        return self
diff --git a/astropy/modeling/models.py b/astropy/modeling/models.py
index a2caa77..6d93e45 100644
--- a/astropy/modeling/models.py
+++ b/astropy/modeling/models.py
@@ -7,6 +7,8 @@ Creates a common namespace for all pre-defined models.
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
+from .core import custom_model
+from .mappings import *
 from .projections import *
 from .rotations import *
 from .polynomial import *
@@ -50,8 +52,9 @@ CONSTRAINTS_DOC = """
 
 
 MODELS_WITH_CONSTRAINTS = [
-    AiryDisk2D, Beta1D, Beta2D, Box1D, Box2D,
-    Const1D, Const2D, Disk2D, Gaussian1D, GaussianAbsorption1D, Gaussian2D,
+    AiryDisk2D, Moffat1D, Moffat2D, Box1D, Box2D,
+    Const1D, Const2D, Ellipse2D, Disk2D,
+    Gaussian1D, GaussianAbsorption1D, Gaussian2D,
     Linear1D, Lorentz1D, MexicanHat1D, MexicanHat2D,
     PowerLaw1D, Sine1D, Trapezoid1D, TrapezoidDisk2D,
     Chebyshev1D, Chebyshev2D, Legendre2D, Legendre1D,
diff --git a/astropy/modeling/optimizers.py b/astropy/modeling/optimizers.py
index 2e2b163..c8ee3ba 100644
--- a/astropy/modeling/optimizers.py
+++ b/astropy/modeling/optimizers.py
@@ -135,8 +135,7 @@ class SLSQP(Optimization):
             other keyword arguments to be passed to the solver
 
         """
-        if 'maxiter' not in kwargs:
-            kwargs['iter'] = self._maxiter
+        kwargs['iter'] = kwargs.pop('maxiter', self._maxiter)
 
         if 'epsilon' not in kwargs:
             kwargs['epsilon'] = self._eps
diff --git a/astropy/modeling/parameters.py b/astropy/modeling/parameters.py
index e962269..59a17d0 100644
--- a/astropy/modeling/parameters.py
+++ b/astropy/modeling/parameters.py
@@ -118,13 +118,16 @@ class Parameter(object):
             raise TypeError('Bound parameters must have a name specified.')
 
         self._name = name
-        self.__doc__ = description.strip()
+        self.__doc__ = self._description = description.strip()
         self._default = default
 
-        self._default_fixed = fixed
-        self._default_tied = tied
-        self._default_min = min
-        self._default_max = max
+        # NOTE: These are *default* constraints--on model instances constraints
+        # are taken from the model if set, otherwise the defaults set here are
+        # used
+        self._fixed = fixed
+        self._tied = tied
+        self._min = min
+        self._max = max
 
         self._order = None
         self._shape = None
@@ -146,7 +149,7 @@ class Parameter(object):
 
         if model is not None:
             with ignored(AttributeError):
-                # This can only work if the paramter's value has been set by
+                # This can only work if the parameter's value has been set by
                 # the model
                 _, self._shape = self._validate_value(model, self.value)
         else:
@@ -154,16 +157,15 @@ class Parameter(object):
             # and ordering ID
             self._order = self._get_nextid()
 
-
     def __get__(self, obj, objtype):
         if obj is None:
             return self
 
         return self.__class__(self._name, default=self._default,
                               getter=self._getter, setter=self._setter,
-                              fixed=self._default_fixed,
-                              tied=self._default_tied, min=self._default_min,
-                              max=self._default_max, model=obj)
+                              fixed=self._fixed,
+                              tied=self._tied, min=self._min,
+                              max=self._max, model=obj)
 
     def __set__(self, obj, value):
         value, shape = self._validate_value(obj, value)
@@ -214,11 +216,13 @@ class Parameter(object):
                     "dimension {2}".format(key, self.name, n_models))
 
     def __repr__(self):
+        args = "'{0}'".format(self._name)
         if self._model is None:
-            return "Parameter('{0}')".format(self._name)
+            if self._default is not None:
+                args += ', default={0}'.format(self._default)
         else:
-            return "Parameter('{0}', value={1})".format(
-                self._name, self.value)
+            args += ', value={0}'.format(self.value)
+        return "Parameter({0})".format(args)
 
     @property
     def name(self):
@@ -299,9 +303,9 @@ class Parameter(object):
 
         if self._model is not None:
             fixed = self._model._constraints['fixed']
-            return fixed.get(self._name, self._default_fixed)
+            return fixed.get(self._name, self._fixed)
         else:
-            return self._default_fixed
+            return self._fixed
 
     @fixed.setter
     def fixed(self, value):
@@ -324,9 +328,9 @@ class Parameter(object):
 
         if self._model is not None:
             tied = self._model._constraints['tied']
-            return tied.get(self._name, self._default_tied)
+            return tied.get(self._name, self._tied)
         else:
-            return self._default_tied
+            return self._tied
 
     @tied.setter
     def tied(self, value):
@@ -346,10 +350,10 @@ class Parameter(object):
 
         if self._model is not None:
             bounds = self._model._constraints['bounds']
-            default_bounds = (self._default_min, self._default_max)
+            default_bounds = (self._min, self._max)
             return bounds.get(self._name, default_bounds)
         else:
-            return (self._default_min, self._default_max)
+            return (self._min, self._max)
 
     @bounds.setter
     def bounds(self, value):
@@ -405,6 +409,46 @@ class Parameter(object):
             raise AttributeError("can't set attribute 'max' on Parameter "
                                  "definition")
 
+    def copy(self, name=None, description=None, default=None, getter=None,
+             setter=None, fixed=False, tied=False, min=None, max=None):
+        """
+        Make a copy of this `Parameter`, overriding any of its core attributes
+        in the process (or an exact copy).
+
+        The arguments to this method are the same as those for the `Parameter`
+        initializer.  This simply returns a new `Parameter` instance with any
+        or all of the attributes overridden, and so returns the equivalent of:
+
+        .. code:: python
+
+            Parameter(self.name, self.description, ...)
+
+        """
+
+        kwargs = locals().copy()
+        del kwargs['self']
+
+        for key, value in six.iteritems(kwargs):
+            if value is None:
+                kwargs[key] = getattr(self, '_' + key)
+
+        return self.__class__(**kwargs)
+
+    @property
+    def _raw_value(self):
+        """
+        Currently for internal use only.
+
+        Like Parameter.value but does not pass the result through
+        Parameter.getter.  By design this should only be used from bound
+        parameters.
+
+        This will probably be removed are retweaked at some point in the
+        process of rethinking how parameter values are stored/updated.
+        """
+
+        return self._get_model_value(self._model)
+
     @classmethod
     def _get_nextid(cls):
         """Returns a monotonically increasing ID used to order Parameter
@@ -435,7 +479,8 @@ class Parameter(object):
 
         # Use the _param_metrics to extract the parameter value from the
         # _parameters array
-        param_slice, param_shape = model._param_metrics[self._name]
+        param_slice = model._param_metrics[self._name]['slice']
+        param_shape = model._param_metrics[self._name]['shape']
         value = model._parameters[param_slice]
         if param_shape:
             value = value.reshape(param_shape)
@@ -454,7 +499,8 @@ class Parameter(object):
         """
 
         # TODO: Maybe handle exception on invalid input shape
-        param_slice, param_shape = model._param_metrics[self._name]
+        param_slice = model._param_metrics[self._name]['slice']
+        param_shape = model._param_metrics[self._name]['shape']
         param_size = np.prod(param_shape)
 
         if np.size(value) != param_size:
@@ -514,6 +560,21 @@ class Parameter(object):
 
         return wrapper
 
+    def __array__(self, dtype=None):
+        # Make np.asarray(self) work a little more straightforwardly
+        if self._model is None:
+            return np.array([], dtype=np.float)
+        else:
+            return np.asarray(self.value, dtype=dtype)
+
+    def __nonzero__(self):
+        if self._model is None:
+            return True
+        else:
+            return bool(self.value)
+
+    __bool__ = __nonzero__
+
     def __add__(self, val):
         return self.value + val
 
diff --git a/astropy/modeling/polynomial.py b/astropy/modeling/polynomial.py
index 4b6879c..9a07a8e 100644
--- a/astropy/modeling/polynomial.py
+++ b/astropy/modeling/polynomial.py
@@ -7,15 +7,12 @@ This module contains predefined polynomial models.
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
-import collections
-
 import numpy as np
 
-from .core import FittableModel, Model, SerialCompositeModel, format_input
+from .core import FittableModel, Model
 from .functional_models import Shift
 from .parameters import Parameter
 from .utils import poly_map_domain, comb
-from ..logger import log
 from ..utils import lazyproperty, indent
 
 
@@ -30,7 +27,7 @@ __all__ = [
 class PolynomialBase(FittableModel):
     """
     Base class for all polynomial-like models with an arbitrary number of
-    parameters in the form of coeffecients.
+    parameters in the form of coefficients.
 
     In this case Parameter instances are returned through the class's
     ``__getattr__`` rather than through class descriptors.
@@ -38,7 +35,7 @@ class PolynomialBase(FittableModel):
 
     # Default _param_names list; this will be filled in by the implementation's
     # __init__
-    _param_names = []
+    _param_names = ()
 
     linear = True
     col_fit_deriv = False
@@ -99,19 +96,18 @@ class PolynomialModel(PolynomialBase):
     default values, names and ordering.
     """
 
-    def __init__(self, degree, n_inputs=1, n_outputs=1, n_models=None,
-                 model_set_axis=None, **params):
+    def __init__(self, degree, n_models=None, model_set_axis=None,
+                 name=None, meta=None, **params):
         self._degree = degree
-        self._order = self.get_num_coeff(n_inputs)
-        self._param_names = self._generate_coeff_names(n_inputs)
-        self._n_inputs = n_inputs
-        self._n_outputs = n_outputs
+        self._order = self.get_num_coeff(self.n_inputs)
+        self._param_names = self._generate_coeff_names(self.n_inputs)
 
         if params:
             self._validate_params(**params)
 
         super(PolynomialModel, self).__init__(
-            n_models=n_models, model_set_axis=model_set_axis, **params)
+            n_models=n_models, model_set_axis=model_set_axis, name=name,
+            meta=meta, **params)
 
     def __repr__(self):
         return self._format_repr([self.degree])
@@ -125,18 +121,6 @@ class PolynomialModel(PolynomialBase):
 
         return self._degree
 
-    @property
-    def n_inputs(self):
-        """The number of input variables to model evaluation."""
-
-        return self._n_inputs
-
-    @property
-    def n_outputs(self):
-        """The number of outputs returned when model is evaluated."""
-
-        return self._n_outputs
-
     def get_num_coeff(self, ndim):
         """
         Return the number of coefficients in one parameter set
@@ -176,7 +160,7 @@ class PolynomialModel(PolynomialBase):
                 for j in range(1, self.degree):
                     if i + j < self.degree + 1:
                         names.append('c{0}_{1}'.format(i, j))
-        return names
+        return tuple(names)
 
 
 class OrthoPolynomialBase(PolynomialBase):
@@ -206,12 +190,12 @@ class OrthoPolynomialBase(PolynomialBase):
         {keyword: value} pairs, representing {parameter_name: value}
     """
 
-    n_inputs = 2
-    n_outputs = 1
+    inputs = ('x', 'y')
+    outputs = ('z',)
 
     def __init__(self, x_degree, y_degree, x_domain=None, x_window=None,
                  y_domain=None, y_window=None, n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         # TODO: Perhaps some of these other parameters should be properties?
         # TODO: An awful lot of the functionality in this method is still
         # shared by PolynomialModel; perhaps some of it can be generalized in
@@ -229,7 +213,8 @@ class OrthoPolynomialBase(PolynomialBase):
             self._validate_params(**params)
 
         super(OrthoPolynomialBase, self).__init__(
-            n_models=n_models, model_set_axis=model_set_axis, **params)
+            n_models=n_models, model_set_axis=model_set_axis,
+            name=name, meta=meta, **params)
 
     def __repr__(self):
         return self._format_repr([self.x_degree, self.y_degree])
@@ -319,7 +304,7 @@ class OrthoPolynomialBase(PolynomialBase):
         for j in range(self.y_degree + 1):
             for i in range(self.x_degree + 1):
                 names.append('c{0}_{1}'.format(i, j))
-        return names
+        return tuple(names)
 
     def _fcache(self, x, y):
         # TODO: Write a docstring explaining the actual purpose of this method
@@ -327,16 +312,15 @@ class OrthoPolynomialBase(PolynomialBase):
 
         raise NotImplementedError("Subclasses should implement this")
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        """
-        Transforms data using this model.
+    def evaluate(self, x, y, *coeffs):
+        invcoeff = self.invlex_coeff()
+        return self.imhorner(x, y, invcoeff)
 
-        Parameters
-        --------------
-        x : scalar, list or array
-        y : scalar, lis or array
-        """
+    def prepare_inputs(self, x, y, **kwargs):
+        inputs, format_info = \
+                super(OrthoPolynomialBase, self).prepare_inputs(x, y, **kwargs)
+
+        x, y = inputs
 
         if x.shape != y.shape:
             raise ValueError("Expected input arrays to have the same shape")
@@ -344,9 +328,8 @@ class OrthoPolynomialBase(PolynomialBase):
             x = poly_map_domain(x, self.x_domain, self.x_window)
         if self.y_domain is not None:
             y = poly_map_domain(y, self.y_domain, self.y_window)
-        invcoeff = self.invlex_coeff()
 
-        return self.imhorner(x, y, invcoeff)
+        return (x, y), format_info
 
 
 class Chebyshev1D(PolynomialModel):
@@ -367,34 +350,16 @@ class Chebyshev1D(PolynomialModel):
         keyword : value pairs, representing parameter_name: value
     """
 
+    inputs = ('x',)
+    outputs = ('y',)
+
     def __init__(self, degree, domain=None, window=[-1, 1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         self.domain = domain
         self.window = window
         super(Chebyshev1D, self).__init__(
-            degree, n_inputs=1, n_outputs=1, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
-
-    def clenshaw(self, x, coeff):
-        """Evaluates the polynomial using Clenshaw's algorithm."""
-
-        if isinstance(x, tuple) or isinstance(x, list):
-            x = np.asarray(x)
-        if len(coeff) == 1:
-            c0 = coeff[0]
-            c1 = 0
-        elif len(coeff) == 2:
-            c0 = coeff[0]
-            c1 = coeff[1]
-        else:
-            x2 = 2 * x
-            c0 = coeff[-2]
-            c1 = coeff[-1]
-            for i in range(3, len(coeff) + 1):
-                tmp = c0
-                c0 = coeff[-i] - c1
-                c1 = tmp + c1 * x2
-        return c0 + c1 * x
+            degree, n_models=n_models, model_set_axis=model_set_axis,
+            name=name, meta=meta, **params)
 
     def fit_deriv(self, x, *params):
         """
@@ -422,20 +387,40 @@ class Chebyshev1D(PolynomialModel):
             v[i] = v[i - 1] * x2 - v[i - 2]
         return np.rollaxis(v, 0, v.ndim)
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
+    def prepare_inputs(self, x, **kwargs):
+        inputs, format_info = \
+                super(PolynomialModel, self).prepare_inputs(x, **kwargs)
 
-        Parameters
-        --------------
-        x : scalar, list or array
-            input
-        """
+        x = inputs[0]
 
         if self.domain is not None:
             x = poly_map_domain(x, self.domain, self.window)
-        return self.clenshaw(x, self.param_sets)
+
+        return (x,), format_info
+
+    @classmethod
+    def evaluate(cls, x, *coeffs):
+        return cls.clenshaw(x, coeffs)
+
+    @staticmethod
+    def clenshaw(x, coeffs):
+        """Evaluates the polynomial using Clenshaw's algorithm."""
+
+        if len(coeffs) == 1:
+            c0 = coeffs[0]
+            c1 = 0
+        elif len(coeffs) == 2:
+            c0 = coeffs[0]
+            c1 = coeffs[1]
+        else:
+            x2 = 2 * x
+            c0 = coeffs[-2]
+            c1 = coeffs[-1]
+            for i in range(3, len(coeffs) + 1):
+                tmp = c0
+                c0 = coeffs[-i] - c1
+                c1 = tmp + c1 * x2
+        return c0 + c1 * x
 
 
 class Legendre1D(PolynomialModel):
@@ -456,33 +441,31 @@ class Legendre1D(PolynomialModel):
         keyword: value pairs, representing parameter_name: value
     """
 
+    inputs = ('x',)
+    outputs = ('y',)
+
     def __init__(self, degree, domain=None, window=[-1, 1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         self.domain = domain
         self.window = window
         super(Legendre1D, self).__init__(
-            degree, n_inputs=1, n_outputs=1, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
-
-    def clenshaw(self, x, coeff):
-        if isinstance(x, tuple) or isinstance(x, list):
-            x = np.asarray(x)
-        if len(coeff) == 1:
-            c0 = coeff[0]
-            c1 = 0
-        elif len(coeff) == 2:
-            c0 = coeff[0]
-            c1 = coeff[1]
-        else:
-            nd = len(coeff)
-            c0 = coeff[-2]
-            c1 = coeff[-1]
-            for i in range(3, len(coeff) + 1):
-                tmp = c0
-                nd = nd - 1
-                c0 = coeff[-i] - (c1 * (nd - 1)) / nd
-                c1 = tmp + (c1 * x * (2 * nd - 1)) / nd
-        return c0 + c1 * x
+            degree, n_models=n_models, model_set_axis=model_set_axis,
+            name=name, meta=meta, **params)
+
+    def prepare_inputs(self, x, **kwargs):
+        inputs, format_info = \
+                super(PolynomialModel, self).prepare_inputs(x, **kwargs)
+
+        x = inputs[0]
+
+        if self.domain is not None:
+            x = poly_map_domain(x, self.domain, self.window)
+
+        return (x,), format_info
+
+    @classmethod
+    def evaluate(cls, x, *coeffs):
+        return cls.clenshaw(x, coeffs)
 
     def fit_deriv(self, x, *params):
         """
@@ -509,20 +492,24 @@ class Legendre1D(PolynomialModel):
             v[i] = (v[i - 1] * x * (2 * i - 1) - v[i - 2] * (i - 1)) / i
         return np.rollaxis(v, 0, v.ndim)
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
-
-        Parameters
-        --------------
-        x : scalar, list or array
-            input
-        """
-
-        if self.domain is not None:
-            x = poly_map_domain(x, self.domain, self.window)
-        return self.clenshaw(x, self.param_sets)
+    @staticmethod
+    def clenshaw(x, coeffs):
+        if len(coeffs) == 1:
+            c0 = coeffs[0]
+            c1 = 0
+        elif len(coeffs) == 2:
+            c0 = coeffs[0]
+            c1 = coeffs[1]
+        else:
+            nd = len(coeffs)
+            c0 = coeffs[-2]
+            c1 = coeffs[-1]
+            for i in range(3, len(coeffs) + 1):
+                tmp = c0
+                nd = nd - 1
+                c0 = coeffs[-i] - (c1 * (nd - 1)) / nd
+                c1 = tmp + (c1 * x * (2 * nd - 1)) / nd
+        return c0 + c1 * x
 
 
 class Polynomial1D(PolynomialModel):
@@ -543,13 +530,31 @@ class Polynomial1D(PolynomialModel):
         keyword: value pairs, representing parameter_name: value
     """
 
+    inputs = ('x',)
+    outputs = ('y',)
+
     def __init__(self, degree, domain=[-1, 1], window=[-1, 1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         self.domain = domain
         self.window = window
         super(Polynomial1D, self).__init__(
-            degree, n_inputs=1, n_outputs=1, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
+            degree, n_models=n_models, model_set_axis=model_set_axis,
+            name=name, meta=meta, **params)
+
+    def prepare_inputs(self, x, **kwargs):
+        inputs, format_info = \
+                super(Polynomial1D, self).prepare_inputs(x, **kwargs)
+
+        x = inputs[0]
+
+        if self.domain is not None:
+            x = poly_map_domain(x, self.domain, self.window)
+
+        return (x,), format_info
+
+    @classmethod
+    def evaluate(cls, x, *coeffs):
+        return cls.horner(x, coeffs)
 
     def fit_deriv(self, x, *params):
         """
@@ -575,25 +580,13 @@ class Polynomial1D(PolynomialModel):
             v[i] = v[i - 1] * x
         return np.rollaxis(v, 0, v.ndim)
 
-    def horner(self, x, coef):
-        c0 = coef[-1] + x * 0
-        for i in range(2, len(coef) + 1):
-            c0 = coef[-i] + c0 * x
+    @staticmethod
+    def horner(x, coeffs):
+        c0 = coeffs[-1] + x * 0
+        for i in range(2, len(coeffs) + 1):
+            c0 = coeffs[-i] + c0 * x
         return c0
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
-
-        Parameters
-        --------------
-        x : scalar, list or array
-            input
-        """
-
-        return self.horner(x, self.param_sets)
-
 
 class Polynomial2D(PolynomialModel):
     """
@@ -625,39 +618,39 @@ class Polynomial2D(PolynomialModel):
         keyword: value pairs, representing parameter_name: value
     """
 
+    inputs = ('x', 'y')
+    outputs = ('z',)
+
     def __init__(self, degree, x_domain=[-1, 1], y_domain=[-1, 1],
                  x_window=[-1, 1], y_window=[-1, 1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         super(Polynomial2D, self).__init__(
-            degree, n_inputs=2, n_outputs=1, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
+            degree, n_models=n_models, model_set_axis=model_set_axis,
+            name=name, meta=meta, **params)
         self.x_domain = x_domain
         self.y_domain = y_domain
         self.x_window = x_window
         self.y_window = y_window
 
-    def mhorner(self, x, y, coeff):
-        """
-        Multivariate Horner's scheme
+    def prepare_inputs(self, x, y, **kwargs):
+        inputs, format_info = \
+                super(Polynomial2D, self).prepare_inputs(x, y, **kwargs)
 
-        Parameters
-        --------------
-        x, y : array
-        coeff : array of coefficients in inverse lexical order
-        """
-        alpha = np.array(self._invlex())
-        r0 = coeff[0]
-        r1 = r0 * 0.0
-        r2 = r0 * 0.0
-        karr = np.diff(alpha, axis=0)
-        for n in range(len(karr)):
-            if karr[n, 1] != 0:
-                r2 = y * (r0 + r1 + r2)
-                r1 = coeff[0] * 0.
-            else:
-                r1 = x * (r0 + r1)
-            r0 = coeff[n + 1]
-        return r0 + r1 + r2
+        x, y = inputs
+
+        if x.shape != y.shape:
+            raise ValueError("Expected input arrays to have the same shape")
+
+        if self.x_domain is not None:
+            x = poly_map_domain(x, self.x_domain, self.x_window)
+        if self.y_domain is not None:
+            y = poly_map_domain(y, self.y_domain, self.y_window)
+
+        return (x, y), format_info
+
+    def evaluate(self, x, y, *coeffs):
+        invcoeff = self.invlex_coeff(coeffs)
+        return self.multivariate_horner(x, y, invcoeff)
 
     def fit_deriv(self, x, y, *params):
         """
@@ -700,34 +693,40 @@ class Polynomial2D(PolynomialModel):
             v = np.hstack([designx, designy])
         return v
 
-    def invlex_coeff(self):
-        coeff = []
+    def invlex_coeff(self, coeffs):
+        invlex_coeffs = []
         lencoeff = range(self.degree + 1)
         for i in lencoeff:
             for j in lencoeff:
                 if i + j <= self.degree:
                     name = 'c{0}_{1}'.format(j, i)
-                    coeff.append(getattr(self, name))
-        return np.array(coeff[::-1])
+                    coeff = coeffs[self.param_names.index(name)]
+                    invlex_coeffs.append(coeff)
+        return np.array(invlex_coeffs[::-1])
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
+    def multivariate_horner(self, x, y, coeffs):
         """
-        Transforms data using this model.
+        Multivariate Horner's scheme
 
         Parameters
         --------------
-        x : scalar, list or array
-            input
-        y : scalar, list or array
-            input
+        x, y : array
+        coeff : array of coefficients in inverse lexical order
         """
 
-        invcoeff = self.invlex_coeff()
-        if x.shape != y.shape:
-            raise ValueError("Expected input arrays to have the same shape")
-
-        return self.mhorner(x, y, invcoeff)
+        alpha = np.array(self._invlex())
+        r0 = coeffs[0]
+        r1 = r0 * 0.0
+        r2 = r0 * 0.0
+        karr = np.diff(alpha, axis=0)
+        for n in range(len(karr)):
+            if karr[n, 1] != 0:
+                r2 = y * (r0 + r1 + r2)
+                r1 = coeffs[0] * 0.
+            else:
+                r1 = x * (r0 + r1)
+            r0 = coeffs[n + 1]
+        return r0 + r1 + r2
 
 
 class Chebyshev2D(OrthoPolynomialBase):
@@ -762,11 +761,11 @@ class Chebyshev2D(OrthoPolynomialBase):
 
     def __init__(self, x_degree, y_degree, x_domain=None, x_window=[-1, 1],
                  y_domain=None, y_window=[-1,1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         super(Chebyshev2D, self).__init__(
             x_degree, y_degree, x_domain=x_domain, y_domain=y_domain,
             x_window=x_window, y_window=y_window, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
+            model_set_axis=model_set_axis, name=name, meta=meta, **params)
 
     def _fcache(self, x, y):
         """
@@ -876,11 +875,11 @@ class Legendre2D(OrthoPolynomialBase):
 
     def __init__(self, x_degree, y_degree, x_domain=None, x_window=[-1, 1],
                  y_domain=None, y_window=[-1, 1], n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         super(Legendre2D, self).__init__(
             x_degree, y_degree, x_domain=x_domain, y_domain=y_domain,
             x_window=x_window, y_window=y_window, n_models=n_models,
-            model_set_axis=model_set_axis, **params)
+            model_set_axis=model_set_axis, name=name, meta=meta, **params)
 
     def _fcache(self, x, y):
         """
@@ -905,7 +904,7 @@ class Legendre2D(OrthoPolynomialBase):
 
     def fit_deriv(self, x, y, *params):
         """
-        Derivatives with repect to the coefficients.
+        Derivatives with respect to the coefficients.
         This is an array with Legendre polynomials:
 
         Lx0Ly0  Lx1Ly0...LxnLy0...LxnLym
@@ -960,10 +959,11 @@ class _SIP1D(PolynomialBase):
     and SIP should be used instead.
     """
 
-    n_inputs = 2
+    inputs = ('u', 'v')
+    outputs = ('w',)
 
     def __init__(self, order, coeff_prefix, n_models=None,
-                 model_set_axis=None, **params):
+                 model_set_axis=None, name=None, meta=None, **params):
         self.order = order
         self.coeff_prefix = coeff_prefix
         self._param_names = self._generate_coeff_names(coeff_prefix)
@@ -972,7 +972,8 @@ class _SIP1D(PolynomialBase):
             self._validate_params(**params)
 
         super(_SIP1D, self).__init__(n_models=n_models,
-                                     model_set_axis=model_set_axis, **params)
+                                     model_set_axis=model_set_axis,
+                                     name=name, meta=meta, **params)
 
     def __repr__(self):
         return self._format_repr(args=[self.order, self.coeff_prefix])
@@ -982,6 +983,12 @@ class _SIP1D(PolynomialBase):
             [('Order', self.order),
              ('Coeff. Prefix', self.coeff_prefix)])
 
+    def evaluate(self, x, y, *coeffs):
+        # TODO: Rewrite this so that it uses a simpler method of determining
+        # the matrix based on the number of given coefficients.
+        mcoef = self._coeff_matrix(self.coeff_prefix, coeffs)
+        return self._eval_sip(x, y, mcoef)
+
     def get_num_coeff(self, ndim):
         """
         Return the number of coefficients in one param set
@@ -1007,19 +1014,19 @@ class _SIP1D(PolynomialBase):
                     names.append('{0}_{1}_{2}'.format(coeff_prefix, i, j))
         return names
 
-    def _coef_matrix(self, coeff_prefix):
+    def _coeff_matrix(self, coeff_prefix, coeffs):
         mat = np.zeros((self.order + 1, self.order + 1))
         for i in range(2, self.order + 1):
             attr = '{0}_{1}_{2}'.format(coeff_prefix, i, 0)
-            mat[i, 0] = getattr(self, attr).value
+            mat[i, 0] = coeffs[self.param_names.index(attr)]
         for i in range(2, self.order + 1):
             attr = '{0}_{1}_{2}'.format(coeff_prefix, 0, i)
-            mat[0, i] = getattr(self, attr).value
+            mat[0, i] = coeffs[self.param_names.index(attr)]
         for i in range(1, self.order):
             for j in range(1, self.order):
                 if i + j < self.order + 1:
                     attr = '{0}_{1}_{2}'.format(coeff_prefix, i, j)
-                    mat[i, j] = getattr(self, attr).value
+                    mat[i, j] = coeffs[self.param_names.index(attr)]
         return mat
 
     def _eval_sip(self, x, y, coef):
@@ -1036,10 +1043,6 @@ class _SIP1D(PolynomialBase):
                     result = result + coef[i, j] * x ** i * y ** j
         return result
 
-    def __call__(self, x, y):
-        mcoef = self._coef_matrix(self.coeff_prefix)
-        return self._eval_sip(x, y, mcoef)
-
 
 class SIP(Model):
     """
@@ -1076,12 +1079,13 @@ class SIP(Model):
     .. [1] `David Shupe, et al, ADASS, ASP Conference Series, Vol. 347, 2005 <http://adsabs.harvard.edu/abs/2005ASPC..347..491S>`_
     """
 
-    n_inputs = 2
-    n_outputs = 2
+
+    inputs = ('u', 'v')
+    outputs = ('x', 'y')
 
     def __init__(self, crpix, a_order, b_order, a_coeff={}, b_coeff={},
                  ap_order=None, bp_order=None, ap_coeff={}, bp_coeff={},
-                 n_models=None, model_set_axis=None):
+                 n_models=None, model_set_axis=None, name=None, meta=None):
         self._crpix = crpix
         self._a_order = a_order
         self._b_order = b_order
@@ -1098,7 +1102,8 @@ class SIP(Model):
         self.sip1d_b = _SIP1D(b_order, coeff_prefix='B', n_models=n_models,
                               model_set_axis=model_set_axis, **b_coeff)
         super(SIP, self).__init__(n_models=n_models,
-                                  model_set_axis=model_set_axis)
+                                  model_set_axis=model_set_axis, name=name,
+                                  meta=meta)
 
     def __repr__(self):
         return '<{0}({1!r})>'.format(self.__class__.__name__,
@@ -1112,6 +1117,7 @@ class SIP(Model):
 
         return '\n'.join(parts)
 
+    @property
     def inverse(self):
         if (self._ap_order is not None and self._bp_order is not None):
             return InverseSIP(self._ap_order, self._bp_order,
@@ -1119,11 +1125,11 @@ class SIP(Model):
         else:
             raise NotImplementedError("SIP inverse coefficients are not available.")
 
-    def __call__(self, x, y):
-        u = self.shift_a(x)
-        v = self.shift_b(y)
-        f = self.sip1d_a(u, v)
-        g = self.sip1d_b(u, v)
+    def evaluate(self, x, y):
+        u = self.shift_a.evaluate(x, *self.shift_a.param_sets)
+        v = self.shift_b.evaluate(y, *self.shift_b.param_sets)
+        f = self.sip1d_a.evaluate(u, v, *self.sip1d_a.param_sets)
+        g = self.sip1d_b.evaluate(u, v, *self.sip1d_b.param_sets)
         return f, g
 
 
@@ -1146,11 +1152,11 @@ class InverseSIP(Model):
 
     """
 
-    n_inputs = 2
-    n_outputs = 2
+    inputs = ('x', 'y')
+    outputs = ('u', 'v')
 
     def __init__(self, ap_order, bp_order, ap_coeff={}, bp_coeff={},
-                 n_models=None, model_set_axis=None):
+                 n_models=None, model_set_axis=None, name=None, meta=None):
         self._ap_order = ap_order
         self._bp_order = bp_order
         self._ap_coeff = ap_coeff
@@ -1172,12 +1178,8 @@ class InverseSIP(Model):
                                      model_set_axis=model_set_axis,
                                      **bp_coeff_params)
         super(InverseSIP, self).__init__(n_models=n_models,
-                                         model_set_axis=model_set_axis)
-
-    def __call__(self, x, y):
-        x1 = self.sip1d_ap(x, y)
-        y1 = self.sip1d_bp(x, y)
-        return x1, y1
+                                         model_set_axis=model_set_axis,
+                                         name=name, meta=meta)
 
     def __repr__(self):
         return '<{0}({1!r})>'.format(self.__class__.__name__,
@@ -1190,3 +1192,8 @@ class InverseSIP(Model):
             parts.append('')
 
         return '\n'.join(parts)
+
+    def evaluate(self, x, y):
+        x1 = self.sip1d_ap.evaluate(x, y, *self.sip1d_ap.param_sets)
+        y1 = self.sip1d_bp.evaluate(x, y, *self.sip1d_bp.param_sets)
+        return x1, y1
diff --git a/astropy/modeling/powerlaws.py b/astropy/modeling/powerlaws.py
index 77d0763..5fc0ba0 100644
--- a/astropy/modeling/powerlaws.py
+++ b/astropy/modeling/powerlaws.py
@@ -42,16 +42,12 @@ class PowerLaw1D(Fittable1DModel):
 
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    alpha = Parameter()
-
-    def __init__(self, amplitude, x_0, alpha, **constraints):
-        super(PowerLaw1D, self).__init__(amplitude=amplitude, x_0=x_0,
-                                         alpha=alpha, **constraints)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=1)
+    alpha = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, alpha):
+    def evaluate(x, amplitude, x_0, alpha):
         """One dimensional power law model function"""
 
         xx = x / x_0
@@ -104,18 +100,13 @@ class BrokenPowerLaw1D(Fittable1DModel):
                    \\right.
     """
 
-    amplitude = Parameter()
-    x_break = Parameter()
-    alpha_1 = Parameter()
-    alpha_2 = Parameter()
-
-    def __init__(self, amplitude, x_break, alpha_1, alpha_2, **constraints):
-        super(BrokenPowerLaw1D, self).__init__(
-            amplitude=amplitude, x_break=x_break, alpha_1=alpha_1,
-            alpha_2=alpha_2, **constraints)
+    amplitude = Parameter(default=1)
+    x_break = Parameter(default=1)
+    alpha_1 = Parameter(default=1)
+    alpha_2 = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_break, alpha_1, alpha_2):
+    def evaluate(x, amplitude, x_break, alpha_1, alpha_2):
         """One dimensional broken power law model function"""
 
         alpha = np.where(x < x_break, alpha_1, alpha_2)
@@ -165,18 +156,13 @@ class ExponentialCutoffPowerLaw1D(Fittable1DModel):
 
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    alpha = Parameter()
-    x_cutoff = Parameter()
-
-    def __init__(self, amplitude, x_0, alpha, x_cutoff, **constraints):
-        super(ExponentialCutoffPowerLaw1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, alpha=alpha, x_cutoff=x_cutoff,
-            **constraints)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=1)
+    alpha = Parameter(default=1)
+    x_cutoff = Parameter(default=1)
 
     @staticmethod
-    def eval(x, amplitude, x_0, alpha, x_cutoff):
+    def evaluate(x, amplitude, x_0, alpha, x_cutoff):
         """One dimensional exponential cutoff power law model function"""
 
         xx = x / x_0
@@ -224,19 +210,14 @@ class LogParabola1D(Fittable1DModel):
 
     """
 
-    amplitude = Parameter()
-    x_0 = Parameter()
-    alpha = Parameter()
-    beta = Parameter()
-
-    def __init__(self, amplitude, x_0, alpha, beta, **constraints):
-        super(LogParabola1D, self).__init__(
-            amplitude=amplitude, x_0=x_0, alpha=alpha, beta=beta,
-            **constraints)
+    amplitude = Parameter(default=1)
+    x_0 = Parameter(default=1)
+    alpha = Parameter(default=1)
+    beta = Parameter(default=0)
 
     @staticmethod
-    def eval(x, amplitude, x_0, alpha, beta):
-        """One dimenional log parabola model function"""
+    def evaluate(x, amplitude, x_0, alpha, beta):
+        """One dimensional log parabola model function"""
 
         xx = x / x_0
         exponent = -alpha - beta * np.log(xx)
@@ -244,7 +225,7 @@ class LogParabola1D(Fittable1DModel):
 
     @staticmethod
     def fit_deriv(x, amplitude, x_0, alpha, beta):
-        """One dimensional log parabola derivative with repsect to parameters"""
+        """One dimensional log parabola derivative with respect to parameters"""
 
         xx = x / x_0
         log_xx = np.log(xx)
diff --git a/astropy/modeling/projections.py b/astropy/modeling/projections.py
index 8559b86..42111f8 100644
--- a/astropy/modeling/projections.py
+++ b/astropy/modeling/projections.py
@@ -15,9 +15,11 @@ References
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
+import abc
+
 import numpy as np
 
-from .core import (Model, format_input)
+from .core import Model
 from .parameters import Parameter, InputParameterError
 
 from ..utils.compat import ignored
@@ -27,7 +29,8 @@ projcodes = ['TAN', 'AZP', 'SZP', 'STG', 'SIN', 'ARC', 'ZPN', 'ZEA', 'AIR',
              'CYP', 'CEA', 'MER']
 
 
-__all__ = ['Pix2Sky_AZP', 'Sky2Pix_AZP', 'Pix2Sky_CAR', 'Sky2Pix_CAR',
+__all__ = ['Projection', 'Pix2SkyProjection', 'Sky2PixProjection',
+           'Pix2Sky_AZP', 'Sky2Pix_AZP', 'Pix2Sky_CAR', 'Sky2Pix_CAR',
            'Pix2Sky_CEA', 'Sky2Pix_CEA', 'Pix2Sky_CYP', 'Sky2Pix_CYP',
            'Pix2Sky_MER', 'Sky2Pix_MER',
            'Pix2Sky_SIN', 'Sky2Pix_SIN', 'Pix2Sky_STG', 'Sky2Pix_STG',
@@ -36,33 +39,37 @@ __all__ = ['Pix2Sky_AZP', 'Sky2Pix_AZP', 'Pix2Sky_CAR', 'Sky2Pix_CAR',
 
 
 class Projection(Model):
-    """
-    Base class for all sky projections.
-
-    """
-
-    n_inputs = 2
-    n_outputs = 2
+    """Base class for all sky projections."""
 
     # the radius of the projection sphere, by which x,y are scaled
     r0 = 180 / np.pi
 
+    @abc.abstractproperty
+    def inverse(self):
+        """
+        Inverse projection--all projection models must provide an inverse.
+        """
+
 
-class Zenithal(Projection):
-    """
-    Base class for all Zenithal projections.
+class Pix2SkyProjection(Projection):
+    """Base class for all Pix2Sky projections."""
 
-    """
+    inputs = ('x', 'y')
+    outputs = ('phi', 'theta')
 
-    def _compute_rtheta(self):
-        # Subclasses must implement this method
-        raise NotImplementedError("Subclasses should implement this")
 
-    def __call__(self, x, y):
-        raise NotImplementedError("Subclasses should implement this")
+class Sky2PixProjection(Projection):
+    """Base class for all Sky2Pix projections."""
 
+    inputs = ('phi', 'theta')
+    outputs = ('x', 'y')
 
-class Pix2Sky_AZP(Zenithal):
+
+class Zenithal(Projection):
+    """Base class for all Zenithal projections."""
+
+
+class Pix2Sky_AZP(Pix2SkyProjection, Zenithal):
     """
     AZP : Zenital perspective projection - pixel to sky.
 
@@ -77,45 +84,39 @@ class Pix2Sky_AZP(Zenithal):
 
 
     def _validate_mu(mu):
-        if mu == -1:
+        if np.asarray(mu == -1).any():
             raise ValueError("AZP projection is not defined for mu=-1")
         return mu
 
     mu = Parameter(default=0.0, setter=_validate_mu)
     gamma = Parameter(default=0.0, getter=np.rad2deg, setter=np.deg2rad)
 
-    def __init__(self, mu=mu.default, gamma=gamma.default):
+    def __init__(self, mu=mu.default, gamma=gamma.default, **kwargs):
         self.check_mu(mu)
         # units : mu - in spherical radii, gamma - in deg
         # TODO: Support quantity objects here and in similar contexts
-        super(Pix2Sky_AZP, self).__init__(mu, gamma)
+        super(Pix2Sky_AZP, self).__init__(mu, gamma, **kwargs)
 
     def check_mu(self, val):
-        if val == -1:
+        if np.asarray(val == -1).any():
             raise ValueError("AZP projection is not defined for mu=-1")
 
+    @property
     def inverse(self):
         return Sky2Pix_AZP(self.mu.value, self.gamma.value)
 
-    # TODO: This contains many superfluous conversions of gamma from radians to
-    # degrees back to radians again--this is going to be reworked in a future
-    # changeset
-    def _compute_rtheta(self, x, y):
-        gamma = np.deg2rad(self.gamma)
-        return np.sqrt(x ** 2 + y ** 2 * (np.cos(gamma)) ** 2)
-
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        gamma = np.deg2rad(self.gamma)
-        phi = np.rad2deg(np.arctan2(x / np.cos(gamma), -y))
-        r = self._compute_rtheta(x, y)
-        pho = r / (self.r0 * (self.mu + 1) +
-                   y * np.sin(gamma))
+    @classmethod
+    def evaluate(cls, x, y, mu, gamma):
+        phi = np.arctan2(x / np.cos(gamma), -y)
+        r = cls._compute_r_theta(x, y, gamma)
+        pho = r / (cls.r0 * (mu + 1) + y * np.sin(gamma))
         psi = np.arctan2(1, pho)
-        omega = np.arcsin((pho * self.mu) / (np.sqrt(pho ** 2 + 1)))
+        omega = np.arcsin((pho * mu) / np.sqrt(pho ** 2 + 1))
+
         theta1 = np.rad2deg(psi - omega)
         theta2 = np.rad2deg(psi + omega) + 180
-        if np.abs(self.mu) < 1:
+
+        if np.abs(mu) < 1:
             if theta1 < 90 and theta1 > -90:
                 theta = theta1
             else:
@@ -127,10 +128,16 @@ class Pix2Sky_AZP(Zenithal):
                 theta = theta1
             else:
                 theta = theta2
+
+        phi = np.rad2deg(phi)
         return phi, theta
 
+    @staticmethod
+    def _compute_r_theta(x, y, gamma):
+        return np.sqrt(x ** 2 + y ** 2 * (np.cos(gamma)) ** 2)
 
-class Sky2Pix_AZP(Zenithal):
+
+class Sky2Pix_AZP(Sky2PixProjection, Zenithal):
     """
     AZP : Zenital perspective projection - sky to pixel.
 
@@ -144,173 +151,184 @@ class Sky2Pix_AZP(Zenithal):
     """
 
     def _validate_mu(mu):
-        if mu == -1:
+        if np.asarray(mu == -1).any():
             raise ValueError("AZP projection is not defined for mu=-1")
         return mu
 
     mu = Parameter(default=0.0, setter=_validate_mu)
     gamma = Parameter(default=0.0, getter=np.rad2deg, setter=np.deg2rad)
 
-    def __init__(self, mu=mu.default, gamma=gamma.default):
-        super(Sky2Pix_AZP, self).__init__(mu, gamma)
-
     def check_mu(self, val):
-        if val == -1:
+        if np.asarray(val == -1).any():
             raise ValueError("AZP projection is not defined for mu=-1")
 
+    @property
     def inverse(self):
         return Pix2Sky_AZP(self.mu.value, self.gamma.value)
 
-    def _compute_rtheta(self, phi, theta):
-        gamma = np.deg2rad(self.gamma)
-        rtheta = (self.r0 * (self.mu + 1) *
-                  np.cos(theta)) / ((self.mu + np.sin(theta)) +
-                                    np.cos(theta) * np.cos(phi) *
-                                    np.tan(gamma))
-        return rtheta
-
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta, mu, gamma):
         phi = np.deg2rad(phi)
         theta = np.deg2rad(theta)
-        gamma = np.deg2rad(self.gamma)
-        r = self._compute_rtheta(phi, theta)
+
+        r = cls._compute_r_theta(phi, theta, mu, gamma)
         x = r * np.sin(phi)
         y = (-r * np.cos(phi)) / np.cos(gamma)
+
         return x, y
 
+    @classmethod
+    def _compute_r_theta(cls, phi, theta, mu, gamma):
+        return ((cls.r0 * (mu + 1) * np.cos(theta)) /
+                (mu + np.sin(theta) +
+                 np.cos(theta) * np.cos(phi) * np.tan(gamma)))
+
 
-class Pix2Sky_TAN(Zenithal):
+class Pix2Sky_TAN(Pix2SkyProjection, Zenithal):
     """
     TAN : Gnomonic projection - pixel to sky.
     """
 
-    def _compute_rtheta(self, x, y):
-        return np.sqrt(x ** 2 + y ** 2)
-
+    @property
     def inverse(self):
         return Sky2Pix_TAN()
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, x, y):
         phi = np.rad2deg(np.arctan2(x, -y))
-        rtheta = self._compute_rtheta(x, y)
-        theta = np.rad2deg(np.arctan2(self.r0, rtheta))
+        r_theta = cls._compute_r_theta(x, y)
+        theta = np.rad2deg(np.arctan2(cls.r0, r_theta))
+
         return phi, theta
 
+    @staticmethod
+    def _compute_r_theta(x, y):
+        return np.sqrt(x ** 2 + y ** 2)
+
 
-class Sky2Pix_TAN(Zenithal):
+class Sky2Pix_TAN(Sky2PixProjection, Zenithal):
     """
     TAN : Gnomonic Projection - sky to pixel.
     """
 
-    def _compute_rtheta(self, theta):
-        return 1 / np.tan(theta)
-
+    @property
     def inverse(self):
         return Pix2Sky_TAN()
 
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta):
         phi = np.deg2rad(phi)
         theta = np.deg2rad(theta)
-        rtheta = self._compute_rtheta(theta)
-        x = np.rad2deg(rtheta * np.sin(phi))
-        y = - np.rad2deg(rtheta * np.cos(phi))
+
+        r_theta = cls._compute_r_theta(theta)
+        x = np.rad2deg(r_theta * np.sin(phi))
+        y = -np.rad2deg(r_theta * np.cos(phi))
+
         return x, y
 
+    @staticmethod
+    def _compute_r_theta(theta):
+        return 1 / np.tan(theta)
+
 
-class Pix2Sky_STG(Zenithal):
+class Pix2Sky_STG(Pix2SkyProjection, Zenithal):
     """
     STG : Stereographic Projection - pixel to sky.
     """
 
-    def _compute_rtheta(self, x, y):
-        return np.sqrt(x ** 2 + y ** 2)
-
+    @property
     def inverse(self):
         return Sky2Pix_STG()
 
-    def __call__(self, x, y):
+    @classmethod
+    def evaluate(cls, x, y):
         phi = np.rad2deg(np.arctan2(x, -y))
-        rtheta = self._compute_rtheta(x, y)
-        theta = 90 - np.rad2deg(2 * np.arctan(rtheta / (2 * self.r0)))
+        rtheta = cls._compute_r_theta(x, y)
+        theta = 90 - np.rad2deg(2 * np.arctan(rtheta / (2 * cls.r0)))
+
         return phi, theta
 
+    @staticmethod
+    def _compute_r_theta(x, y):
+        return np.sqrt(x ** 2 + y ** 2)
+
 
-class Sky2Pix_STG(Zenithal):
+class Sky2Pix_STG(Sky2PixProjection, Zenithal):
     """
     STG : Stereographic Projection - sky to pixel.
     """
 
+    @property
     def inverse(self):
         return Pix2Sky_STG()
 
-    def _compute_rtheta(self, theta):
-        return (self.r0 * 2 * np.cos(theta)) / (1 + np.sin(theta))
-
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta):
         phi = np.deg2rad(phi)
         theta = np.deg2rad(theta)
-        rtheta = self._compute_rtheta(theta)
-        x = rtheta * np.sin(phi)
-        y = - rtheta * np.cos(phi)
+
+        r_theta = cls._compute_r_theta(theta)
+        x = r_theta * np.sin(phi)
+        y = -r_theta * np.cos(phi)
+
         return x, y
 
+    @classmethod
+    def _compute_r_theta(cls, theta):
+        return (cls.r0 * 2 * np.cos(theta)) / (1 + np.sin(theta))
 
-class Pix2Sky_SIN(Zenithal):
+
+class Pix2Sky_SIN(Pix2SkyProjection, Zenithal):
     """
     SIN : Slant orthographic projection - pixel to sky.
     """
 
+    @property
     def inverse(self):
         return Sky2Pix_SIN()
 
-    def _compute_rtheta(self, x, y):
-        return np.sqrt(x ** 2 + y ** 2)
-
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        rtheta = self._compute_rtheta(x, y)
-        theta = np.rad2deg(np.arccos(rtheta / self.r0))
+    @classmethod
+    def evaluate(cls, x, y):
+        r_theta = cls._compute_r_theta(x, y)
         phi = np.rad2deg(np.arctan2(x, -y))
+        theta = np.rad2deg(np.arccos(r_theta / cls.r0))
+
         return phi, theta
 
+    @staticmethod
+    def _compute_r_theta(x, y):
+        return np.sqrt(x ** 2 + y ** 2)
 
-class Sky2Pix_SIN(Zenithal):
+
+class Sky2Pix_SIN(Sky2PixProjection, Zenithal):
     """
-    SIN : Slant othographic projection - sky to pixel.
+    SIN : Slant orthographic projection - sky to pixel.
     """
 
+    @property
     def inverse(self):
         return Pix2Sky_SIN()
 
-    def _compute_rtheta(self, theta):
-        return self.r0 * np.cos(theta)
-
-    def __call__(self, phi, theta):
+    @classmethod
+    def evaluate(cls, phi, theta):
         phi = np.deg2rad(phi)
         theta = np.deg2rad(theta)
-        rtheta = self._compute_rtheta(theta)
-        x = rtheta * np.sin(phi)
-        y = - rtheta * np.cos(phi)
+        r_theta = cls._compute_r_theta(theta)
+        x = r_theta * np.sin(phi)
+        y = -r_theta * np.cos(phi)
+
         return x, y
 
+    @classmethod
+    def _compute_r_theta(cls, theta):
+        return cls.r0 * np.cos(theta)
 
-class Cylindrical(Projection):
-    """
-    Base class for Cylindrical projections.
-    """
 
-    def inverse(self):
-        raise NotImplementedError()
-
-    def __call__(self, x, y):
-        raise NotImplementedError()
+class Cylindrical(Projection):
+    """Base class for Cylindrical projections."""
 
 
-class Pix2Sky_CYP(Cylindrical):
+class Pix2Sky_CYP(Pix2SkyProjection, Cylindrical):
     """
     CYP : Cylindrical perspective - pixel to sky.
     """
@@ -318,7 +336,7 @@ class Pix2Sky_CYP(Cylindrical):
     def _validate_mu(mu, model):
         with ignored(AttributeError):
             # An attribute error can occur if model.lam has not been set yet
-            if mu == -model.lam:
+            if np.asarray(mu == -model.lam).any():
                 raise ValueError(
                     "CYP projection is not defined for mu=-lambda")
         return mu
@@ -326,30 +344,29 @@ class Pix2Sky_CYP(Cylindrical):
     def _validate_lam(lam, model):
         with ignored(AttributeError):
             # An attribute error can occur if model.lam has not been set yet
-            if lam == -model.mu:
+            if np.asarray(lam == -model.mu).any():
                 raise ValueError(
                     "CYP projection is not defined for mu=-lambda")
         return lam
 
-    mu = Parameter(setter=_validate_mu)
-    lam = Parameter(setter=_validate_lam)
-
-    def __init__(self, mu, lam):
-        super(Pix2Sky_CYP, self).__init__(mu, lam)
+    mu = Parameter(default=0, setter=_validate_mu)
+    lam = Parameter(default=0, setter=_validate_lam)
 
+    @property
     def inverse(self):
         return Sky2Pix_CYP(self.mu.value, self.lam.value)
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        phi = x / self.lam
-        eta = y / (self.r0 * (self.mu + self.lam))
-        theta = np.arctan2(eta, 1) + np.arcsin(eta * self.mu /
-                                               (np.sqrt(eta ** 2 + 1)))
+    @classmethod
+    def evaluate(cls, x, y, mu, lam):
+        phi = x / lam
+        eta = y / (cls.r0 * (mu + lam))
+        theta = (np.arctan2(eta, 1) +
+                 np.arcsin(eta * mu / np.sqrt(eta ** 2 + 1)))
+
         return phi, np.rad2deg(theta)
 
 
-class Sky2Pix_CYP(Cylindrical):
+class Sky2Pix_CYP(Sky2PixProjection, Cylindrical):
     """
     CYP : Cylindrical Perspective - sky to pixel.
     """
@@ -357,128 +374,141 @@ class Sky2Pix_CYP(Cylindrical):
     # TODO: Eliminate duplication on these
     def _validate_mu(mu, model):
         with ignored(AttributeError):
-            if mu == -model.lam:
+            if np.asarray(mu == -model.lam).any():
                 raise ValueError(
                     "CYP projection is not defined for mu=-lambda")
         return mu
 
     def _validate_lam(lam, model):
         with ignored(AttributeError):
-            if lam == -model.mu:
+            if np.asarray(lam == -model.mu).any():
                 raise ValueError(
                     "CYP projection is not defined for mu=-lambda")
         return lam
 
-    mu = Parameter(setter=_validate_mu)
-    lam = Parameter(setter=_validate_lam)
-
-    def __init__(self, mu, lam):
-        super(Sky2Pix_CYP, self).__init__(mu, lam)
+    mu = Parameter(default=0, setter=_validate_mu)
+    lam = Parameter(default=0, setter=_validate_lam)
 
+    @property
     def inverse(self):
         return Pix2Sky_CYP(self.mu, self.lam)
 
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta, mu, lam):
         theta = np.deg2rad(theta)
-        x = self.lam * phi
-        y = (self.r0 * ((self.mu + self.lam) /
-                        (self.mu + np.cos(theta))) * np.sin(theta))
+        x = lam * phi
+        y = (cls.r0 * (mu + lam) / (mu + np.cos(theta))) * np.sin(theta)
+
         return x, y
 
 
-class Pix2Sky_CEA(Cylindrical):
+class Pix2Sky_CEA(Pix2SkyProjection, Cylindrical):
     """
     CEA : Cylindrical equal area projection - pixel to sky.
     """
 
     lam = Parameter(default=1)
 
-    def __init__(self, lam=lam.default):
-        super(Pix2Sky_CEA, self).__init__(lam)
-
+    @property
     def inverse(self):
         return Sky2Pix_CEA(self.lam)
 
-    def __call__(self, x, y):
-        phi = np.asarray(x)
-        theta = np.rad2deg(np.arcsin(1 / self.r0 * self.lam * y))
+    @classmethod
+    def evaluate(cls, x, y, lam):
+        phi = x.copy()
+        theta = np.rad2deg(np.arcsin(1 / cls.r0 * lam * y))
+
         return phi, theta
 
 
-class Sky2Pix_CEA(Cylindrical):
+class Sky2Pix_CEA(Sky2PixProjection, Cylindrical):
     """
     CEA: Cylindrical equal area projection - sky to pixel.
     """
 
     lam = Parameter(default=1)
 
-    def __init__(self, lam=lam.default):
-        super(Sky2Pix_CEA, self).__init__(lam)
-
+    @property
     def inverse(self):
         return Pix2Sky_CEA(self.lam)
 
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta, lam):
         x = phi.copy()
         theta = np.deg2rad(theta)
-        y = self.r0 * np.sin(theta) / self.lam
+        y = cls.r0 * np.sin(theta) / lam
+
         return x, y
 
 
-class Pix2Sky_CAR(Cylindrical):
+class Pix2Sky_CAR(Pix2SkyProjection, Cylindrical):
     """
     CAR: Plate carree projection - pixel to sky.
     """
 
+    @property
     def inverse(self):
         return Sky2Pix_CAR()
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
-        return x.copy(), y.copy()
+    @staticmethod
+    def evaluate(x, y):
+        # The intermediate variables are only used here for clarity
+        phi = x.copy()
+        theta = y.copy()
+
+        return phi, theta
+
 
-class Sky2Pix_CAR(Cylindrical):
+class Sky2Pix_CAR(Sky2PixProjection, Cylindrical):
     """
     CAR: Plate carree projection - sky to pixel.
     """
 
+    @property
     def inverse(self):
         return Pix2Sky_CAR()
 
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
-        return phi.copy(), theta.copy()
+    @staticmethod
+    def evaluate(phi, theta):
+        # The intermediate variables are only used here for clarity
+        x = phi.copy()
+        y = theta.copy()
+
+        return x, y
+
 
-class Pix2Sky_MER(Cylindrical):
+class Pix2Sky_MER(Pix2SkyProjection, Cylindrical):
     """
     MER: Mercator - pixel to sky.
     """
 
+    @property
     def inverse(self):
         return Sky2Pix_MER()
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, x, y):
         phi = x.copy()
-        theta = np.rad2deg(2 * np.arctan(np.e ** (y * np.pi / 180.))) - 90.
+        theta = np.rad2deg(2 * np.arctan(np.exp(y / cls.r0))) - 90
+
         return phi, theta
 
 
-class Sky2Pix_MER(Cylindrical):
+class Sky2Pix_MER(Sky2PixProjection, Cylindrical):
     """
     MER: Mercator - sky to pixel.
     """
 
+    @property
     def inverse(self):
         return Pix2Sky_MER()
 
-    @format_input
-    def __call__(self, phi, theta, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, phi, theta):
         x = phi.copy()
         theta = np.deg2rad(theta)
-        y = self.r0 * np.log(np.tan((np.pi / 2 + theta) / 2))
+        y = cls.r0 * np.log(np.tan((np.pi / 2 + theta) / 2))
+
         return x, y
 
 
@@ -497,8 +527,9 @@ class AffineTransformation2D(Model):
         translation to apply to the inputs
     """
 
-    n_inputs = 2
-    n_outputs = 2
+    inputs = ('x', 'y')
+    outputs = ('x', 'y')
+
     standard_broadcasting = False
 
     matrix = Parameter(
@@ -508,12 +539,7 @@ class AffineTransformation2D(Model):
         setter=lambda t: AffineTransformation2D._validate_vector(t),
         default=[0.0, 0.0])
 
-    def __init__(self, matrix=matrix.default,
-                 translation=translation.default):
-        super(AffineTransformation2D, self).__init__(matrix, translation)
-        self._augmented_matrix = self._create_augmented_matrix(
-            self.matrix.value, self.translation.value)
-
+    @property
     def inverse(self):
         """
         Inverse transformation.
@@ -533,8 +559,8 @@ class AffineTransformation2D(Model):
 
         return self.__class__(matrix=matrix, translation=translation)
 
-    @format_input
-    def __call__(self, x, y, model_set_axis=None):
+    @classmethod
+    def evaluate(cls, x, y, matrix, translation):
         """
         Apply the transformation to a set of 2D Cartesian coordinates given as
         two lists--one for the x coordinates and one for a y coordinates--or a
@@ -549,19 +575,17 @@ class AffineTransformation2D(Model):
         if x.shape != y.shape:
             raise ValueError("Expected input arrays to have the same shape")
 
-        shape = x.shape
+        shape = x.shape or (1,)
         inarr = np.vstack([x.flatten(), y.flatten(), np.ones(x.size)])
 
         if inarr.shape[0] != 3 or inarr.ndim != 2:
             raise ValueError("Incompatible input shapes")
 
-        result = np.dot(self._augmented_matrix, inarr)
+        augmented_matrix = cls._create_augmented_matrix(matrix, translation)
+        result = np.dot(augmented_matrix, inarr)
 
         x, y = result[0], result[1]
-
-        if x.shape != shape:
-            x.shape = shape
-            y.shape = shape
+        x.shape = y.shape = shape
 
         return x, y
 
diff --git a/astropy/modeling/rotations.py b/astropy/modeling/rotations.py
index 8a0d62a..df27a47 100644
--- a/astropy/modeling/rotations.py
+++ b/astropy/modeling/rotations.py
@@ -1,7 +1,7 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
 """
-Implements roations, including spherical rotations as defined in WCS Paper II
+Implements rotations, including spherical rotations as defined in WCS Paper II
 [1]_
 
 `RotateNative2Celestial` and `RotateCelestial2Native` follow the convention in
@@ -24,7 +24,7 @@ import math
 import numpy as np
 
 from .core import Model
-from .parameters import Parameter, InputParameterError
+from .parameters import Parameter
 
 
 __all__ = ['RotateCelestial2Native', 'RotateNative2Celestial', 'Rotation2D']
@@ -40,14 +40,33 @@ class EulerAngleRotation(Model):
         Euler angles in deg
     """
 
-    n_inputs = 2
-    n_outputs = 2
-    phi = Parameter(getter=np.rad2deg, setter=np.deg2rad)
-    theta = Parameter(getter=np.rad2deg, setter=np.deg2rad)
-    psi = Parameter(getter=np.rad2deg, setter=np.deg2rad)
+    phi = Parameter(default=0, getter=np.rad2deg, setter=np.deg2rad)
+    theta = Parameter(default=0, getter=np.rad2deg, setter=np.deg2rad)
+    psi = Parameter(default=0, getter=np.rad2deg, setter=np.deg2rad)
 
-    def __init__(self, phi, theta, psi):
-        super(EulerAngleRotation, self).__init__(phi, theta, psi)
+    @staticmethod
+    def _rotate_zxz(phi_i, theta_i, phi, theta, psi):
+        """
+        Defines a ZXZ rotation from initial coordinates phi_i, theta_i.
+
+        All inputs and outputs are in radians.
+        """
+
+        cos_theta_i = np.cos(theta_i)
+        sin_theta_i = np.sin(theta_i)
+        cos_theta = np.cos(theta)
+        sin_theta = np.sin(theta)
+        delta = phi_i - psi
+        cos_delta = np.cos(delta)
+
+        phi_f = phi + np.arctan2(-cos_theta_i * np.sin(delta),
+                                 sin_theta_i * cos_theta -
+                                 cos_theta_i * sin_theta * cos_delta)
+
+        theta_f = np.arcsin(sin_theta_i * sin_theta +
+                            cos_theta_i * cos_theta * cos_delta)
+
+        return phi_f, theta_f
 
 
 class RotateNative2Celestial(EulerAngleRotation):
@@ -62,36 +81,34 @@ class RotateNative2Celestial(EulerAngleRotation):
         Euler angles in deg
     """
 
+    inputs = ('phi_N', 'theta_N')
+    outputs = ('alpha_C', 'delta_C')
+
+    @property
     def inverse(self):
         return RotateCelestial2Native(self.phi, self.theta, self.psi)
 
-    def __call__(self, nphi, ntheta):
-        nphi = np.deg2rad(nphi)
-        ntheta = np.deg2rad(ntheta)
-        # TODO: Unfortunately right now this superfluously converts from
-        # radians to degrees back to radians again--this will be addressed in a
-        # future change
-        phi = np.deg2rad(self.phi)
-        psi = np.deg2rad(self.psi)
-        theta = np.deg2rad(self.theta)
+    @classmethod
+    def evaluate(cls, phi_N, theta_N, phi, theta, psi):
+        """
+        Evaluate ZXZ rotation into celestial coordinates.
+        """
+
+        phi_N = np.deg2rad(phi_N)
+        theta_N = np.deg2rad(theta_N)
 
-        calpha = np.rad2deg(
-            phi +
-            np.arctan2(-np.cos(ntheta) * np.sin(nphi - psi),
-                       np.sin(ntheta) * np.cos(theta) -
-                       np.cos(ntheta) * np.sin(theta) * np.cos(nphi - psi)))
+        alpha_C, delta_C = cls._rotate_zxz(phi_N, theta_N, phi, theta, psi)
 
-        cdelta = np.rad2deg(
-            np.arcsin(np.sin(ntheta) * np.sin(theta) +
-                      np.cos(ntheta) * np.cos(theta) * np.cos(nphi - psi)))
+        alpha_C = np.rad2deg(alpha_C)
+        delta_C = np.rad2deg(delta_C)
 
-        ind = calpha < 0
-        if isinstance(ind, np.ndarray):
-            calpha[ind] += 360
-        elif ind:
-            calpha += 360
+        mask = alpha_C < 0
+        if isinstance(mask, np.ndarray):
+            alpha_C[mask] += 360
+        elif mask:
+            alpha_C += 360
 
-        return calpha, cdelta
+        return alpha_C, delta_C
 
 
 class RotateCelestial2Native(EulerAngleRotation):
@@ -106,37 +123,37 @@ class RotateCelestial2Native(EulerAngleRotation):
         Euler angles in deg
     """
 
+    inputs = ('alpha_C', 'delta_C')
+    outputs = ('phi_N', 'theta_N')
+
+    @property
     def inverse(self):
         return RotateNative2Celestial(self.phi, self.theta, self.psi)
 
-    def __call__(self, calpha, cdelta):
-        calpha = np.deg2rad(calpha)
-        cdelta = np.deg2rad(cdelta)
+    @classmethod
+    def evaluate(cls, alpha_C, delta_C, phi, theta, psi):
+        """
+        Evaluate ZXZ rotation into native coordinates.
+
+        This is like RotateNative2Celestial.evaluate except phi and psi are
+        swapped in ZXZ rotation.
+        """
 
-        # TODO: Unfortunately right now this superfluously converts from
-        # radians to degrees back to radians again--this will be addressed in a
-        # future change
-        phi = np.deg2rad(self.phi)
-        psi = np.deg2rad(self.psi)
-        theta = np.deg2rad(self.theta)
+        alpha_C = np.deg2rad(alpha_C)
+        delta_C = np.deg2rad(delta_C)
 
-        nphi = np.rad2deg(
-            psi +
-            np.arctan2(-np.cos(cdelta) * np.sin(calpha - phi),
-                       np.sin(cdelta) * np.cos(theta) -
-                       np.cos(cdelta) * np.sin(theta) * np.cos(calpha - phi)))
+        phi_N, theta_N = cls._rotate_zxz(alpha_C, delta_C, psi, theta, phi)
 
-        ntheta = np.rad2deg(
-            np.arcsin(np.sin(cdelta) * np.sin(theta) +
-                      np.cos(cdelta) * np.cos(theta) * np.cos(calpha - phi)))
+        phi_N = np.rad2deg(phi_N)
+        theta_N = np.rad2deg(theta_N)
 
-        ind = nphi > 180
-        if isinstance(ind, np.ndarray):
-            nphi[ind] -= 360
-        elif ind:
-            nphi -= 360
+        mask = phi_N > 180
+        if isinstance(mask, np.ndarray):
+            phi_N[mask] -= 360
+        elif mask:
+            phi_N -= 360
 
-        return nphi, ntheta
+        return phi_N, theta_N
 
 
 class Rotation2D(Model):
@@ -151,45 +168,38 @@ class Rotation2D(Model):
         angle of rotation in deg
     """
 
-    n_inputs = 2
-    n_outputs = 2
+    inputs = ('x', 'y')
+    outputs = ('x', 'y')
 
     angle = Parameter(default=0.0, getter=np.rad2deg, setter=np.deg2rad)
 
-    def __init__(self, angle=angle.default):
-        super(Rotation2D, self).__init__(angle)
-        self._matrix = self._compute_matrix(np.deg2rad(angle))
-
+    @property
     def inverse(self):
         """Inverse rotation."""
 
         return self.__class__(angle=-self.angle)
 
-    def __call__(self, x, y):
+    @classmethod
+    def evaluate(cls, x, y, angle):
         """
         Apply the rotation to a set of 2D Cartesian coordinates given as two
         lists--one for the x coordinates and one for a y coordinates--or a
         single coordinate pair.
-
-        Parameters
-        ----------
-        x, y : array, float
-            x and y coordinates
         """
 
-        x = np.asarray(x)
-        y = np.asarray(y)
         if x.shape != y.shape:
             raise ValueError("Expected input arrays to have the same shape")
-        shape = x.shape
-        inarr = np.array([x.flatten(), y.flatten()], dtype=np.float64)
-        if inarr.shape[0] != 2 or inarr.ndim != 2:
-            raise ValueError("Incompatible input shapes")
-        result = np.dot(self._matrix, inarr)
+
+        # Note: If the original shape was () (an array scalar) convert to a
+        # 1-element 1-D array on output for consistency with most other models
+        orig_shape = x.shape or (1,)
+
+        inarr = np.array([x.flatten(), y.flatten()])
+        result = np.dot(cls._compute_matrix(angle), inarr)
+
         x, y = result[0], result[1]
-        if x.shape != shape:
-            x.shape = shape
-            y.shape = shape
+        x.shape = y.shape = orig_shape
+
         return x, y
 
     @staticmethod
diff --git a/astropy/modeling/tests/example_models.py b/astropy/modeling/tests/example_models.py
index df738f8..b15fb95 100644
--- a/astropy/modeling/tests/example_models.py
+++ b/astropy/modeling/tests/example_models.py
@@ -1,7 +1,8 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 """
-Here are all the test parameters and values for the each `~astropy.modeling.FittableModel`
-defined. There is a dictionary for 1D and a dictionary for 2D models.
+Here are all the test parameters and values for the each
+`~astropy.modeling.FittableModel` defined. There is a dictionary for 1D and a
+dictionary for 2D models.
 
 Explanation of keywords of the dictionaries:
 
@@ -53,9 +54,9 @@ from __future__ import (absolute_import, division, print_function,
 
 from ..functional_models import (
     Gaussian1D, Sine1D, Box1D, Linear1D, Lorentz1D,
-    MexicanHat1D, Trapezoid1D, Const1D, Beta1D,
+    MexicanHat1D, Trapezoid1D, Const1D, Moffat1D,
     Gaussian2D, Const2D, Box2D, MexicanHat2D,
-    TrapezoidDisk2D, AiryDisk2D, Beta2D, Disk2D,
+    TrapezoidDisk2D, AiryDisk2D, Moffat2D, Disk2D,
     Ring2D)
 from ..polynomial import Polynomial1D, Polynomial2D
 from ..powerlaws import (
@@ -129,7 +130,7 @@ models_1D = {
         'integral': 20
     },
 
-    Beta1D: {
+    Moffat1D: {
         'parameters': [1, 0, 1, 2],
         'x_values': [0, 1, -1, 3, -3],
         'y_values': [1.0, 0.25, 0.25, 0.01, 0.01],
@@ -252,7 +253,7 @@ models_2D = {
         'requires_scipy': True
     },
 
-    Beta2D: {
+    Moffat2D: {
         'parameters': [1, 0, 0, 1, 2],
         'x_values': [0, 1, -1, 3, -3],
         'y_values': [0, -1, 3, 1, -3],
diff --git a/astropy/modeling/tests/test_compound.py b/astropy/modeling/tests/test_compound.py
new file mode 100644
index 0000000..7d463f4
--- /dev/null
+++ b/astropy/modeling/tests/test_compound.py
@@ -0,0 +1,716 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import inspect
+
+import numpy as np
+
+from numpy.testing.utils import (assert_allclose, assert_array_equal,
+                                 assert_almost_equal)
+
+from ...tests.helper import pytest
+
+from ..core import Model, ModelDefinitionError
+from ..models import (Const1D, Shift, Scale, Rotation2D, Gaussian1D,
+                      Gaussian2D, Polynomial1D, Polynomial2D,
+                      AffineTransformation2D,
+                      Identity, Mapping)
+
+
+ at pytest.mark.parametrize(('expr', 'result'),
+                         [(lambda x, y: x + y, 5.0),
+                          (lambda x, y: x - y, -1.0),
+                          (lambda x, y: x * y, 6.0),
+                          (lambda x, y: x / y, 2.0 / 3.0),
+                          (lambda x, y: x ** y, 8.0)])
+def test_two_model_class_arithmetic_1d(expr, result):
+    # Const1D is perhaps the simplest model to test basic arithmetic with.
+    # TODO: Should define more tests later on for more complicated
+    # combinations of models
+
+    S = expr(Const1D, Const1D)
+
+    assert issubclass(S, Model)
+    assert S.n_inputs == 1
+    assert S.n_outputs == 1
+
+    # Initialize an instance of the model, providing values for the two
+    # "amplitude" parameters
+    s = S(2, 3)
+
+    # It shouldn't matter what input we evaluate on since this is a constant
+    # function
+    out = s(0)
+    assert out == result
+    assert isinstance(out, float)
+
+
+ at pytest.mark.parametrize(('expr', 'result'),
+                         [(lambda x, y: x + y, 5.0),
+                          (lambda x, y: x - y, -1.0),
+                          (lambda x, y: x * y, 6.0),
+                          (lambda x, y: x / y, 2.0 / 3.0),
+                          (lambda x, y: x ** y, 8.0)])
+def test_two_model_instance_arithmetic_1d(expr, result):
+    """
+    Like test_two_model_class_arithmetic_1d, but creates a new model from two
+    model *instances* with fixed parameters.
+    """
+
+    s = expr(Const1D(2), Const1D(3))
+
+    assert isinstance(s, Model)
+    assert s.n_inputs == 1
+    assert s.n_outputs == 1
+
+    out = s(0)
+    assert out == result
+    assert isinstance(out, float)
+
+
+ at pytest.mark.parametrize(('expr', 'result'),
+                         [(lambda x, y: x + y, 5.0),
+                          (lambda x, y: x - y, -1.0),
+                          (lambda x, y: x * y, 6.0),
+                          (lambda x, y: x / y, 2.0 / 3.0),
+                          (lambda x, y: x ** y, 8.0)])
+def test_two_model_mixed_arithmetic_1d(expr, result):
+    """
+    Like test_two_model_class_arithmetic_1d, but creates a new model from an
+    expression of one model class with one model instance (and vice-versa).
+    """
+
+    S1 = expr(Const1D, Const1D(3))
+    S2 = expr(Const1D(2), Const1D)
+
+    for cls in (S1, S2):
+        assert issubclass(cls, Model)
+        assert cls.n_inputs == 1
+        assert cls.n_outputs == 1
+
+    # Requires values for both amplitudes even though one of them them has a
+    # default
+    # TODO: We may wish to fix that eventually, so that if a parameter has a
+    # default it doesn't *have* to be given in the init
+    s1 = S1(2, 3)
+    s2 = S2(2, 3)
+
+    for out in (s1(0), s2(0)):
+        assert out == result
+        assert isinstance(out, float)
+
+
+def test_simple_two_model_class_compose_1d():
+    """
+    Shift and Scale are two of the simplest models to test model composition
+    with.
+    """
+
+    S1 = Shift | Scale  # First shift then scale
+    assert issubclass(S1, Model)
+    assert S1.n_inputs == 1
+    assert S1.n_outputs == 1
+
+    s1 = S1(2, 3)  # Shift by 2 and scale by 3
+    assert s1(1) == 9.0
+
+    S2 = Scale | Shift  # First scale then shift
+    assert issubclass(S2, Model)
+    assert S2.n_inputs == 1
+    assert S2.n_outputs == 1
+
+    s2 = S2(2, 3)  # Scale by 2 then shift by 3
+    assert s2(1) == 5.0
+
+    # Test with array inputs
+    assert_array_equal(s2([1, 2, 3]), [5.0, 7.0, 9.0])
+
+
+def test_simple_two_model_class_compose_2d():
+    """
+    A simple example consisting of two rotations.
+    """
+
+    R = Rotation2D | Rotation2D
+    assert issubclass(R, Model)
+    assert R.n_inputs == 2
+    assert R.n_outputs == 2
+
+    r1 = R(45, 45)  # Rotate twice by 45 degrees
+    assert_allclose(r1(0, 1), (-1, 0), atol=1e-10)
+
+    r2 = R(90, 90)  # Rotate twice by 90 degrees
+    assert_allclose(r2(0, 1), (0, -1), atol=1e-10)
+
+    # Compose R with itself to produce 4 rotations
+    R2 = R | R
+
+    r3 = R2(45, 45, 45, 45)
+    assert_allclose(r3(0, 1), (0, -1), atol=1e-10)
+
+
+class TestCompositeLegacy(object):
+    """
+    Tests inspired by the original _CompositeModel tests in test_core.py,
+    this implements the equivalent tests implemented in the new framework.
+
+    Note: These aren't *exactly* the same as the original tests, as they used
+    overly trivial models (polynomials with all coeffs 0).
+    """
+
+    def setup_class(self):
+        self.y, self.x = np.mgrid[:5, :5]
+
+    def test_single_array_input(self):
+        p1 = Polynomial1D(3, c0=1, c1=2, c2=3, c3=4)
+        p2 = Polynomial1D(3, c0=2, c1=3, c2=4, c3=5)
+        m = p1 | p2
+        assert_almost_equal(p2(p1(self.x)), m(self.x))
+
+    def test_labeledinput_1(self):
+        # Note: No actual use of LabeledInput in this test; this just uses the
+        # same name for symmetry with the old tests
+        p1 = Polynomial1D(3, c0=1, c1=2, c2=3, c3=4)
+        p2 = Polynomial2D(3, c0_0=1, c2_0=2, c0_1=3, c2_1=4)
+        m = p2 | p1
+        assert_almost_equal(p1(p2(self.x, self.y)), m(self.x, self.y))
+
+    def test_labledinput_2(self):
+        rot = Rotation2D(angle=23.4)
+        offx = Shift(-2)
+        offy = Shift(1.2)
+        m = rot | (offx & Identity(1)) | (Identity(1) & offy)
+
+        x, y = rot(self.x, self.y)
+        x = offx(x)
+        y = offy(y)
+
+        assert_almost_equal(x, m(self.x, self.y)[0])
+        assert_almost_equal(y, m(self.x, self.y)[1])
+
+        a = np.deg2rad(23.4)
+        # For kicks
+        matrix = [[np.cos(a), -np.sin(a)],
+                  [np.sin(a), np.cos(a)]]
+        x, y = AffineTransformation2D(matrix, [-2, 1.2])(self.x, self.y)
+        assert_almost_equal(x, m(self.x, self.y)[0])
+        assert_almost_equal(y, m(self.x, self.y)[1])
+
+    def test_multiple_input(self):
+        """
+        Despite the name, this actually tests inverting composite models,
+        which is not yet supported in the new framework (but should be).
+        """
+
+        rot = Rotation2D(-60)
+        m = rot | rot
+        xx, yy = m(self.x, self.y)
+        x0, y0 = m.inverse(xx, yy)
+        assert_almost_equal(x0, self.x)
+        assert_almost_equal(y0, self.y)
+
+
+def test_expression_formatting():
+    """
+    Test that the expression strings from compound models are formatted
+    correctly.
+    """
+
+    # For the purposes of this test it doesn't matter a great deal what
+    # model(s) are used in the expression, I don't think
+    G = Gaussian1D
+    G2 = Gaussian2D
+
+    M = G + G
+    assert M._format_expression() == '[0] + [1]'
+
+    M = G + G + G
+    assert M._format_expression() == '[0] + [1] + [2]'
+
+    M = G + G * G
+    assert M._format_expression() == '[0] + [1] * [2]'
+
+    M = G * G + G
+    assert M._format_expression() == '[0] * [1] + [2]'
+
+    M = G + G * G + G
+    assert M._format_expression() == '[0] + [1] * [2] + [3]'
+
+    M = (G + G) * (G + G)
+    assert M._format_expression() == '([0] + [1]) * ([2] + [3])'
+
+    # This example uses parentheses in the expression, but those won't be
+    # preserved in the expression formatting since they technically aren't
+    # necessary, and there's no way to know that they were originally
+    # parenthesized (short of some deep, and probably not worthwhile
+    # introspection)
+    M = (G * G) + (G * G)
+    assert M._format_expression() == '[0] * [1] + [2] * [3]'
+
+    M = G ** G
+    assert M._format_expression() == '[0] ** [1]'
+
+    M = G + G ** G
+    assert M._format_expression() == '[0] + [1] ** [2]'
+
+    M = (G + G) ** G
+    assert M._format_expression() == '([0] + [1]) ** [2]'
+
+    M = G + G | G
+    assert M._format_expression() == '[0] + [1] | [2]'
+
+    M = G + (G | G)
+    assert M._format_expression() == '[0] + ([1] | [2])'
+
+    M = G & G | G2
+    assert M._format_expression() == '[0] & [1] | [2]'
+
+    M = G & (G | G)
+    assert M._format_expression() == '[0] & ([1] | [2])'
+
+
+def test_indexing_on_class():
+    """
+    Test indexing on compound model class objects, including cases where the
+    submodels are classes, as well as instances, or both.
+    """
+
+    g = Gaussian1D(1, 2, 3, name='g')
+    p = Polynomial1D(2, name='p')
+
+    M = Gaussian1D + Const1D
+    assert M[0] is Gaussian1D
+    assert M[1] is Const1D
+    assert M['Gaussian1D'] is M[0]
+    assert M['Const1D'] is M[1]
+
+    M = Gaussian1D + p
+    assert M[0] is Gaussian1D
+    assert M[1] is p
+    assert M['Gaussian1D'] is M[0]
+    assert M['p'] is M[1]
+
+    m = g + p
+    assert isinstance(m[0], Gaussian1D)
+    assert isinstance(m[1], Polynomial1D)
+    assert isinstance(m['g'], Gaussian1D)
+    assert isinstance(m['p'], Polynomial1D)
+
+    # Test negative indexing
+    assert isinstance(m[-1], Polynomial1D)
+    assert isinstance(m[-2], Gaussian1D)
+
+    with pytest.raises(IndexError):
+        m[42]
+
+    with pytest.raises(IndexError):
+        m['foobar']
+
+
+# TODO: It would be good if there were an easier way to interrogate a compound
+# model class for what expression it represents.  Not sure what that would look
+# like though.
+def test_slicing_on_class():
+    """
+    Test slicing a simple compound model class using integers.
+    """
+
+    A = Const1D.rename('A')
+    B = Const1D.rename('B')
+    C = Const1D.rename('C')
+    D = Const1D.rename('D')
+    E = Const1D.rename('E')
+    F = Const1D.rename('F')
+
+    M = A + B - C * D / E ** F
+
+    assert M[0:1] is A
+    # This test will also check that the correct parameter names are generated
+    # for each slice (fairly trivial in this case since all the submodels have
+    # the same parameter, but if any corner cases are found that aren't covered
+    # by this test we can do something different...)
+    assert M[0:1].param_names == ('amplitude',)
+    # This looks goofy but if you slice by name to the sub-model of the same
+    # name it should just return that model, logically.
+    assert M['A':'A'] is A
+    assert M['A':'A'].param_names == ('amplitude',)
+    assert M[5:6] is F
+    assert M[5:6].param_names == ('amplitude',)
+    assert M['F':'F'] is F
+    assert M['F':'F'].param_names == ('amplitude',)
+
+    # 1 + 2
+    assert M[:2](1, 2)(0) == 3
+    assert M[:2].param_names == ('amplitude_0', 'amplitude_1')
+    assert M[:'B'](1, 2)(0) == 3
+    assert M[:'B'].param_names == ('amplitude_0', 'amplitude_1')
+    # 2 - 3
+    assert M[1:3](2, 3)(0) == -1
+    assert M[1:3].param_names == ('amplitude_1', 'amplitude_2')
+    assert M['B':'C'](2, 3)(0) == -1
+    assert M['B':'C'].param_names == ('amplitude_1', 'amplitude_2')
+    # 3 * 4
+    assert M[2:4](3, 4)(0) == 12
+    assert M[2:4].param_names == ('amplitude_2', 'amplitude_3')
+    assert M['C':'D'](3, 4)(0) == 12
+    assert M['C':'D'].param_names == ('amplitude_2', 'amplitude_3')
+    # 4 / 5
+    assert M[3:5](4, 5)(0) == 0.8
+    assert M[3:5].param_names == ('amplitude_3', 'amplitude_4')
+    assert M['D':'E'](4, 5)(0) == 0.8
+    assert M['D':'E'].param_names == ('amplitude_3', 'amplitude_4')
+    # 5 ** 6
+    assert M[4:6](5, 6)(0) == 15625
+    assert M[4:6].param_names == ('amplitude_4', 'amplitude_5')
+    assert M['E':'F'](5, 6)(0) == 15625
+    assert M['E':'F'].param_names == ('amplitude_4', 'amplitude_5')
+
+
+def test_slicing_on_instance():
+    """
+    Test slicing a simple compound model class using integers.
+    """
+
+    A = Const1D.rename('A')
+    B = Const1D.rename('B')
+    C = Const1D.rename('C')
+    D = Const1D.rename('D')
+    E = Const1D.rename('E')
+    F = Const1D.rename('F')
+
+    M = A + B - C * D / E ** F
+    m = M(1, 2, 3, 4, 5, 6)
+
+    assert isinstance(m[0:1], A)
+    assert isinstance(m['A':'A'], A)
+    assert isinstance(m[5:6], F)
+    assert isinstance(m['F':'F'], F)
+
+    # 1 + 2
+    assert m[:'B'](0) == 3
+    assert m[:'B'].param_names == ('amplitude_0', 'amplitude_1')
+    assert np.all(m[:'B'].parameters == [1, 2])
+    # 2 - 3
+    assert m['B':'C'](0) == -1
+    assert m['B':'C'].param_names == ('amplitude_1', 'amplitude_2')
+    assert np.all(m['B':'C'].parameters == [2, 3])
+    # 3 * 4
+    assert m['C':'D'](0) == 12
+    assert m['C':'D'].param_names == ('amplitude_2', 'amplitude_3')
+    assert np.all(m['C':'D'].parameters == [3, 4])
+    # 4 / 5
+    assert m['D':'E'](0) == 0.8
+    assert m['D':'E'].param_names == ('amplitude_3', 'amplitude_4')
+    assert np.all(m['D':'E'].parameters == [4, 5])
+    # 5 ** 6
+    assert m['E':'F'](0) == 15625
+    assert m['E':'F'].param_names == ('amplitude_4', 'amplitude_5')
+    assert np.all(m['E':'F'].parameters == [5, 6])
+
+
+def test_indexing_on_instance():
+    """Test indexing on compound model instances."""
+
+    M = Gaussian1D + Const1D
+    m = M(1, 0, 0.1, 2)
+    assert isinstance(m[0], Gaussian1D)
+    assert isinstance(m[1], Const1D)
+    assert isinstance(m['Gaussian1D'], Gaussian1D)
+    assert isinstance(m['Const1D'], Const1D)
+
+    # Test parameter equivalence
+    assert m[0].amplitude == 1 == m.amplitude_0
+    assert m[0].mean == 0 == m.mean_0
+    assert m[0].stddev == 0.1 == m.stddev_0
+    assert m[1].amplitude == 2 == m.amplitude_1
+
+    # Test that parameter value updates are symmetric between the compound
+    # model and the submodel returned by indexing
+    const = m[1]
+    m.amplitude_1 = 42
+    assert const.amplitude == 42
+    const.amplitude = 137
+    assert m.amplitude_1 == 137
+
+
+    # Similar couple of tests, but now where the compound model was created
+    # from model instances
+    g = Gaussian1D(1, 2, 3, name='g')
+    p = Polynomial1D(2, name='p')
+    m = g + p
+    assert m[0].name == 'g'
+    assert m[1].name == 'p'
+    assert m['g'].name == 'g'
+    assert m['p'].name == 'p'
+
+    poly = m[1]
+    m.c0_1 = 12345
+    assert poly.c0 == 12345
+    poly.c1 = 6789
+    assert m.c1_1 == 6789
+
+    # Ensure this did *not* modify the original models we used as templates
+    assert p.c0 == 0
+    assert p.c1 == 0
+
+    # Test negative indexing
+    assert isinstance(m[-1], Polynomial1D)
+    assert isinstance(m[-2], Gaussian1D)
+
+    with pytest.raises(IndexError):
+        m[42]
+
+    with pytest.raises(IndexError):
+        m['foobar']
+
+
+def test_basic_compound_inverse():
+    """
+    Test basic inversion of compound models in the limited sense supported for
+    models made from compositions and joins only.
+    """
+
+    t = (Shift(2) & Shift(3)) | (Scale(2) & Scale(3)) | Rotation2D(90)
+    assert_allclose(t.inverse(*t(0, 1)), (0, 1))
+
+
+ at pytest.mark.parametrize('model', [
+    Shift(0) + Shift(0) | Shift(0),
+    Shift(0) - Shift(0) | Shift(0),
+    Shift(0) * Shift(0) | Shift(0),
+    Shift(0) / Shift(0) | Shift(0),
+    Shift(0) ** Shift(0) | Shift(0),
+    Gaussian1D(1, 2, 3) | Gaussian1D(4, 5, 6)])
+def test_compound_unsupported_inverse(model):
+    """
+    Ensure inverses aren't supported in cases where it shouldn't be.
+    """
+
+    with pytest.raises(NotImplementedError):
+        model.inverse
+
+
+def test_mapping_basic_permutations():
+    """
+    Tests a couple basic examples of the Mapping model--specifically examples
+    that merely permute the outputs.
+    """
+
+    x, y = Rotation2D(90)(1, 2)
+
+    RS = Rotation2D | Mapping((1, 0))
+    x_prime, y_prime = RS(90)(1, 2)
+    assert_allclose((x, y), (y_prime, x_prime))
+
+    # A more complicated permutation
+    M = Rotation2D & Scale
+    m = M(90, 2)
+    x, y, z = m(1, 2, 3)
+
+    MS = M | Mapping((2, 0, 1))
+    ms = MS(90, 2)
+    x_prime, y_prime, z_prime = ms(1, 2, 3)
+    assert_allclose((x, y, z), (y_prime, z_prime, x_prime))
+
+
+def test_mapping_inverse():
+    """Tests inverting a compound model that includes a `Mapping`."""
+
+    RS = Rotation2D & Scale
+
+    # Rotates 2 of the coordinates and scales the third--then rotates on a
+    # different axis and scales on the axis of rotation.  No physical meaning
+    # here just a simple test
+    M = RS | Mapping([2, 0, 1]) | RS
+
+    m = M(12.1, 13.2, 14.3, 15.4)
+
+    assert_allclose((0, 1, 2), m.inverse(*m(0, 1, 2)), atol=1e-08)
+
+
+def test_identity_input():
+    """
+    Test a case where an Identity (or Mapping) model is the first in a chain
+    of composite models and thus is responsible for handling input broadcasting
+    properly.
+
+    Regression test for https://github.com/astropy/astropy/pull/3362
+    """
+
+    ident1 = Identity(1)
+    shift = Shift(1)
+    rotation = Rotation2D(angle=90)
+    model = ident1 & shift | rotation
+    assert_allclose(model(1, 2), [-3.0, 1.0])
+
+    # Same test case but using class composition
+    TestModel = ident1 & Shift | Rotation2D
+    model = TestModel(offset_1=1, angle_2=90)
+    assert_allclose(model(1, 2), [-3.0, 1.0])
+
+
+def test_slicing_on_instances_2():
+    """
+    More slicing tests.
+
+    Regression test for https://github.com/embray/astropy/pull/10
+    """
+
+    model_a = Shift(1, name='a')
+    model_b = Shift(2, name='b')
+    model_c = Rotation2D(3, name='c')
+    model_d = Scale(2, name='d')
+    model_e = Scale(3, name='e')
+
+    m = (model_a & model_b) | model_c | (model_d & model_e)
+
+    with pytest.raises(ModelDefinitionError):
+        # The slice can't actually be taken since the resulting model cannot be
+        # evaluated
+        assert m[1:].submodel_names == ('b', 'c', 'd', 'e')
+
+    assert m[:].submodel_names == ('a', 'b', 'c', 'd', 'e')
+    assert m['a':].submodel_names == ('a', 'b', 'c', 'd', 'e')
+
+    with pytest.raises(ModelDefinitionError):
+        assert m['c':'d'].submodel_names == ('c', 'd')
+
+    assert m[1:2].name == 'b'
+    assert m[2:7].submodel_names == ('c', 'd', 'e')
+    with pytest.raises(IndexError):
+        m['x']
+    with pytest.raises(IndexError):
+        m['a' : 'r']
+
+    with pytest.raises(ModelDefinitionError):
+        assert m[-4:4].submodel_names == ('b', 'c', 'd')
+
+    with pytest.raises(ModelDefinitionError):
+        assert m[-4:-2].submodel_names == ('b', 'c')
+
+
+def test_slicing_on_instances_3():
+    """
+    Like `test_slicing_on_instances_2` but uses a compound model that does not
+    have any invalid slices due to the resulting model being invalid
+    (originally test_slicing_on_instances_2 passed without any
+    ModelDefinitionErrors being raised, but that was before we prevented
+    invalid models from being created).
+    """
+
+    model_a = Shift(1, name='a')
+    model_b = Shift(2, name='b')
+    model_c = Gaussian1D(3, 0, 0.1, name='c')
+    model_d = Scale(2, name='d')
+    model_e = Scale(3, name='e')
+
+    m = (model_a + model_b) | model_c | (model_d + model_e)
+
+    assert m[1:].submodel_names == ('b', 'c', 'd', 'e')
+    assert m[:].submodel_names == ('a', 'b', 'c', 'd', 'e')
+    assert m['a':].submodel_names == ('a', 'b', 'c', 'd', 'e')
+    assert m['c':'d'].submodel_names == ('c', 'd')
+    assert m[1:2].name == 'b'
+    assert m[2:7].submodel_names == ('c', 'd', 'e')
+    with pytest.raises(IndexError):
+        m['x']
+    with pytest.raises(IndexError):
+        m['a' : 'r']
+    assert m[-4:4].submodel_names == ('b', 'c', 'd')
+    assert m[-4:-2].submodel_names == ('b', 'c')
+
+
+def test_slicing_on_instance_with_parameterless_model():
+    """
+    Regression test to fix an issue where the indices attached to parameter
+    names on a compound model were not handled properly when one or more
+    submodels have no parameters.  This was especially evident in slicing.
+    """
+
+    p2 = Polynomial2D(1, c0_0=1, c1_0=2, c0_1=3)
+    p1 = Polynomial2D(1, c0_0=1, c1_0=2, c0_1=3)
+    mapping = Mapping((0, 1, 0, 1))
+    offx = Shift(-2, name='x_translation')
+    offy = Shift(-1, name='y_translation')
+    aff = AffineTransformation2D(matrix=[[1, 2], [3, 4]], name='rotation')
+    model = mapping | (p1 & p2) | (offx & offy) | aff
+
+    assert model.param_names == ('c0_0_1', 'c1_0_1', 'c0_1_1',
+                                 'c0_0_2', 'c1_0_2', 'c0_1_2',
+                                 'offset_3', 'offset_4',
+                                 'matrix_5', 'translation_5')
+    assert model(1, 2) == (23.0, 53.0)
+
+    m = model[3:]
+    assert m.param_names == ('offset_3', 'offset_4', 'matrix_5',
+                             'translation_5')
+    assert m(1, 2) == (1.0, 1.0)
+
+
+def test_compound_model_with_nonstandard_broadcasting():
+    """
+    Ensure that the ``standard_broadcasting`` flag is properly propagated when
+    creating compound models.
+
+    See the commit message for the commit in which this was added for more
+    details.
+    """
+
+    offx = Shift(1)
+    offy = Shift(2)
+    rot = AffineTransformation2D([[0, -1], [1, 0]])
+    m = (offx & offy) | rot
+
+    x, y = m(0, 0)
+    assert x == -2
+    assert y == 1
+
+    # make sure conversion back to scalars is working properly
+    assert isinstance(x, float)
+    assert isinstance(y, float)
+
+    x, y = m([0, 1, 2], [0, 1, 2])
+    assert np.all(x == [-2, -3, -4])
+    assert np.all(y == [1, 2, 3])
+
+
+def test_compound_model_classify_attributes():
+    """
+    Regression test for an issue raised here:
+    https://github.com/astropy/astropy/pull/3231#discussion_r22221123
+
+    The issue is that part of the `help` implementation calls a utility
+    function called `inspect.classify_class_attrs`, which was leading to an
+    infinite recursion.
+
+    This is a useful test in its own right just in that it tests that compound
+    models can be introspected in some useful way without crashing--this works
+    as sort of a test of its somewhat complicated internal state management.
+
+    This test does not check any of the results of
+    `~inspect.classify_class_attrs`, though it might be useful to at some
+    point.
+    """
+
+    inspect.classify_class_attrs(Gaussian1D + Gaussian1D)
+
+
+def test_invalid_operands():
+    """
+    Test that certain operators do not work with models whose inputs/outputs do
+    not match up correctly.
+    """
+
+    with pytest.raises(ModelDefinitionError):
+        Rotation2D | Gaussian1D
+
+    with pytest.raises(ModelDefinitionError):
+        Rotation2D(90) | Gaussian1D(1, 0, 0.1)
+
+    with pytest.raises(ModelDefinitionError):
+        Rotation2D + Gaussian1D
+
+    with pytest.raises(ModelDefinitionError):
+        Rotation2D(90) + Gaussian1D(1, 0, 0.1)
diff --git a/astropy/modeling/tests/test_constraints.py b/astropy/modeling/tests/test_constraints.py
index ac89923..52b74a4 100644
--- a/astropy/modeling/tests/test_constraints.py
+++ b/astropy/modeling/tests/test_constraints.py
@@ -37,7 +37,8 @@ class TestNonLinearConstraints(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_fixed_par(self):
-        g1 = models.Gaussian1D(10, mean=14.9, stddev=.3, fixed={'amplitude': True})
+        g1 = models.Gaussian1D(10, mean=14.9, stddev=.3,
+                               fixed={'amplitude': True})
         fitter = fitting.LevMarLSQFitter()
         model = fitter(g1, self.x, self.ny1)
         assert model.amplitude.value == 10
@@ -51,7 +52,8 @@ class TestNonLinearConstraints(object):
         g1 = models.Gaussian1D(10, mean=14.9, stddev=.3, tied={'mean': tied})
         fitter = fitting.LevMarLSQFitter()
         model = fitter(g1, self.x, self.ny1)
-        utils.assert_allclose(model.mean.value, 50 * model.stddev, rtol=10 ** (-5))
+        utils.assert_allclose(model.mean.value, 50 * model.stddev,
+                              rtol=10 ** (-5))
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_joint_fitter(self):
@@ -70,10 +72,15 @@ class TestNonLinearConstraints(object):
         p2 = [13, .4]
         A = 9.8
         p = np.r_[A, p1, p2]
-        compmodel = lambda A, p, x: A * np.exp(-0.5 / p[1] ** 2 * (x - p[0]) ** 2)
-        errf = lambda p, x1, y1, x2, y2: np.ravel(
-            np.r_[compmodel(p[0], p[1:3], x1) - y1,
-                  compmodel(p[0], p[3:], x2) - y2])
+
+        def compmodel(A, p, x):
+            return A * np.exp(-0.5 / p[1] ** 2 * (x - p[0]) ** 2)
+
+        def errf(p, x1, y1, x2, y2):
+            return np.ravel(
+                np.r_[compmodel(p[0], p[1:3], x1) - y1,
+                      compmodel(p[0], p[3:], x2) - y2])
+
         fitparams, _ = optimize.leastsq(errf, p, args=(x, ny1, x, ny2))
         utils.assert_allclose(jf.fitparams, fitparams, rtol=10 ** (-5))
         utils.assert_allclose(g1.amplitude.value, g2.amplitude.value)
@@ -81,8 +88,13 @@ class TestNonLinearConstraints(object):
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_no_constraints(self):
         g1 = models.Gaussian1D(9.9, 14.5, stddev=.3)
-        func = lambda p, x: p[0] * np.exp(-0.5 / p[2] ** 2 * (x - p[1]) ** 2)
-        errf = lambda p, x, y: func(p, x) - y
+
+        def func(p, x):
+            return p[0] * np.exp(-0.5 / p[2] ** 2 * (x - p[1]) ** 2)
+
+        def errf(p, x, y):
+            return func(p, x) - y
+
         p0 = [9.9, 14.5, 0.3]
         y = g1(self.x)
         n = np.random.randn(100)
@@ -119,7 +131,8 @@ class TestBounds(object):
         guess_slope = 1.1
         guess_intercept = 0.0
         bounds = {'slope': (-1.5, 5.0), 'intercept': (-1.0, 1.0)}
-        line_model = models.Linear1D(guess_slope, guess_intercept, bounds=bounds)
+        line_model = models.Linear1D(guess_slope, guess_intercept,
+                                     bounds=bounds)
         fitter = fitting.LevMarLSQFitter()
         model = fitter(line_model, self.x, self.y)
         slope = model.slope.value
@@ -133,10 +146,13 @@ class TestBounds(object):
         guess_slope = 1.1
         guess_intercept = 0.0
         bounds = {'slope': (-1.5, 5.0), 'intercept': (-1.0, 1.0)}
-        line_model = models.Linear1D(guess_slope, guess_intercept, bounds=bounds)
+        line_model = models.Linear1D(guess_slope, guess_intercept,
+                                     bounds=bounds)
         fitter = fitting.SLSQPLSQFitter()
+
         with ignore_non_integer_warning():
             model = fitter(line_model, self.x, self.y)
+
         slope = model.slope.value
         intercept = model.intercept.value
         assert slope + 10 ** -5 >= bounds['slope'][0]
@@ -224,7 +240,8 @@ def test_set_fixed_1():
 
 
 def test_set_fixed_2():
-    gauss = models.Gaussian1D(amplitude=20, mean=2, stddev=1, fixed={'mean': True})
+    gauss = models.Gaussian1D(amplitude=20, mean=2, stddev=1,
+                              fixed={'mean': True})
     assert gauss.mean.fixed is True
 
 
@@ -235,7 +252,7 @@ def test_set_tied_1():
     gauss = models.Gaussian1D(amplitude=20, mean=2, stddev=1)
     gauss.amplitude.tied = tie_amplitude
     assert gauss.amplitude.tied is not False
-    assert type(gauss.tied['amplitude']) == types.FunctionType
+    assert isinstance(gauss.tied['amplitude'], types.FunctionType)
 
 
 def test_set_tied_2():
@@ -248,7 +265,8 @@ def test_set_tied_2():
 
 
 def test_unset_fixed():
-    gauss = models.Gaussian1D(amplitude=20, mean=2, stddev=1, fixed={'mean': True})
+    gauss = models.Gaussian1D(amplitude=20, mean=2, stddev=1,
+                              fixed={'mean': True})
     gauss.mean.fixed = False
     assert gauss.fixed == {'amplitude': False, 'mean': False, 'stddev': False}
 
@@ -301,7 +319,7 @@ def test_default_constraints():
         b = Parameter(default=0, min=0, fixed=True)
 
         @staticmethod
-        def eval(x, a, b):
+        def evaluate(x, a, b):
             return x * a + b
 
     assert MyModel.a.default == 1
@@ -378,7 +396,7 @@ def test_fit_with_bound_constraints_estimate_jacobian():
         b = Parameter(default=2)
 
         @staticmethod
-        def eval(x, a, b):
+        def evaluate(x, a, b):
             return a * x + b
 
     m_real = MyModel(a=1.5, b=-3)
diff --git a/astropy/modeling/tests/test_core.py b/astropy/modeling/tests/test_core.py
index 8db4a0a..0e1acdc 100644
--- a/astropy/modeling/tests/test_core.py
+++ b/astropy/modeling/tests/test_core.py
@@ -4,16 +4,18 @@ from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
 import collections
+import inspect
+
 import pytest
 import numpy as np
 from numpy.testing.utils import assert_allclose
-from ..core import Model, InputParameterError
+from ..core import Model, InputParameterError, custom_model
 from ..parameters import Parameter
 from .. import models
 
 
 class NonFittableModel(Model):
-    """An example class directly subclassing Model for testing"""
+    """An example class directly subclassing Model for testing."""
 
     a = Parameter()
 
@@ -21,18 +23,18 @@ class NonFittableModel(Model):
         super(NonFittableModel, self).__init__(
             a, model_set_axis=model_set_axis)
 
-    def __call__(self):
+    @staticmethod
+    def evaluate():
         pass
 
 
-def test_Model():
-    """Some silly tests just to have all lines in the Model code covered by unit tests"""
+def test_Model_instance_repr_and_str():
     m = NonFittableModel(42)
     assert repr(m) == "<NonFittableModel(a=42.0)>"
     assert (str(m) ==
         "Model: NonFittableModel\n"
-        "Inputs: 1\n"
-        "Outputs: 1\n"
+        "Inputs: ()\n"
+        "Outputs: ()\n"
         "Model set size: 1\n"
         "Parameters:\n"
         "     a  \n"
@@ -65,5 +67,106 @@ def test_ParametericModel():
         models.Gaussian1D(1, 2, 3, wrong=4)
 
 
-def test_a():
-    pass
+def test_custom_model_signature():
+    """
+    Tests that the signatures for the __init__ and __call__
+    methods of custom models are useful.
+    """
+
+    @custom_model
+    def model_a(x):
+        return x
+
+    assert model_a.param_names == ()
+    assert model_a.n_inputs == 1
+    argspec = inspect.getargspec(model_a.__init__)
+    assert argspec.args == ['self']
+    argspec = inspect.getargspec(model_a.__call__)
+    assert argspec.args == ['self', 'x', 'model_set_axis']
+
+    @custom_model
+    def model_b(x, a=1, b=2):
+        return x + a + b
+
+    assert model_b.param_names == ('a', 'b')
+    assert model_b.n_inputs == 1
+    argspec = inspect.getargspec(model_b.__init__)
+    assert argspec.args == ['self', 'a', 'b']
+    assert argspec.defaults == (1, 2)
+    argspec = inspect.getargspec(model_b.__call__)
+    assert argspec.args == ['self', 'x', 'model_set_axis']
+
+    @custom_model
+    def model_c(x, y, a=1, b=2):
+        return x + y + a + b
+
+    assert model_c.param_names == ('a', 'b')
+    assert model_c.n_inputs == 2
+    argspec = inspect.getargspec(model_c.__init__)
+    assert argspec.args == ['self', 'a', 'b']
+    assert argspec.defaults == (1, 2)
+    argspec = inspect.getargspec(model_c.__call__)
+    assert argspec.args == ['self', 'x', 'y', 'model_set_axis']
+
+
+def test_custom_model_subclass():
+    """Test that custom models can be subclassed."""
+
+    @custom_model
+    def model_a(x, a=1):
+        return x * a
+
+    class model_b(model_a):
+        # Override the evaluate from model_a
+        @classmethod
+        def evaluate(cls, x, a):
+            return -super(model_b, cls).evaluate(x, a)
+
+    b = model_b()
+    assert b.param_names == ('a',)
+    assert b.a == 1
+    assert b(1) == -1
+
+    argspec = inspect.getargspec(model_b.__init__)
+    assert argspec.args == ['self', 'a']
+    argspec = inspect.getargspec(model_b.__call__)
+    assert argspec.args == ['self', 'x', 'model_set_axis']
+
+
+def test_custom_model_parametrized_decorator():
+    """Tests using custom_model as a decorator with parameters."""
+
+    def cosine(x, amplitude=1):
+        return [amplitude * np.cos(x)]
+
+    @custom_model(fit_deriv=cosine)
+    def sine(x, amplitude=1):
+        return amplitude * np.sin(x)
+
+    assert issubclass(sine, Model)
+    s = sine(2)
+    assert_allclose(s(np.pi / 2), 2)
+    assert_allclose(s.fit_deriv(0, 2), 2)
+
+
+def test_custom_inverse():
+    """Test setting a custom inverse on a model."""
+
+    p = models.Polynomial1D(1, c0=-2, c1=3)
+    # A trivial inverse for a trivial polynomial
+    inv = models.Polynomial1D(1, c0=(2./3.), c1=(1./3.))
+
+    with pytest.raises(NotImplementedError):
+        p.inverse
+
+    p.inverse = inv
+
+    x = np.arange(100)
+
+    assert_allclose(x, p(p.inverse(x)))
+    assert_allclose(x, p.inverse(p(x)))
+
+    p.inverse = None
+
+    with pytest.raises(NotImplementedError):
+        p.inverse
diff --git a/astropy/modeling/tests/test_fitters.py b/astropy/modeling/tests/test_fitters.py
index 633ede6..309f456 100644
--- a/astropy/modeling/tests/test_fitters.py
+++ b/astropy/modeling/tests/test_fitters.py
@@ -165,6 +165,7 @@ class TestJointFitter(object):
 class TestLinearLSQFitter(object):
     def test_chebyshev1D(self):
         """Tests fitting a 1D Chebyshev polynomial to some real world data."""
+
         test_file = get_pkg_data_filename(os.path.join('data',
                                                        'idcompspec.fits'))
         with open(test_file) as f:
@@ -219,12 +220,9 @@ class TestLinearLSQFitter(object):
                         rtol=1e-1)
 
 
-
 @pytest.mark.skipif('not HAS_SCIPY')
 class TestNonLinearFitters(object):
-    """
-    Tests non-linear least squares fitting and the SLSQP algorithm
-    """
+    """Tests non-linear least squares fitting and the SLSQP algorithm."""
 
     def setup_class(self):
         self.initial_values = [100, 5, 1]
@@ -335,12 +333,13 @@ class TestNonLinearFitters(object):
             b = Parameter()
 
             @staticmethod
-            def eval(x, y, a, b):
+            def evaluate(x, y, a, b):
                 return (a - x) ** 2 + b * (y - x ** 2) ** 2
 
         x = y = np.linspace(-3.0, 3.0, 100)
         with NumpyRNGContext(_RANDOM_SEED):
-            z = Rosenbrock.eval(x, y, 1.0, 100.0) + np.random.normal(0., 0.1)
+            z = Rosenbrock.evaluate(x, y, 1.0, 100.0)
+            z += np.random.normal(0., 0.1, size=z.shape)
 
         fitter = SimplexLSQFitter()
         r_i = Rosenbrock(1, 100)
diff --git a/astropy/modeling/tests/test_functional_models.py b/astropy/modeling/tests/test_functional_models.py
index 7fa79cc..3fdf4e4 100644
--- a/astropy/modeling/tests/test_functional_models.py
+++ b/astropy/modeling/tests/test_functional_models.py
@@ -16,9 +16,8 @@ except ImportError:
 
 
 def test_Trapezoid1D():
-    """Regression test for
-    https://github.com/astropy/astropy/issues/1721
-    """
+    """Regression test for https://github.com/astropy/astropy/issues/1721"""
+
     model = models.Trapezoid1D(amplitude=4.2, x_0=2.0, width=1.0, slope=3)
     xx = np.linspace(0, 4, 8)
     yy = model(xx)
@@ -40,6 +39,7 @@ def test_Gaussian2D():
     Test rotated elliptical Gaussian2D model.
     https://github.com/astropy/astropy/pull/2038
     """
+
     model = models.Gaussian2D(4.2, 1.7, 3.1, x_stddev=5.1, y_stddev=3.3,
                               theta=np.pi/6.)
     y, x = np.mgrid[0:5, 0:5]
@@ -57,6 +57,7 @@ def test_Gaussian2DCovariance():
     Test rotated elliptical Gaussian2D model when cov_matrix is input.
     https://github.com/astropy/astropy/pull/2199
     """
+
     cov_matrix = [[49., -16.], [-16., 9.]]
     model = models.Gaussian2D(17., 2.0, 2.5, cov_matrix=cov_matrix)
     y, x = np.mgrid[0:5, 0:5]
@@ -88,13 +89,13 @@ def test_Gaussian2DRotation():
 
 def test_Redshift():
     """Like ``test_ScaleModel()``."""
+
     # Scale by a scalar
     m = models.Redshift(0.4)
     assert m(0) == 0
     assert_array_equal(m([1, 2]), [1.4, 2.8])
 
-    inv_m = m.inverse()
-    assert_allclose(inv_m(m([1, 2])), [1, 2])
+    assert_allclose(m.inverse(m([1, 2])), [1, 2])
 
     # Scale by a list
     m = models.Redshift([-0.5, 0, 0.5], model_set_axis=0)
@@ -102,6 +103,36 @@ def test_Redshift():
     assert_array_equal(m([1, 2], model_set_axis=False),
                        [[0.5, 1], [1, 2], [1.5, 3]])
 
-    inv_m = m.inverse()
-    assert_allclose(inv_m(m([1, 2], model_set_axis=False)),
+    assert_allclose(m.inverse(m([1, 2], model_set_axis=False)),
                     [[1, 2], [1, 2], [1, 2]])
+
+
+def test_Ellipse2D():
+    """Test Ellipse2D model."""
+    amplitude = 7.5
+    x0, y0 = 15, 15
+    theta = Angle(45, 'deg')
+    em = models.Ellipse2D(amplitude, x0, y0, 7, 3, theta.radian)
+    y, x = np.mgrid[0:30, 0:30]
+    e = em(x, y)
+    assert np.all(e[e > 0] == amplitude)
+    assert e[y0, x0] == amplitude
+
+    rotation = models.Rotation2D(angle=theta.degree)
+    point1 = [2, 0]      # Rotation2D center is (0, 0)
+    point2 = rotation(*point1)
+    point1 = np.array(point1) + [x0, y0]
+    point2 = np.array(point2) + [x0, y0]
+    e1 = models.Ellipse2D(amplitude, x0, y0, 7, 3, theta=0.)
+    e2 = models.Ellipse2D(amplitude, x0, y0, 7, 3, theta=theta.radian)
+    assert e1(*point1) == e2(*point2)
+
+
+def test_Scale_inverse():
+    m = models.Scale(1.2345)
+    assert_allclose(m.inverse(m(6.789)), 6.789)
+
+
+def test_Shift_inverse():
+    m = models.Shift(1.2345)
+    assert_allclose(m.inverse(m(6.789)), 6.789)
diff --git a/astropy/modeling/tests/test_input.py b/astropy/modeling/tests/test_input.py
index 49f155f..3f2e967 100644
--- a/astropy/modeling/tests/test_input.py
+++ b/astropy/modeling/tests/test_input.py
@@ -12,11 +12,10 @@ from numpy.testing.utils import assert_allclose
 
 from .. import models
 from .. import fitting
-from ..core import Model, FittableModel, Fittable1DModel, format_input
+from ..core import Model, FittableModel, Fittable1DModel
 from ..parameters import Parameter
 from ...tests.helper import pytest
 
-
 try:
     from scipy import optimize  # pylint: disable=W0611
     HAS_SCIPY = True
@@ -69,18 +68,14 @@ class TestInputType(object):
 
 
 class TestFitting(object):
-    """
-    Test various input options to fitting routines
-    """
+    """Test various input options to fitting routines."""
 
     def setup_class(self):
         self.x1 = np.arange(10)
         self.y, self.x = np.mgrid[:10, :10]
 
     def test_linear_fitter_1set(self):
-        """
-        1 set 1D x, 1pset
-        """
+        """1 set 1D x, 1pset"""
 
         expected = np.array([0, 1, 1, 1])
         p1 = models.Polynomial1D(3)
@@ -91,9 +86,7 @@ class TestFitting(object):
         assert_allclose(model.parameters, expected, atol=10 ** (-7))
 
     def test_linear_fitter_Nset(self):
-        """
-        1 set 1D x, 2 sets 1D y, 2 param_sets
-        """
+        """1 set 1D x, 2 sets 1D y, 2 param_sets"""
 
         expected = np.array([[0, 0], [1, 1], [2, 2], [3, 3]])
         p1 = models.Polynomial1D(3, n_models=2)
@@ -108,9 +101,7 @@ class TestFitting(object):
         assert_allclose(model.param_sets, expected, atol=10 ** (-7))
 
     def test_linear_fitter_1dcheb(self):
-        """
-        1 pset, 1 set 1D x, 1 set 1D y, Chebyshev 1D polynomial
-        """
+        """1 pset, 1 set 1D x, 1 set 1D y, Chebyshev 1D polynomial"""
 
         expected = np.array(
             [[2817.2499999999995,
@@ -165,9 +156,7 @@ class TestFitting(object):
             model = pfit(p1, self.x1, y1)
 
     def test_wrong_pset(self):
-        """
-        A case of 1 set of x and multiple sets of y and parameters
-        """
+        """A case of 1 set of x and multiple sets of y and parameters."""
 
         expected = np.array([[1., 0],
                              [1, 1],
@@ -187,9 +176,8 @@ class TestFitting(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_nonlinear_lsqt_1set_1d(self):
-        """
-        1 set 1D x, 1 set 1D y, 1 pset NonLinearFitter
-        """
+        """1 set 1D x, 1 set 1D y, 1 pset NonLinearFitter"""
+
         g1 = models.Gaussian1D(10, mean=3, stddev=.2)
         y1 = g1(self.x1)
         gfit = fitting.LevMarLSQFitter()
@@ -198,9 +186,8 @@ class TestFitting(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_nonlinear_lsqt_Nset_1d(self):
-        """
-        1 set 1D x, 1 set 1D y, 2 param_sets, NonLinearFitter
-        """
+        """1 set 1D x, 1 set 1D y, 2 param_sets, NonLinearFitter"""
+
         with pytest.raises(ValueError):
             g1 = models.Gaussian1D([10.2, 10], mean=[3, 3.2], stddev=[.23, .2],
                                    n_models=2)
@@ -210,9 +197,8 @@ class TestFitting(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_nonlinear_lsqt_1set_2d(self):
-        """
-        1 set 2d x, 1set 2D y, 1 pset, NonLinearFitter
-        """
+        """1 set 2d x, 1set 2D y, 1 pset, NonLinearFitter"""
+
         g2 = models.Gaussian2D(10, x_mean=3, y_mean=4, x_stddev=.3,
                                y_stddev=.2, theta=0)
         z = g2(self.x, self.y)
@@ -222,9 +208,8 @@ class TestFitting(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_nonlinear_lsqt_Nset_2d(self):
-        """
-         1 set 2d x, 1set 2D y, 2 param_sets, NonLinearFitter
-        """
+        """1 set 2d x, 1set 2D y, 2 param_sets, NonLinearFitter"""
+
         with pytest.raises(ValueError):
             g2 = models.Gaussian2D([10, 10], [3, 3], [4, 4], x_stddev=[.3, .3],
                                    y_stddev=[.2, .2], theta=[0, 0], n_models=2)
@@ -265,18 +250,14 @@ class TestEvaluation(object):
         assert_allclose(y1[:, 0], y1[:, 1], atol=10 ** (-12))
 
     def test_p1_1set_1pset(self):
-        """
-        1 data set, 1 pset, Polynomial1D
-        """
+        """1 data set, 1 pset, Polynomial1D"""
 
         p1 = models.Polynomial1D(4)
         y1 = p1(self.x1)
         assert y1.shape == (20,)
 
     def test_p1_nset_npset(self):
-        """
-        N data sets, N param_sets, Polynomial1D
-        """
+        """N data sets, N param_sets, Polynomial1D"""
 
         p1 = models.Polynomial1D(4, n_models=2)
         y1 = p1(np.array([self.x1, self.x1]).T, model_set_axis=-1)
@@ -284,17 +265,14 @@ class TestEvaluation(object):
         assert_allclose(y1[0, :], y1[1, :], atol=10 ** (-12))
 
     def test_p2_1set_1pset(self):
-        """
-        1 pset, 1 2D data set, Polynomial2D
-        """
+        """1 pset, 1 2D data set, Polynomial2D"""
+
         p2 = models.Polynomial2D(5)
         z = p2(self.x, self.y)
         assert z.shape == (10, 10)
 
     def test_p2_nset_npset(self):
-        """
-        N param_sets, N 2D data sets, Poly2d
-        """
+        """N param_sets, N 2D data sets, Poly2d"""
 
         p2 = models.Polynomial2D(5, n_models=2)
         xx = np.array([self.x, self.x])
@@ -332,7 +310,7 @@ class TestModel_1_1(Fittable1DModel):
     p2 = Parameter()
 
     @staticmethod
-    def eval(x, p1, p2):
+    def evaluate(x, p1, p2):
         return x + p1 + p2
 
 
@@ -647,37 +625,17 @@ class TestSingleInputSingleOutputTwoModel(object):
 
 
 class TestModel_1_2(FittableModel):
-    n_inputs = 1
-    n_outputs = 2
+    inputs = ('x',)
+    outputs = ('y', 'z')
 
     p1 = Parameter()
     p2 = Parameter()
     p3 = Parameter()
 
     @staticmethod
-    def eval(x, p1, p2, p3):
+    def evaluate(x, p1, p2, p3):
         return (x + p1 + p2, x + p1 + p2 + p3)
 
-    @format_input
-    def __call__(self, x, model_set_axis=None):
-        """
-        Transforms data using this model.
-
-        Parameters
-        ----------
-        x : array-like or numeric value
-            Input coordinate values.
-
-        model_set_axis : `int` or `False`, optional
-            For `Model` instances representing a multiple-model set, this picks
-            out which axis of the input array is used to map inputs to specific
-            models in the set.  If `False`, this indicates that the input array
-            has no such axis, and instead the same input should be broadcast to
-            all models in the set.
-        """
-
-        return self.eval(x, *self.param_sets)
-
 
 class TestSingleInputDoubleOutputSingleModel(object):
     """
@@ -864,17 +822,14 @@ class TestSingleInputDoubleOutputSingleModel(object):
 
 class TestInputFormatter(Model):
     """
-    A toy model to test format_input
+    A toy model to test input/output formatting.
     """
 
-    n_inputs = 2
-    n_outputs = 2
-
-    def __init__(self):
-        super(TestInputFormatter, self).__init__()
+    inputs = ('x', 'y')
+    outputs = ('x', 'y')
 
-    @format_input
-    def __call__(self, x, y):
+    @staticmethod
+    def evaluate(x, y):
         return x, y
 
 
@@ -895,4 +850,3 @@ def test_format_input_arrays_transposed():
     input = np.array([[1, 1]]).T, np.array([[2, 2]]).T
     result = model(*input)
     assert_allclose(result, input)
-
diff --git a/astropy/modeling/tests/test_mappings.py b/astropy/modeling/tests/test_mappings.py
new file mode 100644
index 0000000..5d70cee
--- /dev/null
+++ b/astropy/modeling/tests/test_mappings.py
@@ -0,0 +1,64 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+from ...tests.helper import pytest
+from ..models import Shift, Rotation2D, Identity, Mapping
+import numpy as np
+from numpy.testing.utils import (assert_allclose, assert_array_equal)
+
+
+def test_swap_axes():
+    x = np.zeros((2, 3))
+    y = np.ones((2, 3))
+
+    mapping = Mapping((1, 0))
+    assert(mapping(1, 2) == (2.0, 1.0))
+    assert(mapping.inverse(2, 1) == (1, 2))
+    assert_array_equal(mapping(x, y), (y, x))
+    assert_array_equal(mapping.inverse(y, x), (x, y))
+
+
+def test_duplicate_axes():
+    mapping = Mapping((0, 1, 0, 1))
+    assert(mapping(1, 2) == (1.0, 2., 1., 2))
+    assert(mapping.inverse(1, 2, 1, 2) == (1, 2))
+    assert(mapping.inverse.n_inputs == 4)
+    assert(mapping.inverse.n_outputs == 2)
+
+
+def test_drop_axes_1():
+    mapping = Mapping((0,), n_inputs=2)
+    assert(mapping(1, 2) == (1.))
+
+def test_drop_axes_2():
+    mapping = Mapping((1, ))
+    assert(mapping(1, 2) == (2.))
+    with pytest.raises(NotImplementedError):
+        mapping.inverse
+
+
+def test_drop_axes_3():
+    mapping = Mapping((1,), n_inputs=2)
+    assert(mapping.n_inputs == 2)
+    rotation = Rotation2D(60)
+    model = rotation | mapping
+    assert_allclose(model(1, 2), 1.86602540378)
+
+
+def test_identity():
+    x = np.zeros((2, 3))
+    y = np.ones((2, 3))
+
+    ident1 = Identity(1)
+    shift = Shift(1)
+    rotation = Rotation2D(angle=60)
+    model = ident1 & shift | rotation
+    assert_allclose(model(1, 2), (-2.098076211353316, 2.3660254037844393))
+    res_x, res_y = model(x, y)
+    assert_allclose((res_x, res_y),
+                       (np.array([[-1.73205081, -1.73205081, -1.73205081],
+                                  [-1.73205081, -1.73205081, -1.73205081]]),
+                        np.array([[ 1.,  1.,  1.],
+                                  [ 1.,  1.,  1.]])))
+    assert_allclose(model.inverse(res_x, res_y), (x, y))
diff --git a/astropy/modeling/tests/test_models.py b/astropy/modeling/tests/test_models.py
index 00be815..043ac6f 100644
--- a/astropy/modeling/tests/test_models.py
+++ b/astropy/modeling/tests/test_models.py
@@ -20,14 +20,13 @@ import numpy as np
 from numpy.testing import utils
 
 from .example_models import models_1D, models_2D
-from .. import fitting, models
-from ..core import (LabeledInput, SerialCompositeModel, SummedCompositeModel,
-                    Fittable1DModel, Fittable2DModel)
-from ..polynomial import PolynomialModel
+from .. import (fitting, models, LabeledInput, SerialCompositeModel,
+                SummedCompositeModel)
+from ..core import FittableModel
+from ..polynomial import PolynomialBase
 from ...tests.helper import pytest
 
 from ...extern import six
-from ...extern.six.moves import copyreg as copy_reg
 
 try:
     from scipy import optimize  # pylint: disable=W0611
@@ -96,16 +95,13 @@ class TestSerialComposite(object):
         rot = models.Rotation2D(angle=-60)
         model = SerialCompositeModel([rot, rot])
         xx, yy = model(self.x, self.y)
-        inverse_model = model.inverse()
-        x1, y1 = inverse_model(xx, yy)
+        x1, y1 = model.inverse(xx, yy)
         utils.assert_almost_equal(x1, self.x)
         utils.assert_almost_equal(y1, self.y)
 
 
 class TestSummedComposite(object):
-    """
-    Test composite models evaluation in parallel
-    """
+    """Test legacy composite models evaluation."""
 
     def setup_class(self):
         self.x = np.linspace(1, 10, 100)
@@ -126,7 +122,8 @@ class TestSummedComposite(object):
 
     def test_labeledinput(self):
         labeled_input = LabeledInput([self.x, self.y], ['x', 'y'])
-        model = SummedCompositeModel([self.p1, self.p11], inmap=['x'], outmap=['x'])
+        model = SummedCompositeModel([self.p1, self.p11], inmap=['x'],
+                                     outmap=['x'])
         result = model(labeled_input)
         delta11 = self.p11(self.x)
         delta1 = self.p1(self.x)
@@ -141,11 +138,6 @@ class TestSummedComposite(object):
 
 
 def test_pickle():
-    def reduce_method(m):
-        return (getattr, (m.__self__, m.__func__.__name__))
-
-    copy_reg.pickle(types.MethodType, reduce_method)
-
     p1 = models.Polynomial1D(3)
     p11 = models.Polynomial1D(4)
     g1 = models.Gaussian1D(10.3, 5.4, 1.2)
@@ -180,7 +172,7 @@ def test_custom_model(amplitude=4, frequency=1):
     x = np.linspace(0, 4, 50)
     sin_model = SineModel()
 
-    y = sin_model.eval(x, 5., 2.)
+    y = sin_model.evaluate(x, 5., 2.)
     y_prime = sin_model.fit_deriv(x, 5., 2.)
 
     np.random.seed(0)
@@ -194,9 +186,8 @@ def test_custom_model(amplitude=4, frequency=1):
 def test_custom_model_init():
     @models.custom_model_1d
     def SineModel(x, amplitude=4, frequency=1):
-        """
-        Model function
-        """
+        """Model function"""
+
         return amplitude * np.sin(2 * np.pi * frequency * x)
 
     sin_model = SineModel(amplitude=2., frequency=0.5)
@@ -207,9 +198,8 @@ def test_custom_model_init():
 def test_custom_model_defaults():
     @models.custom_model_1d
     def SineModel(x, amplitude=4, frequency=1):
-        """
-        Model function
-        """
+        """Model function"""
+
         return amplitude * np.sin(2 * np.pi * frequency * x)
 
     sin_model = SineModel()
@@ -224,13 +214,14 @@ class Fittable2DModelTester(object):
     """
     Test class for all two dimensional parametric models.
 
-    Test values have to be defined in example_models.py. It currently test the model
-    with different input types, evaluates the model at different positions and
-    assures that it gives the correct values. And tests if the  model works with
-    the NonLinearFitter.
+    Test values have to be defined in example_models.py. It currently test the
+    model with different input types, evaluates the model at different
+    positions and assures that it gives the correct values. And tests if the
+    model works with non-linear fitters.
 
     This can be used as a base class for user defined model testing.
     """
+
     def setup_class(self):
         self.N = 100
         self.M = 100
@@ -243,18 +234,16 @@ class Fittable2DModelTester(object):
         self.y2, self.x2 = np.mgrid[:10, :8]
 
     def test_input2D(self, model_class, test_parameters):
-        """
-        Test model with different input types.
-        """
+        """Test model with different input types."""
+
         model = create_model(model_class, test_parameters)
         model(self.x, self.y)
         model(self.x1, self.y1)
         model(self.x2, self.y2)
 
     def test_eval2D(self, model_class, test_parameters):
-        """
-        Test model values add certain given points
-        """
+        """Test model values add certain given points"""
+
         model = create_model(model_class, test_parameters)
         x = test_parameters['x_values']
         y = test_parameters['y_values']
@@ -263,9 +252,8 @@ class Fittable2DModelTester(object):
 
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_fitter2D(self, model_class, test_parameters):
-        """
-        Test if the parametric model works with the fitter.
-        """
+        """Test if the parametric model works with the fitter."""
+
         x_lim = test_parameters['x_lim']
         y_lim = test_parameters['y_lim']
 
@@ -304,14 +292,15 @@ class Fittable2DModelTester(object):
     def test_deriv_2D(self, model_class, test_parameters):
         """
         Test the derivative of a model by fitting with an estimated and
-        analytical derivative
+        analytical derivative.
         """
+
         x_lim = test_parameters['x_lim']
         y_lim = test_parameters['y_lim']
 
         if model_class.fit_deriv is None:
             pytest.skip("Derivative function is not defined for model.")
-        if issubclass(model_class, (models.PolynomialModel, models.OrthoPolynomialBase)):
+        if issubclass(model_class, PolynomialBase):
             pytest.skip("Skip testing derivative of polynomials.")
 
         if "log_fit" in test_parameters:
@@ -325,26 +314,36 @@ class Fittable2DModelTester(object):
 
         try:
             model_with_deriv = create_model(model_class, test_parameters,
-                                    use_constraints=False, parameter_key='deriv_initial')
+                                            use_constraints=False,
+                                            parameter_key='deriv_initial')
             model_no_deriv = create_model(model_class, test_parameters,
-                                    use_constraints=False, parameter_key='deriv_initial')
-            model = create_model(model_class, test_parameters, use_constraints=False,
+                                          use_constraints=False,
+                                          parameter_key='deriv_initial')
+            model = create_model(model_class, test_parameters,
+                                 use_constraints=False,
                                  parameter_key='deriv_initial')
         except KeyError:
-            model_with_deriv = create_model(model_class, test_parameters, use_constraints=False)
-            model_no_deriv = create_model(model_class, test_parameters, use_constraints=False)
-            model = create_model(model_class, test_parameters, use_constraints=False)
+            model_with_deriv = create_model(model_class, test_parameters,
+                                            use_constraints=False)
+            model_no_deriv = create_model(model_class, test_parameters,
+                                          use_constraints=False)
+            model = create_model(model_class, test_parameters,
+                                 use_constraints=False)
 
         # add 10% noise to the amplitude
         rsn = np.random.RandomState(1234567890)
-        n = 0.1 * test_parameters['parameters'][0] * (rsn.rand(self.M, self.N) - 0.5)
+        amplitude = test_parameters['parameters'][0]
+        n = 0.1 * amplitude * (rsn.rand(self.M, self.N) - 0.5)
 
         data = model(xv, yv) + n
         fitter_with_deriv = fitting.LevMarLSQFitter()
-        new_model_with_deriv = fitter_with_deriv(model_with_deriv, xv, yv, data)
+        new_model_with_deriv = fitter_with_deriv(model_with_deriv, xv, yv,
+                                                 data)
         fitter_no_deriv = fitting.LevMarLSQFitter()
-        new_model_no_deriv = fitter_no_deriv(model_no_deriv, xv, yv, data, estimate_jacobian=True)
-        utils.assert_allclose(new_model_with_deriv.parameters, new_model_no_deriv.parameters,
+        new_model_no_deriv = fitter_no_deriv(model_no_deriv, xv, yv, data,
+                                             estimate_jacobian=True)
+        utils.assert_allclose(new_model_with_deriv.parameters,
+                              new_model_no_deriv.parameters,
                               rtol=0.1)
 
 
@@ -352,10 +351,10 @@ class Fittable1DModelTester(object):
     """
     Test class for all one dimensional parametric models.
 
-    Test values have to be defined in example_models.py. It currently test the model
-    with different input types, evaluates the model at different positions and
-    assures that it gives the correct values. And tests if the  model works with
-    the NonLinearFitter.
+    Test values have to be defined in example_models.py. It currently test the
+    model with different input types, evaluates the model at different
+    positions and assures that it gives the correct values. And tests if the
+    model works with non-linear fitters.
 
     This can be used as a base class for user defined model testing.
     """
@@ -372,20 +371,13 @@ class Fittable1DModelTester(object):
         self.y2, self.x2 = np.mgrid[:10, :8]
 
     def test_input1D(self, model_class, test_parameters):
-        """
-        Test model with different input types.
-        """
+        """Test model with different input types."""
+
         model = create_model(model_class, test_parameters)
         model(self.x)
         model(self.x1)
         model(self.x2)
 
-    def test_dict(self, model_class, test_parameters):
-        """
-        Test type of test_parameters and model_class
-        """
-        assert type(test_parameters) == dict
-
     def test_eval1D(self, model_class, test_parameters):
         """
         Test model values at certain given points
@@ -416,7 +408,8 @@ class Fittable1DModelTester(object):
         np.random.seed(0)
         # add 10% noise to the amplitude
         relative_noise_amplitude = 0.01
-        data = (1 + relative_noise_amplitude * np.random.randn(len(x))) * model(x)
+        data = ((1 + relative_noise_amplitude * np.random.randn(len(x))) *
+                model(x))
         fitter = fitting.LevMarLSQFitter()
         new_model = fitter(model, x, data)
 
@@ -432,13 +425,15 @@ class Fittable1DModelTester(object):
     @pytest.mark.skipif('not HAS_SCIPY')
     def test_deriv_1D(self, model_class, test_parameters):
         """
-        Test the derivative of a model by comparing results with an estimated derivative
+        Test the derivative of a model by comparing results with an estimated
+        derivative.
         """
+
         x_lim = test_parameters['x_lim']
 
         if model_class.fit_deriv is None:
             pytest.skip("Derivative function is not defined for model.")
-        if issubclass(model_class, (models.PolynomialModel, models.OrthoPolynomialBase)):
+        if issubclass(model_class, PolynomialBase):
             pytest.skip("Skip testing derivative of polynomials.")
 
         if "log_fit" in test_parameters:
@@ -448,8 +443,10 @@ class Fittable1DModelTester(object):
             x = np.linspace(x_lim[0], x_lim[1], self.N)
 
         parameters = test_parameters['parameters']
-        model_with_deriv = create_model(model_class, test_parameters, use_constraints=False)
-        model_no_deriv = create_model(model_class, test_parameters, use_constraints=False)
+        model_with_deriv = create_model(model_class, test_parameters,
+                                        use_constraints=False)
+        model_no_deriv = create_model(model_class, test_parameters,
+                                      use_constraints=False)
 
         # add 10% noise to the amplitude
         rsn = np.random.RandomState(1234567890)
@@ -459,33 +456,34 @@ class Fittable1DModelTester(object):
         fitter_with_deriv = fitting.LevMarLSQFitter()
         new_model_with_deriv = fitter_with_deriv(model_with_deriv, x, data)
         fitter_no_deriv = fitting.LevMarLSQFitter()
-        new_model_no_deriv = fitter_no_deriv(model_no_deriv, x, data, estimate_jacobian=True)
-        utils.assert_allclose(new_model_with_deriv.parameters, new_model_no_deriv.parameters, atol=0.1)
+        new_model_no_deriv = fitter_no_deriv(model_no_deriv, x, data,
+                                             estimate_jacobian=True)
+        utils.assert_allclose(new_model_with_deriv.parameters,
+                              new_model_no_deriv.parameters, atol=0.1)
 
 
-def create_model(model_class, test_parameters, use_constraints=True, parameter_key='parameters'):
-    """
-    Create instance of model class.
-    """
+def create_model(model_class, test_parameters, use_constraints=True,
+                 parameter_key='parameters'):
+    """Create instance of model class."""
 
     constraints = {}
-    if issubclass(model_class, Fittable1DModel) or issubclass(model_class, Fittable2DModel): 
+    if issubclass(model_class, PolynomialBase):
+        return model_class(**test_parameters[parameter_key])
+    elif issubclass(model_class, FittableModel):
         if "requires_scipy" in test_parameters and not HAS_SCIPY:
             pytest.skip("SciPy not found")
         if use_constraints:
             if 'constraints' in test_parameters:
                 constraints = test_parameters['constraints']
         return model_class(*test_parameters[parameter_key], **constraints)
-    elif issubclass(model_class, PolynomialModel):
-        return model_class(**test_parameters[parameter_key])
 
 
- at pytest.mark.parametrize(('model_class', 'test_parameters'), list(models_1D.items()))
+ at pytest.mark.parametrize(('model_class', 'test_parameters'), models_1D.items())
 class TestFittable1DModels(Fittable1DModelTester):
     pass
 
 
- at pytest.mark.parametrize(('model_class', 'test_parameters'), list(models_2D.items()))
+ at pytest.mark.parametrize(('model_class', 'test_parameters'), models_2D.items())
 class TestFittable2DModels(Fittable2DModelTester):
     pass
 
@@ -516,9 +514,6 @@ def test_ScaleModel():
                        [[ 42,  84], [ 43,  86]])
 
 
-def test_parametric_model_repr():
-    """Some unit tests that cover lines in core.py that are untested at the
-    moment"""
-
+def test_model_instance_repr():
     m = models.Gaussian1D(1, 2, 3)
     assert repr(m) == '<Gaussian1D(amplitude=1.0, mean=2.0, stddev=3.0)>'
diff --git a/astropy/modeling/tests/test_parameters.py b/astropy/modeling/tests/test_parameters.py
index bb9ca76..509c6f0 100644
--- a/astropy/modeling/tests/test_parameters.py
+++ b/astropy/modeling/tests/test_parameters.py
@@ -13,7 +13,7 @@ from numpy.testing import utils
 
 from . import irafutil
 from .. import models, fitting
-from ..core import Model, ModelDefinitionError
+from ..core import Model, FittableModel, ModelDefinitionError
 from ..parameters import Parameter, InputParameterError
 from ...utils.data import get_pkg_data_filename
 from ...tests.helper import pytest
@@ -30,18 +30,21 @@ class TestParModel(Model):
     def __init__(self, coeff, e, **kwargs):
         super(TestParModel, self).__init__(coeff=coeff, e=e, **kwargs)
 
-    def __call__(self):
+    @staticmethod
+    def evaluate(coeff, e):
         pass
 
 
-def test_parameter_properties():
-    """Test if getting / setting of Parameter properties works."""
+class MockModel(FittableModel):
+    alpha = Parameter(name='alpha', default=42)
+
+    @staticmethod
+    def evaluate(*args):
+        pass
 
-    class MockModel(Model):
-        alpha = Parameter(name='alpha', default=42)
 
-        def __call__(self):
-            pass
+def test_parameter_properties():
+    """Test if getting / setting of Parameter properties works."""
 
     m = MockModel()
     p = m.alpha
@@ -75,18 +78,11 @@ def test_parameter_properties():
 
 
 def test_parameter_operators():
-    """Test if the parameter arithmetic operators works,
-    i.e. whether parameters behave like numbers."""
-
-    class MockModel(Model):
-        alpha = Parameter(name='alpha', default=5)
-
-        def __call__(self):
-            pass
+    """Test if the parameter arithmetic operators work."""
 
     m = MockModel()
     par = m.alpha
-    num = 5.
+    num = 42.
     val = 3
 
     assert par - val == num - val
@@ -95,8 +91,8 @@ def test_parameter_operators():
     assert val / par == val / num
     assert par ** val == num ** val
     assert val ** par == val ** num
-    assert par < 6
-    assert par > 3
+    assert par < 45
+    assert par > 41
     assert par <= par
     assert par >= par
     assert par == par
@@ -105,7 +101,8 @@ def test_parameter_operators():
 
 
 def test_parameter_name_attribute_mismatch():
-    """It should not be possible to define Parameters on a model with different
+    """
+    It should not be possible to define Parameters on a model with different
     names from the attributes they are assigned to.
     """
 
@@ -132,9 +129,9 @@ class TestParameters(object):
         """
         Unit tests for parameters
 
-        Read an iraf database file created by onedspec.identify.
-        Use the information to create a 1D Chebyshev model and
-        perform the same fit.
+        Read an iraf database file created by onedspec.identify.  Use the
+        information to create a 1D Chebyshev model and perform the same fit.
+
         Create also a gausian model.
         """
         test_file = get_pkg_data_filename('data/idcompspec.fits')
@@ -155,29 +152,27 @@ class TestParameters(object):
     def test_set_slice(self):
         """
         Tests updating the parameters attribute with a slice.
+
         This is what fitters internally do.
         """
+
         self.model.parameters[:] = np.array([3, 4, 5, 6, 7])
         assert (self.model.parameters == [3., 4., 5., 6., 7.]).all()
 
     def test_set_parameters_as_list(self):
-        """
-        Tests updating parameters using a list.
-        """
+        """Tests updating parameters using a list."""
+
         self.model.parameters = [30, 40, 50, 60, 70]
         assert (self.model.parameters == [30., 40., 50., 60, 70]).all()
 
     def test_set_parameters_as_array(self):
-        """
-        Tests updating parameters using an array.
-        """
+        """Tests updating parameters using an array."""
+
         self.model.parameters = np.array([3, 4, 5, 6, 7])
         assert (self.model.parameters == [3., 4., 5., 6., 7.]).all()
 
     def test_set_as_tuple(self):
-        """
-        Tests updating parameters using a tuple.
-        """
+        """Tests updating parameters using a tuple."""
 
         self.model.parameters = (1, 2, 3, 4, 5)
         assert (self.model.parameters == [1, 2, 3, 4, 5]).all()
@@ -187,21 +182,20 @@ class TestParameters(object):
         Tests updating the parameters attribute when a model's
         parameter (in this case coeff) is updated.
         """
+
         self.model.parameters = [0, 0., 0., 0, 0]
         self.model.c0 = 7
         assert (self.model.parameters == [7, 0., 0., 0, 0]).all()
 
     def test_set_model_attr_num(self):
-        """
-        Update the parameter list when a model's parameter is updated.
-        """
+        """Update the parameter list when a model's parameter is updated."""
+
         self.gmodel.amplitude = 7
         assert (self.gmodel.parameters == [7, 3, 4]).all()
 
     def test_set_item(self):
-        """
-        Update the parameters using indexing.
-        """
+        """Update the parameters using indexing."""
+
         self.model.parameters = [1, 2, 3, 4, 5]
         self.model.parameters[0] = 10.
         assert (self.model.parameters == [10, 2, 3, 4, 5]).all()
@@ -212,22 +206,25 @@ class TestParameters(object):
         Tests raising an error when attempting to reset the parameters
         using a list of a different size.
         """
+
         with pytest.raises(InputParameterError):
             self.model.parameters = [1, 2, 3]
 
     def test_wrong_size2(self):
         """
-        Tests raising an exception when attemppting to update a model's
+        Tests raising an exception when attempting to update a model's
         parameter (in this case coeff) with a sequence of the wrong size.
         """
+
         with pytest.raises(InputParameterError):
             self.model.c0 = [1, 2, 3]
 
     def test_wrong_shape(self):
         """
-        Tests raising an exception when attemppting to update a model's
+        Tests raising an exception when attempting to update a model's
         parameter and the new value has the wrong shape.
         """
+
         with pytest.raises(InputParameterError):
             self.gmodel.amplitude = [1, 2]
 
@@ -237,6 +234,7 @@ class TestParameters(object):
 
         Uses an iraf example.
         """
+
         new_model = self.linear_fitter(self.model, self.x, self.y)
         print(self.y, self.x)
         utils.assert_allclose(new_model.parameters,
@@ -282,20 +280,22 @@ class TestParameters(object):
         utils.assert_equal(p2.parameters, [2, 3, 1, 2, 4, 5,
                                            1, 1, 2, 2, 5, 5])
 
-    def test_non_fittable_model_parameters1d(self):
+    def test_shift_model_parameters1d(self):
         sh1 = models.Shift(2)
-        sh1.offsets = 3
-        assert(sh1.offsets == 3)
+        sh1.offset = 3
+        assert sh1.offset == 3
+        assert sh1.offset.value == 3
 
-    def test_non_fittable_model_parametersnd(self):
+    def test_scale_model_parametersnd(self):
         sc1 = models.Scale([2, 2])
-        sc1.factors = [3, 3]
-        assert(sc1.factors == [3, 3])
+        sc1.factor = [3, 3]
+        assert sc1.factor == [3, 3]
+        utils.assert_array_equal(sc1.factor.value, [3, 3])
 
-    def test_non_fittable_model_parameters_wrong_shape(self):
+    def test_parameters_wrong_shape(self):
         sh1 = models.Shift(2)
         with pytest.raises(InputParameterError):
-            sh1.offsets = [3, 3]
+            sh1.offset = [3, 3]
 
 
 class TestMultipleParameterSets(object):
@@ -309,8 +309,7 @@ class TestMultipleParameterSets(object):
 
     def test_change_par(self):
         """
-        Test that a change to one parameter as a set propagates
-        to param_sets.
+        Test that a change to one parameter as a set propagates to param_sets.
         """
         self.gmodel.amplitude = [1, 10]
         utils.assert_almost_equal(
@@ -325,8 +324,8 @@ class TestMultipleParameterSets(object):
 
     def test_change_par2(self):
         """
-        Test that a change to one single parameter in a set propagates
-        to param_sets.
+        Test that a change to one single parameter in a set propagates to
+        param_sets.
         """
         self.gmodel.amplitude[0] = 11
         utils.assert_almost_equal(
@@ -570,8 +569,8 @@ class TestParameterInitialization(object):
 
     def test_array_parameter4(self):
         """
-        Test multiple parameter model with array-valued parameters of the
-        same size as the number of parameter sets.
+        Test multiple parameter model with array-valued parameters of the same
+        size as the number of parameter sets.
         """
 
         t4 = TestParModel([[1, 2], [3, 4]], [5, 6], model_set_axis=False)
@@ -599,8 +598,8 @@ def test_non_broadcasting_parameters():
         p2 = Parameter()
         p3 = Parameter()
 
-        def __call__(self):
-            pass
+        def evaluate(self, *args):
+            return
 
     # a broadcasts with both b and c, but b does not broadcast with c
     for args in itertools.permutations((a, b, c)):
diff --git a/astropy/modeling/tests/test_polynomial.py b/astropy/modeling/tests/test_polynomial.py
index d733c4e..a52c289 100644
--- a/astropy/modeling/tests/test_polynomial.py
+++ b/astropy/modeling/tests/test_polynomial.py
@@ -1,8 +1,6 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
-"""
-Tests for polynomial models.
-"""
+"""Tests for polynomial models."""
 
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
@@ -25,6 +23,7 @@ try:
 except ImportError:
     HAS_SCIPY = False
 
+
 linear1d = {
     Chebyshev1D: {'parameters': [3],
                   'kwargs': {'c0': 1.2, 'c1': 2, 'c2': 2.3, 'c3': 0.2,
@@ -36,7 +35,8 @@ linear1d = {
                    'kwargs': {'c0': 1.2, 'c1': 2, 'c2': 2.3, 'c3': 0.2}},
     Linear1D: {'parameters': [1.2, 23.1],
                'kwargs': {}}
-    }
+}
+
 
 linear2d = {
     Chebyshev2D: {'parameters': [1, 1],
@@ -47,14 +47,12 @@ linear2d = {
                             'x_domain': [0, 99], 'y_domain': [0, 82]}},
     Polynomial2D: {'parameters': [1],
                    'kwargs': {'c0_0': 1.2, 'c1_0': 2, 'c0_1': 2.3}},
-    }
+}
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
 class TestFitting(object):
-    """
-    Test linear fitter
-    """
+    """Test linear fitter with polynomial models."""
 
     def setup_class(self):
         self.N = 100
@@ -70,49 +68,56 @@ class TestFitting(object):
 
     @pytest.mark.parametrize(('model_class'), linear1d.keys())
     def test_linear_fitter_1D(self, model_class):
-        """ Test fitting with LinearLSQFitter"""
+        """Test fitting with LinearLSQFitter"""
+
         parameters = linear1d[model_class]['parameters']
         kwargs = linear1d[model_class]['kwargs']
         model = model_class(*parameters, **kwargs)
         y1 = model(self.x1)
         model_lin = self.linear_fitter(model, self.x1, y1 + self.n1)
-        utils.assert_allclose(model_lin.parameters, model.parameters, atol=0.2)
+        utils.assert_allclose(model_lin.parameters, model.parameters,
+                              atol=0.2)
 
     @pytest.mark.parametrize(('model_class'), linear1d.keys())
     def test_non_linear_fitter_1D(self, model_class):
-        """ Test fitting with non-linear LevMarLSQFitter"""
+        """Test fitting with non-linear LevMarLSQFitter"""
+
         parameters = linear1d[model_class]['parameters']
         kwargs = linear1d[model_class]['kwargs']
         model = model_class(*parameters, **kwargs)
         y1 = model(self.x1)
         model_nlin = self.non_linear_fitter(model, self.x1, y1 + self.n1)
-        utils.assert_allclose(model_nlin.parameters, model.parameters, atol=0.2)
+        utils.assert_allclose(model_nlin.parameters, model.parameters,
+                              atol=0.2)
 
     @pytest.mark.parametrize(('model_class'), linear2d.keys())
     def test_linear_fitter_2D(self, model_class):
-        """ Test fitting with LinearLSQFitter"""
+        """Test fitting with LinearLSQFitter"""
+
         parameters = linear2d[model_class]['parameters']
         kwargs = linear2d[model_class]['kwargs']
         model = model_class(*parameters, **kwargs)
         z = model(self.x2, self.y2)
         model_lin = self.linear_fitter(model, self.x2, self.y2, z + self.n2)
-        utils.assert_allclose(model_lin.parameters, model.parameters, atol=0.2)
+        utils.assert_allclose(model_lin.parameters, model.parameters,
+                              atol=0.2)
 
     @pytest.mark.parametrize(('model_class'), linear2d.keys())
     def test_non_linear_fitter_2D(self, model_class):
-        """ Test fitting with non-linear LevMarLSQFitter"""
+        """Test fitting with non-linear LevMarLSQFitter"""
+
         parameters = linear2d[model_class]['parameters']
         kwargs = linear2d[model_class]['kwargs']
         model = model_class(*parameters, **kwargs)
         z = model(self.x2, self.y2)
-        model_nlin = self.non_linear_fitter(model, self.x2, self.y2, z + self.n2)
-        utils.assert_allclose(model_nlin.parameters, model.parameters, atol=0.2)
+        model_nlin = self.non_linear_fitter(model, self.x2, self.y2,
+                                            z + self.n2)
+        utils.assert_allclose(model_nlin.parameters, model.parameters,
+                              atol=0.2)
 
 
 def test_sip_hst():
-    """
-    Test SIP againts astropy.wcs
-    """
+    """Test SIP against astropy.wcs"""
 
     test_file = get_pkg_data_filename(os.path.join('data', 'hst_sip.hdr'))
     hdr = fits.Header.fromtextfile(test_file)
@@ -131,9 +136,7 @@ def test_sip_hst():
 
 
 def test_sip_irac():
-    """
-    Test forward and inverse SIP againts astropy.wcs
-    """
+    """Test forward and inverse SIP againts astropy.wcs"""
 
     test_file = get_pkg_data_filename(os.path.join('data', 'irac_sip.hdr'))
     hdr = fits.Header.fromtextfile(test_file)
@@ -155,11 +158,12 @@ def test_sip_irac():
     sip = SIP([crpix1, crpix2], a_order, b_order, a_pars, b_pars,
               ap_order=ap_order, ap_coeff=ap_pars, bp_order=bp_order,
               bp_coeff=bp_pars)
-    invsip = sip.inverse()
+
     foc = wobj.sip_pix2foc([pix], 1)
     newpix = wobj.sip_foc2pix(foc, 1)[0]
     utils.assert_allclose(sip(*pix), foc[0] - rel_pix)
-    utils.assert_allclose(invsip(*foc[0]) + foc[0] - rel_pix, newpix - pix)
+    utils.assert_allclose(sip.inverse(*foc[0]) +
+                          foc[0] - rel_pix, newpix - pix)
 
 
 def test_sip_no_coeff():
@@ -167,4 +171,4 @@ def test_sip_no_coeff():
     utils.assert_allclose(sip.sip1d_a.parameters, [0., 0., 0])
     utils.assert_allclose(sip.sip1d_b.parameters, [0., 0., 0])
     with pytest.raises(NotImplementedError):
-        invsip = sip.inverse()
+        sip.inverse
diff --git a/astropy/modeling/tests/test_projections.py b/astropy/modeling/tests/test_projections.py
index 98392af..68de2a1 100644
--- a/astropy/modeling/tests/test_projections.py
+++ b/astropy/modeling/tests/test_projections.py
@@ -1,11 +1,10 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-Test sky projections defined in WCS Paper II
-"""
+
+"""Test sky projections defined in WCS Paper II"""
 
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
-import os.path
+import os
 import numpy as np
 from numpy.testing import utils
 from .. import projections
@@ -22,8 +21,10 @@ def test_Projection_properties():
     assert projection.n_inputs == 2
     assert projection.n_outputs == 2
 
+
 PIX_COORDINATES = [-10, 30]
 
+
 pars = [
     ('TAN', projections.Sky2Pix_TAN, {}),
     ('STG', projections.Sky2Pix_STG, {}),
@@ -37,7 +38,9 @@ pars = [
 @pytest.mark.parametrize(('ID', 'model', 'args'), pars)
 def test_Sky2Pix(ID, model, args):
     """Check astropy model eval against wcslib eval"""
-    wcs_map = os.path.join("../../wcs/tests/maps", "1904-66_{0}.hdr".format(ID))
+
+    wcs_map = os.path.join(os.pardir, os.pardir, "wcs", "tests", "maps",
+                           "1904-66_{0}.hdr".format(ID))
     test_file = get_pkg_data_filename(wcs_map)
     header = fits.Header.fromfile(test_file, endcard=False, padding=False)
     w = wcs.WCS(header)
@@ -64,7 +67,9 @@ pars = [
 @pytest.mark.parametrize(('ID', 'model', 'args'), pars)
 def test_Pix2Sky(ID, model, args):
     """Check astropy model eval against wcslib eval"""
-    wcs_map = os.path.join("../../wcs/tests/maps", "1904-66_{0}.hdr".format(ID))
+
+    wcs_map = os.path.join(os.pardir, os.pardir, "wcs", "tests", "maps",
+                           "1904-66_{0}.hdr".format(ID))
     test_file = get_pkg_data_filename(wcs_map)
     header = fits.Header.fromfile(test_file, endcard=False, padding=False)
     w = wcs.WCS(header)
@@ -81,13 +86,12 @@ def test_Pix2Sky(ID, model, args):
 
 
 class TestAZP(object):
+    """Test AZP projection"""
 
-    """
-    Test AZP projection
-    """
     def setup_class(self):
         ID = 'AZP'
-        wcs_map = os.path.join("../../wcs/tests/maps", "1904-66_{0}.hdr".format(ID))
+        wcs_map = os.path.join(os.pardir, os.pardir, "wcs", "tests", "maps",
+                               "1904-66_{0}.hdr".format(ID))
         test_file = get_pkg_data_filename(wcs_map)
         header = fits.Header.fromfile(test_file, endcard=False, padding=False)
         self.wazp = wcs.WCS(header)
@@ -97,7 +101,6 @@ class TestAZP(object):
         self.pv_kw = [kw[2] for kw in self.wazp.wcs.get_pv()]
         proj = projections.__getattribute__("Pix2Sky_{0}".format(ID))
         self.azp = proj(*self.pv_kw)
-        self.azpinv = self.azp.inverse()
 
     def test_AZP_p2s(self):
         wcslibout = self.wazp.wcs.p2s([[-10, 30]], 1)
@@ -110,19 +113,18 @@ class TestAZP(object):
     def test_AZP_s2p(self):
         wcslibout = self.wazp.wcs.p2s([[-10, 30]], 1)
         wcs_pix = self.wazp.wcs.s2p(wcslibout['world'], 1)['pixcrd']
-        x, y = self.azpinv(wcslibout['phi'], wcslibout['theta'])
+        x, y = self.azp.inverse(wcslibout['phi'], wcslibout['theta'])
         utils.assert_almost_equal(np.asarray(x), wcs_pix[:, 0])
         utils.assert_almost_equal(np.asarray(y), wcs_pix[:, 1])
 
 
 class TestCYP(object):
+    """Test CYP projection"""
 
-    """
-    Test CYP projection
-    """
     def setup_class(self):
         ID = "CYP"
-        wcs_map = os.path.join("../../wcs/tests/maps", "1904-66_{0}.hdr".format(ID))
+        wcs_map = os.path.join(os.pardir, os.pardir, "wcs", "tests", "maps",
+                               "1904-66_{0}.hdr".format(ID))
         test_file = get_pkg_data_filename(wcs_map)
         header = fits.Header.fromfile(test_file, endcard=False, padding=False)
         self.wazp = wcs.WCS(header)
@@ -132,7 +134,6 @@ class TestCYP(object):
         self.pv_kw = [kw[2] for kw in self.wazp.wcs.get_pv()]
         proj = projections.__getattribute__("Pix2Sky_{0}".format(ID))
         self.azp = proj(*self.pv_kw)
-        self.azpinv = self.azp.inverse()
 
     def test_CYP_p2s(self):
         wcslibout = self.wazp.wcs.p2s([[-10, 30]], 1)
@@ -145,7 +146,7 @@ class TestCYP(object):
     def test_CYP_s2p(self):
         wcslibout = self.wazp.wcs.p2s([[-10, 30]], 1)
         wcs_pix = self.wazp.wcs.s2p(wcslibout['world'], 1)['pixcrd']
-        x, y = self.azpinv(wcslibout['phi'], wcslibout['theta'])
+        x, y = self.azp.inverse(wcslibout['phi'], wcslibout['theta'])
         utils.assert_almost_equal(np.asarray(x), wcs_pix[:, 0])
         utils.assert_almost_equal(np.asarray(y), wcs_pix[:, 1])
 
@@ -171,17 +172,16 @@ def test_AffineTransformation2D_inverse():
         matrix=[[1, 1], [1, 1]])
 
     with pytest.raises(InputParameterError):
-        model1.inverse()
+        model1.inverse
 
     model2 = projections.AffineTransformation2D(
         matrix=[[1.2, 3.4], [5.6, 7.8]], translation=[9.1, 10.11])
-    inverse = model2.inverse()
 
     # Coordinates for vertices of a rectangle
     rect = [[0, 0], [1, 0], [0, 3], [1, 3]]
 
     x, y = zip(*rect)
 
-    x_new, y_new = inverse(*model2(x, y))
+    x_new, y_new = model2.inverse(*model2(x, y))
 
     utils.assert_allclose([x, y], [x_new, y_new], atol=1e-10)
diff --git a/astropy/modeling/tests/test_rotations.py b/astropy/modeling/tests/test_rotations.py
index 3688fdc..9d13c83 100644
--- a/astropy/modeling/tests/test_rotations.py
+++ b/astropy/modeling/tests/test_rotations.py
@@ -30,8 +30,8 @@ def test_native_celestial_native():
     utils.assert_allclose(nnphi2, nnphi)
     utils.assert_allclose(ntheta2, ntheta)
 
-    assert n2c.inverse()(nnphi, ntheta) == c2n(nnphi, ntheta)
-    assert c2n.inverse()(nnphi, ntheta) == n2c(nnphi, ntheta)
+    assert n2c.inverse(nnphi, ntheta) == c2n(nnphi, ntheta)
+    assert c2n.inverse(nnphi, ntheta) == n2c(nnphi, ntheta)
 
 
 def test_native_celestial_theta90():
@@ -49,6 +49,5 @@ def test_Rotation2D():
 
 def test_Rotation2D_inverse():
     model = models.Rotation2D(angle=234.23494)
-    inverse = model.inverse()
-    x, y = inverse(*model(1, 0))
+    x, y = model.inverse(*model(1, 0))
     utils.assert_allclose([x, y], [1, 0], atol=1e-10)
diff --git a/astropy/modeling/tests/test_utils.py b/astropy/modeling/tests/test_utils.py
new file mode 100644
index 0000000..86bda72
--- /dev/null
+++ b/astropy/modeling/tests/test_utils.py
@@ -0,0 +1,68 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import operator
+
+import numpy as np
+
+from ..utils import ExpressionTree as ET
+
+
+def test_traverse_postorder_duplicate_subtrees():
+    """
+    Regression test for a bug in `ExpressionTree.traverse_postorder`
+    where given an expression like ``(1 + 2) + (1 + 2)`` where the two proper
+    subtrees are actually the same object.
+    """
+
+    subtree = ET('+', ET(1), ET(2))
+    tree = ET('+', subtree, subtree)
+    traversal = [n.value for n in tree.traverse_postorder()]
+    assert traversal == [1, 2, '+', 1, 2, '+', '+']
+
+
+# TODO: It might prove useful to implement a simple expression parser to build
+# trees; this would be easy and might find use elsewhere
+def test_tree_evaluate_subexpression():
+    """Test evaluating a subexpression from an expression tree."""
+
+    operators = {'+': operator.add, '-': operator.sub, '*': operator.mul,
+                 '/': operator.truediv, '**': operator.pow}
+    # The full expression represented by this tree is:
+    # 1.0 + 2 - 3 * 4 / 5 ** 6 (= 2.999232 if you must know)
+    tree = ET('+', ET(1.0), ET('-', ET(2.0),
+                   ET('*', ET(3.0), ET('/', ET(4.0),
+                   ET('**', ET(5.0), ET(6.0))))))
+
+    def test_slice(start, stop, expected):
+        assert np.allclose(tree.evaluate(operators, start=start, stop=stop),
+                           expected)
+
+    assert tree.evaluate(operators) == (1.0 + 2.0 - 3.0 * 4.0 / 5.0 ** 6.0)
+    test_slice(0, 5, (1.0 + 2.0 - 3.0 * 4.0 / 5.0))
+    test_slice(0, 4, (1.0 + 2.0 - 3.0 * 4.0))
+    test_slice(0, 3, (1.0 + 2.0 - 3.0))
+    test_slice(0, 2, (1.0 + 2.0))
+    test_slice(0, 1, 1.0)
+
+    test_slice(1, 6, (2.0 - 3.0 * 4.0 / 5.0 ** 6.0))
+    test_slice(1, 5, (2.0 - 3.0 * 4.0 / 5.0))
+    test_slice(1, 4, (2.0 - 3.0 * 4.0))
+    test_slice(1, 3, (2.0 - 3.0))
+    test_slice(1, 2, 2.0)
+
+    test_slice(2, 6, (3.0 * 4.0 / 5.0 ** 6.0))
+    test_slice(2, 5, (3.0 * 4.0 / 5.0))
+    test_slice(2, 4, (3.0 * 4.0))
+    test_slice(2, 3, 3.0)
+
+    test_slice(3, 6, (4.0 / 5.0 ** 6.0))
+    test_slice(3, 5, (4.0 / 5.0))
+    test_slice(3, 4, 4.0)
+
+    test_slice(4, 6, (5.0 ** 6.0))
+    test_slice(4, 5, 5.0)
+
+    test_slice(5, 6, 6.0)
diff --git a/astropy/modeling/utils.py b/astropy/modeling/utils.py
index 73196f1..cbd6deb 100644
--- a/astropy/modeling/utils.py
+++ b/astropy/modeling/utils.py
@@ -7,11 +7,225 @@ This module provides utility functions for the models package
 from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
+from collections import deque
+
 import numpy as np
 
 from ..extern.six.moves import xrange, zip_longest
 
-__all__ = ['check_broadcast', 'poly_map_domain', 'comb']
+
+__all__ = ['ExpressionTree', 'check_broadcast', 'poly_map_domain', 'comb']
+
+
+class ExpressionTree(object):
+    __slots__ = ['left', 'right', 'value']
+
+    def __init__(self, value, left=None, right=None):
+        self.value = value
+        self.left = left
+
+        # Two subtrees can't be the same *object* or else traverse_postorder
+        # breaks, so we just always copy the right subtree to subvert that.
+        if right is not None and left is right:
+            right = right.copy()
+
+        self.right = right
+
+    @property
+    def isleaf(self):
+        return self.left is None and self.right is None
+
+    def traverse_preorder(self):
+        stack = deque([self])
+        while stack:
+            node = stack.pop()
+            yield node
+
+            if node.right is not None:
+                stack.append(node.right)
+            if node.left is not None:
+                stack.append(node.left)
+
+    def traverse_inorder(self):
+        stack = deque()
+        node = self
+        while stack or node is not None:
+            if node is not None:
+                stack.append(node)
+                node = node.left
+            else:
+                node = stack.pop()
+                yield node
+                node = node.right
+
+    def traverse_postorder(self):
+        stack = deque([self])
+        last = None
+        while stack:
+            node = stack[-1]
+            if last is None or node is last.left or node is last.right:
+                if node.left is not None:
+                    stack.append(node.left)
+                elif node.right is not None:
+                    stack.append(node.right)
+            elif node.left is last and node.right is not None:
+                stack.append(node.right)
+            else:
+                yield stack.pop()
+            last = node
+
+    def evaluate(self, operators, getter=None, start=0, stop=None):
+        """Evaluate the expression represented by this tree.
+
+        ``Operators`` should be a dictionary mapping operator names ('tensor',
+        'product', etc.) to a function that implements that operator for the
+        correct number of operands.
+
+        If given, ``getter`` is a function evaluated on each *leaf* node's
+        value before applying the operator between them.  This could be used,
+        for example, to operate on an attribute of the node values rather than
+        directly on the node values.  The ``getter`` is passed both the index
+        of the leaf (a count starting at 0 that is incremented after each leaf
+        is found) and the leaf node itself.
+
+        The ``start`` and ``stop`` arguments allow evaluating a sub-expression
+        within the expression tree.
+
+        TODO: Document this better.
+        """
+
+        stack = deque()
+
+        if getter is None:
+            getter = lambda idx, value: value
+
+        if start is None:
+            start = 0
+
+        leaf_idx = 0
+        for node in self.traverse_postorder():
+            if node.isleaf:
+                # For a "tree" containing just a single operator at the root
+                # Also push the index of this leaf onto the stack, which will
+                # prove useful for evaluating subexpressions
+                stack.append((getter(leaf_idx, node.value), leaf_idx))
+                leaf_idx += 1
+            else:
+                operator = operators[node.value]
+
+                if len(stack) < 2:
+                    # Skip this operator if there are not enough operands on
+                    # the stack; this can happen if some operands were skipped
+                    # when evaluating a sub-expression
+                    continue
+
+                right = stack.pop()
+                left = stack.pop()
+                operands = []
+
+                for operand in (left, right):
+                    # idx is the leaf index; -1 if not a leaf node
+                    if operand[-1] == -1:
+                        operands.append(operand)
+                    else:
+                        operand, idx = operand
+                        if start <= idx and (stop is None or idx < stop):
+                            operands.append((operand, idx))
+
+                if len(operands) == 2:
+                    # evaluate the operator with the given operands and place
+                    # the result on the stack (with -1 for the "leaf index"
+                    # since this result is not a leaf node
+                    left, right = operands
+                    stack.append((operator(left[0], right[0]), -1))
+                elif len(operands) == 0:
+                    # Just push the left one back on the stack
+                    # TODO: Explain and/or refactor this better
+                    # This is here because even if both operands were "skipped"
+                    # due to being outside the (start, stop) range, we've only
+                    # skipped one operator.  But there should be at least 2
+                    # operators involving these operands, so we push the one
+                    # from the left back onto the stack so that the next
+                    # operator will be skipped as well.  Should probably come
+                    # up with an easier to follow way to write this algorithm
+                    stack.append(left)
+                else:
+                    # one or more of the operands was not included in the
+                    # sub-expression slice, so don't evaluate the operator;
+                    # instead place left over operands (if any) back on the
+                    # stack for later use
+                    stack.extend(operands)
+
+        return stack.pop()[0]
+
+    def copy(self):
+        # Hopefully this won't blow the stack for any practical case; if such a
+        # case arises that this won't work then I suppose we can find an
+        # iterative approach.
+
+        children = []
+        for child in (self.left, self.right):
+            if isinstance(child, ExpressionTree):
+                children.append(child.copy())
+            else:
+                children.append(child)
+
+        return self.__class__(self.value, left=children[0], right=children[1])
+
+    def format_expression(self, operator_precedence, format_leaf=None):
+        leaf_idx = 0
+        operands = deque()
+
+        if format_leaf is None:
+            format_leaf = lambda i, l: '[{0}]'.format(i)
+
+        for node in self.traverse_postorder():
+            if node.isleaf:
+                operands.append(format_leaf(leaf_idx, node))
+                leaf_idx += 1
+                continue
+
+            oper_order = operator_precedence[node.value]
+            right = operands.pop()
+            left = operands.pop()
+
+            if (node.left is not None and not node.left.isleaf and
+                    operator_precedence[node.left.value] < oper_order):
+                left = '({0})'.format(left)
+            if (node.right is not None and not node.right.isleaf and
+                    operator_precedence[node.right.value] < oper_order):
+                right = '({0})'.format(right)
+
+            operands.append(' '.join((left, node.value, right)))
+
+        return ''.join(operands)
+
+
+def make_binary_operator_eval(oper, f, g):
+    """
+    Given a binary operator (as a callable of two arguments) ``oper`` and
+    two callables ``f`` and ``g`` which accept the same arguments,
+    returns a *new* function that takes the same arguments as ``f`` and ``g``,
+    but passes the outputs of ``f`` and ``g`` in the given ``oper``.
+
+    ``f`` and ``g`` are assumed to return tuples (which may be 1-tuples).  The
+    given operator is applied element-wise to tuple outputs).
+
+    Example
+    -------
+
+    >>> from operator import add
+    >>> def prod(x, y):
+    ...     return (x * y,)
+    ...
+    >>> sum_of_prod = make_binary_operator_eval(add, prod, prod)
+    >>> sum_of_prod(3, 5)
+    (30,)
+    """
+
+    return lambda inputs, params: \
+            tuple(oper(x, y) for x, y in zip(f(inputs, params),
+                                             g(inputs, params)))
 
 
 class IncompatibleShapeError(ValueError):
@@ -115,3 +329,21 @@ def array_repr_oneline(array):
 
     r = np.array2string(array, separator=',', suppress_small=True)
     return ' '.join(l.strip() for l in r.splitlines())
+
+
+def combine_labels(left, right):
+    """
+    For use with the join operator &: Combine left input/output labels with
+    right input/output labels.
+
+    If none of the labels conflict then this just returns a sum of tuples.
+    However if *any* of the labels conflict, this appends '0' to the left-hand
+    labels and '1' to the right-hand labels so there is no ambiguity).
+    """
+
+    if set(left).intersection(right):
+        left = tuple(l + '0' for l in left)
+        right = tuple(r + '1' for r in right)
+
+    return left + right
+
diff --git a/astropy/nddata/__init__.py b/astropy/nddata/__init__.py
index 478d546..55cf4fb 100644
--- a/astropy/nddata/__init__.py
+++ b/astropy/nddata/__init__.py
@@ -9,9 +9,18 @@ be easily provided by a single array.
 """
 
 from .nddata import *
+from .nddata_base import *
 from .nduncertainty import *
 from .flag_collection import *
 
+from .decorators import *
+
+from .mixins.ndarithmetic import *
+from .mixins.ndslicing import *
+from .mixins.ndio import *
+
+from .compat import *
+
 from .. import config as _config
 
 
diff --git a/astropy/nddata/compat.py b/astropy/nddata/compat.py
new file mode 100644
index 0000000..39baba4
--- /dev/null
+++ b/astropy/nddata/compat.py
@@ -0,0 +1,109 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# This module contains a class equivalent to pre-1.0 NDData.
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+from .. units import UnitsError
+
+from .nddata import NDData
+from .nduncertainty import NDUncertainty
+
+from .mixins.ndslicing import NDSlicingMixin
+from .mixins.ndarithmetic import NDArithmeticMixin
+from .mixins.ndio import NDIOMixin
+
+__all__ = ['NDDataArray']
+
+
+class NDDataArray(NDArithmeticMixin, NDSlicingMixin, NDIOMixin, NDData):
+    """
+    An ``NDData`` object with arithmetic. This class is functionally equivalent
+    to ``NDData`` in astropy  versions prior to 1.0.
+    """
+
+    def __init__(self, *arg, **kwd):
+        # Initialize with the parent...
+        super(NDDataArray, self).__init__(*arg, **kwd)
+
+        # ...then reset uncertainty to force it to go through the
+        # setter logic below. In base NDData all that is done is to
+        # set self._uncertainty to whatever uncertainty is passed in.
+        self.uncertainty = self._uncertainty
+
+        # Same thing for mask...
+        self.mask = self._mask
+
+    # Implement uncertainty as NDUncertainty to support propagation of
+    # uncertainties in arithmetic operations
+    @property
+    def uncertainty(self):
+        return self._uncertainty
+
+    @uncertainty.setter
+    def uncertainty(self, value):
+        if value is not None:
+            if isinstance(value, NDUncertainty):
+                class_name = self.__class__.__name__
+                if self.unit and value._unit:
+                    try:
+                        scaling = (1 * value._unit).to(self.unit)
+                    except UnitsError:
+                        raise UnitsError('Cannot convert unit of uncertainty '
+                                         'to unit of '
+                                         '{0} object.'.format(class_name))
+                    value.array *= scaling
+                elif not self.unit and value._unit:
+                    # Raise an error if uncertainty has unit and data does not
+                    raise ValueError("Cannot assign an uncertainty with unit "
+                                     "to {0} without "
+                                     "a unit".format(class_name))
+                self._uncertainty = value
+                self._uncertainty.parent_nddata = self
+            else:
+                raise TypeError("Uncertainty must be an instance of "
+                                "a NDUncertainty object")
+        else:
+            self._uncertainty = value
+
+    # Implement mask in a way that converts nicely to a numpy masked array
+    @property
+    def mask(self):
+        if self._mask is np.ma.nomask:
+            return None
+        else:
+            return self._mask
+
+    @mask.setter
+    def mask(self, value):
+        # Check that value is not either type of null mask.
+        if (value is not None) and (value is not np.ma.nomask):
+            mask = np.array(value, dtype=np.bool_, copy=False)
+            if mask.shape != self.data.shape:
+                raise ValueError("dimensions of mask do not match data")
+            else:
+                self._mask = mask
+        else:
+            # internal representation should be one numpy understands
+            self._mask = np.ma.nomask
+
+    def __array__(self):
+        """
+        This allows code that requests a Numpy array to use an NDData
+        object as a Numpy array.
+        """
+        if self.mask is not None:
+            return np.ma.masked_array(self.data, self.mask)
+        else:
+            return np.array(self.data)
+
+    def __array_prepare__(self, array, context=None):
+        """
+        This ensures that a masked array is returned if self is masked.
+        """
+        if self.mask is not None:
+            return np.ma.masked_array(array, self.mask)
+        else:
+            return array
diff --git a/astropy/nddata/decorators.py b/astropy/nddata/decorators.py
new file mode 100644
index 0000000..001a79c
--- /dev/null
+++ b/astropy/nddata/decorators.py
@@ -0,0 +1,162 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import inspect
+import warnings
+
+from ..utils import wraps
+from ..utils.exceptions import AstropyUserWarning
+
+from .nddata import NDData
+
+__all__ = ['support_nddata']
+
+
+def support_nddata(_func=None, accepts=NDData, repack=False, returns=None):
+    """
+    Decorator to split NDData properties into function arguments.
+
+    This is a decorator to allow functions to take NDData objects as their
+    first arguments and split up the properties into kwargs as required by the
+    function. For example, if you consider the following function::
+
+        def downsample(data, wcs=None):
+            # downsample data and optionally WCS here
+            pass
+
+    This function takes a Numpy array for the data, and some WCS information
+    with the ``data`` keyword argument. However, you might have an NDData
+    instance that has the ``wcs`` property set and you would like to be able to
+    call the function with ``downsample(my_nddata)`` and have the WCS
+    information, if present, automatically be passed to the ``wcs`` keyword
+    argument.
+
+    This decorator can be used to make this possible::
+
+        @support_nddata
+        def downsample(data, wcs=None):
+            # downsample data and optionally WCS here
+            pass
+
+    This function can now either be called as before, specifying the data and
+    WCS separately, or an NDData instance can be passed to the ``data``
+    argument.
+
+    The restrictions on functions to use this function are:
+
+    * The first positional argument should be ``data`` and take a Numpy array.
+
+    * The following arguments can optionally be specified in the function
+      signature, but if they are specified they should be keyword arguments:
+      ``uncertainty``, ``mask``, ``meta``, ``unit``, and ``wcs``. If
+      you are making use of this decorator, you should be prepared for these
+      keyword arguments to be set to the properties of the NDData object (if
+      present).
+
+    The behavior of the decorator is to check through the NDData properties and
+    if they are set, it checks if the function accepts them as keyword
+    arguments. If an NDData property is set but cannot be passed to a keyword
+    argument, a warning is emitted to tell the user that the NDData property in
+    question will not be used by the function (to ensure that they know when
+    e.g. uncertainties cannot be used).
+
+    If the user passes an NDData object *and* explicitly sets a keyword
+    argument that is one of the valid NDData properties, a warning is emitted
+    to inform the user that the explicitly specified value will take priority.
+    """
+
+    if returns is not None and not repack:
+        raise ValueError('returns should only be set if repack=True')
+
+    if returns is None and repack:
+        raise ValueError('returns should be set if repack=True')
+
+    def support_nddata_decorator(func):
+
+        # Find out args and kwargs
+        wrapped_argspec = inspect.getargspec(func)
+
+        # Find out the args and kwargs
+        if wrapped_argspec.defaults:
+            func_args = wrapped_argspec.args[:-len(wrapped_argspec.defaults)]
+            func_kwargs = wrapped_argspec.args[len(func_args):]
+        else:
+            func_args = wrapped_argspec.args
+            func_kwargs = []
+
+        # First argument should be data
+        if len(func_args) == 0 or func_args[0] != 'data':
+            raise ValueError("Can only wrap functions whose first positional argument is `data`")
+
+        supported_properties = ['uncertainty', 'mask', 'meta', 'unit', 'wcs']
+
+        @wraps(func)
+        def wrapper(data, *args, **kwargs):
+
+            unpack = isinstance(data, accepts)
+            input_data = data
+
+            if not unpack and isinstance(data, NDData):
+                raise TypeError("Only NDData sub-classes that inherit from {0}"
+                                " can be used by this function".format(accepts.__name__))
+
+            # If data is an NDData instance, we can try and find properties that
+            # can be passed as kwargs.
+            if unpack:
+
+                ignored = []
+
+                # We loop over a list of pre-defined properties
+                for prop in supported_properties:
+
+                    # We only need to do something if the property exists on the
+                    # NDData object
+                    if hasattr(data, prop):
+                        value = getattr(data, prop)
+                        if (prop == 'meta' and len(value) > 0) or (prop != 'meta' and value is not None):
+                            if prop in func_kwargs:
+                                if prop in kwargs and kwargs[prop] is not None:
+                                    warnings.warn("Property {0} has been passed explicitly and as an "
+                                                  "NDData property, using explicitly specified value".format(prop),
+                                                  AstropyUserWarning)
+                                else:
+                                    kwargs[prop] = value
+                            else:
+                                ignored.append(prop)
+
+                if ignored:
+                    warnings.warn("The following attributes were set on the data object, "
+                                  "but will be ignored by the function: " + ", ".join(ignored),
+                                  AstropyUserWarning)
+
+                # Finally, replace data by the data itself
+                data = data.data
+
+            result = func(data, *args, **kwargs)
+
+            if unpack:
+
+                if repack:
+                    if len(returns) > 1 and len(returns) != len(result):
+                        raise ValueError("Function did not return the expected number of arguments")
+                    elif len(returns) == 1:
+                        result = [result]
+                    return input_data.__class__(**dict(zip(returns, result)))
+                else:
+                    return result
+
+            else:
+
+                return result
+
+        return wrapper
+
+    # If _func is set, this means that the decorator was used without
+    # parameters so we have to return the result of the support_nddata_decorator
+    # decorator rather than the decorator itself
+    if _func is not None:
+        return support_nddata_decorator(_func)
+    else:
+        return support_nddata_decorator
diff --git a/astropy/nddata/flag_collection.py b/astropy/nddata/flag_collection.py
index 27b02a4..099c44a 100644
--- a/astropy/nddata/flag_collection.py
+++ b/astropy/nddata/flag_collection.py
@@ -1,6 +1,7 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
-from __future__ import absolute_import, division, print_function, unicode_literals
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
 
 import numpy as np
 
@@ -28,9 +29,11 @@ class FlagCollection(OrderedDict):
         if 'shape' in kwargs:
             self.shape = kwargs.pop('shape')
             if not isiterable(self.shape):
-                raise ValueError("FlagCollection shape should be an iterable object")
+                raise ValueError("FlagCollection shape should be "
+                                 "an iterable object")
         else:
-            raise Exception("FlagCollection should be initialized with the shape of the data")
+            raise Exception("FlagCollection should be initialized with "
+                            "the shape of the data")
 
         OrderedDict.__init__(self, *args, **kwargs)
 
@@ -40,6 +43,7 @@ class FlagCollection(OrderedDict):
             if value.shape == self.shape:
                 OrderedDict.__setitem__(self, item, value, **kwargs)
             else:
-                raise ValueError("flags array shape {0} does not match data shape {1}".format(value.shape, self.shape))
+                raise ValueError("flags array shape {0} does not match data "
+                                 "shape {1}".format(value.shape, self.shape))
         else:
             raise TypeError("flags should be given as a Numpy array")
diff --git a/astropy/nddata/mixins/__init__.py b/astropy/nddata/mixins/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy/nddata/mixins/ndarithmetic.py b/astropy/nddata/mixins/ndarithmetic.py
new file mode 100644
index 0000000..62f52e5
--- /dev/null
+++ b/astropy/nddata/mixins/ndarithmetic.py
@@ -0,0 +1,224 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# This module implements the Arithmetic mixin to the NDData class.
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from copy import deepcopy
+
+import numpy as np
+
+from ... units import dimensionless_unscaled, UnitsError
+from ... import log
+from ..nduncertainty import IncompatibleUncertaintiesException
+
+__all__ = ['NDArithmeticMixin']
+
+
+class NDArithmeticMixin(object):
+    """
+    Mixin class to add arithmetic to an NDData object.
+
+    When subclassing, be sure to list the superclasses in the correct order
+    so that the subclass sees NDData as the main superclass. See
+    `~astropy.nddata.NDDataArray` for an example.
+    """
+    def _arithmetic(self, operand, propagate_uncertainties, name, operation):
+        """
+        {name} another dataset (``operand``) to this dataset.
+
+        Parameters
+        ----------
+        operand : `~astropy.nddata.NDData`
+            The second operand in the operation a {operator} b
+
+        propagate_uncertainties : bool
+            Whether to propagate uncertainties following the propagation rules
+            defined by the class used for the ``uncertainty`` attribute.
+
+        Returns
+        -------
+        result : `~astropy.nddata.NDData`
+            The resulting dataset
+
+        Notes
+        -----
+        This method requires the datasets to have identical WCS
+        properties, equivalent units, and identical shapes.
+        Meta-data get set to None in the resulting dataset. The unit
+        in the result is the same as the unit in ``self``. Uncertainties
+        are propagated, although correlated errors are not supported
+        by any of the built-in uncertainty classes.  If uncertainties
+        are assumed to be correlated, a warning is issued by default
+        (though this can be disabled via the
+        ``astropy.nddata.conf.warn_unsupported_correlated``
+        configuration item). Values masked in either dataset before
+        the operation are masked in the resulting dataset.
+        """
+
+        from .. import conf
+
+        if self.wcs != operand.wcs:
+            raise ValueError("WCS properties do not match")
+
+        # get a sensible placeholder if .unit is None
+        self_unit = self.unit or dimensionless_unscaled
+        operand_unit = operand.unit or dimensionless_unscaled
+
+        # This check could be rolled into the calculation of the result
+        # but checking now avoids a potentially expensive calculation that
+        # would fail anyway.
+        try:
+            # Quantity is designed to work with numpy ufuncs, but plain
+            # Unit is not, so convert units to quantities
+            result_unit = operation(1 * self_unit, 1 * operand_unit).unit
+        except UnitsError:
+            # current API raises ValueError in this case, not UnitError
+            raise ValueError("operand units do not match")
+
+        if self.data.shape != operand.data.shape:
+            raise ValueError("operand shapes do not match")
+
+        # Instead of manually scaling the operand data just let Quantity
+        # handle it.
+        # Order of the arguments is important here if the operation is
+        # addition or subtraction and the units of the operands are different
+        # but compatible. NDData follows the convention that Quantity follows
+        # in that case, with the units of the first operand (i.e. self)
+        # determining the units of the result.
+        data = operation(self.data * self_unit, operand.data * operand_unit)
+
+        result_unit = data.unit
+        # If neither self nor operand had units then should return a result
+        # that has no unit. A check that the result_unit is dimensionless
+        # should not be necessary, but also does no harm.
+        if self.unit is None and operand.unit is None:
+            if result_unit is dimensionless_unscaled:
+                result_unit = None
+            else:
+                raise ValueError("arithmetic result was not unitless even "
+                                 "though operands were unitless")
+        data = data.value
+        new_wcs = deepcopy(self.wcs)
+
+        # Call __class__ in case we are dealing with an inherited type
+        result = self.__class__(data, uncertainty=None,
+                                mask=None, wcs=new_wcs,
+                                meta=None, unit=result_unit)
+
+        # Prepare to scale uncertainty if it is needed
+        if operand.uncertainty:
+            operand_uncert_value = operand.uncertainty.array
+
+        # By this point the arithmetic has succeeded, so the input units were
+        # consistent with each other given the operation.
+        #
+        # If the operation is addition or subtraction then need to ensure that
+        # the uncertainty of the operand is the same units as the result
+        # (which will be the same as self.unit).
+
+        # The data ought to also be scaled in this case -- for addition of
+        # a StdDevUncertainty this isn't really necessary but other
+        # uncertainties when added/subtracted may depend on both the operand
+        # uncertainty and the operand data.
+
+        # Since the .unit.to methods create a copy, avoid the conversion
+        # unless it is necessary.
+        if (operation in [np.add, np.subtract] and
+                self.unit != operand.unit):
+            operand_data = operand.unit.to(self.unit, operand.data)
+            if operand.uncertainty:
+                operand_uncert_value = operand.unit.to(self.unit,
+                                                       operand_uncert_value)
+        else:
+            operand_data = operand.data
+
+        if operand.uncertainty:
+            # Create a copy here in case this is returned as the uncertainty
+            # of the result.
+            operand_uncertainty = \
+                operand.uncertainty.__class__(operand_uncert_value, copy=True)
+        else:
+            operand_uncertainty = None
+
+        if propagate_uncertainties is None:
+            result.uncertainty = None
+        elif self.uncertainty is None and operand.uncertainty is None:
+            result.uncertainty = None
+        elif self.uncertainty is None:
+            result.uncertainty = operand_uncertainty
+        elif operand.uncertainty is None:
+            result.uncertainty = self.uncertainty.__class__(self.uncertainty,
+                                                            copy=True)
+        else:  # both self and operand have uncertainties
+            if (conf.warn_unsupported_correlated and
+                (not self.uncertainty.support_correlated or
+                 not operand.uncertainty.support_correlated)):
+                log.info("The uncertainty classes used do not support the "
+                         "propagation of correlated errors, so uncertainties"
+                         " will be propagated assuming they are uncorrelated")
+            operand_scaled = operand.__class__(operand_data,
+                                               uncertainty=operand_uncertainty,
+                                               unit=operand.unit,
+                                               wcs=operand.wcs,
+                                               mask=operand.mask,
+                                               meta=operand.meta)
+            try:
+                method = getattr(self.uncertainty, propagate_uncertainties)
+                result.uncertainty = method(operand_scaled, result.data)
+            except IncompatibleUncertaintiesException:
+                raise IncompatibleUncertaintiesException(
+                    "Cannot propagate uncertainties of type {0:s} with "
+                    "uncertainties of type {1:s} for {2:s}".format(
+                        self.uncertainty.__class__.__name__,
+                        operand.uncertainty.__class__.__name__,
+                        name))
+
+        if self.mask is None and operand.mask is None:
+            result.mask = None
+        elif self.mask is None:
+            result.mask = operand.mask.copy()
+        elif operand.mask is None:
+            result.mask = self.mask.copy()
+        else:  # combine masks as for Numpy masked arrays
+            result.mask = self.mask | operand.mask  # copy implied by operator
+
+        return result
+
+    def add(self, operand, propagate_uncertainties=True):
+        if propagate_uncertainties:
+            propagate_uncertainties = "propagate_add"
+        else:
+            propagate_uncertainties = None
+        return self._arithmetic(
+            operand, propagate_uncertainties, "addition", np.add)
+    add.__doc__ = _arithmetic.__doc__.format(name="Add", operator="+")
+
+    def subtract(self, operand, propagate_uncertainties=True):
+        if propagate_uncertainties:
+            propagate_uncertainties = "propagate_subtract"
+        else:
+            propagate_uncertainties = None
+        return self._arithmetic(
+            operand, propagate_uncertainties, "subtraction", np.subtract)
+    subtract.__doc__ = _arithmetic.__doc__.format(name="Subtract",
+                                                  operator="-")
+
+    def multiply(self, operand, propagate_uncertainties=True):
+        if propagate_uncertainties:
+            propagate_uncertainties = "propagate_multiply"
+        else:
+            propagate_uncertainties = None
+        return self._arithmetic(
+            operand, propagate_uncertainties, "multiplication", np.multiply)
+    multiply.__doc__ = _arithmetic.__doc__.format(name="Multiply",
+                                                  operator="*")
+
+    def divide(self, operand, propagate_uncertainties=True):
+        if propagate_uncertainties:
+            propagate_uncertainties = "propagate_divide"
+        else:
+            propagate_uncertainties = None
+        return self._arithmetic(
+            operand, propagate_uncertainties, "division", np.divide)
+    divide.__doc__ = _arithmetic.__doc__.format(name="Divide", operator="/")
diff --git a/astropy/nddata/mixins/ndio.py b/astropy/nddata/mixins/ndio.py
new file mode 100644
index 0000000..f171c1d
--- /dev/null
+++ b/astropy/nddata/mixins/ndio.py
@@ -0,0 +1,39 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# This module implements the I/O mixin to the NDData class.
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from ...io import registry as io_registry
+
+__all__ = ['NDIOMixin']
+
+
+class NDIOMixin(object):
+    """
+    Mixin class to connect NDData to the astropy input/output registry.
+
+    This mixin adds two methods to its subclasses, ``read`` and ``write``.
+    """
+
+    @classmethod
+    def read(cls, *args, **kwargs):
+        """
+        Read and parse gridded N-dimensional data and return as an
+        NDData-derived object.
+
+        This function provides the NDDataBase interface to the astropy unified
+        I/O layer.  This allows easily reading a file in the supported data
+        formats.
+        """
+        return io_registry.read(cls, *args, **kwargs)
+
+    def write(self, *args, **kwargs):
+        """
+        Write a gridded N-dimensional data object out in specified format.
+
+        This function provides the NDDataBase interface to the astropy unified
+        I/O layer.  This allows easily writing a file in the supported data
+        formats.
+        """
+        io_registry.write(self, *args, **kwargs)
diff --git a/astropy/nddata/mixins/ndslicing.py b/astropy/nddata/mixins/ndslicing.py
new file mode 100644
index 0000000..2d0bf54
--- /dev/null
+++ b/astropy/nddata/mixins/ndslicing.py
@@ -0,0 +1,39 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# This module implements the Slicing mixin to the NDData class.
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+__all__ = ['NDSlicingMixin']
+
+
+class NDSlicingMixin(object):
+    """
+    Mixin to provide slicing on objects using the NDData interface.
+
+    When subclassing, be sure to list the superclasses in the correct order
+    so that the subclass sees NDData as the main superclass. See
+    `~astropy.nddata.NDDataArray` for an example.
+    """
+    def __getitem__(self, item):
+
+        new_data = self.data[item]
+
+        if self.uncertainty is not None:
+            new_uncertainty = self.uncertainty[item]
+        else:
+            new_uncertainty = None
+
+        if self.mask is not None:
+            new_mask = self.mask[item]
+        else:
+            new_mask = None
+
+        if self.wcs is not None:
+            new_wcs = self.wcs[item]
+        else:
+            new_wcs = None
+
+        return self.__class__(new_data, uncertainty=new_uncertainty,
+                              mask=new_mask, wcs=new_wcs,
+                              meta=self.meta, unit=self.unit)
diff --git a/astropy/nddata/nddata.py b/astropy/nddata/nddata.py
index 47b8485..d8ef165 100644
--- a/astropy/nddata/nddata.py
+++ b/astropy/nddata/nddata.py
@@ -1,20 +1,19 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 # This module implements the base NDData class.
 
-from __future__ import absolute_import, division, print_function, unicode_literals
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
 
-from copy import deepcopy
+import collections
 
 import numpy as np
 
-from ..units import Unit, Quantity, UnitsError, dimensionless_unscaled
+from .nddata_base import NDDataBase
+from ..units import Unit, Quantity
 from .. import log
+from ..utils.compat.odict import OrderedDict
 
-from .flag_collection import FlagCollection
-from .nduncertainty import IncompatibleUncertaintiesException, NDUncertainty
-from ..io import registry as io_registry
 from ..config import ConfigAlias
-from ..utils.metadata import MetaData
 
 __all__ = ['NDData']
 
@@ -26,162 +25,149 @@ WARN_UNSUPPORTED_CORRELATED = ConfigAlias(
     '0.4', 'WARN_UNSUPPORTED_CORRELATED', 'warn_unsupported_correlated',
     'astropy.nddata.nddata', 'astropy.nddata')
 
-class NDData(object):
-    """A Superclass for array-based data in Astropy.
+
+class NDData(NDDataBase):
+    """
+    A basic class for array-based data.
 
     The key distinction from raw numpy arrays is the presence of
-    additional metadata such as uncertainties, a mask, units, flags,
+    additional metadata such as uncertainties, a mask, units,
     and/or a coordinate system.
 
     Parameters
     -----------
-    data : `~numpy.ndarray` or `NDData`
-        The actual data contained in this `NDData` object. Not that this
-        will always be copies by *reference* , so you should make copy
-        the ``data`` before passing it in if that's the  desired behavior.
+    data : `~numpy.ndarray`, `~numpy.ndarray`-like, or `NDData`
+        The actual data contained in this `NDData` object. If possible, data
+        will not be copied`data`, so you should make copy the ``data`` before
+        passing it in if that's the desired behavior.
 
-    uncertainty : `~astropy.nddata.NDUncertainty`, optional
-        Uncertainties on the data.
+    uncertainty : any type, optional
+        Uncertainty on the data. The uncertainty *must* have a string attribute
+        named ``uncertainty_type``, but there is otherwise no restriction.
 
     mask : `~numpy.ndarray`-like, optional
-        Mask for the data, given as a boolean Numpy array or any object that
-        can be converted to a boolean Numpy array with a shape
-        matching that of the data. The values must be ``False`` where
+        Mask for the data. The values must be ``False`` where
         the data is *valid* and ``True`` when it is not (like Numpy
         masked arrays). If ``data`` is a numpy masked array, providing
         ``mask`` here will causes the mask from the masked array to be
         ignored.
 
-    flags : `~numpy.ndarray`-like or `~astropy.nddata.FlagCollection`, optional
-        Flags giving information about each pixel. These can be specified
-        either as a Numpy array of any type (or an object which can be converted
-        to a Numpy array) with a shape matching that of the
-        data, or as a `~astropy.nddata.FlagCollection` instance which has a
-        shape matching that of the data.
-
     wcs : undefined, optional
         WCS-object containing the world coordinate system for the data.
 
-        .. warning::
-            This is not yet defind because the discussion of how best to
-            represent this class's WCS system generically is still under
-            consideration. For now just leave it as None
-
     meta : `dict`-like object, optional
-        Metadata for this object.  "Metadata" here means all information that
-        is included with this object but not part of any other attribute
-        of this particular object.  e.g., creation date, unique identifier,
-        simulation parameters, exposure time, telescope name, etc.
+        Metadata for this object. Must be dict-like but no further restriction
+        is placed on meta.
 
     unit : `~astropy.units.UnitBase` instance or str, optional
-        The units of the data.
-
-
-    Raises
-    ------
-    ValueError :
-        If the `uncertainty` or `mask` inputs cannot be broadcast (e.g., match
-        shape) onto ``data``.
+        The units of the data. If data is an `~astropy.units.Quantity` then
+        ``unit`` is set to the unit of the data; is a unit is also explicitly
+        provided an error is raised.
 
     Notes
     -----
-    `NDData` objects can be easily converted to a regular Numpy array
-    using `numpy.asarray`
+    The data in a `NDData` object should be accessed through the data
+    attribute.
 
     For example::
 
         >>> from astropy.nddata import NDData
-        >>> import numpy as np
         >>> x = NDData([1,2,3])
-        >>> np.asarray(x)
+        >>> x.data
         array([1, 2, 3])
-
-    If the `NDData` object has a `mask`, `numpy.asarray` will return a
-    Numpy masked array.
-
-    This is useful, for example, when plotting a 2D image using
-    matplotlib::
-
-        >>> from astropy.nddata import NDData
-        >>> from matplotlib import pyplot as plt
-        >>> x = NDData([[1,2,3], [4,5,6]])
-        >>> plt.imshow(x)
-
     """
 
-    meta = MetaData()
-
-    def __init__(self, data, uncertainty=None, mask=None, flags=None, wcs=None,
+    def __init__(self, data, uncertainty=None, mask=None, wcs=None,
                  meta=None, unit=None):
 
+        super(NDData, self).__init__()
+
         if isinstance(data, self.__class__):
-            self.data = np.array(data.data, subok=True, copy=False)
+            self._data = np.array(data.data, subok=True, copy=False)
             self.uncertainty = data.uncertainty
-            self.mask = data.mask
-            self.flags = data.flags
-            self.wcs = data.wcs
-            self.meta = data.meta
-            self.unit = data.unit
+            self._mask = data.mask
+            self._wcs = data.wcs
+            self._meta = data.meta
+            self._unit = data.unit
 
             if uncertainty is not None:
-                self.uncertainty = uncertainty
+                self._uncertainty = uncertainty
                 log.info("Overwriting NDData's current uncertainty being"
                          " overwritten with specified uncertainty")
 
             if mask is not None:
-                self.mask = mask
-                log.info("Overwriting NDData's current mask with specified mask")
-
-            if flags is not None:
-                self.flags = flags
-                log.info("Overwriting NDData's current flags with specified flag")
+                self._mask = mask
+                log.info("Overwriting NDData's current "
+                         "mask with specified mask")
 
             if wcs is not None:
-                self.wcs = wcs
+                self._wcs = wcs
                 log.info("Overwriting NDData's current wcs with specified wcs")
 
             if meta is not None:
-                self.meta = meta
-                log.info("Overwriting NDData's current meta with specified meta")
+                self._meta = meta
+                log.info("Overwriting NDData's current meta "
+                         "with specified meta")
 
-            if unit is not None:
-                raise ValueError('To convert to different unit please use .to')
+            if unit is not None and unit is not data.unit:
+                raise ValueError('Unit provided in initializer does not '
+                                 'match data unit.')
         else:
             if hasattr(data, 'mask'):
-                self.data = np.array(data.data, subok=True, copy=False)
+                self._data = np.array(data.data, subok=True, copy=False)
 
                 if mask is not None:
-                    self.mask = mask
+                    self._mask = mask
                     log.info("NDData was created with a masked array, and a "
-                             "mask was explictly provided to NDData. The explicitly "
-                             "passed-in mask will be used and the masked array's "
-                             "mask will be ignored.")
+                             "mask was explicitly provided to NDData. The  "
+                             "explicitly passed-in mask will be used and the "
+                             "masked array's mask will be ignored.")
                 else:
-                    self.mask = data.mask
+                    self._mask = data.mask
             elif isinstance(data, Quantity):
-                self.data = np.array(data.value, subok=True, copy=False)
-                self.mask = mask
+                self._data = np.array(data.value, subok=True, copy=False)
+                self._mask = mask
+            elif (not hasattr(data, 'shape') or
+                  not hasattr(data, '__getitem__') or
+                  not hasattr(data, '__array__')):
+                # Data doesn't look like a numpy array, try converting it to
+                # one.
+                self._data = np.array(data, subok=True, copy=False)
+                # Quick check to see if what we got out looks like an array
+                # rather than an object (since numpy will convert a
+                # non-numerical input to an array of objects).
+                if self._data.dtype == 'O':
+                    raise TypeError("Could not convert data to numpy array.")
+                self._mask = mask
             else:
-                self.data = np.array(data, subok=True, copy=False)
-                self.mask = mask
+                self._data = data  # np.array(data, subok=True, copy=False)
+                self._mask = mask
+
+            self._wcs = wcs
+
+            if meta is None:
+                self._meta = OrderedDict()
+            elif not isinstance(meta, collections.Mapping):
+                raise TypeError("meta attribute must be dict-like")
+            else:
+                self._meta = meta
 
-            self.flags = flags
-            self.wcs = wcs
-            self.meta = meta
             if isinstance(data, Quantity):
                 if unit is not None:
                     raise ValueError("Cannot use the unit argument when data "
                                      "is a Quantity")
                 else:
-                    self.unit = data.unit
+                    self._unit = data.unit
             else:
-                self.unit = unit
+                if unit is not None:
+                    self._unit = Unit(unit)
+                else:
+                    self._unit = None
             # This must come after self's unit has been set so that the unit
             # of the uncertainty, if any, can be converted to the unit of the
             # unit of self.
             self.uncertainty = uncertainty
 
-
     def __str__(self):
         return str(self.data)
 
@@ -191,429 +177,25 @@ class NDData(object):
         return ''.join([prefix, body, ')'])
 
     @property
+    def data(self):
+        return self._data
+
+    @property
     def mask(self):
-        if self._mask is np.ma.nomask:
-            return None
-        else:
-            return self._mask
+        return self._mask
 
     @mask.setter
     def mask(self, value):
-        # Check that value is not either type of null mask.
-        if (value is not None) and (value is not np.ma.nomask):
-            mask = np.array(value, dtype=np.bool_, copy=False)
-            if mask.shape != self.shape:
-                raise ValueError("dimensions of mask do not match data")
-            else:
-                self._mask = mask
-        else:
-            # internal representation should be one numpy understands
-            self._mask = np.ma.nomask
-
-    @property
-    def flags(self):
-        return self._flags
-
-    @flags.setter
-    def flags(self, value):
-        if value is not None:
-            if isinstance(value, FlagCollection):
-                if value.shape != self.shape:
-                    raise ValueError("dimensions of FlagCollection does not match data")
-                else:
-                    self._flags = value
-            else:
-                flags = np.array(value, copy=False)
-                if flags.shape != self.shape:
-                    raise ValueError("dimensions of flags do not match data")
-                else:
-                    self._flags = flags
-        else:
-            self._flags = value
-
-    @property
-    def uncertainty(self):
-        return self._uncertainty
-
-    @uncertainty.setter
-    def uncertainty(self, value):
-        if value is not None:
-            if isinstance(value, NDUncertainty):
-                class_name = self.__class__.__name__
-                if self.unit and value._unit:
-                    try:
-                        scaling = (1 * value._unit).to(self.unit)
-                    except UnitsError:
-                        raise UnitsError('Cannot convert unit of uncertainty '
-                                         'to unit of '
-                                         '{0} object.'.format(class_name))
-                    value.array *= scaling
-                elif not self.unit and value._unit:
-                    # Raise an error if uncertainty has unit and data does not
-                    raise ValueError("Cannot assign an uncertainty with unit "
-                                     "to {0} without "
-                                     "a unit".format(class_name))
-                self._uncertainty = value
-                self._uncertainty.parent_nddata = self
-            else:
-                raise TypeError("Uncertainty must be an instance of a NDUncertainty object")
-        else:
-            self._uncertainty = value
+        self._mask = value
 
     @property
     def unit(self):
         return self._unit
 
-    @unit.setter
-    def unit(self, value):
-        from . import conf
-
-        try:
-            if self._unit is not None and conf.warn_setting_unit_directly:
-                log.info('Setting the unit directly changes the unit without '
-                         'updating the data or uncertainty. Use the '
-                         '.convert_unit_to() method to change the unit and '
-                         'scale values appropriately.')
-        except AttributeError:
-            # raised if self._unit has not been set yet, in which case the
-            # warning is irrelevant
-            pass
-
-        if value is None:
-            self._unit = None
-        else:
-            self._unit = Unit(value)
-
-    @property
-    def shape(self):
-        """
-        shape tuple of this object's data.
-        """
-        return self.data.shape
-
     @property
-    def size(self):
-        """
-        integer size of this object's data.
-        """
-        return self.data.size
+    def wcs(self):
+        return self._wcs
 
     @property
-    def dtype(self):
-        """
-        `numpy.dtype` of this object's data.
-        """
-        return self.data.dtype
-
-    @property
-    def ndim(self):
-        """
-        integer dimensions of this object's data
-        """
-        return self.data.ndim
-
-    def __array__(self):
-        """
-        This allows code that requests a Numpy array to use an NDData
-        object as a Numpy array.
-        """
-        if self.mask is not None:
-            return np.ma.masked_array(self.data, self.mask)
-        else:
-            return np.array(self.data)
-
-    def __array_prepare__(self, array, context=None):
-        """
-        This ensures that a masked array is returned if self is masked.
-        """
-        if self.mask is not None:
-            return np.ma.masked_array(array, self.mask)
-        else:
-            return array
-
-    def __getitem__(self, item):
-
-        new_data = self.data[item]
-
-        if self.uncertainty is not None:
-            new_uncertainty = self.uncertainty[item]
-        else:
-            new_uncertainty = None
-
-        if self.mask is not None:
-            new_mask = self.mask[item]
-            # mask setter expects an array, always
-            if new_mask.shape == ():
-                new_mask = np.array(new_mask)
-        else:
-            new_mask = None
-
-        if self.flags is not None:
-            if isinstance(self.flags, np.ndarray):
-                new_flags = self.flags[item]
-                # flags setter expects an array, always
-                if new_flags.shape == ():
-                    new_flags = np.array(new_flags)
-            elif isinstance(self.flags, FlagCollection):
-                raise NotImplementedError('Slicing complex Flags is currently not implemented')
-        else:
-            new_flags = None
-
-        if self.wcs is not None:
-            raise NotImplementedError('Slicing for WCS is not currently implemented')
-        else:
-            new_wcs = None
-
-        return self.__class__(new_data, uncertainty=new_uncertainty,
-                              mask=new_mask, flags=new_flags, wcs=new_wcs,
-                              meta=self.meta, unit=self.unit)
-
-    def _arithmetic(self, operand, propagate_uncertainties, name, operation):
-        """
-        {name} another dataset (``operand``) to this dataset.
-
-        Parameters
-        ----------
-        operand : `~astropy.nddata.NDData`
-            The second operand in the operation a {operator} b
-        propagate_uncertainties : bool
-            Whether to propagate uncertainties following the propagation rules
-            defined by the class used for the `uncertainty` attribute.
-
-        Returns
-        -------
-        result : `~astropy.nddata.NDData`
-            The resulting dataset
-
-        Notes
-        -----
-        This method requires the datasets to have identical WCS
-        properties, equivalent units, and identical shapes. Flags and
-        meta-data get set to None in the resulting dataset. The unit
-        in the result is the same as the unit in ``self``. Uncertainties
-        are propagated, although correlated errors are not supported
-        by any of the built-in uncertainty classes.  If uncertainties
-        are assumed to be correlated, a warning is issued by default
-        (though this can be disabled via the
-        ``astropy.nddata.conf.warn_unsupported_correlated``
-        configuration item). Values masked in either dataset before
-        the operation are masked in the resulting dataset.
-        """
-        from . import conf
-
-        if self.wcs != operand.wcs:
-            raise ValueError("WCS properties do not match")
-
-        # get a sensible placeholder if .unit is None
-        self_unit = self.unit or dimensionless_unscaled
-        operand_unit = operand.unit or dimensionless_unscaled
-
-        # This check could be rolled into the calculation of the result
-        # but checking now avoids a potentially expensive calculation that
-        # would fail anyway.
-        try:
-            # Quantity is designed to work with numpy ufuncs, but plain
-            # Unit is not, so convert units to quantities
-            result_unit = operation(1 * self_unit, 1 * operand_unit).unit
-        except UnitsError:
-            # current API raises ValueError in this case, not UnitError
-            raise ValueError("operand units do not match")
-
-        if self.shape != operand.shape:
-            raise ValueError("operand shapes do not match")
-
-        # Instead of manually scaling the operand data just let Quantity
-        # handle it.
-        # Order of the arguments is important here if the operation is
-        # addition or subtraction and the units of the operands are different
-        # but compatible. NDData follows the convention that Quantity follows
-        # in that case, with the units of the first operand (i.e. self)
-        # determining the units of the result.
-        data = operation(self.data * self_unit, operand.data * operand_unit)
-
-        result_unit = data.unit
-        # If neither self nor operand had units then should return a result
-        # that has no unit. A check that the result_unit is dimensionless
-        # should not be necessary, but also does no harm.
-        if self.unit is None and operand.unit is None:
-            if result_unit is dimensionless_unscaled:
-                result_unit = None
-            else:
-                raise ValueError("arithmetic result was not unitless even "
-                                 "though operands were unitless")
-        data = data.value
-        new_wcs = deepcopy(self.wcs)
-
-        # Call __class__ in case we are dealing with an inherited type
-        result = self.__class__(data, uncertainty=None,
-                                mask=None, flags=None, wcs=new_wcs,
-                                meta=None, unit=result_unit)
-
-        # Prepare to scale uncertainty if it is needed
-        if operand.uncertainty:
-            operand_uncert_value = operand.uncertainty.array
-
-        # By this point the arithmetic has succeeded, so the input units were
-        # consistent with each other given the operation.
-        #
-        # If the operation is addition or subtraction then need to ensure that
-        # the uncertainty of the operand is the same units as the result
-        # (which will be the same as self.unit).
-
-        # The data ought to also be scaled in this case -- for addition of
-        # a StdDevUncertainty this isn't really necessary but other
-        # uncertainties when added/subtracted may depend on both the operand
-        # uncertainty and the operand data.
-
-        # Since the .unit.to methods create a copy, avoid the conversion
-        # unless it is necessary.
-        if (operation in [np.add, np.subtract] and
-                self.unit != operand.unit):
-            operand_data = operand.unit.to(self.unit, operand.data)
-            if operand.uncertainty:
-                operand_uncert_value = operand.unit.to(self.unit,
-                                                       operand_uncert_value)
-        else:
-            operand_data = operand.data
-
-        if operand.uncertainty:
-            # Create a copy here in case this is returned as the uncertainty
-            # of the result.
-            operand_uncertainty = \
-                operand.uncertainty.__class__(operand_uncert_value, copy=True)
-        else:
-            operand_uncertainty = None
-
-        if propagate_uncertainties is None:
-            result.uncertainty = None
-        elif self.uncertainty is None and operand.uncertainty is None:
-            result.uncertainty = None
-        elif self.uncertainty is None:
-            result.uncertainty = operand_uncertainty
-        elif operand.uncertainty is None:
-            result.uncertainty = self.uncertainty.__class__(self.uncertainty,
-                                                            copy=True)
-        else:  # both self and operand have uncertainties
-            if (conf.warn_unsupported_correlated and
-                (not self.uncertainty.support_correlated or
-                 not operand.uncertainty.support_correlated)):
-                log.info("The uncertainty classes used do not support the "
-                         "propagation of correlated errors, so uncertainties"
-                         " will be propagated assuming they are uncorrelated")
-            operand_scaled = operand.__class__(operand_data,
-                                               uncertainty=operand_uncertainty,
-                                               unit=operand.unit,
-                                               wcs=operand.wcs,
-                                               mask=operand.mask,
-                                               flags=operand.flags,
-                                               meta=operand.meta)
-            try:
-                method = getattr(self.uncertainty, propagate_uncertainties)
-                result.uncertainty = method(operand_scaled, result.data)
-            except IncompatibleUncertaintiesException:
-                raise IncompatibleUncertaintiesException(
-                    "Cannot propagate uncertainties of type {0:s} with "
-                    "uncertainties of type {1:s} for {2:s}".format(
-                        self.uncertainty.__class__.__name__,
-                        operand.uncertainty.__class__.__name__,
-                        name))
-
-        if self.mask is None and operand.mask is None:
-            result.mask = None
-        elif self.mask is None:
-            result.mask = operand.mask.copy()
-        elif operand.mask is None:
-            result.mask = self.mask.copy()
-        else:  # combine masks as for Numpy masked arrays
-            result.mask = self.mask | operand.mask  # copy implied by operator
-
-        return result
-
-    def add(self, operand, propagate_uncertainties=True):
-        if propagate_uncertainties:
-            propagate_uncertainties = "propagate_add"
-        else:
-            propagate_uncertainties = None
-        return self._arithmetic(
-            operand, propagate_uncertainties, "addition", np.add)
-    add.__doc__ = _arithmetic.__doc__.format(name="Add", operator="+")
-
-    def subtract(self, operand, propagate_uncertainties=True):
-        if propagate_uncertainties:
-            propagate_uncertainties = "propagate_subtract"
-        else:
-            propagate_uncertainties = None
-        return self._arithmetic(
-            operand, propagate_uncertainties, "subtraction", np.subtract)
-    subtract.__doc__ = _arithmetic.__doc__.format(name="Subtract", operator="-")
-
-    def multiply(self, operand, propagate_uncertainties=True):
-        if propagate_uncertainties:
-            propagate_uncertainties = "propagate_multiply"
-        else:
-            propagate_uncertainties = None
-        return self._arithmetic(
-            operand, propagate_uncertainties, "multiplication", np.multiply)
-    multiply.__doc__ = _arithmetic.__doc__.format(name="Multiply", operator="*")
-
-    def divide(self, operand, propagate_uncertainties=True):
-        if propagate_uncertainties:
-            propagate_uncertainties = "propagate_divide"
-        else:
-            propagate_uncertainties = None
-        return self._arithmetic(
-            operand, propagate_uncertainties, "division", np.divide)
-    divide.__doc__ = _arithmetic.__doc__.format(name="Divide", operator="/")
-
-    def convert_unit_to(self, unit, equivalencies=[]):
-        """
-        Returns a new `NDData` object whose values have been converted
-        to a new unit.
-
-        Parameters
-        ----------
-        unit : `astropy.units.UnitBase` instance or str
-            The unit to convert to.
-
-        equivalencies : list of equivalence pairs, optional
-           A list of equivalence pairs to try if the units are not
-           directly convertible.  See :ref:`unit_equivalencies`.
-
-        Returns
-        -------
-        result : `~astropy.nddata.NDData`
-            The resulting dataset
-
-        Raises
-        ------
-        UnitsError
-            If units are inconsistent.
-
-        Notes
-        -----
-        Flags are set to None in the result.
-        """
-        if self.unit is None:
-            raise ValueError("No unit specified on source data")
-        data = self.unit.to(unit, self.data, equivalencies=equivalencies)
-        if self.uncertainty is not None:
-            uncertainty_values = self.unit.to(unit, self.uncertainty.array,
-                                              equivalencies=equivalencies)
-            # should work for any uncertainty class
-            uncertainty = self.uncertainty.__class__(uncertainty_values)
-        else:
-            uncertainty = None
-        if self.mask is not None:
-            new_mask = self.mask.copy()
-        else:
-            new_mask = None
-        # Call __class__ in case we are dealing with an inherited type
-        result = self.__class__(data, uncertainty=uncertainty,
-                                mask=new_mask, flags=self.flags,
-                                wcs=self.wcs,
-                                meta=self.meta, unit=unit)
-
-        return result
-
-    read = classmethod(io_registry.read)
-    write = io_registry.write
+    def meta(self):
+        return self._meta
diff --git a/astropy/nddata/nddata_base.py b/astropy/nddata/nddata_base.py
new file mode 100644
index 0000000..439f0db
--- /dev/null
+++ b/astropy/nddata/nddata_base.py
@@ -0,0 +1,92 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# This module implements the base NDDataBase class.
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from abc import ABCMeta, abstractproperty, abstractmethod
+
+from ..extern import six
+
+__all__ = ['NDDataBase']
+
+
+ at six.add_metaclass(ABCMeta)
+class NDDataBase(object):
+    """
+    Base metaclass that defines the interface for NDData
+
+    Classes that wish to use this interface without inheriting from
+    `~astropy.nddata.NDData` should subclass ``NDDataBase`` instead.
+
+    All properties and methods except uncertainty must be override by derived
+    classes.
+    """
+
+    @abstractmethod
+    def __init__(self):
+        self._uncertainty = None
+
+    @abstractproperty
+    def data(self):
+        """
+        The data; should be capable of behaving like a numpy array, though it
+        need not actually be a numpy array.
+        """
+        pass
+
+    @abstractproperty
+    def mask(self):
+        """
+        Mask for the data, following the numpy convention that ``True`` means
+        the data should not be used.
+        """
+        return None
+
+    @abstractproperty
+    def unit(self):
+        """
+        Unit for the data, if any.
+        """
+        return None
+
+    @abstractproperty
+    def wcs(self):
+        """
+        WCS for the data, if any.
+        """
+        return None
+
+    @abstractproperty
+    def meta(self):
+        """
+        Metadata, if any, must be dict-like.
+        """
+        return None
+
+    # uncertainty and its setter are implemented as concrete to enforce the
+    # logic in the uncertainty setter. For a long discussion of the problems
+    # with trying to implement them as abstract (particularly the setter but
+    # not the getter), see http://bugs.python.org/issue11610
+    #
+    # In python >= 3.3 it would be easy to decorate one of these (setter or
+    # getter) as abstract but not the other.
+    @property
+    def uncertainty(self):
+        """
+        Uncertainty in the data.
+
+        Uncertainty must have an attribute ``uncertainty_type`` that is
+        a string.
+        """
+        return self._uncertainty
+
+    @uncertainty.setter
+    def uncertainty(self, value):
+        if value is not None:
+            if (not hasattr(value, 'uncertainty_type') or
+                    not isinstance(value.uncertainty_type, six.string_types)):
+
+                raise TypeError('Uncertainty must have attribute '
+                                'uncertainty_type whose type is string.')
+        self._uncertainty = value
diff --git a/astropy/nddata/nduncertainty.py b/astropy/nddata/nduncertainty.py
index b586ebc..efdc354 100644
--- a/astropy/nddata/nduncertainty.py
+++ b/astropy/nddata/nduncertainty.py
@@ -1,6 +1,7 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
-from __future__ import absolute_import, division, print_function, unicode_literals
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
 
 import abc
 
@@ -8,6 +9,7 @@ import numpy as np
 
 from ..utils.compat import ignored
 from ..units import Quantity
+from ..extern import six
 
 __all__ = ['MissingDataAssociationException',
            'IncompatibleUncertaintiesException', 'NDUncertainty',
@@ -29,19 +31,20 @@ class MissingDataAssociationException(Exception):
 
 
 class NDUncertainty(object):
-    '''
+    """
     This is the base class for uncertainty classes used with NDData. It is
     implemented as an abstract class and should never be directly
     instantiated.
 
     Classes inheriting from NDData should overload the ``propagate_*``
     methods, keeping the call signature the same. The propagate methods can
-    assume that a `parent_nddata` attribute is present which links to the parent_nddata
-    dataset, and take an `~astropy.nddata.NDData` instance as the positional
-    argument, *not* an `~astropy.nddata.NDUncertainty` instance, because the
-    `~astropy.nddata.NDData` instance can be used to access both the data and
-    the uncertainties (some propagations require the data values).
-    '''
+    assume that a `parent_nddata` attribute is present which links to the
+    parent_nddata dataset, and take an `~astropy.nddata.NDData` instance as
+    the positional argument, *not* an `~astropy.nddata.NDUncertainty`
+    instance, because the `~astropy.nddata.NDData` instance can be used to
+    access both the data and the uncertainties (some propagations require the
+    data values).
+    """
 
     __metaclass__ = abc.ABCMeta
 
@@ -52,7 +55,8 @@ class NDUncertainty(object):
     @property
     def parent_nddata(self):
         if self._parent_nddata is None:
-            raise MissingDataAssociationException("uncertainty is not associated with an NDData object")
+            message = "uncertainty is not associated with an NDData object"
+            raise MissingDataAssociationException(message)
         else:
             return self._parent_nddata
 
@@ -60,9 +64,19 @@ class NDUncertainty(object):
     def parent_nddata(self, value):
         self._parent_nddata = value
 
+    @property
+    def uncertainty_type(self):
+        return self._uncertainty_type
+
+    @uncertainty_type.setter
+    def uncertainty_type(self, value):
+        if not isinstance(value, six.string_types):
+            raise ValueError('uncertainty_type must be a string.')
+        self._uncertainty_type = value
+
     @abc.abstractmethod
     def propagate_add(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for addition.
 
         Parameters
@@ -81,11 +95,11 @@ class NDUncertainty(object):
         ------
         IncompatibleUncertaintiesException
             Raised if the method does not know how to add the uncertainties
-        '''
+        """
 
     @abc.abstractmethod
     def propagate_subtract(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for subtraction.
 
         Parameters
@@ -104,11 +118,11 @@ class NDUncertainty(object):
         ------
         IncompatibleUncertaintiesException
             Raised if the method does not know how to add the uncertainties
-        '''
+        """
 
     @abc.abstractmethod
     def propagate_multiply(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for multiplication.
 
         Parameters
@@ -122,11 +136,11 @@ class NDUncertainty(object):
         -------
         result_uncertainty : NDUncertainty instance
             The resulting uncertainty
-        '''
+        """
 
     @abc.abstractmethod
     def propagate_divide(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for division.
 
         Parameters
@@ -140,18 +154,19 @@ class NDUncertainty(object):
         -------
         result_uncertainty : NDUncertainty instance
             The resulting uncertainty
-        '''
+        """
 
 
 class StdDevUncertainty(NDUncertainty):
-    '''
+    """
     A class for standard deviation uncertainties
-    '''
+    """
 
     support_correlated = False
 
     def __init__(self, array=None, copy=True):
         self._unit = None
+        self.uncertainty_type = 'std'
         if array is None:
             self.array = None
         elif isinstance(array, StdDevUncertainty):
@@ -164,21 +179,23 @@ class StdDevUncertainty(NDUncertainty):
 
     @property
     def parent_nddata(self):
+        message = "Uncertainty is not associated with an NDData object"
         try:
             if self._parent_nddata is None:
-                raise MissingDataAssociationException("Uncertainty is not associated with an NDData object")
+                raise MissingDataAssociationException(message)
             else:
                 return self._parent_nddata
         except AttributeError:
-            raise MissingDataAssociationException("Uncertainty is not associated with an NDData object")
+            raise MissingDataAssociationException(message)
 
     @parent_nddata.setter
     def parent_nddata(self, value):
         if self.array is None or value is None:
             self._parent_nddata = value
         else:
-            if value.shape != self.array.shape:
-                raise ValueError("parent shape does not match array data shape")
+            if value.data.shape != self.array.shape:
+                raise ValueError("parent shape does not match "
+                                 "array data shape")
         self._parent_nddata = value
 
     @property
@@ -189,13 +206,13 @@ class StdDevUncertainty(NDUncertainty):
     def array(self, value):
         if value is not None:
             with ignored(MissingDataAssociationException):
-                if value.shape != self.parent_nddata.shape:
-                    raise ValueError(
-                            "array shape does not match parent data shape")
+                if value.shape != self.parent_nddata.data.shape:
+                    raise ValueError("array shape does not match "
+                                     "parent data shape")
         self._array = value
 
     def propagate_add(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for addition.
 
         Parameters
@@ -213,8 +230,9 @@ class StdDevUncertainty(NDUncertainty):
         Raises
         ------
         IncompatibleUncertaintiesException
-            Raised if the method does not know how to propagate the uncertainties
-        '''
+            Raised if the method does not know how to propagate the
+            uncertainties.
+        """
 
         if not isinstance(other_nddata.uncertainty, StdDevUncertainty):
             raise IncompatibleUncertaintiesException
@@ -223,23 +241,25 @@ class StdDevUncertainty(NDUncertainty):
             raise ValueError("standard deviation values are not set")
 
         if other_nddata.uncertainty.array is None:
-            raise ValueError("standard deviation values are not set in other_nddata")
+            raise ValueError("standard deviation values are not set "
+                             "in other_nddata")
 
         result_uncertainty = StdDevUncertainty()
-        result_uncertainty.array = np.sqrt(self.array ** 2 + other_nddata.uncertainty.array ** 2)
+        result_uncertainty.array = np.sqrt(self.array**2 +
+                                           other_nddata.uncertainty.array**2)
 
         return result_uncertainty
 
     def __getitem__(self, item):
-        '''
+        """
             Slice the standard deviation array using standard numpy slicing
-        '''
+        """
 
         new_array = self.array[item]
         return self.__class__(new_array, copy=False)
 
     def propagate_subtract(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for subtraction.
 
         Parameters
@@ -257,8 +277,9 @@ class StdDevUncertainty(NDUncertainty):
         Raises
         ------
         IncompatibleUncertaintiesException
-            Raised if the method does not know how to propagate the uncertainties
-        '''
+            Raised if the method does not know how to propagate the
+            uncertainties.
+        """
 
         if not isinstance(other_nddata.uncertainty, StdDevUncertainty):
             raise IncompatibleUncertaintiesException
@@ -267,16 +288,18 @@ class StdDevUncertainty(NDUncertainty):
             raise ValueError("standard deviation values are not set")
 
         if other_nddata.uncertainty.array is None:
-            raise ValueError("standard deviation values are not set in other_nddata")
+            raise ValueError("standard deviation values are not set "
+                             "in other_nddata")
 
         result_uncertainty = StdDevUncertainty()
-        result_uncertainty.array = np.sqrt(self.array ** 2 + other_nddata.uncertainty.array ** 2)
+        result_uncertainty.array = np.sqrt(self.array**2 +
+                                           other_nddata.uncertainty.array**2)
 
         return result_uncertainty
 
     def propagate_multiply(self, other_nddata, result_data):
-        '''
-        Propagate uncertainties for mutliplication.
+        """
+        Propagate uncertainties for multiplication.
 
         Parameters
         ----------
@@ -293,8 +316,9 @@ class StdDevUncertainty(NDUncertainty):
         Raises
         ------
         IncompatibleUncertaintiesException
-            Raised if the method does not know how to propagate the uncertainties
-        '''
+            Raised if the method does not know how to propagate the
+            uncertainties.
+        """
 
         if not isinstance(other_nddata.uncertainty, StdDevUncertainty):
             raise IncompatibleUncertaintiesException
@@ -303,17 +327,19 @@ class StdDevUncertainty(NDUncertainty):
             raise ValueError("standard deviation values are not set")
 
         if other_nddata.uncertainty.array is None:
-            raise ValueError("standard deviation values are not set in other_nddata")
+            raise ValueError("standard deviation values are not set in "
+                             "other_nddata")
 
         result_uncertainty = StdDevUncertainty()
-        result_uncertainty.array = (np.sqrt((self.array / self.parent_nddata.data) ** 2
-                                            + (other_nddata.uncertainty.array / other_nddata.data) ** 2)
-                                    * result_data)
+        result_uncertainty.array = \
+            (np.sqrt((self.array/self.parent_nddata.data)**2
+             + (other_nddata.uncertainty.array/other_nddata.data)**2) *
+             result_data)
 
         return result_uncertainty
 
     def propagate_divide(self, other_nddata, result_data):
-        '''
+        """
         Propagate uncertainties for division.
 
         Parameters
@@ -331,8 +357,9 @@ class StdDevUncertainty(NDUncertainty):
         Raises
         ------
         IncompatibleUncertaintiesException
-            Raised if the method does not know how to propagate the uncertainties
-        '''
+            Raised if the method does not know how to propagate the
+            uncertainties.
+        """
 
         if not isinstance(other_nddata.uncertainty, StdDevUncertainty):
             raise IncompatibleUncertaintiesException
@@ -341,11 +368,13 @@ class StdDevUncertainty(NDUncertainty):
             raise ValueError("standard deviation values are not set")
 
         if other_nddata.uncertainty.array is None:
-            raise ValueError("standard deviation values are not set in other_nddata")
+            raise ValueError("standard deviation values are not set "
+                             "in other_nddata")
 
         result_uncertainty = StdDevUncertainty()
-        result_uncertainty.array = (np.sqrt((self.array / self.parent_nddata.data) ** 2
-                                            + (other_nddata.uncertainty.array / other_nddata.data) ** 2)
-                                    * result_data)
+        result_uncertainty.array = \
+            (np.sqrt((self.array/self.parent_nddata.data)**2
+             + (other_nddata.uncertainty.array/other_nddata.data)**2) *
+             result_data)
 
         return result_uncertainty
diff --git a/astropy/nddata/tests/test_decorators.py b/astropy/nddata/tests/test_decorators.py
new file mode 100644
index 0000000..a7c19ca
--- /dev/null
+++ b/astropy/nddata/tests/test_decorators.py
@@ -0,0 +1,182 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import inspect
+
+import numpy as np
+
+from ...tests.helper import catch_warnings, pytest
+from ... import units as u
+
+from ..nddata import NDData
+from ..decorators import support_nddata
+
+
+ at support_nddata
+def wrapped_function_1(data, wcs=None, unit=None):
+    return data, wcs, unit
+
+
+def test_pass_numpy():
+
+    data_in = np.array([1, 2, 3])
+    data_out, wcs_out, unit_out = wrapped_function_1(data=data_in)
+
+    assert data_out is data_in
+    assert wcs_out is None
+    assert unit_out is None
+
+
+def test_pass_all_separate():
+
+    data_in = np.array([1, 2, 3])
+    wcs_in = "the wcs"
+    unit_in = u.Jy
+
+    data_out, wcs_out, unit_out = wrapped_function_1(data=data_in, wcs=wcs_in, unit=unit_in)
+
+    assert data_out is data_in
+    assert wcs_out is wcs_in
+    assert unit_out is unit_in
+
+
+def test_pass_nddata():
+
+    data_in = np.array([1, 2, 3])
+    wcs_in = "the wcs"
+    unit_in = u.Jy
+
+    nddata_in = NDData(data_in, wcs=wcs_in, unit=unit_in)
+
+    data_out, wcs_out, unit_out = wrapped_function_1(nddata_in)
+
+    assert data_out is data_in
+    assert wcs_out is wcs_in
+    assert unit_out is unit_in
+
+
+def test_pass_nddata_and_explicit():
+
+    data_in = np.array([1, 2, 3])
+    wcs_in = "the wcs"
+    unit_in = u.Jy
+    unit_in_alt = u.mJy
+
+    nddata_in = NDData(data_in, wcs=wcs_in, unit=unit_in)
+
+    with catch_warnings() as w:
+        data_out, wcs_out, unit_out = wrapped_function_1(nddata_in, unit=unit_in_alt)
+
+    assert data_out is data_in
+    assert wcs_out is wcs_in
+    assert unit_out is unit_in_alt
+
+    assert len(w) == 1
+    assert str(w[0].message) == ("Property unit has been passed explicitly and as "
+                                 "an NDData property, using explicitly specified value")
+
+
+def test_pass_nddata_ignored():
+
+    data_in = np.array([1, 2, 3])
+    wcs_in = "the wcs"
+    unit_in = u.Jy
+
+    nddata_in = NDData(data_in, wcs=wcs_in, unit=unit_in, mask=[0, 1, 0])
+
+    with catch_warnings() as w:
+        data_out, wcs_out, unit_out = wrapped_function_1(nddata_in)
+
+    assert data_out is data_in
+    assert wcs_out is wcs_in
+    assert unit_out is unit_in
+
+    assert len(w) == 1
+    assert str(w[0].message) == ("The following attributes were set on the data "
+                                 "object, but will be ignored by the function: mask")
+
+
+def test_incorrect_first_argument():
+
+    with pytest.raises(ValueError) as exc:
+        @support_nddata
+        def wrapped_function_2(something, wcs=None, unit=None):
+            pass
+    assert exc.value.args[0] == "Can only wrap functions whose first positional argument is `data`"
+
+    with pytest.raises(ValueError) as exc:
+        @support_nddata
+        def wrapped_function_3(something, data, wcs=None, unit=None):
+            pass
+    assert exc.value.args[0] == "Can only wrap functions whose first positional argument is `data`"
+
+    with pytest.raises(ValueError) as exc:
+        @support_nddata
+        def wrapped_function_4(wcs=None, unit=None):
+            pass
+    assert exc.value.args[0] == "Can only wrap functions whose first positional argument is `data`"
+
+
+def test_wrap_function_no_kwargs():
+
+    @support_nddata
+    def wrapped_function_5(data, other_data):
+        return data
+
+    data_in = np.array([1, 2, 3])
+    nddata_in = NDData(data_in)
+
+    assert wrapped_function_5(nddata_in, [1, 2, 3]) is data_in
+
+
+def test_wrap_function_repack_valid():
+
+    @support_nddata(repack=True, returns=['data'])
+    def wrapped_function_5(data, other_data):
+        return data
+
+    data_in = np.array([1, 2, 3])
+    nddata_in = NDData(data_in)
+
+    nddata_out = wrapped_function_5(nddata_in, [1, 2, 3])
+
+    assert isinstance(nddata_out, NDData)
+    assert nddata_out.data is data_in
+
+
+def test_wrap_function_accepts():
+
+    class MyData(NDData):
+        pass
+
+    @support_nddata(accepts=MyData)
+    def wrapped_function_5(data, other_data):
+        return data
+
+    data_in = np.array([1, 2, 3])
+    nddata_in = NDData(data_in)
+    mydata_in = MyData(data_in)
+
+    assert wrapped_function_5(mydata_in, [1, 2, 3]) is data_in
+
+    with pytest.raises(TypeError) as exc:
+        wrapped_function_5(nddata_in, [1, 2, 3])
+    assert exc.value.args[0] == "Only NDData sub-classes that inherit from MyData can be used by this function"
+
+
+def test_wrap_preserve_signature_docstring():
+
+    @support_nddata
+    def wrapped_function_6(data, wcs=None, unit=None):
+        """
+        An awesome function
+        """
+        pass
+
+    assert wrapped_function_6.__doc__.strip() == "An awesome function"
+
+    signature = inspect.formatargspec(*inspect.getargspec(wrapped_function_6))
+
+    assert signature == "(data, wcs=None, unit=None)"
diff --git a/astropy/nddata/tests/test_flag_collection.py b/astropy/nddata/tests/test_flag_collection.py
index 31b44c6..373d404 100644
--- a/astropy/nddata/tests/test_flag_collection.py
+++ b/astropy/nddata/tests/test_flag_collection.py
@@ -2,7 +2,10 @@
 
 # TEST_UNICODE_LITERALS
 
-from __future__ import absolute_import, division, print_function, unicode_literals
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import os
 
 import numpy as np
 
@@ -17,13 +20,15 @@ def test_init():
 def test_init_noshape():
     with pytest.raises(Exception) as exc:
         FlagCollection()
-    assert exc.value.args[0] == 'FlagCollection should be initialized with the shape of the data'
+    assert exc.value.args[0] == ('FlagCollection should be initialized with '
+                                 'the shape of the data')
 
 
 def test_init_notiterable():
     with pytest.raises(Exception) as exc:
         FlagCollection(shape=1.)
-    assert exc.value.args[0] == 'FlagCollection shape should be an iterable object'
+    assert exc.value.args[0] == ('FlagCollection shape should be '
+                                 'an iterable object')
 
 
 def test_setitem():
@@ -42,8 +47,10 @@ def test_setitem_invalid_type(value):
     assert exc.value.args[0] == 'flags should be given as a Numpy array'
 
 
+ at pytest.mark.skipif(os.environ.get('APPVEYOR'),  reason="fails on AppVeyor")
 def test_setitem_invalid_shape():
     f = FlagCollection(shape=(1, 2, 3))
-    with pytest.raises(Exception) as exc:
+    with pytest.raises(ValueError) as exc:
         f['a'] = np.ones((3, 2, 1))
-    assert exc.value.args[0] == 'flags array shape (3, 2, 1) does not match data shape (1, 2, 3)'
+    assert exc.value.args[0].startswith('flags array shape')
+    assert exc.value.args[0].endswith('does not match data shape (1, 2, 3)')
diff --git a/astropy/nddata/tests/test_nddata.py b/astropy/nddata/tests/test_nddata.py
index a0cefa2..8d71328 100644
--- a/astropy/nddata/tests/test_nddata.py
+++ b/astropy/nddata/tests/test_nddata.py
@@ -2,7 +2,8 @@
 
 # TEST_UNICODE_LITERALS
 
-from __future__ import absolute_import, division, print_function, unicode_literals
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
 
 import textwrap
 
@@ -10,7 +11,7 @@ import numpy as np
 from numpy.testing import assert_array_equal
 
 from ..nddata import NDData
-from ..nduncertainty import StdDevUncertainty, IncompatibleUncertaintiesException, NDUncertainty
+from ..nduncertainty import StdDevUncertainty, NDUncertainty
 from ...tests.helper import pytest, raises
 from ... import units as u
 from ...utils import NumpyRNGContext
@@ -43,24 +44,47 @@ def test_nddata_empty():
         NDData()  # empty initializer should fail
 
 
+def test_nddata_init_with_nonarray():
+    inp = [1, 2, 3]
+    nd = NDData(inp)
+    assert (np.array(inp) == nd.data).all()
+
+
 def test_nddata_simple():
     with NumpyRNGContext(123):
         nd = NDData(np.random.random((10, 10)))
-    assert nd.shape == (10, 10)
-    assert nd.size == 100
-    assert nd.dtype == np.dtype(float)
+    assert nd.data.shape == (10, 10)
+    assert nd.data.size == 100
+    assert nd.data.dtype == np.dtype(float)
+
+
+def test_nddata_data_properties():
+    # First one is slicable but has no shape, so should fail.
+    with pytest.raises(TypeError):
+        NDData({'a': 'dict'})
+
+    # This has a shape but is not slicable
+    class Shape(object):
+        def __init__(self):
+            self.shape = 5
+
+        def __repr__(self):
+            return '7'
+
+    with pytest.raises(TypeError):
+        NDData(Shape())
 
 
 def test_nddata_str():
-    arr1d = NDData([1, 2, 3])
+    arr1d = NDData(np.array([1, 2, 3]))
     assert str(arr1d) == '[1 2 3]'
 
-    arr2d = NDData([[1, 2], [3, 4]])
+    arr2d = NDData(np.array([[1, 2], [3, 4]]))
     assert str(arr2d) == textwrap.dedent("""
         [[1 2]
          [3 4]]"""[1:])
 
-    arr3d = NDData([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
+    arr3d = NDData(np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]))
     assert str(arr3d) == textwrap.dedent("""
         [[[1 2]
           [3 4]]
@@ -70,15 +94,15 @@ def test_nddata_str():
 
 
 def test_nddata_repr():
-    arr1d = NDData([1, 2, 3])
+    arr1d = NDData(np.array([1, 2, 3]))
     assert repr(arr1d) == 'NDData([1, 2, 3])'
 
-    arr2d = NDData([[1, 2], [3, 4]])
+    arr2d = NDData(np.array([[1, 2], [3, 4]]))
     assert repr(arr2d) == textwrap.dedent("""
         NDData([[1, 2],
                 [3, 4]])"""[1:])
 
-    arr3d = NDData([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
+    arr3d = NDData(np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]))
     assert repr(arr3d) == textwrap.dedent("""
         NDData([[[1, 2],
                  [3, 4]],
@@ -89,82 +113,36 @@ def test_nddata_repr():
 
 def test_nddata_mask_valid():
     with NumpyRNGContext(456):
-        NDData(np.random.random((10, 10)), mask=np.random.random((10, 10)) > 0.5)
-
-
- at pytest.mark.parametrize('mask_in', [
-                         np.array([True, False]),
-                         np.array([1, 0]),
-                         [True, False],
-                         [1, 0]])
-def test_nddata_mask_init_without_np_array(mask_in):
-    ndd = NDData([1, 1], mask=mask_in)
-    assert (ndd.mask == mask_in).all()
-
-
- at pytest.mark.parametrize(('shape'), [(10,), (5, 5), (3, 10, 10)])
-def test_nddata_mask_invalid_shape(shape):
-    with pytest.raises(ValueError) as exc:
-        with NumpyRNGContext(789):
-            NDData(np.random.random((10, 10)), mask=np.random.random(shape) > 0.5)
-    assert exc.value.args[0] == 'dimensions of mask do not match data'
-
-
- at pytest.mark.parametrize('flags_in', [
-                         np.array([True, False]),
-                         np.array([1, 0]),
-                         [True, False],
-                         [1, 0],
-                         np.array(['a', 'b']),
-                         ['a', 'b']])
-def test_nddata_flags_init_without_np_array(flags_in):
-    ndd = NDData([1, 1], flags=flags_in)
-    assert (ndd.flags == flags_in).all()
-
-
- at pytest.mark.parametrize(('shape'), [(10,), (5, 5), (3, 10, 10)])
-def test_nddata_flags_invalid_shape(shape):
-    with pytest.raises(ValueError) as exc:
-        with NumpyRNGContext(789):
-            NDData(np.random.random((10, 10)), flags=np.random.random(shape))
-    assert exc.value.args[0] == 'dimensions of flags do not match data'
-
+        NDData(np.random.random((10, 10)),
+               mask=np.random.random((10, 10)) > 0.5)
 
 
 def test_nddata_uncertainty_init():
     u = StdDevUncertainty(array=np.ones((5, 5)))
     d = NDData(np.ones((5, 5)), uncertainty=u)
 
+    # Expect a TypeError if the uncertainty is missing
+    # attribute uncertainty_type.
+    with pytest.raises(TypeError):
+        NDData(np.array([1]), uncertainty=5)
 
-def test_nddata_uncertainty_init_invalid_shape_1():
-    u = StdDevUncertainty(array=np.ones((6, 6)))
-    with pytest.raises(ValueError) as exc:
-        NDData(np.ones((5, 5)), uncertainty=u)
-    assert exc.value.args[0] == 'parent shape does not match array data shape'
-
-
-def test_nddata_uncertainty_init_invalid_shape_2():
-    u = StdDevUncertainty()
-    NDData(np.ones((5, 5)), uncertainty=u)
-    with pytest.raises(ValueError) as exc:
-        u.array = np.ones((6, 6))
-    assert exc.value.args[0] == 'array shape does not match parent data shape'
+    # Expect a TypeError if the uncertainty has attribute uncertainty_type
+    # but it is not a string.
 
+    class BadUncertainty(object):
+        def __init__(self):
+            self.uncertainty_type = 5
 
- at pytest.mark.parametrize(('uncertainty'), [1., 'spam', np.ones((5, 5))])
-def test_nddata_uncertainty_invalid_type(uncertainty):
-    with pytest.raises(TypeError) as exc:
-        NDData(np.ones((5, 5)), uncertainty=uncertainty)
-    assert exc.value.args[0] == 'Uncertainty must be an instance of a NDUncertainty object'
+    with pytest.raises(TypeError):
+        NDData(np.array([1]), uncertainty=BadUncertainty())
 
 
 def test_nddata_init_from_nddata_data_argument_only():
-    ndd1 = NDData([1])
+    ndd1 = NDData(np.array([1]))
     ndd2 = NDData(ndd1)
     assert ndd2.wcs == ndd1.wcs
     assert ndd2.uncertainty == ndd1.uncertainty
     assert ndd2.mask == ndd1.mask
-    assert ndd2.flags == ndd1.flags
     assert ndd2.unit == ndd1.unit
     assert ndd2.meta == ndd1.meta
 
@@ -180,311 +158,9 @@ def test_nddata_copy_ref():
 
 
 def test_nddata_conversion():
-    nd = NDData([[1, 2, 3], [4, 5, 6]])
-    assert nd.size == 6
-    assert nd.dtype == np.dtype(int)
-
-
-def test_ndddata_with_mask_acts_like_masked_array():
-    # test for #2414
-    input_mask = np.array([True, False, False])
-    input_data = np.array([1, 2, 3])
-    ndd_masked = NDData(input_data.copy(), mask=input_mask.copy())
-    other = - np.ones_like(input_data)
-    result1 = ndd_masked * other
-    result2 = other * ndd_masked
-    # Test for both orders of multiplication -- if multiplication is
-    # eventually overridden for NDData the result can depend on order.
-    for result in [result1, result2]:
-        # Result should be a masked array because input NDData was masked
-        assert isinstance(result, np.ma.MaskedArray)
-        # Result mask should match input mask because other has no mask
-        assert np.all(result.mask == input_mask)
-        assert np.all(result[~result.mask] == - input_data[~input_mask])
-
-
-def test_nddata_unmasked_in_operation_with_masked_numpy_array():
-    # test for #2417
-    ndd = NDData([1, 2, 3])
-    np_data = -np.ones_like(ndd)
-    np_mask = np.array([True, False, True])
-    np_arr_masked = np.ma.masked_array(np_data, mask=np_mask, copy=True)
-    # check multiplication in both orders as in test above
-    result1 = ndd * np_arr_masked
-    result2 = np_arr_masked * ndd
-    for result in [result1, result2]:
-        # multiplying by a masked numpy array should return a masked array
-        assert isinstance(result, np.ma.MaskedArray)
-        assert np.all(result.mask == np_mask)
-        assert np.all(result[~result.mask] == -ndd.data[~np_mask])
-
-
-def test_nddata_add():
-    d1 = NDData(np.ones((5, 5)))
-    d2 = NDData(np.ones((5, 5)))
-    d3 = d1.add(d2)
-    assert np.all(d3.data == 2.)
-
-
-def test_nddata_add_mismatch_wcs():
-    d1 = NDData(np.ones((5, 5)), wcs=1.)
-    d2 = NDData(np.ones((5, 5)), wcs=2.)
-    with pytest.raises(ValueError) as exc:
-        d1.add(d2)
-    assert exc.value.args[0] == "WCS properties do not match"
-
-
-def test_nddata_add_mismatch_units():
-    d1 = NDData(np.ones((5, 5)), unit='Jy')
-    d2 = NDData(np.ones((5, 5)), unit='erg/s')
-    with pytest.raises(ValueError) as exc:
-        d1.add(d2)
-    assert exc.value.args[0] == "operand units do not match"
-
-
-def test_nddata_add_mismatch_shape():
-    d1 = NDData(np.ones((5, 5)))
-    d2 = NDData(np.ones((6, 6)))
-    with pytest.raises(ValueError) as exc:
-        d1.add(d2)
-    assert exc.value.args[0] == "operand shapes do not match"
-
-
-def test_nddata_add_with_masks():
-    # numpy masked arrays mask the result of binary operations if the
-    # mask of either operand is set.
-    # Does NDData?
-    ndd1 = NDData([1, 2], mask=np.array([True, False]))
-    other_mask = ~ ndd1.mask
-    ndd2 = NDData([1, 2], mask=other_mask)
-    result = ndd1.add(ndd2)
-    # The result should have all entries masked...
-    assert result.mask.all()
-
-
-def test_nddata_add_uncertainties():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = StdDevUncertainty(array=np.ones((5, 5)))
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)), uncertainty=u2)
-    d3 = d1.add(d2)
-    assert np.all(d3.data == 2.)
-    assert_array_equal(d3.uncertainty.array, np.sqrt(10.))
-
-
-def test_nddata_add_uncertainties_mismatch():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = FakeUncertainty()
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)), uncertainty=u2)
-    with pytest.raises(IncompatibleUncertaintiesException) as exc:
-        d3 = d1.add(d2)
-    assert exc.value.args[0] == 'Cannot propagate uncertainties of type StdDevUncertainty with uncertainties of type FakeUncertainty for addition'
-
-
-def test_nddata_subtract():
-    d1 = NDData(np.ones((5, 5)))
-    d2 = NDData(np.ones((5, 5)) * 2.)
-    d3 = d1.subtract(d2)
-    assert np.all(d3.data == -1.)
-
-
-def test_nddata_subtract_mismatch_wcs():
-    d1 = NDData(np.ones((5, 5)), wcs=1.)
-    d2 = NDData(np.ones((5, 5)) * 2., wcs=2.)
-    with pytest.raises(ValueError) as exc:
-        d1.subtract(d2)
-    assert exc.value.args[0] == "WCS properties do not match"
-
-
-def test_nddata_subtract_mismatch_units():
-    d1 = NDData(np.ones((5, 5)), unit='Jy')
-    d2 = NDData(np.ones((5, 5)) * 2., unit='erg/s')
-    with pytest.raises(ValueError) as exc:
-        d1.subtract(d2)
-    assert exc.value.args[0] == "operand units do not match"
-
-
-def test_nddata_subtract_mismatch_shape():
-    d1 = NDData(np.ones((5, 5)))
-    d2 = NDData(np.ones((6, 6)) * 2.)
-    with pytest.raises(ValueError) as exc:
-        d1.subtract(d2)
-    assert exc.value.args[0] == "operand shapes do not match"
-
-
-def test_nddata_subtract_uncertainties():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = StdDevUncertainty(array=np.ones((5, 5)))
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)) * 2., uncertainty=u2)
-    d3 = d1.subtract(d2)
-    assert np.all(d3.data == -1.)
-    assert_array_equal(d3.uncertainty.array, np.sqrt(10.))
-
-
-def test_nddata_multiply_uncertainties():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = StdDevUncertainty(array=np.ones((5, 5)))
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)) * 2., uncertainty=u2)
-    d3 = d1.multiply(d2)
-    assert np.all(d3.data == 2.)
-    assert_array_equal(d3.uncertainty.array, 2 * np.sqrt(9.25))
-
-
-def test_nddata_divide_uncertainties():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = StdDevUncertainty(array=np.ones((5, 5)))
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)) * 2., uncertainty=u2)
-    d3 = d1.divide(d2)
-    assert np.all(d3.data == 0.5)
-    assert_array_equal(d3.uncertainty.array, 0.5 * np.sqrt(9.25))
-
-
-def test_nddata_subtract_uncertainties_mismatch():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    u2 = FakeUncertainty()
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = NDData(np.ones((5, 5)) * 2., uncertainty=u2)
-    with pytest.raises(IncompatibleUncertaintiesException) as exc:
-        d3 = d1.subtract(d2)
-    assert exc.value.args[0] == 'Cannot propagate uncertainties of type StdDevUncertainty with uncertainties of type FakeUncertainty for subtraction'
-
-
- at pytest.mark.parametrize('op1_unc,op2_unc', [
-                         (None, None),
-                         (StdDevUncertainty([1]), None),
-                         (None, StdDevUncertainty([1])),
-                         (StdDevUncertainty([1]), StdDevUncertainty([1]))
-                         ])
-def test_arithmetic_result_not_tied_to_operands_uncertainty(op1_unc, op2_unc):
-    # Expectation is that the result of an arithmetic operation should be a
-    # new object whose members are not tied to the members of the operand.
-    # The only reliable test of this is to change elements of the result and
-    # see if the corresponding elements of the operands change.
-    # All four of the cases parametrized in this test do need to be checked
-    # because each of the four cases is handled separately in the code (well,
-    # except for the None, None case).
-    # Only one of the arithmetic operations need to be checked because the
-    # logic for propagating the uncertainties is common to all of the
-    # operations.
-    op1 = NDData([1], uncertainty=op1_unc)
-    op2 = NDData([1], uncertainty=op2_unc)
-
-    result = op1.add(op2)
-    if result.uncertainty:
-        result.uncertainty.array[0] = 0
-
-    if op1_unc:
-        assert op1.uncertainty.array[0] == 1
-    if op2_unc:
-        assert op2.uncertainty.array[0] == 1
-
-    result.data[0] = np.pi
-    assert op1.data[0] == 1
-    assert op2.data[0] == 1
-
-
- at pytest.mark.parametrize('op1_mask,op2_mask', [
-                         (None, None),
-                         (None, np.array([False])),
-                         (np.array([False]), None),
-                         (np.array([False]), np.array([False]))])
-def test_arithmetic_result_not_tied_to_operands_mask(op1_mask, op2_mask):
-    # See test_arithmetic_result_not_tied_to_operands_uncertainty for comments
-    op1 = NDData([1], mask=op1_mask)
-    op2 = NDData([1], mask=op2_mask)
-    result = op1.add(op2)
-
-    if result.mask is not None:
-        result.mask[0] = True
-
-    if op1_mask is not None:
-        assert op1.mask[0] == (not result.mask[0])
-
-    if op2_mask is not None:
-        assert op2.mask[0] == (not result.mask[0])
-
-
-def test_arithmetic_result_not_tied_to_operands_wcs_unit():
-    # Unlike the previous two tests, we only need to check a case where both
-    # operands have the same wcs because operands with different wcs is not
-    # supported
-    op1 = NDData([1], wcs=np.array([1]), unit='m')
-    op2 = NDData([1], wcs=np.array([1]), unit='m')
-    result = op1.add(op2)
-    result.wcs[0] = 12345
-    assert op1.wcs[0] != result.wcs[0]
-    assert op2.wcs[0] != result.wcs[0]
-    result.unit = u.km
-    assert op1.unit != u.km
-    assert op2.unit != u.km
-
-
-# first operand has unit km, second has unit m
- at pytest.mark.parametrize('operation,result_unit', [
-                         ('add', u.km),
-                         ('subtract', u.km),
-                         ('multiply', u.km * u.m),
-                         ('divide', u.km / u.m)])
-def test_uncertainty_unit_conversion_add_subtract(operation, result_unit):
-    in_km = NDData([1, 1], unit=u.km, uncertainty=StdDevUncertainty([.1, .1]))
-    in_m = NDData(in_km.data * 1000, unit=u.m)
-    in_m.uncertainty = StdDevUncertainty(in_km.uncertainty.array * 1000)
-    operator_km = in_km.__getattribute__(operation)
-    combined = operator_km(in_m)
-    assert combined.unit == result_unit
-    if operation in ['add', 'subtract']:
-        # uncertainty is not scaled by result values
-        assert_array_equal(combined.uncertainty.array,
-                           np.sqrt(2) * in_km.uncertainty.array)
-    else:
-        # uncertainty is scaled by result
-        assert_array_equal(combined.uncertainty.array,
-                np.sqrt(2) * in_km.uncertainty.array * combined.data)
-
-
- at pytest.mark.parametrize('unit1,unit2,op,result_unit', [
-                         (None, None, 'add', None),
-                         (None, None, 'multiply', None),
-                         (None, u.m, 'multiply', u.m),
-                         (u.dimensionless_unscaled, None, 'multiply',
-                          u.dimensionless_unscaled),
-                         (u.adu, u.adu, 'add', u.adu),
-                         (u.adu, u.adu, 'subtract', u.adu),
-                         (u.adu, u.adu, 'divide', u.dimensionless_unscaled),
-                         (u.adu, u.m, 'multiply', u.m * u.adu)
-                         ])
-def test_arithmetic_unit_calculation(unit1, unit2, op, result_unit):
-    # Test for #2413
-    ndd1 = NDData([1], unit=unit1)
-    ndd2 = NDData([1], unit=unit2)
-    ndd1_method = ndd1.__getattribute__(op)
-    result = ndd1_method(ndd2)
-    assert result.unit == result_unit
-
-
-def test_convert_unit_to():
-    # convert_unit_to should return a copy of its input
-    d = NDData(np.ones((5, 5)))
-    d.unit = 'km'
-    d.uncertainty = StdDevUncertainty(0.1 + np.zeros_like(d))
-    # workaround because zeros_like does not support dtype arg until v1.6
-    # and NDData accepts only bool ndarray as mask
-    tmp = np.zeros_like(d)
-    d.mask = np.array(tmp, dtype=np.bool)
-    d1 = d.convert_unit_to('m')
-    assert np.all(d1 == np.array(1000.0))
-    assert np.all(d1.uncertainty.array == 1000.0 * d.uncertainty.array)
-    assert d1.unit == u.m
-    # changing the output mask should not change the original
-    d1.mask[0, 0] = True
-    assert d.mask[0, 0] != d1.mask[0, 0]
-    d.flags = np.zeros_like(d.data)
-    d1 = d.convert_unit_to('m')
-    assert (d1.flags == d.flags).all()
+    nd = NDData(np.array([[1, 2, 3], [4, 5, 6]]))
+    assert nd.data.size == 6
+    assert nd.data.dtype == np.dtype(int)
 
 
 @raises(ValueError)
@@ -492,32 +168,10 @@ def test_invalid_unit():
     d = NDData(np.ones((5, 5)), unit="NotAValidUnit")
 
 
-def test_simple_slicing():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    assert d1.shape == (5, 5)
-    d2 = d1[2:3, 2:3]
-    assert d2.shape == (1, 1)
-    d3 = d1[2, 2]
-    assert d3.shape == ()
-
-
-def test_slicing_reference():
-    u1 = StdDevUncertainty(array=np.ones((5, 5)) * 3)
-    d1 = NDData(np.ones((5, 5)), uncertainty=u1)
-    d2 = d1[2:3, 2:3]
-    # asserting that the new nddata contains references to the original nddata
-    assert d2.data.base is d1.data
-    assert d2.uncertainty.array.base is d1.uncertainty.array
-
-
-def test_slicing_with_mask_or_flag():
-    # Regression test for #2170
-    ndd = NDData([1, 2, 3], mask=np.array([False, False, False]),
-                 flags=np.array([-1, -1, -1]))
-    assert ndd[0].shape == ()
-    assert not ndd[0].mask
-    assert ndd[0].flags == -1
+def test_slicing_not_supported():
+    ndd = NDData(np.ones((5, 5)))
+    with pytest.raises(TypeError):
+        ndd[0]
 
 
 def test_initializing_from_nddata():
@@ -553,38 +207,6 @@ def test_initializing_nddata_from_quantity_and_unit_raises_error():
         NDData([1, 2, 3] * u.adu, unit=u.adu)
 
 
-def test_initializing_nduncertainty_from_quantity():
-    # Until nddata and quantity are integrated initializing with a quantity
-    # should raise an error.
-    input_ndd_unit = u.kg
-    ndd = NDData(np.array([1, 2, 3]), unit=input_ndd_unit)
-    std_data = np.array([1, 2, 3])
-
-    # Unit of the uncertainty not convertible to unit of ndd, should raise
-    # an error.
-    std_error = StdDevUncertainty(u.adu * std_data)
-    assert std_error._unit is u.adu
-    with pytest.raises(u.UnitsError):
-        ndd.uncertainty = std_error
-
-    # Uncertainty should be settable without any change in its values
-    # because uncertainty unit is same as data unit.
-    std_error = StdDevUncertainty(u.kg * std_data)
-    ndd.uncertainty = std_error
-    assert_array_equal(std_data, ndd.uncertainty.array)
-
-    # If the uncertainty unit is grams there should be no error, but the
-    # values of the uncertainty should be scaled.
-    std_error = StdDevUncertainty(u.g * std_data)
-    ndd.uncertainty = std_error
-    assert_array_equal(std_data, 1000 * ndd.uncertainty.array)
-
-    # If ndd has no unit but the uncertainty does an error should be raised.
-    ndd.unit = None
-    with pytest.raises(ValueError):
-        ndd.uncertainty = std_error
-
-
 def test_masked_array_input():
 
     with NumpyRNGContext(12345):
@@ -604,15 +226,6 @@ def test_masked_array_input():
     assert_array_equal(nd.mask, marr.mask)
     assert_array_equal(nd.data, marr.data)
 
-def test_unmasked_masked_array_input():
-    # Test for #2784
-    marr = np.ma.array([1,2,5]) # Masked array with no masked entries
-    nd = NDData(marr) # Before fix this raised a ValueError
-    
-    # Check that masks are correct
-    assert marr.mask is np.ma.nomask  
-    assert nd.mask is None  # Internal representation is np.ma.nomask but getter returns None
-
 
 # Check that the meta descriptor is working as expected. The MetaBaseTest class
 # takes care of defining all the tests, and we simply have to define the class
@@ -639,22 +252,3 @@ class SubNDData(NDData):
             raise ValueError("Unit for subclass must be specified")
         if self.wcs is None:
             raise ValueError("WCS for subclass must be specified")
-
-
-def test_init_of_subclasses_in_arithmetic():
-    with NumpyRNGContext(12345):
-        data = np.ones([10, 10])
-    # The wcs only needs to be not None for this test to succeed
-    arr1 = SubNDData(data, unit='adu', wcs=5)
-    arr2 = SubNDData(data, unit='adu', wcs=5)
-    result = arr1.add(arr2)
-    assert result.unit == arr1.unit
-    assert result.wcs == arr1.wcs
-
-
-def test_init_of_subclass_in_convert_unit_to():
-    with NumpyRNGContext(12345):
-        data = np.ones([10, 10])
-    arr1 = SubNDData(data, unit='m', wcs=5)
-    result = arr1.convert_unit_to('km')
-    assert_array_equal(arr1.data, 1000 * result.data)
diff --git a/astropy/nddata/tests/test_nddata_base.py b/astropy/nddata/tests/test_nddata_base.py
new file mode 100644
index 0000000..68b51c5
--- /dev/null
+++ b/astropy/nddata/tests/test_nddata_base.py
@@ -0,0 +1,60 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+# Tests of NDDataBase
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from ..nddata_base import NDDataBase
+from ...tests.helper import pytest
+
+
+class MinimalSubclass(NDDataBase):
+    def __init__(self):
+        super(MinimalSubclass, self).__init__()
+
+    @property
+    def data(self):
+        return None
+
+    @property
+    def mask(self):
+        return super(MinimalSubclass, self).mask
+
+    @property
+    def unit(self):
+        return super(MinimalSubclass, self).unit
+
+    @property
+    def wcs(self):
+        return super(MinimalSubclass, self).wcs
+
+    @property
+    def meta(self):
+        return super(MinimalSubclass, self).meta
+
+
+class MinimalUncertainty(object):
+    """
+    Define the minimum attributes acceptable as an uncertainty object.
+    """
+    def __init__(self, value):
+        self._uncertainty = value
+
+    @property
+    def uncertainty_type(self):
+        return "totally and completely fake"
+
+
+def test_nddata_base_subclass():
+    a = MinimalSubclass()
+    assert a.meta is None
+    assert a.data is None
+    assert a.mask is None
+    assert a.unit is None
+    assert a.wcs is None
+    good_uncertainty = MinimalUncertainty(5)
+    a.uncertainty = good_uncertainty
+    assert a.uncertainty is good_uncertainty
+    bad_uncertainty = 5
+    with pytest.raises(TypeError):
+        a.uncertainty = bad_uncertainty
diff --git a/astropy/nddata/tests/test_utils.py b/astropy/nddata/tests/test_utils.py
new file mode 100644
index 0000000..80a0ba9
--- /dev/null
+++ b/astropy/nddata/tests/test_utils.py
@@ -0,0 +1,75 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+import numpy as np
+from numpy.testing import assert_allclose
+
+from ...tests.helper import pytest
+from ..utils import extract_array, add_array, subpixel_indices
+
+test_positions = [(10.52, 3.12), (5.62, 12.97), (31.33, 31.77),
+                  (0.46, 0.94), (20.45, 12.12), (42.24, 24.42)]
+
+test_position_indices = [(0, 3), (0, 2), (4, 1),
+                         (4, 2), (4, 3), (3, 4)]
+
+test_slices = [slice(10.52, 3.12), slice(5.62, 12.97),
+               slice(31.33, 31.77), slice(0.46, 0.94),
+               slice(20.45, 12.12), slice(42.24, 24.42)]
+
+subsampling = 5
+
+
+def test_extract_array():
+    """
+    Test extract_array utility function.
+
+    Test by extracting an array of ones out of an array of zeros.
+    """
+    large_test_array = np.zeros((11, 11))
+    small_test_array = np.ones((5, 5))
+    large_test_array[3:8, 3:8] = small_test_array
+    extracted_array = extract_array(large_test_array, (5, 5), (5, 5))
+    assert np.all(extracted_array == small_test_array)
+
+
+def test_add_array_odd_shape():
+    """
+    Test add_array utility function.
+
+    Test by adding an array of ones out of an array of zeros.
+    """
+    large_test_array = np.zeros((11, 11))
+    small_test_array = np.ones((5, 5))
+    large_test_array_ref = large_test_array.copy()
+    large_test_array_ref[3:8, 3:8] += small_test_array
+
+    added_array = add_array(large_test_array, small_test_array, (5, 5))
+    assert np.all(added_array == large_test_array_ref)
+
+
+def test_add_array_even_shape():
+    """
+    Test add_array_2D utility function.
+
+    Test by adding an array of ones out of an array of zeros.
+    """
+    large_test_array = np.zeros((11, 11))
+    small_test_array = np.ones((4, 4))
+    large_test_array_ref = large_test_array.copy()
+    large_test_array_ref[0:2, 0:2] += small_test_array[2:4, 2:4]
+
+    added_array = add_array(large_test_array, small_test_array, (0, 0))
+    assert np.all(added_array == large_test_array_ref)
+
+
+ at pytest.mark.parametrize(('position', 'subpixel_index'),
+                         zip(test_positions, test_position_indices))
+def test_subpixel_indices(position, subpixel_index):
+    """
+    Test subpixel_indices utility function.
+
+    Test by asserting that the function returns correct results for
+    given test values.
+    """
+    assert np.all(subpixel_indices(position, subsampling) == subpixel_index)
diff --git a/astropy/nddata/utils.py b/astropy/nddata/utils.py
new file mode 100644
index 0000000..8366f15
--- /dev/null
+++ b/astropy/nddata/utils.py
@@ -0,0 +1,196 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This module includes helper functions for array operations.
+"""
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+__all__ = ['extract_array', 'add_array', 'subpixel_indices',
+           'overlap_slices']
+
+
+def overlap_slices(large_array_shape, small_array_shape, position):
+    """
+    Get slices for the overlapping part of a small and a large array.
+
+    Given a certain position of the center of the small array, with
+    respect to the large array, tuples of slices are returned which can be
+    used to extract, add or subtract the small array at the given
+    position. This function takes care of the correct behavior at the
+    boundaries, where the small array is cut of appropriately.
+
+    Parameters
+    ----------
+    large_array_shape : tuple
+        Shape of the large array.
+    small_array_shape : tuple
+        Shape of the small array.
+    position : tuple
+        Position of the small array's center, with respect to the large array.
+        Coordinates should be in the same order as the array shape.
+
+    Returns
+    -------
+    slices_large : tuple of slices
+        Slices in all directions for the large array, such that
+        ``large_array[slices_large]`` extracts the region of the large array
+        that overlaps with the small array.
+    slices_small : slice
+        Slices in all directions for the small array, such that
+        ``small_array[slices_small]`` extracts the region that is inside the
+        large array.
+    """
+    # Get edge coordinates
+    edges_min = [int(pos + 0.5 - small_shape / 2.) for (pos, small_shape) in
+                 zip(position, small_array_shape)]
+    edges_max = [int(pos + 0.5 + small_shape / 2.) for (pos, small_shape) in
+                 zip(position, small_array_shape)]
+
+    # Set up slices
+    slices_large = tuple(slice(max(0, edge_min), min(large_shape, edge_max))
+                         for (edge_min, edge_max, large_shape) in
+                         zip(edges_min, edges_max, large_array_shape))
+    slices_small = tuple(slice(max(0, -edge_min),
+                               min(large_shape - edge_min, edge_max - edge_min))
+                         for (edge_min, edge_max, large_shape) in
+                         zip(edges_min, edges_max, large_array_shape))
+
+    return slices_large, slices_small
+
+
+def extract_array(array_large, shape, position):
+    """
+    Extract smaller array of given shape and position out of a larger array.
+
+    Parameters
+    ----------
+    array_large : `~numpy.ndarray`
+        Array to extract another array from.
+    shape : tuple
+        Shape of the extracted array.
+    position : tuple
+        Position of the small array's center, with respect to the large array.
+        Coordinates should be in the same order as the array shape.
+
+    Returns
+    -------
+    array_small : `~numpy.ndarray`
+        The extracted array
+
+    Examples
+    --------
+    We consider a large array with the shape 11x10, from which we extract
+    a small array of shape 3x5:
+
+    >>> import numpy as np
+    >>> from astropy.nddata.utils import extract_array
+    >>> large_array = np.arange(110).reshape((11, 10))
+    >>> large_array[4:9, 4:9] = np.ones((5, 5))
+    >>> extract_array(large_array, (3, 5), (7, 7))
+    array([[ 1,  1,  1,  1, 69],
+           [ 1,  1,  1,  1, 79],
+           [ 1,  1,  1,  1, 89]])
+    """
+    # Check if larger array is really larger
+    if all(large_shape > small_shape for (large_shape, small_shape)
+           in zip(array_large.shape, shape)):
+        large_slices, _ = overlap_slices(array_large.shape, shape, position)
+        return array_large[large_slices]
+    else:
+        raise ValueError("Can't extract array. Shape too large.")
+
+
+def add_array(array_large, array_small, position):
+    """
+    Add a smaller array at a given position in a larger array.
+
+    Parameters
+    ----------
+    array_large : `~numpy.ndarray`
+        Large array.
+    array_small : `~numpy.ndarray`
+        Small array to add.
+    position : tuple
+        Position of the small array's center, with respect to the large array.
+        Coordinates should be in the same order as the array shape.
+
+    Returns
+    -------
+    new_array : `~numpy.ndarray`
+        The new array formed from the sum of ``array_large`` and
+        ``array_small``.
+
+    Notes
+    -----
+    The addition is done in-place.
+
+    Examples
+    --------
+    We consider a large array of zeros with the shape 5x5 and a small
+    array of ones with a shape of 3x3:
+
+    >>> import numpy as np
+    >>> from astropy.nddata.utils import add_array
+    >>> large_array = np.zeros((5, 5))
+    >>> small_array = np.ones((3, 3))
+    >>> add_array(large_array, small_array, (1, 2))
+    array([[ 0.,  1.,  1.,  1.,  0.],
+           [ 0.,  1.,  1.,  1.,  0.],
+           [ 0.,  1.,  1.,  1.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.]])
+    """
+    # Check if large array is really larger
+    if all(large_shape > small_shape for (large_shape, small_shape)
+           in zip(array_large.shape, array_small.shape)):
+        large_slices, small_slices = overlap_slices(array_large.shape,
+                                                    array_small.shape, position)
+        array_large[large_slices] += array_small[small_slices]
+        return array_large
+    else:
+        raise ValueError("Can't add array. Small array too large.")
+
+
+def subpixel_indices(position, subsampling):
+    """
+    Convert decimal points to indices, given a subsampling factor.
+
+    This discards the integer part of the position and uses only the decimal
+    place, and converts this to a subpixel position depending on the
+    subsampling specified. The center of a pixel corresponds to an integer
+    position.
+
+    Parameters
+    ----------
+    position : `~numpy.ndarray` or array-like
+        Positions in pixels.
+    subsampling : int
+        Subsampling factor per pixel.
+
+    Returns
+    -------
+    indices : `~numpy.ndarray`
+        The integer subpixel indices corresponding to the input positions.
+
+    Examples
+    --------
+
+    If no subsampling is used, then the subpixel indices returned are always 0:
+
+    >>> from astropy.nddata.utils import subpixel_indices
+    >>> subpixel_indices([1.2, 3.4, 5.6],1)
+    array([ 0.,  0.,  0.])
+
+    If instead we use a subsampling of 2, we see that for the two first values
+    (1.1 and 3.4) the subpixel position is 1, while for 5.6 it is 0. This is
+    because the values of 1, 3, and 6 lie in the center of pixels, and 1.1 and
+    3.4 lie in the left part of the pixels and 5.6 lies in the right part.
+
+    >>> subpixel_indices([1.2, 3.4, 5.5],2)
+    array([ 1.,  1.,  0.])
+    """
+    # Get decimal points
+    fractions = np.modf(np.asanyarray(position) + 0.5)[0]
+    return np.floor(fractions * subsampling)
diff --git a/astropy/setup_helpers.py b/astropy/setup_helpers.py
deleted file mode 100644
index 6026344..0000000
--- a/astropy/setup_helpers.py
+++ /dev/null
@@ -1,1535 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-
-##############################################################################
-# Note: this file exists only for backward-compatibility purposes - the      #
-#       contents have been moved to the separate astropy-helpers package,    #
-#       located at https://github.com/astropy/astropy-helpers. Any new       #
-#       development or bug fixes should be done there.                       #
-##############################################################################
-
-"""
-This module contains a number of utilities for use during
-setup/build/packaging that are useful to astropy as a whole.
-"""
-
-from __future__ import absolute_import, print_function
-
-import collections
-import errno
-import imp
-import inspect
-import os
-import re
-import shlex
-import shutil
-import subprocess
-import sys
-import textwrap
-import warnings
-
-from distutils import log, ccompiler, sysconfig
-from distutils.cmd import DistutilsOptionError
-from distutils.dist import Distribution
-from distutils.errors import DistutilsError
-from distutils.core import Extension
-from distutils.core import Command
-from distutils.command.sdist import sdist as DistutilsSdist
-from setuptools.command.build_ext import build_ext as SetuptoolsBuildExt
-from setuptools.command.build_py import build_py as SetuptoolsBuildPy
-from setuptools.command.install import install as SetuptoolsInstall
-from setuptools.command.install_lib import install_lib as SetuptoolsInstallLib
-
-from setuptools.command.register import register as SetuptoolsRegister
-from setuptools import find_packages
-
-from .tests.helper import astropy_test
-from .utils import silence
-from .utils.compat.misc import invalidate_caches
-from .utils.misc import walk_skip_hidden
-from .utils.exceptions import AstropyDeprecationWarning
-
-from .extern import six
-
-
-try:
-    import Cython
-    HAVE_CYTHON = True
-except ImportError:
-    HAVE_CYTHON = False
-
-
-try:
-    import sphinx
-    from sphinx.setup_command import BuildDoc as SphinxBuildDoc
-    HAVE_SPHINX = True
-except ImportError:
-    HAVE_SPHINX = False
-except SyntaxError:  # occurs if markupsafe is recent version, which doesn't support Python 3.2
-    HAVE_SPHINX = False
-
-
-PY3 = sys.version_info[0] >= 3
-
-
-# This adds a new keyword to the setup() function
-Distribution.skip_2to3 = []
-
-
-_adjusted_compiler = False
-def adjust_compiler(package):
-    """
-    This function detects broken compilers and switches to another.  If
-    the environment variable CC is explicitly set, or a compiler is
-    specified on the commandline, no override is performed -- the purpose
-    here is to only override a default compiler.
-
-    The specific compilers with problems are:
-
-        * The default compiler in XCode-4.2, llvm-gcc-4.2,
-          segfaults when compiling wcslib.
-
-    The set of broken compilers can be updated by changing the
-    compiler_mapping variable.  It is a list of 2-tuples where the
-    first in the pair is a regular expression matching the version
-    of the broken compiler, and the second is the compiler to change
-    to.
-    """
-
-    compiler_mapping = [
-        (b'i686-apple-darwin[0-9]*-llvm-gcc-4.2', 'clang')
-        ]
-
-    global _adjusted_compiler
-    if _adjusted_compiler:
-        return
-
-    # Whatever the result of this function is, it only needs to be run once
-    _adjusted_compiler = True
-
-    if 'CC' in os.environ:
-
-        # Check that CC is not set to llvm-gcc-4.2
-        c_compiler = os.environ['CC']
-
-        try:
-            version = get_compiler_version(c_compiler)
-        except OSError:
-            msg = textwrap.dedent(
-                    """
-                    The C compiler set by the CC environment variable:
-
-                        {compiler:s}
-
-                    cannot be found or executed.
-                    """.format(compiler=c_compiler))
-            log.warn(msg)
-            sys.exit(1)
-
-        for broken, fixed in compiler_mapping:
-            if re.match(broken, version):
-                msg = textwrap.dedent(
-                    """Compiler specified by CC environment variable
-                    ({compiler:s}:{version:s}) will fail to compile {pkg:s}.
-                    Please set CC={fixed:s} and try again.
-                    You can do this, for example, by running:
-
-                        CC={fixed:s} python setup.py <command>
-
-                    where <command> is the command you ran.
-                    """.format(compiler=c_compiler, version=version,
-                               pkg=package, fixed=fixed))
-                log.warn(msg)
-                sys.exit(1)
-
-        # If C compiler is set via CC, and isn't broken, we are good to go. We
-        # should definitely not try accessing the compiler specified by
-        # ``sysconfig.get_config_var('CC')`` lower down, because this may fail
-        # if the compiler used to compile Python is missing (and maybe this is
-        # why the user is setting CC). For example, the official Python 2.7.3
-        # MacOS X binary was compled with gcc-4.2, which is no longer available
-        # in XCode 4.
-        return
-
-    if get_distutils_build_option('compiler'):
-        return
-
-    compiler_type = ccompiler.get_default_compiler()
-
-    if compiler_type == 'unix':
-
-        # We have to get the compiler this way, as this is the one that is
-        # used if os.environ['CC'] is not set. It is actually read in from
-        # the Python Makefile. Note that this is not necessarily the same
-        # compiler as returned by ccompiler.new_compiler()
-        c_compiler = sysconfig.get_config_var('CC')
-
-        try:
-            version = get_compiler_version(c_compiler)
-        except OSError:
-            msg = textwrap.dedent(
-                    """
-                    The C compiler used to compile Python {compiler:s}, and
-                    which is normally used to compile C extensions, is not
-                    available. You can explicitly specify which compiler to
-                    use by setting the CC environment variable, for example:
-
-                        CC=gcc python setup.py <command>
-
-                    or if you are using MacOS X, you can try:
-
-                        CC=clang python setup.py <command>
-                    """.format(compiler=c_compiler))
-            log.warn(msg)
-            sys.exit(1)
-
-
-        for broken, fixed in compiler_mapping:
-            if re.match(broken, version):
-                os.environ['CC'] = fixed
-                break
-
-
-def get_compiler_version(compiler):
-
-    process = subprocess.Popen(
-        shlex.split(compiler) + ['--version'], stdout=subprocess.PIPE)
-
-    output = process.communicate()[0].strip()
-    try:
-        version = output.split()[0]
-    except IndexError:
-        return 'unknown'
-
-    return version
-
-
-def get_dummy_distribution():
-    """Returns a distutils Distribution object used to instrument the setup
-    environment before calling the actual setup() function.
-    """
-
-    global _registered_commands
-
-    if _registered_commands is None:
-        raise RuntimeError('astropy.setup_helpers.register_commands() must be '
-                           'called before using '
-                           'astropy.setup_helpers.get_dummy_distribution()')
-
-    # Pre-parse the Distutils command-line options and config files to if
-    # the option is set.
-    dist = Distribution({'script_name': os.path.basename(sys.argv[0]),
-                         'script_args': sys.argv[1:]})
-    dist.cmdclass.update(_registered_commands)
-
-    with silence():
-        try:
-            dist.parse_config_files()
-            dist.parse_command_line()
-        except (DistutilsError, AttributeError, SystemExit):
-            # Let distutils handle DistutilsErrors itself AttributeErrors can
-            # get raise for ./setup.py --help SystemExit can be raised if a
-            # display option was used, for example
-            pass
-
-    return dist
-
-
-def get_distutils_option(option, commands):
-    """ Returns the value of the given distutils option.
-
-    Parameters
-    ----------
-    option : str
-        The name of the option
-
-    commands : list of str
-        The list of commands on which this option is available
-
-    Returns
-    -------
-    val : str or None
-        the value of the given distutils option. If the option is not set,
-        returns None.
-    """
-
-    dist = get_dummy_distribution()
-
-    for cmd in commands:
-        cmd_opts = dist.command_options.get(cmd)
-        if cmd_opts is not None and option in cmd_opts:
-            return cmd_opts[option][1]
-    else:
-        return None
-
-
-def get_distutils_build_option(option):
-    """ Returns the value of the given distutils build option.
-
-    Parameters
-    ----------
-    option : str
-        The name of the option
-
-    Returns
-    -------
-    val : str or None
-        The value of the given distutils build option. If the option
-        is not set, returns None.
-    """
-    return get_distutils_option(option, ['build', 'build_ext', 'build_clib'])
-
-
-def get_distutils_install_option(option):
-    """ Returns the value of the given distutils install option.
-
-    Parameters
-    ----------
-    option : str
-        The name of the option
-
-    Returns
-    -------
-    val : str or None
-        The value of the given distutils build option. If the option
-        is not set, returns None.
-    """
-    return get_distutils_option(option, ['install'])
-
-
-def get_distutils_build_or_install_option(option):
-    """ Returns the value of the given distutils build or install option.
-
-    Parameters
-    ----------
-    option : str
-        The name of the option
-
-    Returns
-    -------
-    val : str or None
-        The value of the given distutils build or install option. If the
-        option is not set, returns None.
-    """
-    return get_distutils_option(option, ['build', 'build_ext', 'build_clib',
-                                         'install'])
-
-
-def get_compiler_option():
-    """ Determines the compiler that will be used to build extension modules.
-
-    Returns
-    -------
-    compiler : str
-        The compiler option specificied for the build, build_ext, or build_clib
-        command; or the default compiler for the platform if none was
-        specified.
-
-    """
-
-    compiler = get_distutils_build_option('compiler')
-    if compiler is None:
-        return ccompiler.get_default_compiler()
-
-    return compiler
-
-
-def get_debug_option():
-    """ Determines if the build is in debug mode.
-
-    Returns
-    -------
-    debug : bool
-        True if the current build was started with the debug option, False
-        otherwise.
-
-    """
-
-    try:
-        from .version import debug as current_debug
-    except ImportError:
-        current_debug = None
-
-    # Only modify the debug flag if one of the build commands was explicitly
-    # run (i.e. not as a sub-command of something else)
-    dist = get_dummy_distribution()
-    if any(cmd in dist.commands for cmd in ['build', 'build_ext']):
-        debug = bool(get_distutils_build_option('debug'))
-    else:
-        debug = bool(current_debug)
-
-    if current_debug is not None and current_debug != debug:
-        build_ext_cmd = dist.get_command_class('build_ext')
-        build_ext_cmd.force_rebuild = True
-
-    return debug
-
-
-_registered_commands = None
-def register_commands(package, version, release):
-    global _registered_commands
-
-    if _registered_commands is not None:
-        return _registered_commands
-
-    _registered_commands = {
-        'test': generate_test_command(package),
-
-        # Use distutils' sdist because it respects package_data.
-        # setuptools/distributes sdist requires duplication of information in
-        # MANIFEST.in
-        'sdist': DistutilsSdist,
-
-        # The exact form of the build_ext command depends on whether or not
-        # we're building a release version
-        'build_ext': generate_build_ext_command(package, release),
-
-        # We have a custom build_py to generate the default configuration file
-        'build_py': AstropyBuildPy,
-
-        # Since install can (in some circumstances) be run without
-        # first building, we also need to override install and
-        # install_lib.  See #2223
-        'install': AstropyInstall,
-        'install_lib': AstropyInstallLib,
-
-        'register': AstropyRegister
-    }
-
-    if HAVE_SPHINX:
-        _registered_commands['build_sphinx'] = AstropyBuildSphinx
-    else:
-        _registered_commands['build_sphinx'] = FakeBuildSphinx
-
-    # Need to override the __name__ here so that the commandline options are
-    # presented as being related to the "build" command, for example; normally
-    # this wouldn't be necessary since commands also have a command_name
-    # attribute, but there is a bug in distutils' help display code that it
-    # uses __name__ instead of command_name. Yay distutils!
-    for name, cls in _registered_commands.items():
-        cls.__name__ = name
-
-    # Add a few custom options; more of these can be added by specific packages
-    # later
-    for option in [
-            ('use-system-libraries',
-             "Use system libraries whenever possible", True)]:
-        add_command_option('build', *option)
-        add_command_option('install', *option)
-
-    return _registered_commands
-
-
-def generate_test_command(package_name):
-    return type(package_name + '_test_command', (astropy_test,),
-                {'package_name': package_name})
-
-
-def generate_build_ext_command(packagename, release):
-    """
-    Creates a custom 'build_ext' command that allows for manipulating some of
-    the C extension options at build time.  We use a function to build the
-    class since the base class for build_ext may be different depending on
-    certain build-time parameters (for example, we may use Cython's build_ext
-    instead of the default version in distutils).
-
-    Uses the default distutils.command.build_ext by default.
-    """
-
-    uses_cython = should_build_with_cython(packagename, release)
-
-    if uses_cython:
-        from Cython.Distutils import build_ext as basecls
-    else:
-        basecls = SetuptoolsBuildExt
-
-    attrs = dict(basecls.__dict__)
-    orig_run = getattr(basecls, 'run', None)
-    orig_finalize = getattr(basecls, 'finalize_options', None)
-
-    def finalize_options(self):
-        if orig_finalize is not None:
-            orig_finalize(self)
-
-        # Generate
-        if self.uses_cython:
-            try:
-                from Cython import __version__ as cython_version
-            except ImportError:
-                # This shouldn't happen if we made it this far
-                cython_version = None
-
-            if (cython_version is not None and
-                    cython_version != self.uses_cython):
-                self.force_rebuild = True
-                # Update the used cython version
-                self.uses_cython = cython_version
-
-        # Regardless of the value of the '--force' option, force a rebuild if
-        # the debug flag changed from the last build
-        if self.force_rebuild:
-            self.force = True
-
-    def run(self):
-        # For extensions that require 'numpy' in their include dirs, replace
-        # 'numpy' with the actual paths
-        np_include = get_numpy_include_path()
-        for extension in self.extensions:
-            if 'numpy' in extension.include_dirs:
-                idx = extension.include_dirs.index('numpy')
-                extension.include_dirs.insert(idx, np_include)
-                extension.include_dirs.remove('numpy')
-
-            # Replace .pyx with C-equivalents, unless c files are missing
-            for jdx, src in enumerate(extension.sources):
-                if src.endswith('.pyx'):
-                    pyxfn = src
-                    cfn = src[:-4] + '.c'
-                elif src.endswith('.c'):
-                    pyxfn = src[:-2] + '.pyx'
-                    cfn = src
-
-                if os.path.isfile(pyxfn):
-                    if self.uses_cython:
-                        extension.sources[jdx] = pyxfn
-                    else:
-                        if os.path.isfile(cfn):
-                            extension.sources[jdx] = cfn
-                        else:
-                            msg = (
-                                'Could not find C file {0} for Cython file '
-                                '{1} when building extension {2}. '
-                                'Cython must be installed to build from a '
-                                'git checkout'.format(cfn, pyxfn,
-                                                      extension.name))
-                            raise IOError(errno.ENOENT, msg, cfn)
-
-        if orig_run is not None:
-            # This should always be the case for a correctly implemented
-            # distutils command.
-            orig_run(self)
-
-        # Update cython_version.py if building with Cython
-        try:
-            from .version import cython_version
-        except ImportError:
-            cython_version = 'unknown'
-        if self.uses_cython and self.uses_cython != cython_version:
-            package_dir = os.path.relpath(packagename)
-            cython_py = os.path.join(package_dir, 'cython_version.py')
-            with open(cython_py, 'w') as f:
-                f.write('# Generated file; do not modify\n')
-                f.write('cython_version = {0!r}\n'.format(self.uses_cython))
-
-            if os.path.isdir(self.build_lib):
-                # The build/lib directory may not exist if the build_py command
-                # was not previously run, which may sometimes be the case
-                self.copy_file(cython_py,
-                               os.path.join(self.build_lib, cython_py),
-                               preserve_mode=False)
-
-            invalidate_caches()
-
-        # REMOVE: in astropy 0.5
-        if not self.distribution.is_pure() and os.path.isdir(self.build_lib):
-            # Finally, generate the default astropy.cfg; this can only be done
-            # after extension modules are built as some extension modules
-            # include config items.  We only do this if it's not pure python,
-            # though, because if it is, we already did it in build_py
-            generate_default_config(
-                os.path.abspath(self.build_lib),
-                self.distribution.packages[0], self)
-
-    attrs['run'] = run
-    attrs['finalize_options'] = finalize_options
-    attrs['force_rebuild'] = False
-    attrs['uses_cython'] = uses_cython
-
-    return type('build_ext', (basecls, object), attrs)
-
-
-def _get_platlib_dir(cmd):
-    plat_specifier = '.{0}-{1}'.format(cmd.plat_name, sys.version[0:3])
-    return os.path.join(cmd.build_base, 'lib' + plat_specifier)
-
-
-class AstropyInstall(SetuptoolsInstall):
-
-    def finalize_options(self):
-        build_cmd = self.get_finalized_command('build')
-        platlib_dir = _get_platlib_dir(build_cmd)
-        self.build_lib = platlib_dir
-        SetuptoolsInstall.finalize_options(self)
-
-
-class AstropyInstallLib(SetuptoolsInstallLib):
-
-    def finalize_options(self):
-        build_cmd = self.get_finalized_command('build')
-        platlib_dir = _get_platlib_dir(build_cmd)
-        self.build_dir = platlib_dir
-        SetuptoolsInstallLib.finalize_options(self)
-
-
-class AstropyBuildPy(SetuptoolsBuildPy):
-
-    def finalize_options(self):
-        # Update build_lib settings from the build command to always put
-        # build files in platform-specific subdirectories of build/, even
-        # for projects with only pure-Python source (this is desirable
-        # specifically for support of multiple Python version).
-        build_cmd = self.get_finalized_command('build')
-        platlib_dir = _get_platlib_dir(build_cmd)
-
-        build_cmd.build_purelib = platlib_dir
-        build_cmd.build_lib = platlib_dir
-        self.build_lib = platlib_dir
-
-        SetuptoolsBuildPy.finalize_options(self)
-
-    def run_2to3(self, files, doctests=False):
-        # Filter the files to exclude things that shouldn't be 2to3'd
-        skip_2to3 = self.distribution.skip_2to3
-        filtered_files = []
-        for file in files:
-            for package in skip_2to3:
-                if file[len(self.build_lib) + 1:].startswith(package):
-                    break
-            else:
-                filtered_files.append(file)
-
-        SetuptoolsBuildPy.run_2to3(self, filtered_files, doctests)
-
-    def run(self):
-        # first run the normal build_py
-        SetuptoolsBuildPy.run(self)
-
-        pkgnm = self.distribution.packages[0]
-
-        # REMOVE: in astropy 0.5
-        if self.distribution.is_pure():
-            # Generate the default astropy.cfg - we only do this here if it's
-            # pure python.  Otherwise, it'll happen at the end of build_exp
-            generate_default_config(
-                os.path.abspath(self.build_lib),
-                pkgnm, self)
-
-        # Also copy over *only* the pytest part of setup.cfg.  This is necessary
-        # because the astropy.test() function needs this information to know how
-        # it should be configured.
-        p = six.moves.configparser.SafeConfigParser()
-        p.add_section('pytest')
-
-        pkgnmsection = r'"' + pkgnm + r'[\/]'
-        for k, (fnsrc, v) in six.iteritems(self.distribution.command_options['pytest']):
-            # also need to adjust any part of the pytest section that contains
-            # reference to the package directory (e.g., "astropy" for the core
-            # package), because this file is actually written *into* that
-            # directory.
-            if pkgnmsection in v:
-                v = v.replace(pkgnmsection, '"')
-            p.set('pytest', k, v)
-
-        with open(os.path.join(self.build_lib, pkgnm, 'pytest.ini'), 'w') as f:
-            p.write(f)
-
-
-# REMOVE: in astropy 0.5
-def generate_default_config(build_lib, package, command):
-    config_path = os.path.relpath(package)
-    filename = os.path.join(config_path, package + '.cfg')
-
-    if os.path.exists(filename):
-        return
-
-    log.info('generating default {0}.cfg file in {1}'.format(package, filename))
-
-    if PY3:
-        builtins = 'builtins'
-    else:
-        builtins = '__builtin__'
-
-    # astropy may have been built with a numpy that setuptools
-    # downloaded and installed into the current directory for us.
-    # Therefore, we need to extend the sys.path of the subprocess
-    # that's generating the config file, with the sys.path of this
-    # process.
-
-    subproccode = (
-        'import sys; sys.path.extend({paths!r});'
-        'import {builtins};{builtins}._ASTROPY_SETUP_ = True;'
-        'from astropy.config.configuration import generate_all_config_items;'
-        'generate_all_config_items({pkgnm!r}, True, filename={filenm!r})')
-    subproccode = subproccode.format(builtins=builtins,
-                                     pkgnm=package,
-                                     filenm=os.path.abspath(filename),
-                                     paths=sys.path)
-
-    # Note that cwd=build_lib--we're importing astropy from the build/ dir
-    # but using the astropy/ source dir as the config directory
-    proc = subprocess.Popen([sys.executable, '-c', subproccode],
-                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                             cwd=build_lib)
-    stdout, stderr = proc.communicate()
-
-    if proc.returncode == 0 and os.path.exists(filename):
-        default_cfg = os.path.relpath(filename)
-        command.copy_file(default_cfg,
-                          os.path.join(command.build_lib, default_cfg),
-                          preserve_mode=False)
-    else:
-        msg = ('Generation of default configuration item failed! Stdout '
-               'and stderr are shown below.\n'
-               'Stdout:\n{stdout}\nStderr:\n{stderr}')
-        if isinstance(msg, bytes):
-            msg = msg.decode('UTF-8')
-        log.error(msg.format(stdout=stdout.decode('UTF-8'),
-                             stderr=stderr.decode('UTF-8')))
-
-
-def add_command_option(command, name, doc, is_bool=False):
-    """
-    Add a custom option to a setup command.
-
-    Issues a warning if the option already exists on that command.
-
-    Parameters
-    ----------
-    command : str
-        The name of the command as given on the command line
-
-    name : str
-        The name of the build option
-
-    doc : str
-        A short description of the option, for the `--help` message
-
-    is_bool : bool, optional
-        When `True`, the option is a boolean option and doesn't
-        require an associated value.
-    """
-
-    dist = get_dummy_distribution()
-    cmdcls = dist.get_command_class(command)
-
-    attr = name.replace('-', '_')
-
-    if hasattr(cmdcls, attr):
-        raise RuntimeError(
-            '{0!r} already has a {1!r} class attribute, barring {2!r} from '
-            'being usable as a custom option name.'.format(cmdcls, attr, name))
-
-    for idx, cmd in enumerate(cmdcls.user_options):
-        if cmd[0] == name:
-            log.warning('Overriding existing {0!r} option '
-                        '{1!r}'.format(command, name))
-            del cmdcls.user_options[idx]
-            if name in cmdcls.boolean_options:
-                cmdcls.boolean_options.remove(name)
-            break
-
-    cmdcls.user_options.append((name, None, doc))
-
-    if is_bool:
-        cmdcls.boolean_options.append(name)
-
-    # Distutils' command parsing requires that a command object have an
-    # attribute with the same name as the option (with '-' replaced with '_')
-    # in order for that option to be recognized as valid
-    setattr(cmdcls, attr, None)
-
-
-class AstropyRegister(SetuptoolsRegister):
-    """Extends the built in 'register' command to support a ``--hidden`` option
-    to make the registered version hidden on PyPI by default.
-
-    The result of this is that when a version is registered as "hidden" it can
-    still be downloaded from PyPI, but it does not show up in the list of
-    actively supported versions under http://pypi.python.org/pypi/astropy, and
-    is not set as the most recent version.
-
-    Although this can always be set through the web interface it may be more
-    convenient to be able to specify via the 'register' command.  Hidden may
-    also be considered a safer default when running the 'register' command,
-    though this command uses distutils' normal behavior if the ``--hidden``
-    option is omitted.
-    """
-
-    user_options = SetuptoolsRegister.user_options + [
-        ('hidden', None, 'mark this release as hidden on PyPI by default')
-    ]
-    boolean_options = SetuptoolsRegister.boolean_options + ['hidden']
-
-    def initialize_options(self):
-        SetuptoolsRegister.initialize_options(self)
-        self.hidden = False
-
-    def build_post_data(self, action):
-        data = SetuptoolsRegister.build_post_data(self, action)
-        if action == 'submit' and self.hidden:
-            data['_pypi_hidden'] = '1'
-        return data
-
-    def _set_config(self):
-        # The original register command is buggy--if you use .pypirc with a
-        # server-login section *at all* the repository you specify with the -r
-        # option will be overwritten with either the repository in .pypirc or
-        # with the default,
-        # If you do not have a .pypirc using the -r option will just crash.
-        # Way to go distutils
-
-        # If we don't set self.repository back to a default value _set_config
-        # can crash if there was a user-supplied value for this option; don't
-        # worry, we'll get the real value back afterwards
-        self.repository = 'pypi'
-        SetuptoolsRegister._set_config(self)
-        options = self.distribution.get_option_dict('register')
-        if 'repository' in options:
-            source, value = options['repository']
-            # Really anything that came from setup.cfg or the command line
-            # should override whatever was in .pypirc
-            self.repository = value
-
-
-if HAVE_SPHINX:
-    class AstropyBuildSphinx(SphinxBuildDoc):
-        """ A version of the ``build_sphinx`` command that uses the
-        version of Astropy that is built by the setup ``build`` command,
-        rather than whatever is installed on the system - to build docs
-        against the installed version, run ``make html`` in the
-        ``astropy/docs`` directory.
-
-        This also automatically creates the docs/_static directories -
-        this is needed because github won't create the _static dir
-        because it has no tracked files.
-        """
-
-        description = 'Build Sphinx documentation for Astropy environment'
-        user_options = SphinxBuildDoc.user_options[:]
-        user_options.append(('warnings-returncode', 'w',
-                             'Parses the sphinx output and sets the return '
-                             'code to 1 if there are any warnings. Note that '
-                             'this will cause the sphinx log to only update '
-                             'when it completes, rather than continuously as '
-                             'is normally the case.'))
-        user_options.append(('clean-docs', 'l',
-                             'Completely clean previous builds, including '
-                             'automodapi-generated files before building new '
-                             'ones'))
-        user_options.append(('no-intersphinx', 'n',
-                             'Skip intersphinx, even if conf.py says to use '
-                             'it'))
-        user_options.append(('open-docs-in-browser', 'o',
-                             'Open the docs in a browser (using the '
-                             'webbrowser module) if the build finishes '
-                             'successfully.'))
-
-        boolean_options = SphinxBuildDoc.boolean_options[:]
-        boolean_options.append('warnings-returncode')
-        boolean_options.append('clean-docs')
-        boolean_options.append('no-intersphinx')
-        boolean_options.append('open-docs-in-browser')
-
-        _self_iden_rex = re.compile(r"self\.([^\d\W][\w]+)", re.UNICODE)
-
-        def initialize_options(self):
-            SphinxBuildDoc.initialize_options(self)
-            self.clean_docs = False
-            self.no_intersphinx = False
-            self.open_docs_in_browser = False
-            self.warnings_returncode = False
-
-        def finalize_options(self):
-            #Clear out previous sphinx builds, if requested
-            if self.clean_docs:
-                dirstorm = ['docs/api']
-                if self.build_dir is None:
-                    dirstorm.append('docs/_build')
-                else:
-                    dirstorm.append(self.build_dir)
-
-                for d in dirstorm:
-                    if os.path.isdir(d):
-                        log.info('Cleaning directory ' + d)
-                        shutil.rmtree(d)
-                    else:
-                        log.info('Not cleaning directory ' + d + ' because '
-                                 'not present or not a directory')
-
-            SphinxBuildDoc.finalize_options(self)
-
-        def run(self):
-            import webbrowser
-
-            if PY3:
-                from urllib.request import pathname2url
-            else:
-                from urllib import pathname2url
-
-            # This is used at the very end of `run` to decide if sys.exit should
-            # be called. If it's None, it won't be.
-            retcode = None
-
-            # If possible, create the _static dir
-            if self.build_dir is not None:
-                # the _static dir should be in the same place as the _build dir
-                # for Astropy
-                basedir, subdir = os.path.split(self.build_dir)
-                if subdir == '':  # the path has a trailing /...
-                    basedir, subdir = os.path.split(basedir)
-                staticdir = os.path.join(basedir, '_static')
-                if os.path.isfile(staticdir):
-                    raise DistutilsOptionError(
-                        'Attempted to build_sphinx in a location where' +
-                        staticdir + 'is a file.  Must be a directory.')
-                self.mkpath(staticdir)
-
-            #Now make sure Astropy is built and determine where it was built
-            build_cmd = self.reinitialize_command('build')
-            build_cmd.inplace = 0
-            self.run_command('build')
-            build_cmd = self.get_finalized_command('build')
-            build_cmd_path = os.path.abspath(build_cmd.build_lib)
-
-            #Now generate the source for and spawn a new process that runs the
-            #command.  This is needed to get the correct imports for the built
-            #version
-
-            runlines, runlineno = inspect.getsourcelines(SphinxBuildDoc.run)
-            subproccode = textwrap.dedent("""
-            from sphinx.setup_command import *
-
-            os.chdir({srcdir!r})
-            sys.path.insert(0, {build_cmd_path!r})
-
-            """).format(build_cmd_path=build_cmd_path, srcdir=self.source_dir)
-            #runlines[1:] removes 'def run(self)' on the first line
-            subproccode += textwrap.dedent(''.join(runlines[1:]))
-
-            # All "self.foo" in the subprocess code needs to be replaced by the
-            # values taken from the current self in *this* process
-            subproccode = AstropyBuildSphinx._self_iden_rex.split(subproccode)
-            for i in range(1, len(subproccode), 2):
-                iden = subproccode[i]
-                val = getattr(self, iden)
-                if iden.endswith('_dir'):
-                    #Directories should be absolute, because the `chdir` call
-                    #in the new process moves to a different directory
-                    subproccode[i] = repr(os.path.abspath(val))
-                else:
-                    subproccode[i] = repr(val)
-            subproccode = ''.join(subproccode)
-
-            if self.no_intersphinx:
-                #the confoverrides variable in sphinx.setup_command.BuildDoc can
-                #be used to override the conf.py ... but this could well break
-                #if future versions of sphinx change the internals of BuildDoc,
-                #so remain vigilant!
-                subproccode = subproccode.replace('confoverrides = {}',
-                    'confoverrides = {\'intersphinx_mapping\':{}}')
-
-            log.debug('Starting subprocess of {0} with python code:\n{1}\n'
-                      '[CODE END])'.format(sys.executable, subproccode))
-
-            # To return the number of warnings, we need to capture stdout. This
-            # prevents a continuous updating at the terminal, but there's no
-            # apparent way around this.
-            if self.warnings_returncode:
-                proc = subprocess.Popen([sys.executable],
-                                        stdin=subprocess.PIPE,
-                                        stdout=subprocess.PIPE,
-                                        stderr=subprocess.STDOUT)
-                stdo, stde = proc.communicate(subproccode)
-
-                print(stdo)
-
-                stdolines = stdo.split('\n')
-
-                if stdolines[-2] == 'build succeeded.':
-                    retcode = 0
-                else:
-                    retcode = 1
-
-                if retcode != 0:
-                    if os.environ.get('TRAVIS', None) == 'true':
-                        #this means we are in the travis build, so customize
-                        #the message appropriately.
-                        msg = ('The build_sphinx travis build FAILED '
-                               'because sphinx issued documentation '
-                               'warnings (scroll up to see the warnings).')
-                    else:  # standard failure message
-                        msg = ('build_sphinx returning a non-zero exit '
-                               'code because sphinx issued documentation '
-                               'warnings.')
-                    log.warn(msg)
-
-            else:
-                proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE)
-                proc.communicate(subproccode.encode('utf-8'))
-
-            if proc.returncode == 0:
-                if self.open_docs_in_browser:
-                    if self.builder == 'html':
-                        absdir = os.path.abspath(self.builder_target_dir)
-                        index_path = os.path.join(absdir, 'index.html')
-                        fileurl = 'file://' + pathname2url(index_path)
-                        webbrowser.open(fileurl)
-                    else:
-                        log.warn('open-docs-in-browser option was given, but '
-                                 'the builder is not html! Ignogring.')
-            else:
-                log.warn('Sphinx Documentation subprocess failed with return '
-                         'code ' + str(proc.returncode))
-
-            if retcode is not None:
-                # this is potentially dangerous in that there might be something
-                # after the call to `setup` in `setup.py`, and exiting here will
-                # prevent that from running.  But there's no other apparent way
-                # to signal what the return code should be.
-                sys.exit(retcode)
-
-
-def get_distutils_display_options():
-    """ Returns a set of all the distutils display options in their long and
-    short forms.  These are the setup.py arguments such as --name or --version
-    which print the project's metadata and then exit.
-
-    Returns
-    -------
-    opts : set
-        The long and short form display option arguments, including the - or --
-    """
-
-    short_display_opts = set('-' + o[1] for o in Distribution.display_options
-                             if o[1])
-    long_display_opts = set('--' + o[0] for o in Distribution.display_options)
-
-    # Include -h and --help which are not explicitly listed in
-    # Distribution.display_options (as they are handled by optparse)
-    short_display_opts.add('-h')
-    long_display_opts.add('--help')
-
-    # This isn't the greatest approach to hardcode these commands.
-    # However, there doesn't seem to be a good way to determine
-    # whether build *will be* run as part of the command at this
-    # phase.
-    display_commands = set([
-        'clean', 'register', 'setopt', 'saveopts', 'egg_info',
-        'alias'])
-
-    return short_display_opts.union(long_display_opts.union(display_commands))
-
-
-def is_distutils_display_option():
-    """ Returns True if sys.argv contains any of the distutils display options
-    such as --version or --name.
-    """
-
-    display_options = get_distutils_display_options()
-    return bool(set(sys.argv[1:]).intersection(display_options))
-
-
-def update_package_files(srcdir, extensions, package_data, packagenames,
-                         package_dirs):
-    """
-    This function is deprecated and maintained for backward compatibility
-    with affiliated packages.  Affiliated packages should update their
-    setup.py to use `get_package_info` instead.
-    """
-    warnings.warn(
-        "astropy.setup_helpers.update_package_files is deprecated.  Update "
-        "your setup.py to use astropy.setup_helpers.get_package_info instead.",
-        AstropyDeprecationWarning)
-
-    info = get_package_info(srcdir)
-    extensions.extend(info['ext_modules'])
-    package_data.update(info['package_data'])
-    packagenames = list(set(packagenames + info['packages']))
-    package_dirs.update(info['package_dir'])
-
-
-def get_package_info(srcdir):
-    """
-    Collates all of the information for building all subpackages
-    subpackages and returns a dictionary of keyword arguments that can
-    be passed directly to `distutils.setup`.
-
-    The purpose of this function is to allow subpackages to update the
-    arguments to the package's ``setup()`` function in its setup.py
-    script, rather than having to specify all extensions/package data
-    directly in the ``setup.py``.  See Astropy's own
-    ``setup.py`` for example usage and the Astropy development docs
-    for more details.
-
-    This function obtains that information by iterating through all
-    packages in ``srcdir`` and locating a ``setup_package.py`` module.
-    This module can contain the following functions:
-    ``get_extensions()``, ``get_package_data()``,
-    ``get_build_options()``, ``get_external_libraries()``,
-    and ``requires_2to3()``.
-
-    Each of those functions take no arguments.
-
-    - ``get_extensions`` returns a list of
-      `distutils.extension.Extension` objects.
-
-    - ``get_package_data()`` returns a dict formatted as required by
-      the ``package_data`` argument to ``setup()``.
-
-    - ``get_build_options()`` returns a list of tuples describing the
-      extra build options to add.
-
-    - ``get_external_libraries()`` returns
-      a list of libraries that can optionally be built using external
-      dependencies.
-
-    - ``requires_2to3()`` should return `True` when the source code
-      requires `2to3` processing to run on Python 3.x.  If
-      ``requires_2to3()`` is missing, it is assumed to return `True`.
-
-    """
-    ext_modules = []
-    packages = []
-    package_data = {}
-    package_dir = {}
-    skip_2to3 = []
-
-    # Add the package's .cfg file
-    package_data[''] = [srcdir + ".cfg"]
-
-    # Use the find_packages tool to locate all packages and modules
-    packages = filter_packages(find_packages())
-
-    # For each of the setup_package.py modules, extract any
-    # information that is needed to install them.  The build options
-    # are extracted first, so that their values will be available in
-    # subsequent calls to `get_extensions`, etc.
-    for setuppkg in iter_setup_packages(srcdir):
-        if hasattr(setuppkg, 'get_build_options'):
-            options = setuppkg.get_build_options()
-            for option in options:
-                add_command_option('build', *option)
-        if hasattr(setuppkg, 'get_external_libraries'):
-            libraries = setuppkg.get_external_libraries()
-            for library in libraries:
-                add_external_library(library)
-        if hasattr(setuppkg, 'requires_2to3'):
-            requires_2to3 = setuppkg.requires_2to3()
-        else:
-            requires_2to3 = True
-        if not requires_2to3:
-            skip_2to3.append(
-                os.path.dirname(setuppkg.__file__))
-
-    for setuppkg in iter_setup_packages(srcdir):
-        # get_extensions must include any Cython extensions by their .pyx
-        # filename.
-        if hasattr(setuppkg, 'get_extensions'):
-            ext_modules.extend(setuppkg.get_extensions())
-        if hasattr(setuppkg, 'get_package_data'):
-            package_data.update(setuppkg.get_package_data())
-
-    # Locate any .pyx files not already specified, and add their extensions in.
-    # The default include dirs include numpy to facilitate numerical work.
-    ext_modules.extend(get_cython_extensions(srcdir, ext_modules, ['numpy']))
-
-    # Now remove extensions that have the special name 'skip_cython', as they
-    # exist Only to indicate that the cython extensions shouldn't be built
-    for i, ext in reversed(list(enumerate(ext_modules))):
-        if ext.name == 'skip_cython':
-            del ext_modules[i]
-
-    # On Microsoft compilers, we need to pass the '/MANIFEST'
-    # commandline argument.  This was the default on MSVC 9.0, but is
-    # now required on MSVC 10.0, but it doesn't seeem to hurt to add
-    # it unconditionally.
-    if get_compiler_option() == 'msvc':
-        for ext in ext_modules:
-            ext.extra_link_args.append('/MANIFEST')
-
-    return {
-        'ext_modules': ext_modules,
-        'packages': packages,
-        'package_dir': package_dir,
-        'package_data': package_data,
-        'skip_2to3': skip_2to3
-        }
-
-
-def iter_setup_packages(srcdir):
-    """ A generator that finds and imports all of the ``setup_package.py``
-    modules in the source packages.
-
-    Returns
-    -------
-    modgen : generator
-        A generator that yields (modname, mod), where `mod` is the module and
-        `modname` is the module name for the ``setup_package.py`` modules.
-
-    """
-    for root, dirs, files in walk_skip_hidden(srcdir):
-        if 'setup_package.py' in files:
-            filename = os.path.join(root, 'setup_package.py')
-            module = import_file(filename)
-            yield module
-
-
-def iter_pyx_files(srcdir):
-    """ A generator that yields Cython source files (ending in '.pyx') in the
-    source packages.
-
-    Returns
-    -------
-    pyxgen : generator
-        A generator that yields (extmod, fullfn) where `extmod` is the
-        full name of the module that the .pyx file would live in based
-        on the source directory structure, and `fullfn` is the path to
-        the .pyx file.
-
-    """
-    for dirpath, dirnames, filenames in walk_skip_hidden(srcdir):
-        modbase = dirpath.replace(os.sep, '.')
-        for fn in filenames:
-            if fn.endswith('.pyx'):
-                fullfn = os.path.join(dirpath, fn)
-                # Package must match file name
-                extmod = modbase + '.' + fn[:-4]
-                yield (extmod, fullfn)
-
-
-def should_build_with_cython(package, release=None):
-    """Returns the previously used Cython version (or 'unknown' if not
-    previously built) if Cython should be used to build extension modules from
-    pyx files.  If the ``release`` parameter is not specified an attempt is
-    made to determine the release flag from `astropy.version`.
-    """
-
-    try:
-        version_module = __import__(package + '.cython_version',
-                                    fromlist=['release', 'cython_version'])
-    except ImportError:
-        version_module = None
-
-    if release is None and version_module is not None:
-        try:
-            release = version_module.release
-        except AttributeError:
-            pass
-
-    try:
-        cython_version = version_module.cython_version
-    except AttributeError:
-        cython_version = 'unknown'
-
-    # Only build with Cython if, of course, Cython is installed, we're in a
-    # development version (i.e. not release) or the Cython-generated source
-    # files haven't been created yet (cython_version == 'unknown'). The latter
-    # case can happen even when release is True if checking out a release tag
-    # from the repository
-    if HAVE_CYTHON and (not release or cython_version == 'unknown'):
-        return cython_version
-    else:
-        return False
-
-
-def get_cython_extensions(srcdir, prevextensions=tuple(), extincludedirs=None):
-    """ Looks for Cython files and generates Extensions if needed.
-
-    Parameters
-    ----------
-    srcdir : str
-        Path to the root of the source directory to search.
-    prevextensions : list of `~distutils.core.Extension` objects
-        The extensions that are already defined.  Any .pyx files already here
-        will be ignored.
-    extincludedirs : list of str or None
-        Directories to include as the `include_dirs` argument to the generated
-        `~distutils.core.Extension` objects.
-
-    Returns
-    -------
-    exts : list of `~distutils.core.Extension` objects
-        The new extensions that are needed to compile all .pyx files (does not
-        include any already in `prevextensions`).
-    """
-
-    # Vanilla setuptools and old versions of distribute include Cython files
-    # as .c files in the sources, not .pyx, so we cannot simply look for
-    # existing .pyx sources in the previous sources, but we should also check
-    # for .c files with the same remaining filename. So we look for .pyx and
-    # .c files, and we strip the extension.
-
-    prevsourcepaths = []
-    for ext in prevextensions:
-        for s in ext.sources:
-            if s.endswith(('.pyx', '.c')):
-                prevsourcepaths.append(os.path.realpath(os.path.splitext(s)[0]))
-
-    ext_modules = []
-    for extmod, pyxfn in iter_pyx_files(srcdir):
-        if os.path.realpath(os.path.splitext(pyxfn)[0]) not in prevsourcepaths:
-            ext_modules.append(Extension(extmod, [pyxfn],
-                                         include_dirs=extincludedirs))
-
-    return ext_modules
-
-
-def write_if_different(filename, data):
-    """ Write `data` to `filename`, if the content of the file is different.
-
-    Parameters
-    ----------
-    filename : str
-        The file name to be written to.
-    data : bytes
-        The data to be written to `filename`.
-    """
-    assert isinstance(data, bytes)
-
-    if os.path.exists(filename):
-        with open(filename, 'rb') as fd:
-            original_data = fd.read()
-    else:
-        original_data = None
-
-    if original_data != data:
-        with open(filename, 'wb') as fd:
-            fd.write(data)
-
-
-def get_numpy_include_path():
-    """
-    Gets the path to the numpy headers.
-    """
-    # We need to go through this nonsense in case setuptools
-    # downloaded and installed Numpy for us as part of the build or
-    # install, since Numpy may still think it's in "setup mode", when
-    # in fact we're ready to use it to build astropy now.
-
-    if PY3:
-        import builtins
-        if hasattr(builtins, '__NUMPY_SETUP__'):
-            del builtins.__NUMPY_SETUP__
-        import numpy
-        imp.reload(numpy)
-    else:
-        import __builtin__
-        if hasattr(__builtin__, '__NUMPY_SETUP__'):
-            del __builtin__.__NUMPY_SETUP__
-        import numpy
-        reload(numpy)
-
-    try:
-        numpy_include = numpy.get_include()
-    except AttributeError:
-        numpy_include = numpy.get_numpy_include()
-    return numpy_include
-
-
-def import_file(filename):
-    """
-    Imports a module from a single file as if it doesn't belong to a
-    particular package.
-    """
-    # Specifying a traditional dot-separated fully qualified name here
-    # results in a number of "Parent module 'astropy' not found while
-    # handling absolute import" warnings.  Using the same name, the
-    # namespaces of the modules get merged together.  So, this
-    # generates an underscore-separated name which is more likely to
-    # be unique, and it doesn't really matter because the name isn't
-    # used directly here anyway.
-    with open(filename, 'U') as fd:
-        name = '_'.join(
-            os.path.relpath(os.path.splitext(filename)[0]).split(os.sep)[1:])
-        return imp.load_module(name, fd, filename, ('.py', 'U', 1))
-
-
-class DistutilsExtensionArgs(collections.defaultdict):
-    """
-    A special dictionary whose default values are the empty list.
-
-    This is useful for building up a set of arguments for
-    `distutils.Extension` without worrying whether the entry is
-    already present.
-    """
-    def __init__(self, *args, **kwargs):
-        def default_factory():
-            return []
-
-        super(DistutilsExtensionArgs, self).__init__(
-            default_factory, *args, **kwargs)
-
-    def update(self, other):
-        for key, val in other.items():
-            self[key].extend(val)
-
-
-def pkg_config(packages, default_libraries):
-    """
-    Uses pkg-config to update a set of distutils Extension arguments
-    to include the flags necessary to link against the given packages.
-
-    If the pkg-config lookup fails, default_libraries is applied to
-    libraries.
-
-    Parameters
-    ----------
-    packages : list of str
-        A list of pkg-config packages to look up.
-
-    default_libraries : list of str
-        A list of library names to use if the pkg-config lookup fails.
-
-    Returns
-    -------
-    config : dict
-        A dictionary containing keyword arguments to
-        `distutils.Extension`.  These entries include:
-
-        - ``include_dirs``: A list of include directories
-        - ``library_dirs``: A list of library directories
-        - ``libraries``: A list of libraries
-        - ``define_macros``: A list of macro defines
-        - ``undef_macros``: A list of macros to undefine
-        - ``extra_compile_args``: A list of extra arguments to pass to
-          the compiler
-    """
-
-    flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries',
-                '-D': 'define_macros', '-U': 'undef_macros'}
-    command = "pkg-config --libs --cflags {0}".format(' '.join(packages)),
-
-    result = DistutilsExtensionArgs()
-
-    try:
-        pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
-        output = pipe.communicate()[0].strip()
-    except subprocess.CalledProcessError as e:
-        lines = [
-            "pkg-config failed.  This may cause the build to fail below.",
-            "  command: {0}".format(e.cmd),
-            "  returncode: {0}".format(e.returncode),
-            "  output: {0}".format(e.output)
-            ]
-        log.warn('\n'.join(lines))
-        result['libraries'].extend(default_libraries)
-    else:
-        if pipe.returncode != 0:
-            lines = [
-                "pkg-config could not lookup up package(s) {0}.".format(
-                    ", ".join(packages)),
-                "This may cause the build to fail below."
-                ]
-            log.warn('\n'.join(lines))
-            result['libraries'].extend(default_libraries)
-        else:
-            for token in output.split():
-                # It's not clear what encoding the output of
-                # pkg-config will come to us in.  It will probably be
-                # some combination of pure ASCII (for the compiler
-                # flags) and the filesystem encoding (for any argument
-                # that includes directories or filenames), but this is
-                # just conjecture, as the pkg-config documentation
-                # doesn't seem to address it.
-                arg = token[:2].decode('ascii')
-                value = token[2:].decode(sys.getfilesystemencoding())
-                if arg in flag_map:
-                    if arg == '-D':
-                        value = tuple(value.split('=', 1))
-                    result[flag_map[arg]].append(value)
-                else:
-                    result['extra_compile_args'].append(value)
-
-    return result
-
-
-def add_external_library(library):
-    """
-    Add a build option for selecting the internal or system copy of a library.
-
-    Parameters
-    ----------
-    library : str
-        The name of the library.  If the library is `foo`, the build
-        option will be called `--use-system-foo`.
-    """
-
-    for command in ['build', 'build_ext', 'install']:
-        add_command_option(command, str('use-system-' + library),
-                           'Use the system {0} library'.format(library),
-                           is_bool=True)
-
-
-def use_system_library(library):
-    """
-    Returns `True` if the build configuration indicates that the given
-    library should use the system copy of the library rather than the
-    internal one.
-
-    For the given library `foo`, this will be `True` if
-    `--use-system-foo` or `--use-system-libraries` was provided at the
-    commandline or in `setup.cfg`.
-
-    Parameters
-    ----------
-    library : str
-        The name of the library
-
-    Returns
-    -------
-    use_system : bool
-        `True` if the build should use the system copy of the library.
-    """
-    return (
-        get_distutils_build_or_install_option('use_system_{0}'.format(library))
-        or get_distutils_build_or_install_option('use_system_libraries'))
-
-
-def filter_packages(packagenames):
-    """
-    Removes some packages from the package list that shouldn't be
-    installed on the current version of Python.
-    """
-
-    if PY3:
-        exclude = '_py2'
-    else:
-        exclude = '_py3'
-
-    return [x for x in packagenames if not x.endswith(exclude)]
-
-
-class FakeBuildSphinx(Command):
-    """
-    A dummy build_sphinx command that is called if Sphinx is not
-    installed and displays a relevant error message
-    """
-
-    #user options inherited from sphinx.setup_command.BuildDoc
-    user_options = [
-         ('fresh-env', 'E', '' ),
-         ('all-files', 'a', ''),
-         ('source-dir=', 's', ''),
-         ('build-dir=', None, ''),
-         ('config-dir=', 'c', ''),
-         ('builder=', 'b', ''),
-         ('project=', None, ''),
-         ('version=', None, ''),
-         ('release=', None, ''),
-         ('today=', None, ''),
-         ('link-index', 'i', ''),
-     ]
-
-    #user options appended in astropy.setup_helpers.AstropyBuildSphinx
-    user_options.append(('warnings-returncode', 'w',''))
-    user_options.append(('clean-docs', 'l', ''))
-    user_options.append(('no-intersphinx', 'n', ''))
-    user_options.append(('open-docs-in-browser', 'o',''))
-
-
-
-    def initialize_options(self):
-        try:
-            raise RuntimeError("Sphinx must be installed for build_sphinx")
-        except:
-            log.error('error : Sphinx must be installed for build_sphinx')
-            sys.exit(1)
diff --git a/astropy/sphinx/__init__.py b/astropy/sphinx/__init__.py
deleted file mode 100644
index 7face25..0000000
--- a/astropy/sphinx/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""
-This package contains utilities and extensions for the Astropy sphinx
-documentation.  In particular, the `astropy.sphinx.conf` should be imported by
-the sphinx ``conf.py`` file for affiliated packages that wish to make use of
-the Astropy documentation format.
-"""
diff --git a/astropy/sphinx/conf.py b/astropy/sphinx/conf.py
deleted file mode 100644
index 3d7fd16..0000000
--- a/astropy/sphinx/conf.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-#
-# Astropy shared Sphinx settings.  These settings are shared between
-# astropy itself and affiliated packages.
-#
-# Note that not all possible configuration values are present in this file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import warnings
-from os import path
-
-
-# -- General configuration ----------------------------------------------------
-
-# The version check in Sphinx itself can only compare the major and
-# minor parts of the version number, not the micro.  To do a more
-# specific version check, call check_sphinx_version("x.y.z.") from
-# your project's conf.py
-needs_sphinx = '1.2'
-
-
-def check_sphinx_version(expected_version):
-    import sphinx
-    from distutils import version
-
-    sphinx_version = version.LooseVersion(sphinx.__version__)
-    expected_version = version.LooseVersion(expected_version)
-    if sphinx_version < expected_version:
-        raise RuntimeError(
-            "At least Sphinx version {0} is required to build this "
-            "documentation.  Found {1}.".format(
-                expected_version, sphinx_version))
-
-
-# Configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {
-    'python': ('http://docs.python.org/', None),
-    'numpy': ('http://docs.scipy.org/doc/numpy/', None),
-    'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None),
-    'matplotlib': ('http://matplotlib.sourceforge.net/', None),
-    'astropy': ('http://docs.astropy.org/en/stable/', None),
-    'h5py': ('http://docs.h5py.org/en/latest/', None)
-    }
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# Add any paths that contain templates here, relative to this directory.
-# templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents. Set to the "smart" one.
-default_role = 'obj'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# This is added to the end of RST files - a good place to put substitutions to
-# be used globally.
-rst_epilog = """
-.. _Astropy: http://astropy.org
-"""
-
-
-# -- Project information ------------------------------------------------------
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-#pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Settings for extensions and extension options ----------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
-    'sphinx.ext.autodoc',
-    'sphinx.ext.intersphinx',
-    'sphinx.ext.todo',
-    'sphinx.ext.coverage',
-    'sphinx.ext.pngmath',
-    'sphinx.ext.inheritance_diagram',
-    'astropy.sphinx.ext.numpydoc',
-    'astropy.sphinx.ext.astropyautosummary',
-    'astropy.sphinx.ext.automodsumm',
-    'astropy.sphinx.ext.automodapi',
-    'astropy.sphinx.ext.tocdepthfix',
-    'astropy.sphinx.ext.doctest',
-    'astropy.sphinx.ext.changelog_links',
-    'astropy.sphinx.ext.viewcode',  # Use patched version of viewcode
-    'astropy.sphinx.ext.smart_resolver'
-    ]
-
-# Above, we use a patched version of viewcode rather than 'sphinx.ext.viewcode'
-# This can be changed to the sphinx version once the following issue is fixed
-# in sphinx:
-# https://bitbucket.org/birkenfeld/sphinx/issue/623/
-# extension-viewcode-fails-with-function
-
-try:
-    import matplotlib.sphinxext.plot_directive
-    extensions += [matplotlib.sphinxext.plot_directive.__name__]
-# AttributeError is checked here in case matplotlib is installed but
-# Sphinx isn't.  Note that this module is imported by the config file
-# generator, even if we're not building the docs.
-except (ImportError, AttributeError):
-    warnings.warn(
-        "matplotlib's plot_directive could not be imported. " +
-        "Inline plots will not be included in the output")
-
-# Don't show summaries of the members in each class along with the
-# class' docstring
-numpydoc_show_class_members = False
-
-autosummary_generate = True
-
-automodapi_toctreedirnm = 'api'
-
-# Class documentation should contain *both* the class docstring and
-# the __init__ docstring
-autoclass_content = "both"
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = [path.abspath(path.join(path.dirname(__file__), 'themes'))]
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-html_theme = 'bootstrap-astropy'
-
-# Custom sidebar templates, maps document names to template names.
-html_sidebars = {
-    '**': ['localtoc.html'],
-    'search': [],
-    'genindex': [],
-    'py-modindex': [],
-}
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-html_favicon = 'astropy_logo.ico'  # included in the bootstrap-astropy theme
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%d %b %Y'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# -- Options for LaTeX output ------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-latex_use_parts = True
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-latex_preamble = r"""
-% Use a more modern-looking monospace font
-\usepackage{inconsolata}
-
-% The enumitem package provides unlimited nesting of lists and enums.
-% Sphinx may use this in the future, in which case this can be removed.
-% See https://bitbucket.org/birkenfeld/sphinx/issue/777/latex-output-too-deeply-nested
-\usepackage{enumitem}
-\setlistdepth{15}
-
-% In the parameters section, place a newline after the Parameters
-% header.  (This is stolen directly from Numpy's conf.py, since it
-% affects Numpy-style docstrings).
-\usepackage{expdlist}
-\let\latexdescription=\description
-\def\description{\latexdescription{}{} \breaklabel}
-
-% Support the superscript Unicode numbers used by the "unicode" units
-% formatter
-\DeclareUnicodeCharacter{2070}{\ensuremath{^0}}
-\DeclareUnicodeCharacter{00B9}{\ensuremath{^1}}
-\DeclareUnicodeCharacter{00B2}{\ensuremath{^2}}
-\DeclareUnicodeCharacter{00B3}{\ensuremath{^3}}
-\DeclareUnicodeCharacter{2074}{\ensuremath{^4}}
-\DeclareUnicodeCharacter{2075}{\ensuremath{^5}}
-\DeclareUnicodeCharacter{2076}{\ensuremath{^6}}
-\DeclareUnicodeCharacter{2077}{\ensuremath{^7}}
-\DeclareUnicodeCharacter{2078}{\ensuremath{^8}}
-\DeclareUnicodeCharacter{2079}{\ensuremath{^9}}
-\DeclareUnicodeCharacter{207B}{\ensuremath{^-}}
-\DeclareUnicodeCharacter{00B0}{\ensuremath{^{\circ}}}
-\DeclareUnicodeCharacter{2032}{\ensuremath{^{\prime}}}
-\DeclareUnicodeCharacter{2033}{\ensuremath{^{\prime\prime}}}
-
-% Make the "warning" and "notes" sections use a sans-serif font to
-% make them stand out more.
-\renewenvironment{notice}[2]{
-  \def\py at noticetype{#1}
-  \csname py at noticestart@#1\endcsname
-  \textsf{\textbf{#2}}
-}{\csname py at noticeend@\py at noticetype\endcsname}
-"""
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# -- Options for the linkcheck builder ----------------------------------------
-
-# A timeout value, in seconds, for the linkcheck builder
-linkcheck_timeout = 60
diff --git a/astropy/sphinx/ext/__init__.py b/astropy/sphinx/ext/__init__.py
deleted file mode 100644
index 1e9731c..0000000
--- a/astropy/sphinx/ext/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""
-This package contains the sphinx extensions used by Astropy.
-
-The `automodsumm` and `automodapi` modules contain extensions used by Astropy
-to generate API documentation - see the docstrings for details.  The `numpydoc`
-module is dervied from the documentation tools numpy and scipy use to parse
-docstrings in the numpy/scipy format, and are also used by Astropy.  The
-other modules are dependencies for `numpydoc`.
-"""
diff --git a/astropy/sphinx/ext/astropyautosummary.py b/astropy/sphinx/ext/astropyautosummary.py
deleted file mode 100644
index 5d2f368..0000000
--- a/astropy/sphinx/ext/astropyautosummary.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This sphinx extension builds off of `sphinx.ext.autosummary` to
-clean up some issues it presents in the Astropy docs.
-
-The main issue this fixes is the summary tables getting cut off before the
-end of the sentence in some cases.
-
-"""
-import re
-
-from sphinx.ext.autosummary import Autosummary
-
-# used in AstropyAutosummary.get_items
-_itemsummrex = re.compile(r'^([A-Z].*?\.(?:\s|$))')
-
-
-class AstropyAutosummary(Autosummary):
-    def get_items(self, names):
-        """Try to import the given names, and return a list of
-        ``[(name, signature, summary_string, real_name), ...]``.
-        """
-        from sphinx.ext.autosummary import (get_import_prefixes_from_env,
-            import_by_name, get_documenter, mangle_signature)
-
-        env = self.state.document.settings.env
-
-        prefixes = get_import_prefixes_from_env(env)
-
-        items = []
-
-        max_item_chars = 50
-
-        for name in names:
-            display_name = name
-            if name.startswith('~'):
-                name = name[1:]
-                display_name = name.split('.')[-1]
-
-            try:
-                real_name, obj, parent = import_by_name(name, prefixes=prefixes)
-            except ImportError:
-                self.warn('[astropyautosummary] failed to import %s' % name)
-                items.append((name, '', '', name))
-                continue
-
-            # NB. using real_name here is important, since Documenters
-            #     handle module prefixes slightly differently
-            documenter = get_documenter(obj, parent)(self, real_name)
-            if not documenter.parse_name():
-                self.warn('[astropyautosummary] failed to parse name %s' % real_name)
-                items.append((display_name, '', '', real_name))
-                continue
-            if not documenter.import_object():
-                self.warn('[astropyautosummary] failed to import object %s' % real_name)
-                items.append((display_name, '', '', real_name))
-                continue
-
-            # -- Grab the signature
-
-            sig = documenter.format_signature()
-            if not sig:
-                sig = ''
-            else:
-                max_chars = max(10, max_item_chars - len(display_name))
-                sig = mangle_signature(sig, max_chars=max_chars)
-                sig = sig.replace('*', r'\*')
-
-            # -- Grab the summary
-
-            doc = list(documenter.process_doc(documenter.get_doc()))
-
-            while doc and not doc[0].strip():
-                doc.pop(0)
-            m = _itemsummrex.search(" ".join(doc).strip())
-            if m:
-                summary = m.group(1).strip()
-            elif doc:
-                summary = doc[0].strip()
-            else:
-                summary = ''
-
-            items.append((display_name, sig, summary, real_name))
-
-        return items
-
-
-def setup(app):
-    # need autosummary, of course
-    app.setup_extension('sphinx.ext.autosummary')
-    # this replaces the default autosummary with the astropy one
-    app.add_directive('autosummary', AstropyAutosummary)
diff --git a/astropy/sphinx/ext/automodapi.py b/astropy/sphinx/ext/automodapi.py
deleted file mode 100644
index 87df319..0000000
--- a/astropy/sphinx/ext/automodapi.py
+++ /dev/null
@@ -1,353 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This sphinx extension adds a tools to simplify generating the API
-documentation for Astropy packages and affiliated packages.
-
-.. _automodapi:
-
-========================
-automodapi directive
-========================
-This directive takes a single argument that must be a module or package. It
-will produce a block of documentation that includes the docstring for the
-package, an :ref:`automodsumm` directive, and an :ref:`automod-diagram` if
-there are any classes in the module. If only the main docstring of the
-module/package is desired in the documentation, use `automodule`_ instead of
-`automodapi`_.
-
-It accepts the following options:
-
-    * ``:no-inheritance-diagram:``
-        If present, the inheritance diagram will not be shown even if
-        the module/package has classes.
-
-    * ``:skip: str``
-        This option results in the
-        specified object being skipped, that is the object will *not* be
-        included in the generated documentation. This option may appear
-        any number of times to skip multiple objects.
-
-    * ``:no-main-docstr:``
-        If present, the docstring for the module/package will not be generated.
-        The function and class tables will still be used, however.
-
-    * ``:headings: str``
-        Specifies the characters (in one string) used as the heading
-        levels used for the generated section. This must have at least 2
-        characters (any after 2 will be ignored). This also *must* match
-        the rest of the documentation on this page for sphinx to be
-        happy. Defaults to "-^", which matches the convention used for
-        Python's documentation, assuming the automodapi call is inside a
-        top-level section (which usually uses '=').
-
-    * ``:no-heading:``
-        If specified do not create a top level heading for the section.
-        That is, do not create a title heading with text like "packagename
-        Package".  The actual docstring for the package/module will still be
-        shown, though, unless ``:no-main-docstr:`` is given.
-
-    * ``:allowed-package-names: str``
-        Specifies the packages that functions/classes documented here are
-        allowed to be from, as comma-separated list of package names. If not
-        given, only objects that are actually in a subpackage of the package
-        currently being documented are included.
-
-This extension also adds two sphinx configuration options:
-
-* ``automodapi_toctreedirnm``
-    This must be a string that specifies the name of the directory the
-    automodsumm generated documentation ends up in. This directory path should
-    be relative to the documentation root (e.g., same place as ``index.rst``).
-    Defaults to ``'api'``.
-
-* ``automodapi_writereprocessed``
-    Should be a bool, and if `True`, will cause `automodapi`_ to write files
-    with any `automodapi`_ sections replaced with the content Sphinx
-    processes after `automodapi`_ has run.  The output files are not
-    actually used by sphinx, so this option is only for figuring out the
-    cause of sphinx warnings or other debugging.  Defaults to `False`.
-
-.. _automodule: http://sphinx-doc.org/latest/ext/autodoc.html?highlight=automodule#directive-automodule
-"""
-
-# Implementation note:
-# The 'automodapi' directive is not actually implemented as a docutils
-# directive. Instead, this extension searches for the 'automodapi' text in
-# all sphinx documents, and replaces it where necessary from a template built
-# into this extension. This is necessary because automodsumm (and autosummary)
-# use the "builder-inited" event, which comes before the directives are
-# actually built.
-
-import inspect
-import os
-import re
-import sys
-
-automod_templ_modheader = """
-{modname} {pkgormod}
-{modhds}{pkgormodhds}
-
-{automoduleline}
-"""
-
-automod_templ_classes = """
-Classes
-{clshds}
-
-.. automodsumm:: {modname}
-    :classes-only:
-    {clsfuncoptions}
-"""
-
-automod_templ_funcs = """
-Functions
-{funchds}
-
-.. automodsumm:: {modname}
-    :functions-only:
-    {clsfuncoptions}
-"""
-
-automod_templ_inh = """
-Class Inheritance Diagram
-{clsinhsechds}
-
-.. automod-diagram:: {modname}
-    :private-bases:
-    :parts: 1
-    {allowedpkgnms}
-"""
-
-_automodapirex = re.compile(r'^(?:\s*\.\.\s+automodapi::\s*)([A-Za-z0-9_.]+)'
-                            r'\s*$((?:\n\s+:[a-zA-Z_\-]+:.*$)*)',
-                            flags=re.MULTILINE)
-# the last group of the above regex is intended to go into finall with the below
-_automodapiargsrex = re.compile(r':([a-zA-Z_\-]+):(.*)$', flags=re.MULTILINE)
-
-
-def automodapi_replace(sourcestr, app, dotoctree=True, docname=None,
-                       warnings=True):
-    """
-    Replaces `sourcestr`'s entries of ".. automdapi::" with the
-    automodapi template form based on provided options.
-
-    This is used with the sphinx event 'source-read' to replace
-    `automodapi`_ entries before sphinx actually processes them, as
-    automodsumm needs the code to be present to generate stub
-    documentation.
-
-    Parameters
-    ----------
-    sourcestr : str
-        The string with sphinx source to be checked for automodapi
-        replacement.
-    app : `sphinx.application.Application`
-        The sphinx application.
-    dotoctree : bool
-        If `True`, a ":toctree:" option will be added in the "..
-        automodsumm::" sections of the template, pointing to the
-        appropriate "generated" directory based on the Astropy convention
-        (e.g. in ``docs/api``)
-    docname : str
-        The name of the file for this `sourcestr` (if known - if not, it
-        can be `None`). If not provided and `dotoctree` is `True`, the
-        generated files may end up in the wrong place.
-    warnings : bool
-        If `False`, all warnings that would normally be issued are
-        silenced.
-
-    Returns
-    -------
-    newstr :str
-        The string with automodapi entries replaced with the correct
-        sphinx markup.
-    """
-
-    spl = _automodapirex.split(sourcestr)
-    if len(spl) > 1:  # automodsumm is in this document
-
-        if dotoctree:
-            toctreestr = ':toctree: '
-            dirnm = app.config.automodapi_toctreedirnm
-            if not dirnm.endswith(os.sep):
-                dirnm += os.sep
-            if docname is not None:
-                toctreestr += '../' * docname.count('/') + dirnm
-            else:
-                toctreestr += dirnm
-        else:
-            toctreestr = ''
-
-        newstrs = [spl[0]]
-        for grp in range(len(spl) // 3):
-            modnm = spl[grp * 3 + 1]
-
-            # find where this is in the document for warnings
-            if docname is None:
-                location = None
-            else:
-                location = (docname, spl[0].count('\n'))
-
-            # initialize default options
-            toskip = []
-            inhdiag = maindocstr = top_head = True
-            hds = '-^'
-            allowedpkgnms = []
-
-            # look for actual options
-            unknownops = []
-            for opname, args in _automodapiargsrex.findall(spl[grp * 3 + 2]):
-                if opname == 'skip':
-                    toskip.append(args.strip())
-                elif opname == 'no-inheritance-diagram':
-                    inhdiag = False
-                elif opname == 'no-main-docstr':
-                    maindocstr = False
-                elif opname == 'headings':
-                    hds = args
-                elif opname == 'no-heading':
-                    top_head = False
-                elif opname == 'allowed-package-names':
-                    allowedpkgnms.append(args.strip())
-                else:
-                    unknownops.append(opname)
-
-            #join all the allowedpkgnms
-            if len(allowedpkgnms) == 0:
-                allowedpkgnms = ''
-                onlylocals = True
-            else:
-                allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms)
-                onlylocals = allowedpkgnms
-
-            # get the two heading chars
-            if len(hds) < 2:
-                msg = 'Not enough headings (got {0}, need 2), using default -^'
-                if warnings:
-                    app.warn(msg.format(len(hds)), location)
-                hds = '-^'
-            h1, h2 = hds.lstrip()[:2]
-
-            # tell sphinx that the remaining args are invalid.
-            if len(unknownops) > 0 and app is not None:
-                opsstrs = ','.join(unknownops)
-                msg = 'Found additional options ' + opsstrs + ' in automodapi.'
-                if warnings:
-                    app.warn(msg, location)
-
-            ispkg, hascls, hasfuncs = _mod_info(modnm, toskip, onlylocals=onlylocals)
-
-            # add automodule directive only if no-main-docstr isn't present
-            if maindocstr:
-                automodline = '.. automodule:: {modname}'.format(modname=modnm)
-            else:
-                automodline = ''
-            if top_head:
-                newstrs.append(automod_templ_modheader.format(modname=modnm,
-                    modhds=h1 * len(modnm),
-                    pkgormod='Package' if ispkg else 'Module',
-                    pkgormodhds=h1 * (8 if ispkg else 7),
-                    automoduleline=automodline))
-            else:
-                newstrs.append(automod_templ_modheader.format(
-                    modname='',
-                    modhds='',
-                    pkgormod='',
-                    pkgormodhds='',
-                    automoduleline=automodline))
-
-            #construct the options for the class/function sections
-            #start out indented at 4 spaces, but need to keep the indentation.
-            clsfuncoptions = []
-            if toctreestr:
-                clsfuncoptions.append(toctreestr)
-            if toskip:
-                clsfuncoptions.append(':skip: ' + ','.join(toskip))
-            if allowedpkgnms:
-                clsfuncoptions.append(allowedpkgnms)
-            clsfuncoptionstr = '\n    '.join(clsfuncoptions)
-
-            if hasfuncs:
-                newstrs.append(automod_templ_funcs.format(
-                    modname=modnm,
-                    funchds=h2 * 9,
-                    clsfuncoptions=clsfuncoptionstr))
-
-            if hascls:
-                newstrs.append(automod_templ_classes.format(
-                    modname=modnm,
-                    clshds=h2 * 7,
-                    clsfuncoptions=clsfuncoptionstr))
-
-            if inhdiag and hascls:
-                # add inheritance diagram if any classes are in the module
-                newstrs.append(automod_templ_inh.format(
-                    modname=modnm,
-                    clsinhsechds=h2 * 25,
-                    allowedpkgnms=allowedpkgnms))
-
-            newstrs.append(spl[grp * 3 + 3])
-
-        newsourcestr = ''.join(newstrs)
-
-        if app.config.automodapi_writereprocessed:
-            # sometimes they are unicode, sometimes not, depending on how
-            # sphinx has processed things
-            if isinstance(newsourcestr, unicode):
-                ustr = newsourcestr
-            else:
-                ustr = newsourcestr.decode(app.config.source_encoding)
-
-            if docname is None:
-                with open(os.path.join(app.srcdir, 'unknown.automodapi'), 'a') as f:
-                    f.write('\n**NEW DOC**\n\n')
-                    f.write(ustr.encode('utf8'))
-            else:
-                with open(os.path.join(app.srcdir, docname + '.automodapi'), 'w') as f:
-                    f.write(ustr.encode('utf8'))
-
-        return newsourcestr
-    else:
-        return sourcestr
-
-
-def _mod_info(modname, toskip=[], onlylocals=True):
-    """
-    Determines if a module is a module or a package and whether or not
-    it has classes or functions.
-    """
-
-    from ...utils.misc import find_mod_objs
-
-    hascls = hasfunc = False
-
-    for localnm, fqnm, obj in zip(*find_mod_objs(modname, onlylocals=onlylocals)):
-        if localnm not in toskip:
-            hascls = hascls or inspect.isclass(obj)
-            hasfunc = hasfunc or inspect.isfunction(obj)
-            if hascls and hasfunc:
-                break
-
-    # find_mod_objs has already imported modname
-    pkg = sys.modules[modname]
-    ispkg = '__init__.' in os.path.split(pkg.__name__)[1]
-
-    return ispkg, hascls, hasfunc
-
-
-def process_automodapi(app, docname, source):
-    source[0] = automodapi_replace(source[0], app, True, docname)
-
-
-def setup(app):
-    # need automodsumm for automodapi
-    app.setup_extension('astropy.sphinx.ext.automodsumm')
-
-    app.connect('source-read', process_automodapi)
-
-    app.add_config_value('automodapi_toctreedirnm', 'api', True)
-    app.add_config_value('automodapi_writereprocessed', False, True)
diff --git a/astropy/sphinx/ext/automodsumm.py b/astropy/sphinx/ext/automodsumm.py
deleted file mode 100644
index 7697aed..0000000
--- a/astropy/sphinx/ext/automodsumm.py
+++ /dev/null
@@ -1,579 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This sphinx extension adds two directives for summarizing the public
-members of a module or package.
-
-These directives are primarily for use with the `automodapi`_ extension,
-but can be used independently.
-
-.. _automodsumm:
-
-=======================
-automodsumm directive
-=======================
-
-This directive will produce an "autosummary"-style table for public
-attributes of a specified module. See the `sphinx.ext.autosummary`_ extension
-for details on this process. The main difference from the `autosummary`_
-directive is that `autosummary`_ requires manually inputting all attributes
-that appear in the table, while this captures the entries automatically.
-
-This directive requires a single argument that must be a module or
-package.
-
-It also accepts any options supported by the `autosummary`_ directive-
-see `sphinx.ext.autosummary`_ for details. It also accepts two additional
-options:
-
-    * ``:classes-only:``
-        If present, the autosummary table will only contain entries for
-        classes. This cannot be used at the same time with
-        ``:functions-only:`` .
-
-    * ``:functions-only:``
-        If present, the autosummary table will only contain entries for
-        functions. This cannot be used at the same time with
-        ``:classes-only:`` .
-
-    * ``:skip: obj1, [obj2, obj3, ...]``
-        If present, specifies that the listed objects should be skipped
-        and not have their documentation generated, nor be includded in
-        the summary table.
-
-    * ``:allowed-package-names: pkgormod1, [pkgormod2, pkgormod3, ...]``
-        Specifies the packages that functions/classes documented here are
-        allowed to be from, as comma-separated list of package names. If not
-        given, only objects that are actually in a subpackage of the package
-        currently being documented are included.
-
-This extension also adds one sphinx configuration option:
-
-* ``automodsumm_writereprocessed``
-    Should be a bool, and if True, will cause `automodsumm`_ to write files
-    with any ``automodsumm`` sections replaced with the content Sphinx
-    processes after ``automodsumm`` has run.  The output files are not
-    actually used by sphinx, so this option is only for figuring out the
-    cause of sphinx warnings or other debugging.  Defaults to `False`.
-
-.. _sphinx.ext.autosummary: http://sphinx-doc.org/latest/ext/autosummary.html
-.. _autosummary: http://sphinx-doc.org/latest/ext/autosummary.html#directive-autosummary
-
-.. _automod-diagram:
-
-===========================
-automod-diagram directive
-===========================
-
-This directive will produce an inheritance diagram like that of the
-`sphinx.ext.inheritance_diagram`_ extension.
-
-This directive requires a single argument that must be a module or
-package. It accepts no options.
-
-.. note::
-    Like 'inheritance-diagram', 'automod-diagram' requires
-    `graphviz <http://www.graphviz.org/>`_ to generate the inheritance diagram.
-
-.. _sphinx.ext.inheritance_diagram: http://sphinx-doc.org/latest/ext/inheritance.html
-"""
-
-import inspect
-import os
-import re
-
-from sphinx.ext.autosummary import Autosummary
-from sphinx.ext.inheritance_diagram import InheritanceDiagram
-from docutils.parsers.rst.directives import flag
-
-from ...utils.misc import find_mod_objs
-from .astropyautosummary import AstropyAutosummary
-
-
-def _str_list_converter(argument):
-    """
-    A directive option conversion function that converts the option into a list
-    of strings. Used for 'skip' option.
-    """
-    if argument is None:
-        return []
-    else:
-        return [s.strip() for s in argument.split(',')]
-
-
-class Automodsumm(AstropyAutosummary):
-    required_arguments = 1
-    optional_arguments = 0
-    final_argument_whitespace = False
-    has_content = False
-    option_spec = dict(Autosummary.option_spec)
-    option_spec['functions-only'] = flag
-    option_spec['classes-only'] = flag
-    option_spec['skip'] = _str_list_converter
-    option_spec['allowed-package-names'] = _str_list_converter
-
-    def run(self):
-        env = self.state.document.settings.env
-        modname = self.arguments[0]
-
-        self.warnings = []
-        nodelist = []
-
-        try:
-            localnames, fqns, objs = find_mod_objs(modname)
-        except ImportError:
-            self.warnings = []
-            self.warn("Couldn't import module " + modname)
-            return self.warnings
-
-        try:
-            # set self.content to trick the Autosummary internals.
-            # Be sure to respect functions-only and classes-only.
-            funconly = 'functions-only' in self.options
-            clsonly = 'classes-only' in self.options
-
-            skipnames = []
-            if 'skip' in self.options:
-                option_skipnames = set(self.options['skip'])
-                for lnm in localnames:
-                    if lnm in option_skipnames:
-                        option_skipnames.remove(lnm)
-                        skipnames.append(lnm)
-                if len(option_skipnames) > 0:
-                    self.warn('Tried to skip objects {objs} in module {mod}, '
-                              'but they were not present.  Ignoring.'.format(
-                              objs=option_skipnames, mod=modname))
-
-            if funconly and not clsonly:
-                cont = []
-                for nm, obj in zip(localnames, objs):
-                    if nm not in skipnames and inspect.isfunction(obj):
-                        cont.append(nm)
-            elif clsonly:
-                cont = []
-                for nm, obj in zip(localnames, objs):
-                    if nm not in skipnames and inspect.isclass(obj):
-                        cont.append(nm)
-            else:
-                if clsonly and funconly:
-                    self.warning('functions-only and classes-only both '
-                                 'defined. Skipping.')
-                cont = [nm for nm in localnames if nm not in skipnames]
-
-            self.content = cont
-
-            #for some reason, even though ``currentmodule`` is substituted in, sphinx
-            #doesn't necessarily recognize this fact.  So we just force it
-            #internally, and that seems to fix things
-            env.temp_data['py:module'] = modname
-
-            #can't use super because Sphinx/docutils has trouble
-            #return super(Autosummary,self).run()
-            nodelist.extend(Autosummary.run(self))
-            return self.warnings + nodelist
-        finally:  # has_content = False for the Automodsumm
-            self.content = []
-
-
-#<-------------------automod-diagram stuff------------------------------------>
-class Automoddiagram(InheritanceDiagram):
-
-    option_spec = dict(InheritanceDiagram.option_spec)
-    option_spec['allowed-package-names'] = _str_list_converter
-
-    def run(self):
-        try:
-            ols = self.options.get('allowed-package-names', [])
-            ols = True if len(ols) == 0 else ols  # if none are given, assume only local
-
-            nms, objs = find_mod_objs(self.arguments[0], onlylocals=ols)[1:]
-        except ImportError:
-            self.warnings = []
-            self.warn("Couldn't import module " + self.arguments[0])
-            return self.warnings
-
-        clsnms = []
-        for n, o in zip(nms, objs):
-
-            if inspect.isclass(o):
-                clsnms.append(n)
-
-        oldargs = self.arguments
-        try:
-            if len(clsnms) > 0:
-                self.arguments = [u' '.join(clsnms)]
-            return InheritanceDiagram.run(self)
-        finally:
-            self.arguments = oldargs
-
-
-#<---------------------automodsumm generation stuff--------------------------->
-def process_automodsumm_generation(app):
-    env = app.builder.env
-    ext = app.config.source_suffix
-
-    filestosearch = [x + ext for x in env.found_docs
-                     if os.path.isfile(env.doc2path(x))]\
-
-    liness = []
-    for sfn in filestosearch:
-        lines = automodsumm_to_autosummary_lines(sfn, app)
-        liness.append(lines)
-        if app.config.automodsumm_writereprocessed:
-            if lines:  # empty list means no automodsumm entry is in the file
-                outfn = os.path.join(app.srcdir, sfn) + '.automodsumm'
-                with open(outfn, 'w') as f:
-                    for l in lines:
-                        f.write(l)
-                        f.write('\n')
-
-    for sfn, lines in zip(filestosearch, liness):
-        if len(lines) > 0:
-            generate_automodsumm_docs(lines, sfn, builder=app.builder,
-                                      warn=app.warn, info=app.info,
-                                      suffix=app.config.source_suffix,
-                                      base_path=app.srcdir)
-
-#_automodsummrex = re.compile(r'^(\s*)\.\. automodsumm::\s*([A-Za-z0-9_.]+)\s*'
-#                             r'\n\1(\s*)(\S|$)', re.MULTILINE)
-_lineendrex = r'(?:\n|$)'
-_hdrex = r'^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*' + _lineendrex
-_oprex1 = r'(?:\1(\s+)\S.*' + _lineendrex + ')'
-_oprex2 = r'(?:\1\4\S.*' + _lineendrex + ')'
-_automodsummrex = re.compile(_hdrex + '(' + _oprex1 + '?' + _oprex2 + '*)',
-                             re.MULTILINE)
-
-
-def automodsumm_to_autosummary_lines(fn, app):
-    """
-    Generates lines from a file with an "automodsumm" entry suitable for
-    feeding into "autosummary".
-
-    Searches the provided file for `automodsumm` directives and returns
-    a list of lines specifying the `autosummary` commands for the modules
-    requested. This does *not* return the whole file contents - just an
-    autosummary section in place of any :automodsumm: entries. Note that
-    any options given for `automodsumm` are also included in the
-    generated `autosummary` section.
-
-    Parameters
-    ----------
-    fn : str
-        The name of the file to search for `automodsumm` entries.
-    app : sphinx.application.Application
-        The sphinx Application object
-
-    Return
-    ------
-    lines : list of str
-        Lines for all `automodsumm` entries with the entries replaced by
-        `autosummary` and the module's members added.
-
-
-    """
-    fullfn = os.path.join(app.builder.env.srcdir, fn)
-
-    with open(fullfn) as fr:
-        if 'astropy.sphinx.ext.automodapi' in app._extensions:
-            from astropy.sphinx.ext.automodapi import automodapi_replace
-            # Must do the automodapi on the source to get the automodsumm
-            # that might be in there
-            filestr = automodapi_replace(fr.read(), app, True, fn, False)
-        else:
-            filestr = fr.read()
-
-    spl = _automodsummrex.split(filestr)
-    #0th entry is the stuff before the first automodsumm line
-    indent1s = spl[1::5]
-    mods = spl[2::5]
-    opssecs = spl[3::5]
-    indent2s = spl[4::5]
-    remainders = spl[5::5]
-
-    # only grab automodsumm sections and convert them to autosummary with the
-    # entries for all the public objects
-    newlines = []
-
-    #loop over all automodsumms in this document
-    for i, (i1, i2, modnm, ops, rem) in enumerate(zip(indent1s, indent2s, mods,
-                                                    opssecs, remainders)):
-        allindent = i1 + ('' if i2 is None else i2)
-
-        #filter out functions-only and classes-only options if present
-        oplines = ops.split('\n')
-        toskip = []
-        allowedpkgnms = []
-        funcsonly = clssonly = False
-        for i, ln in reversed(list(enumerate(oplines))):
-            if ':functions-only:' in ln:
-                funcsonly = True
-                del oplines[i]
-            if ':classes-only:' in ln:
-                clssonly = True
-                del oplines[i]
-            if ':skip:' in ln:
-                toskip.extend(_str_list_converter(ln.replace(':skip:', '')))
-                del oplines[i]
-            if ':allowed-package-names:' in ln:
-                allowedpkgnms.extend(_str_list_converter(ln.replace(':allowed-package-names:', '')))
-                del oplines[i]
-        if funcsonly and clssonly:
-            msg = ('Defined both functions-only and classes-only options. '
-                   'Skipping this directive.')
-            lnnum = sum([spl[j].count('\n') for j in range(i * 5 + 1)])
-            app.warn('[automodsumm]' + msg, (fn, lnnum))
-            continue
-
-        # Use the currentmodule directive so we can just put the local names
-        # in the autosummary table.  Note that this doesn't always seem to
-        # actually "take" in Sphinx's eyes, so in `Automodsumm.run`, we have to
-        # force it internally, as well.
-        newlines.extend([i1 + '.. currentmodule:: ' + modnm,
-                         '',
-                         '.. autosummary::'])
-        newlines.extend(oplines)
-
-        ols = True if len(allowedpkgnms) == 0 else allowedpkgnms
-        for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols)):
-            if nm in toskip:
-                continue
-            if funcsonly and not inspect.isfunction(obj):
-                continue
-            if clssonly and not inspect.isclass(obj):
-                continue
-            newlines.append(allindent + nm)
-
-    return newlines
-
-
-def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None,
-                              info=None, base_path=None, builder=None,
-                              template_dir=None):
-    """
-    This function is adapted from
-    `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
-    generate source for the automodsumm directives that should be
-    autosummarized. Unlike generate_autosummary_docs, this function is
-    called one file at a time.
-    """
-
-    from sphinx.jinja2glue import BuiltinTemplateLoader
-    from sphinx.ext.autosummary import import_by_name, get_documenter
-    from sphinx.ext.autosummary.generate import (find_autosummary_in_lines,
-                                                 _simple_info, _simple_warn)
-    from sphinx.util.osutil import ensuredir
-    from sphinx.util.inspect import safe_getattr
-    from jinja2 import FileSystemLoader, TemplateNotFound
-    from jinja2.sandbox import SandboxedEnvironment
-
-    if info is None:
-        info = _simple_info
-    if warn is None:
-        warn = _simple_warn
-
-    #info('[automodsumm] generating automodsumm for: ' + srcfn)
-
-    # Create our own templating environment - here we use Astropy's
-    # templates rather than the default autosummary templates, in order to
-    # allow docstrings to be shown for methods.
-    template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'),
-                     os.path.join(base_path, '_templates')]
-    if builder is not None:
-        # allow the user to override the templates
-        template_loader = BuiltinTemplateLoader()
-        template_loader.init(builder, dirs=template_dirs)
-    else:
-        if template_dir:
-            template_dirs.insert(0, template_dir)
-        template_loader = FileSystemLoader(template_dirs)
-    template_env = SandboxedEnvironment(loader=template_loader)
-
-    # read
-    #items = find_autosummary_in_files(sources)
-    items = find_autosummary_in_lines(lines, filename=srcfn)
-    if len(items) > 0:
-        msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
-        info(msg.format(len(items), srcfn))
-
-#    gennms = [item[0] for item in items]
-#    if len(gennms) > 20:
-#        gennms = gennms[:10] + ['...'] + gennms[-10:]
-#    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))
-
-    # remove possible duplicates
-    items = dict([(item, True) for item in items]).keys()
-
-    # keep track of new files
-    new_files = []
-
-    # write
-    for name, path, template_name in sorted(items):
-        if path is None:
-            # The corresponding autosummary:: directive did not have
-            # a :toctree: option
-            continue
-
-        path = os.path.abspath(path)
-        ensuredir(path)
-
-        try:
-            name, obj, parent = import_by_name(name)
-        except ImportError, e:
-            warn('[automodsumm] failed to import %r: %s' % (name, e))
-            continue
-
-        fn = os.path.join(path, name + suffix)
-
-        # skip it if it exists
-        if os.path.isfile(fn):
-            continue
-
-        new_files.append(fn)
-
-        f = open(fn, 'w')
-
-        try:
-            doc = get_documenter(obj, parent)
-
-            if template_name is not None:
-                template = template_env.get_template(template_name)
-            else:
-                tmplstr = 'autosummary/%s.rst'
-                try:
-                    template = template_env.get_template(tmplstr % doc.objtype)
-                except TemplateNotFound:
-                    template = template_env.get_template(tmplstr % 'base')
-
-            def get_members_mod(obj, typ, include_public=[]):
-                """
-                typ = None -> all
-                """
-                items = []
-                for name in dir(obj):
-                    try:
-                        documenter = get_documenter(safe_getattr(obj, name),
-                                                    obj)
-                    except AttributeError:
-                        continue
-                    if typ is None or documenter.objtype == typ:
-                        items.append(name)
-                public = [x for x in items
-                          if x in include_public or not x.startswith('_')]
-                return public, items
-
-            def get_members_class(obj, typ, include_public=[],
-                                  include_base=False):
-                """
-                typ = None -> all
-                include_base -> include attrs that are from a base class
-                """
-                items = []
-
-                # using dir gets all of the attributes, including the elements
-                # from the base class, otherwise use __slots__ or __dict__
-                if include_base:
-                    names = dir(obj)
-                else:
-                    if hasattr(obj, '__slots__'):
-                        names = tuple(getattr(obj, '__slots__'))
-                    else:
-                        names = getattr(obj, '__dict__').keys()
-
-                for name in names:
-                    try:
-                        documenter = get_documenter(safe_getattr(obj, name),
-                                                    obj)
-                    except AttributeError:
-                        continue
-                    if typ is None or documenter.objtype == typ:
-                        items.append(name)
-                public = [x for x in items
-                          if x in include_public or not x.startswith('_')]
-                return public, items
-
-            ns = {}
-
-            if doc.objtype == 'module':
-                ns['members'] = get_members_mod(obj, None)
-                ns['functions'], ns['all_functions'] = \
-                                   get_members_mod(obj, 'function')
-                ns['classes'], ns['all_classes'] = \
-                                 get_members_mod(obj, 'class')
-                ns['exceptions'], ns['all_exceptions'] = \
-                                   get_members_mod(obj, 'exception')
-            elif doc.objtype == 'class':
-                api_class_methods = ['__init__', '__call__']
-                ns['members'] = get_members_class(obj, None)
-                ns['methods'], ns['all_methods'] = \
-                                 get_members_class(obj, 'method', api_class_methods)
-                ns['attributes'], ns['all_attributes'] = \
-                                 get_members_class(obj, 'attribute')
-                ns['methods'].sort()
-                ns['attributes'].sort()
-
-            parts = name.split('.')
-            if doc.objtype in ('method', 'attribute'):
-                mod_name = '.'.join(parts[:-2])
-                cls_name = parts[-2]
-                obj_name = '.'.join(parts[-2:])
-                ns['class'] = cls_name
-            else:
-                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]
-
-            ns['fullname'] = name
-            ns['module'] = mod_name
-            ns['objname'] = obj_name
-            ns['name'] = parts[-1]
-
-            ns['objtype'] = doc.objtype
-            ns['underline'] = len(name) * '='
-
-            # We now check whether a file for reference footnotes exists for
-            # the module being documented. We first check if the
-            # current module is a file or a directory, as this will give a
-            # different path for the reference file. For example, if
-            # documenting astropy.wcs then the reference file is at
-            # ../wcs/references.txt, while if we are documenting
-            # astropy.config.logging_helper (which is at
-            # astropy/config/logging_helper.py) then the reference file is set
-            # to ../config/references.txt
-            if '.' in mod_name:
-                mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1]
-            else:
-                mod_name_dir = mod_name
-            if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \
-               and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])):
-                mod_name_dir = mod_name_dir.rsplit('/', 1)[0]
-
-            # We then have to check whether it exists, and if so, we pass it
-            # to the template.
-            if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')):
-                # An important subtlety here is that the path we pass in has
-                # to be relative to the file being generated, so we have to
-                # figure out the right number of '..'s
-                ndirsback = path.replace(base_path, '').count('/')
-                ref_file_rel_segments = ['..'] * ndirsback
-                ref_file_rel_segments.append(mod_name_dir)
-                ref_file_rel_segments.append('references.txt')
-                ns['referencefile'] = os.path.join(*ref_file_rel_segments)
-
-            rendered = template.render(**ns)
-            f.write(rendered)
-        finally:
-            f.close()
-
-
-def setup(app):
-    # need our autosummary
-    app.setup_extension('astropy.sphinx.ext.astropyautosummary')
-    # need inheritance-diagram for automod-diagram
-    app.setup_extension('sphinx.ext.inheritance_diagram')
-
-    app.add_directive('automod-diagram', Automoddiagram)
-    app.add_directive('automodsumm', Automodsumm)
-    app.connect('builder-inited', process_automodsumm_generation)
-
-    app.add_config_value('automodsumm_writereprocessed', False, True)
diff --git a/astropy/sphinx/ext/changelog_links.py b/astropy/sphinx/ext/changelog_links.py
deleted file mode 100644
index ab9ebfc..0000000
--- a/astropy/sphinx/ext/changelog_links.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This sphinx extension makes the issue numbers in the changelog into links to
-GitHub issues.
-"""
-
-from __future__ import print_function
-
-import re
-
-from docutils.nodes import Text, reference
-
-BLOCK_PATTERN = re.compile('\[#.+\]', flags=re.DOTALL)
-ISSUE_PATTERN = re.compile('#[0-9]+')
-
-
-def process_changelog_links(app, doctree, docname):
-
-    if 'changelog' in docname and app.config.github_issues_url is not None:
-
-        for item in doctree.traverse():
-
-            if isinstance(item, Text):
-
-                # We build a new list of items to replace the current item. If
-                # a link is found, we need to use a 'reference' item.
-                children = []
-
-                # First cycle through blocks of issues (delimited by []) then
-                # iterate inside each one to find the individual issues.
-                prev_block_end = 0
-                for block in BLOCK_PATTERN.finditer(item):
-                    block_start, block_end = block.start(), block.end()
-                    children.append(Text(item[prev_block_end:block_start]))
-                    block = item[block_start:block_end]
-                    prev_end = 0
-                    for m in ISSUE_PATTERN.finditer(block):
-                        start, end = m.start(), m.end()
-                        children.append(Text(block[prev_end:start]))
-                        issue_number = block[start:end]
-                        children.append(reference(text=issue_number,
-                                                  name=issue_number,
-                                                  refuri=app.config.github_issues_url + issue_number[1:]))
-                        prev_end = end
-
-                    prev_block_end = block_end
-
-                    # If no issues were found, this adds the whole item,
-                    # otherwise it adds the remaining text.
-                    children.append(Text(block[prev_end:block_end]))
-
-                # If no blocks were found, this adds the whole item, otherwise
-                # it adds the remaining text.
-                children.append(Text(item[prev_block_end:]))
-
-                # Replace item by the new list of items we have generated,
-                # which may contain links.
-                item.parent.replace(item, children)
-
-
-def setup(app):
-    app.connect('doctree-resolved', process_changelog_links)
-    app.add_config_value('github_issues_url', None, True)
diff --git a/astropy/sphinx/ext/comment_eater.py b/astropy/sphinx/ext/comment_eater.py
deleted file mode 100644
index 8b6ff35..0000000
--- a/astropy/sphinx/ext/comment_eater.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-from cStringIO import StringIO
-import compiler
-import inspect
-import textwrap
-import tokenize
-
-from compiler_unparse import unparse
-
-
-class Comment(object):
-    """ A comment block.
-    """
-    is_comment = True
-    def __init__(self, start_lineno, end_lineno, text):
-        # int : The first line number in the block. 1-indexed.
-        self.start_lineno = start_lineno
-        # int : The last line number. Inclusive!
-        self.end_lineno = end_lineno
-        # str : The text block including '#' character but not any leading spaces.
-        self.text = text
-
-    def add(self, string, start, end, line):
-        """ Add a new comment line.
-        """
-        self.start_lineno = min(self.start_lineno, start[0])
-        self.end_lineno = max(self.end_lineno, end[0])
-        self.text += string
-
-    def __repr__(self):
-        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.start_lineno,
-            self.end_lineno, self.text)
-
-
-class NonComment(object):
-    """ A non-comment block of code.
-    """
-    is_comment = False
-    def __init__(self, start_lineno, end_lineno):
-        self.start_lineno = start_lineno
-        self.end_lineno = end_lineno
-
-    def add(self, string, start, end, line):
-        """ Add lines to the block.
-        """
-        if string.strip():
-            # Only add if not entirely whitespace.
-            self.start_lineno = min(self.start_lineno, start[0])
-            self.end_lineno = max(self.end_lineno, end[0])
-
-    def __repr__(self):
-        return '%s(%r, %r)' % (self.__class__.__name__, self.start_lineno,
-            self.end_lineno)
-
-
-class CommentBlocker(object):
-    """ Pull out contiguous comment blocks.
-    """
-    def __init__(self):
-        # Start with a dummy.
-        self.current_block = NonComment(0, 0)
-
-        # All of the blocks seen so far.
-        self.blocks = []
-
-        # The index mapping lines of code to their associated comment blocks.
-        self.index = {}
-
-    def process_file(self, file):
-        """ Process a file object.
-        """
-        for token in tokenize.generate_tokens(file.next):
-            self.process_token(*token)
-        self.make_index()
-
-    def process_token(self, kind, string, start, end, line):
-        """ Process a single token.
-        """
-        if self.current_block.is_comment:
-            if kind == tokenize.COMMENT:
-                self.current_block.add(string, start, end, line)
-            else:
-                self.new_noncomment(start[0], end[0])
-        else:
-            if kind == tokenize.COMMENT:
-                self.new_comment(string, start, end, line)
-            else:
-                self.current_block.add(string, start, end, line)
-
-    def new_noncomment(self, start_lineno, end_lineno):
-        """ We are transitioning from a noncomment to a comment.
-        """
-        block = NonComment(start_lineno, end_lineno)
-        self.blocks.append(block)
-        self.current_block = block
-
-    def new_comment(self, string, start, end, line):
-        """ Possibly add a new comment.
-        
-        Only adds a new comment if this comment is the only thing on the line.
-        Otherwise, it extends the noncomment block.
-        """
-        prefix = line[:start[1]]
-        if prefix.strip():
-            # Oops! Trailing comment, not a comment block.
-            self.current_block.add(string, start, end, line)
-        else:
-            # A comment block.
-            block = Comment(start[0], end[0], string)
-            self.blocks.append(block)
-            self.current_block = block
-
-    def make_index(self):
-        """ Make the index mapping lines of actual code to their associated
-        prefix comments.
-        """
-        for prev, block in zip(self.blocks[:-1], self.blocks[1:]):
-            if not block.is_comment:
-                self.index[block.start_lineno] = prev
-
-    def search_for_comment(self, lineno, default=None):
-        """ Find the comment block just before the given line number.
-
-        Returns None (or the specified default) if there is no such block.
-        """
-        if not self.index:
-            self.make_index()
-        block = self.index.get(lineno, None)
-        text = getattr(block, 'text', default)
-        return text
-
-
-def strip_comment_marker(text):
-    """ Strip # markers at the front of a block of comment text.
-    """
-    lines = []
-    for line in text.splitlines():
-        lines.append(line.lstrip('#'))
-    text = textwrap.dedent('\n'.join(lines))
-    return text
-
-
-def get_class_traits(klass):
-    """ Yield all of the documentation for trait definitions on a class object.
-    """
-    # FIXME: gracefully handle errors here or in the caller?
-    source = inspect.getsource(klass)
-    cb = CommentBlocker()
-    cb.process_file(StringIO(source))
-    mod_ast = compiler.parse(source)
-    class_ast = mod_ast.node.nodes[0]
-    for node in class_ast.code.nodes:
-        # FIXME: handle other kinds of assignments?
-        if isinstance(node, compiler.ast.Assign):
-            name = node.nodes[0].name
-            rhs = unparse(node.expr).strip()
-            doc = strip_comment_marker(cb.search_for_comment(node.lineno, default=''))
-            yield name, rhs, doc
-
diff --git a/astropy/sphinx/ext/compiler_unparse.py b/astropy/sphinx/ext/compiler_unparse.py
deleted file mode 100644
index ff54b1f..0000000
--- a/astropy/sphinx/ext/compiler_unparse.py
+++ /dev/null
@@ -1,864 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-""" Turn compiler.ast structures back into executable python code.
-
-    The unparse method takes a compiler.ast tree and transforms it back into
-    valid python code.  It is incomplete and currently only works for
-    import statements, function calls, function definitions, assignments, and
-    basic expressions.
-
-    Inspired by python-2.5-svn/Demo/parser/unparse.py
-
-    fixme: We may want to move to using _ast trees because the compiler for
-           them is about 6 times faster than compiler.compile.
-"""
-
-import sys
-import cStringIO
-from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add
-
-def unparse(ast, single_line_functions=False):
-    s = cStringIO.StringIO()
-    UnparseCompilerAst(ast, s, single_line_functions)
-    return s.getvalue().lstrip()
-
-op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2,
-                  'compiler.ast.Add':1, 'compiler.ast.Sub':1 }
-
-class UnparseCompilerAst:
-    """ Methods in this class recursively traverse an AST and
-        output source code for the abstract syntax; original formatting
-        is disregarged.
-    """
-
-    #########################################################################
-    # object interface.
-    #########################################################################
-
-    def __init__(self, tree, file = sys.stdout, single_line_functions=False):
-        """ Unparser(tree, file=sys.stdout) -> None.
-
-            Print the source for tree to file.
-        """
-        self.f = file
-        self._single_func = single_line_functions
-        self._do_indent = True
-        self._indent = 0
-        self._dispatch(tree)
-        self._write("\n")
-        self.f.flush()
-
-    #########################################################################
-    # Unparser private interface.
-    #########################################################################
-
-    ### format, output, and dispatch methods ################################
-
-    def _fill(self, text = ""):
-        "Indent a piece of text, according to the current indentation level"
-        if self._do_indent:
-            self._write("\n"+"    "*self._indent + text)
-        else:
-            self._write(text)
-
-    def _write(self, text):
-        "Append a piece of text to the current line."
-        self.f.write(text)
-
-    def _enter(self):
-        "Print ':', and increase the indentation."
-        self._write(": ")
-        self._indent += 1
-
-    def _leave(self):
-        "Decrease the indentation level."
-        self._indent -= 1
-
-    def _dispatch(self, tree):
-        "_dispatcher function, _dispatching tree type T to method _T."
-        if isinstance(tree, list):
-            for t in tree:
-                self._dispatch(t)
-            return
-        meth = getattr(self, "_"+tree.__class__.__name__)
-        if tree.__class__.__name__ == 'NoneType' and not self._do_indent:
-            return
-        meth(tree)
-
-
-    #########################################################################
-    # compiler.ast unparsing methods.
-    #
-    # There should be one method per concrete grammar type. They are
-    # organized in alphabetical order.
-    #########################################################################
-
-    def _Add(self, t):
-        self.__binary_op(t, '+')
-
-    def _And(self, t):
-        self._write(" (")
-        for i, node in enumerate(t.nodes):
-            self._dispatch(node)
-            if i != len(t.nodes)-1:
-                self._write(") and (")
-        self._write(")")
-               
-    def _AssAttr(self, t):
-        """ Handle assigning an attribute of an object
-        """
-        self._dispatch(t.expr)
-        self._write('.'+t.attrname)
- 
-    def _Assign(self, t):
-        """ Expression Assignment such as "a = 1".
-
-            This only handles assignment in expressions.  Keyword assignment
-            is handled separately.
-        """
-        self._fill()
-        for target in t.nodes:
-            self._dispatch(target)
-            self._write(" = ")
-        self._dispatch(t.expr)
-        if not self._do_indent:
-            self._write('; ')
-
-    def _AssName(self, t):
-        """ Name on left hand side of expression.
-
-            Treat just like a name on the right side of an expression.
-        """
-        self._Name(t)
-
-    def _AssTuple(self, t):
-        """ Tuple on left hand side of an expression.
-        """
-
-        # _write each elements, separated by a comma.
-        for element in t.nodes[:-1]:
-            self._dispatch(element)
-            self._write(", ")
-
-        # Handle the last one without writing comma
-        last_element = t.nodes[-1]
-        self._dispatch(last_element)
-
-    def _AugAssign(self, t):
-        """ +=,-=,*=,/=,**=, etc. operations
-        """
-        
-        self._fill()
-        self._dispatch(t.node)
-        self._write(' '+t.op+' ')
-        self._dispatch(t.expr)
-        if not self._do_indent:
-            self._write(';')
-            
-    def _Bitand(self, t):
-        """ Bit and operation.
-        """
-        
-        for i, node in enumerate(t.nodes):
-            self._write("(")
-            self._dispatch(node)
-            self._write(")")
-            if i != len(t.nodes)-1:
-                self._write(" & ")
-                
-    def _Bitor(self, t):
-        """ Bit or operation
-        """
-        
-        for i, node in enumerate(t.nodes):
-            self._write("(")
-            self._dispatch(node)
-            self._write(")")
-            if i != len(t.nodes)-1:
-                self._write(" | ")
-                
-    def _CallFunc(self, t):
-        """ Function call.
-        """
-        self._dispatch(t.node)
-        self._write("(")
-        comma = False
-        for e in t.args:
-            if comma: self._write(", ")
-            else: comma = True
-            self._dispatch(e)
-        if t.star_args:
-            if comma: self._write(", ")
-            else: comma = True
-            self._write("*")
-            self._dispatch(t.star_args)
-        if t.dstar_args:
-            if comma: self._write(", ")
-            else: comma = True
-            self._write("**")
-            self._dispatch(t.dstar_args)
-        self._write(")")
-
-    def _Compare(self, t):
-        self._dispatch(t.expr)
-        for op, expr in t.ops:
-            self._write(" " + op + " ")
-            self._dispatch(expr)
-
-    def _Const(self, t):
-        """ A constant value such as an integer value, 3, or a string, "hello".
-        """
-        self._dispatch(t.value)
-
-    def _Decorators(self, t):
-        """ Handle function decorators (eg. @has_units)
-        """
-        for node in t.nodes:
-            self._dispatch(node)
-
-    def _Dict(self, t):
-        self._write("{")
-        for  i, (k, v) in enumerate(t.items):
-            self._dispatch(k)
-            self._write(": ")
-            self._dispatch(v)
-            if i < len(t.items)-1:
-                self._write(", ")
-        self._write("}")
-
-    def _Discard(self, t):
-        """ Node for when return value is ignored such as in "foo(a)".
-        """
-        self._fill()
-        self._dispatch(t.expr)
-
-    def _Div(self, t):
-        self.__binary_op(t, '/')
-
-    def _Ellipsis(self, t):
-        self._write("...")
-
-    def _From(self, t):
-        """ Handle "from xyz import foo, bar as baz".
-        """
-        # fixme: Are From and ImportFrom handled differently?
-        self._fill("from ")
-        self._write(t.modname)
-        self._write(" import ")
-        for i, (name,asname) in enumerate(t.names):
-            if i != 0:
-                self._write(", ")
-            self._write(name)
-            if asname is not None:
-                self._write(" as "+asname)
-                
-    def _Function(self, t):
-        """ Handle function definitions
-        """
-        if t.decorators is not None:
-            self._fill("@")
-            self._dispatch(t.decorators)
-        self._fill("def "+t.name + "(")
-        defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults)
-        for i, arg in enumerate(zip(t.argnames, defaults)):
-            self._write(arg[0])
-            if arg[1] is not None:
-                self._write('=')
-                self._dispatch(arg[1])
-            if i < len(t.argnames)-1:
-                self._write(', ')
-        self._write(")")
-        if self._single_func:
-            self._do_indent = False
-        self._enter()
-        self._dispatch(t.code)
-        self._leave()
-        self._do_indent = True
-
-    def _Getattr(self, t):
-        """ Handle getting an attribute of an object
-        """
-        if isinstance(t.expr, (Div, Mul, Sub, Add)):
-            self._write('(')
-            self._dispatch(t.expr)
-            self._write(')')
-        else:
-            self._dispatch(t.expr)
-            
-        self._write('.'+t.attrname)
-        
-    def _If(self, t):
-        self._fill()
-        
-        for i, (compare,code) in enumerate(t.tests):
-            if i == 0:
-                self._write("if ")
-            else:
-                self._write("elif ")
-            self._dispatch(compare)
-            self._enter()
-            self._fill()
-            self._dispatch(code)
-            self._leave()
-            self._write("\n")
-
-        if t.else_ is not None:
-            self._write("else")
-            self._enter()
-            self._fill()
-            self._dispatch(t.else_)
-            self._leave()
-            self._write("\n")
-            
-    def _IfExp(self, t):
-        self._dispatch(t.then)
-        self._write(" if ")
-        self._dispatch(t.test)
-
-        if t.else_ is not None:
-            self._write(" else (")
-            self._dispatch(t.else_)
-            self._write(")")
-
-    def _Import(self, t):
-        """ Handle "import xyz.foo".
-        """
-        self._fill("import ")
-        
-        for i, (name,asname) in enumerate(t.names):
-            if i != 0:
-                self._write(", ")
-            self._write(name)
-            if asname is not None:
-                self._write(" as "+asname)
-
-    def _Keyword(self, t):
-        """ Keyword value assignment within function calls and definitions.
-        """
-        self._write(t.name)
-        self._write("=")
-        self._dispatch(t.expr)
-        
-    def _List(self, t):
-        self._write("[")
-        for  i,node in enumerate(t.nodes):
-            self._dispatch(node)
-            if i < len(t.nodes)-1:
-                self._write(", ")
-        self._write("]")
-
-    def _Module(self, t):
-        if t.doc is not None:
-            self._dispatch(t.doc)
-        self._dispatch(t.node)
-
-    def _Mul(self, t):
-        self.__binary_op(t, '*')
-
-    def _Name(self, t):
-        self._write(t.name)
-
-    def _NoneType(self, t):
-        self._write("None")
-        
-    def _Not(self, t):
-        self._write('not (')
-        self._dispatch(t.expr)
-        self._write(')')
-        
-    def _Or(self, t):
-        self._write(" (")
-        for i, node in enumerate(t.nodes):
-            self._dispatch(node)
-            if i != len(t.nodes)-1:
-                self._write(") or (")
-        self._write(")")
-                
-    def _Pass(self, t):
-        self._write("pass\n")
-
-    def _Printnl(self, t):
-        self._fill("print ")
-        if t.dest:
-            self._write(">> ")
-            self._dispatch(t.dest)
-            self._write(", ")
-        comma = False
-        for node in t.nodes:
-            if comma: self._write(', ')
-            else: comma = True
-            self._dispatch(node)
-
-    def _Power(self, t):
-        self.__binary_op(t, '**')
-
-    def _Return(self, t):
-        self._fill("return ")
-        if t.value:
-            if isinstance(t.value, Tuple):
-                text = ', '.join([ name.name for name in t.value.asList() ])
-                self._write(text)
-            else:
-                self._dispatch(t.value)
-            if not self._do_indent:
-                self._write('; ')
-
-    def _Slice(self, t):
-        self._dispatch(t.expr)
-        self._write("[")
-        if t.lower:
-            self._dispatch(t.lower)
-        self._write(":")
-        if t.upper:
-            self._dispatch(t.upper)
-        #if t.step:
-        #    self._write(":")
-        #    self._dispatch(t.step)
-        self._write("]")
-
-    def _Sliceobj(self, t):
-        for i, node in enumerate(t.nodes):
-            if i != 0:
-                self._write(":")
-            if not (isinstance(node, Const) and node.value is None):
-                self._dispatch(node)
-
-    def _Stmt(self, tree):
-        for node in tree.nodes:
-            self._dispatch(node)
-
-    def _Sub(self, t):
-        self.__binary_op(t, '-')
-
-    def _Subscript(self, t):
-        self._dispatch(t.expr)
-        self._write("[")
-        for i, value in enumerate(t.subs):
-            if i != 0:
-                self._write(",")
-            self._dispatch(value)
-        self._write("]")
-
-    def _TryExcept(self, t):
-        self._fill("try")
-        self._enter()
-        self._dispatch(t.body)
-        self._leave()
-
-        for handler in t.handlers:
-            self._fill('except ')
-            self._dispatch(handler[0])
-            if handler[1] is not None:
-                self._write(', ')
-                self._dispatch(handler[1])
-            self._enter()
-            self._dispatch(handler[2])
-            self._leave()
-            
-        if t.else_:
-            self._fill("else")
-            self._enter()
-            self._dispatch(t.else_)
-            self._leave()
-
-    def _Tuple(self, t):
-
-        if not t.nodes:
-            # Empty tuple.
-            self._write("()")
-        else:
-            self._write("(")
-
-            # _write each elements, separated by a comma.
-            for element in t.nodes[:-1]:
-                self._dispatch(element)
-                self._write(", ")
-
-            # Handle the last one without writing comma
-            last_element = t.nodes[-1]
-            self._dispatch(last_element)
-
-            self._write(")")
-            
-    def _UnaryAdd(self, t):
-        self._write("+")
-        self._dispatch(t.expr)
-        
-    def _UnarySub(self, t):
-        self._write("-")
-        self._dispatch(t.expr)        
-
-    def _With(self, t):
-        self._fill('with ')
-        self._dispatch(t.expr)
-        if t.vars:
-            self._write(' as ')
-            self._dispatch(t.vars.name)
-        self._enter()
-        self._dispatch(t.body)
-        self._leave()
-        self._write('\n')
-        
-    def _int(self, t):
-        self._write(repr(t))
-
-    def __binary_op(self, t, symbol):
-        # Check if parenthesis are needed on left side and then dispatch
-        has_paren = False
-        left_class = str(t.left.__class__)
-        if (left_class in op_precedence.keys() and
-            op_precedence[left_class] < op_precedence[str(t.__class__)]):
-            has_paren = True
-        if has_paren:
-            self._write('(')
-        self._dispatch(t.left)
-        if has_paren:
-            self._write(')')
-        # Write the appropriate symbol for operator
-        self._write(symbol)
-        # Check if parenthesis are needed on the right side and then dispatch
-        has_paren = False
-        right_class = str(t.right.__class__)
-        if (right_class in op_precedence.keys() and
-            op_precedence[right_class] < op_precedence[str(t.__class__)]):
-            has_paren = True
-        if has_paren:
-            self._write('(')
-        self._dispatch(t.right)
-        if has_paren:
-            self._write(')')
-
-    def _float(self, t):
-        # if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001'
-        # We prefer str here.
-        self._write(str(t))
-
-    def _str(self, t):
-        self._write(repr(t))
-        
-    def _tuple(self, t):
-        self._write(str(t))
-
-    #########################################################################
-    # These are the methods from the _ast modules unparse.
-    #
-    # As our needs to handle more advanced code increase, we may want to
-    # modify some of the methods below so that they work for compiler.ast.
-    #########################################################################
-
-#    # stmt
-#    def _Expr(self, tree):
-#        self._fill()
-#        self._dispatch(tree.value)
-#
-#    def _Import(self, t):
-#        self._fill("import ")
-#        first = True
-#        for a in t.names:
-#            if first:
-#                first = False
-#            else:
-#                self._write(", ")
-#            self._write(a.name)
-#            if a.asname:
-#                self._write(" as "+a.asname)
-#
-##    def _ImportFrom(self, t):
-##        self._fill("from ")
-##        self._write(t.module)
-##        self._write(" import ")
-##        for i, a in enumerate(t.names):
-##            if i == 0:
-##                self._write(", ")
-##            self._write(a.name)
-##            if a.asname:
-##                self._write(" as "+a.asname)
-##        # XXX(jpe) what is level for?
-##
-#
-#    def _Break(self, t):
-#        self._fill("break")
-#
-#    def _Continue(self, t):
-#        self._fill("continue")
-#
-#    def _Delete(self, t):
-#        self._fill("del ")
-#        self._dispatch(t.targets)
-#
-#    def _Assert(self, t):
-#        self._fill("assert ")
-#        self._dispatch(t.test)
-#        if t.msg:
-#            self._write(", ")
-#            self._dispatch(t.msg)
-#
-#    def _Exec(self, t):
-#        self._fill("exec ")
-#        self._dispatch(t.body)
-#        if t.globals:
-#            self._write(" in ")
-#            self._dispatch(t.globals)
-#        if t.locals:
-#            self._write(", ")
-#            self._dispatch(t.locals)
-#
-#    def _Print(self, t):
-#        self._fill("print ")
-#        do_comma = False
-#        if t.dest:
-#            self._write(">>")
-#            self._dispatch(t.dest)
-#            do_comma = True
-#        for e in t.values:
-#            if do_comma:self._write(", ")
-#            else:do_comma=True
-#            self._dispatch(e)
-#        if not t.nl:
-#            self._write(",")
-#
-#    def _Global(self, t):
-#        self._fill("global")
-#        for i, n in enumerate(t.names):
-#            if i != 0:
-#                self._write(",")
-#            self._write(" " + n)
-#
-#    def _Yield(self, t):
-#        self._fill("yield")
-#        if t.value:
-#            self._write(" (")
-#            self._dispatch(t.value)
-#            self._write(")")
-#
-#    def _Raise(self, t):
-#        self._fill('raise ')
-#        if t.type:
-#            self._dispatch(t.type)
-#        if t.inst:
-#            self._write(", ")
-#            self._dispatch(t.inst)
-#        if t.tback:
-#            self._write(", ")
-#            self._dispatch(t.tback)
-#
-#
-#    def _TryFinally(self, t):
-#        self._fill("try")
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#
-#        self._fill("finally")
-#        self._enter()
-#        self._dispatch(t.finalbody)
-#        self._leave()
-#
-#    def _excepthandler(self, t):
-#        self._fill("except ")
-#        if t.type:
-#            self._dispatch(t.type)
-#        if t.name:
-#            self._write(", ")
-#            self._dispatch(t.name)
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#
-#    def _ClassDef(self, t):
-#        self._write("\n")
-#        self._fill("class "+t.name)
-#        if t.bases:
-#            self._write("(")
-#            for a in t.bases:
-#                self._dispatch(a)
-#                self._write(", ")
-#            self._write(")")
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#
-#    def _FunctionDef(self, t):
-#        self._write("\n")
-#        for deco in t.decorators:
-#            self._fill("@")
-#            self._dispatch(deco)
-#        self._fill("def "+t.name + "(")
-#        self._dispatch(t.args)
-#        self._write(")")
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#
-#    def _For(self, t):
-#        self._fill("for ")
-#        self._dispatch(t.target)
-#        self._write(" in ")
-#        self._dispatch(t.iter)
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#        if t.orelse:
-#            self._fill("else")
-#            self._enter()
-#            self._dispatch(t.orelse)
-#            self._leave
-#
-#    def _While(self, t):
-#        self._fill("while ")
-#        self._dispatch(t.test)
-#        self._enter()
-#        self._dispatch(t.body)
-#        self._leave()
-#        if t.orelse:
-#            self._fill("else")
-#            self._enter()
-#            self._dispatch(t.orelse)
-#            self._leave
-#
-#    # expr
-#    def _Str(self, tree):
-#        self._write(repr(tree.s))
-##
-#    def _Repr(self, t):
-#        self._write("`")
-#        self._dispatch(t.value)
-#        self._write("`")
-#
-#    def _Num(self, t):
-#        self._write(repr(t.n))
-#
-#    def _ListComp(self, t):
-#        self._write("[")
-#        self._dispatch(t.elt)
-#        for gen in t.generators:
-#            self._dispatch(gen)
-#        self._write("]")
-#
-#    def _GeneratorExp(self, t):
-#        self._write("(")
-#        self._dispatch(t.elt)
-#        for gen in t.generators:
-#            self._dispatch(gen)
-#        self._write(")")
-#
-#    def _comprehension(self, t):
-#        self._write(" for ")
-#        self._dispatch(t.target)
-#        self._write(" in ")
-#        self._dispatch(t.iter)
-#        for if_clause in t.ifs:
-#            self._write(" if ")
-#            self._dispatch(if_clause)
-#
-#    def _IfExp(self, t):
-#        self._dispatch(t.body)
-#        self._write(" if ")
-#        self._dispatch(t.test)
-#        if t.orelse:
-#            self._write(" else ")
-#            self._dispatch(t.orelse)
-#
-#    unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
-#    def _UnaryOp(self, t):
-#        self._write(self.unop[t.op.__class__.__name__])
-#        self._write("(")
-#        self._dispatch(t.operand)
-#        self._write(")")
-#
-#    binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
-#                    "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
-#                    "FloorDiv":"//", "Pow": "**"}
-#    def _BinOp(self, t):
-#        self._write("(")
-#        self._dispatch(t.left)
-#        self._write(")" + self.binop[t.op.__class__.__name__] + "(")
-#        self._dispatch(t.right)
-#        self._write(")")
-#
-#    boolops = {_ast.And: 'and', _ast.Or: 'or'}
-#    def _BoolOp(self, t):
-#        self._write("(")
-#        self._dispatch(t.values[0])
-#        for v in t.values[1:]:
-#            self._write(" %s " % self.boolops[t.op.__class__])
-#            self._dispatch(v)
-#        self._write(")")
-#
-#    def _Attribute(self,t):
-#        self._dispatch(t.value)
-#        self._write(".")
-#        self._write(t.attr)
-#
-##    def _Call(self, t):
-##        self._dispatch(t.func)
-##        self._write("(")
-##        comma = False
-##        for e in t.args:
-##            if comma: self._write(", ")
-##            else: comma = True
-##            self._dispatch(e)
-##        for e in t.keywords:
-##            if comma: self._write(", ")
-##            else: comma = True
-##            self._dispatch(e)
-##        if t.starargs:
-##            if comma: self._write(", ")
-##            else: comma = True
-##            self._write("*")
-##            self._dispatch(t.starargs)
-##        if t.kwargs:
-##            if comma: self._write(", ")
-##            else: comma = True
-##            self._write("**")
-##            self._dispatch(t.kwargs)
-##        self._write(")")
-#
-#    # slice
-#    def _Index(self, t):
-#        self._dispatch(t.value)
-#
-#    def _ExtSlice(self, t):
-#        for i, d in enumerate(t.dims):
-#            if i != 0:
-#                self._write(': ')
-#            self._dispatch(d)
-#
-#    # others
-#    def _arguments(self, t):
-#        first = True
-#        nonDef = len(t.args)-len(t.defaults)
-#        for a in t.args[0:nonDef]:
-#            if first:first = False
-#            else: self._write(", ")
-#            self._dispatch(a)
-#        for a,d in zip(t.args[nonDef:], t.defaults):
-#            if first:first = False
-#            else: self._write(", ")
-#            self._dispatch(a),
-#            self._write("=")
-#            self._dispatch(d)
-#        if t.vararg:
-#            if first:first = False
-#            else: self._write(", ")
-#            self._write("*"+t.vararg)
-#        if t.kwarg:
-#            if first:first = False
-#            else: self._write(", ")
-#            self._write("**"+t.kwarg)
-#
-##    def _keyword(self, t):
-##        self._write(t.arg)
-##        self._write("=")
-##        self._dispatch(t.value)
-#
-#    def _Lambda(self, t):
-#        self._write("lambda ")
-#        self._dispatch(t.args)
-#        self._write(": ")
-#        self._dispatch(t.body)
-
-
-
diff --git a/astropy/sphinx/ext/docscrape.py b/astropy/sphinx/ext/docscrape.py
deleted file mode 100644
index 1bdc61c..0000000
--- a/astropy/sphinx/ext/docscrape.py
+++ /dev/null
@@ -1,512 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""Extract reference documentation from the NumPy source tree.
-
-"""
-
-import inspect
-import textwrap
-import re
-import pydoc
-from StringIO import StringIO
-
-class Reader(object):
-    """A line-based string reader.
-
-    """
-    def __init__(self, data):
-        """
-        Parameters
-        ----------
-        data : str
-           String with lines separated by '\n'.
-
-        """
-        if isinstance(data,list):
-            self._str = data
-        else:
-            self._str = data.split('\n') # store string as list of lines
-
-        self.reset()
-
-    def __getitem__(self, n):
-        return self._str[n]
-
-    def reset(self):
-        self._l = 0 # current line nr
-
-    def read(self):
-        if not self.eof():
-            out = self[self._l]
-            self._l += 1
-            return out
-        else:
-            return ''
-
-    def seek_next_non_empty_line(self):
-        for l in self[self._l:]:
-            if l.strip():
-                break
-            else:
-                self._l += 1
-
-    def eof(self):
-        return self._l >= len(self._str)
-
-    def read_to_condition(self, condition_func):
-        start = self._l
-        for line in self[start:]:
-            if condition_func(line):
-                return self[start:self._l]
-            self._l += 1
-            if self.eof():
-                return self[start:self._l+1]
-        return []
-
-    def read_to_next_empty_line(self):
-        self.seek_next_non_empty_line()
-        def is_empty(line):
-            return not line.strip()
-        return self.read_to_condition(is_empty)
-
-    def read_to_next_unindented_line(self):
-        def is_unindented(line):
-            return (line.strip() and (len(line.lstrip()) == len(line)))
-        return self.read_to_condition(is_unindented)
-
-    def peek(self,n=0):
-        if self._l + n < len(self._str):
-            return self[self._l + n]
-        else:
-            return ''
-
-    def is_empty(self):
-        return not ''.join(self._str).strip()
-
-
-class NumpyDocString(object):
-    def __init__(self, docstring, config={}, warn=None):
-        from warnings import warn as stdlib_warn
-
-        self.warn = stdlib_warn if warn is None else warn
-
-        docstring = textwrap.dedent(docstring).split('\n')
-        self._doc = Reader(docstring)
-        self._parsed_data = {
-            'Signature': '',
-            'Summary': [''],
-            'Extended Summary': [],
-            'Parameters': [],
-            'Returns': [],
-            'Raises': [],
-            'Warns': [],
-            'Other Parameters': [],
-            'Attributes': [],
-            'Methods': [],
-            'See Also': [],
-            'Notes': [],
-            'Warnings': [],
-            'References': '',
-            'Examples': '',
-            'index': {}
-            }
-
-        self._parse()
-
-
-    def __getitem__(self,key):
-        return self._parsed_data[key]
-
-    def __setitem__(self,key,val):
-        if not self._parsed_data.has_key(key):
-            self.warn("Unknown section %s" % key)
-        else:
-            self._parsed_data[key] = val
-
-    def _is_at_section(self):
-        self._doc.seek_next_non_empty_line()
-
-        if self._doc.eof():
-            return False
-
-        l1 = self._doc.peek().strip()  # e.g. Parameters
-
-        if l1.startswith('.. index::'):
-            return True
-
-        l2 = self._doc.peek(1).strip() #    ---------- or ==========
-        return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1))
-
-    def _strip(self,doc):
-        i = 0
-        j = 0
-        for i,line in enumerate(doc):
-            if line.strip(): break
-
-        for j,line in enumerate(doc[::-1]):
-            if line.strip(): break
-
-        return doc[i:len(doc)-j]
-
-    def _read_to_next_section(self):
-        section = self._doc.read_to_next_empty_line()
-
-        while not self._is_at_section() and not self._doc.eof():
-            if not self._doc.peek(-1).strip(): # previous line was empty
-                section += ['']
-
-            section += self._doc.read_to_next_empty_line()
-
-        return section
-
-    def _read_sections(self):
-        while not self._doc.eof():
-            data = self._read_to_next_section()
-            name = data[0].strip()
-
-            if name.startswith('..'): # index section
-                yield name, data[1:]
-            elif len(data) < 2:
-                yield StopIteration
-            else:
-                yield name, self._strip(data[2:])
-
-    def _parse_param_list(self,content):
-        r = Reader(content)
-        params = []
-        while not r.eof():
-            header = r.read().strip()
-            if ' : ' in header:
-                arg_name, arg_type = header.split(' : ')[:2]
-            else:
-                arg_name, arg_type = header, ''
-
-            desc = r.read_to_next_unindented_line()
-            desc = dedent_lines(desc)
-
-            params.append((arg_name,arg_type,desc))
-
-        return params
-
-
-    _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
-                           r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
-    def _parse_see_also(self, content):
-        """
-        func_name : Descriptive text
-            continued text
-        another_func_name : Descriptive text
-        func_name1, func_name2, :meth:`func_name`, func_name3
-
-        """
-        items = []
-
-        def parse_item_name(text):
-            """Match ':role:`name`' or 'name'"""
-            m = self._name_rgx.match(text)
-            if m:
-                g = m.groups()
-                if g[1] is None:
-                    return g[3], None
-                else:
-                    return g[2], g[1]
-            raise ValueError("%s is not a item name" % text)
-
-        def push_item(name, rest):
-            if not name:
-                return
-            name, role = parse_item_name(name)
-            items.append((name, list(rest), role))
-            del rest[:]
-
-        current_func = None
-        rest = []
-
-        for line in content:
-            if not line.strip(): continue
-
-            m = self._name_rgx.match(line)
-            if m and line[m.end():].strip().startswith(':'):
-                push_item(current_func, rest)
-                current_func, line = line[:m.end()], line[m.end():]
-                rest = [line.split(':', 1)[1].strip()]
-                if not rest[0]:
-                    rest = []
-            elif not line.startswith(' '):
-                push_item(current_func, rest)
-                current_func = None
-                if ',' in line:
-                    for func in line.split(','):
-                        if func.strip():
-                            push_item(func, [])
-                elif line.strip():
-                    current_func = line
-            elif current_func is not None:
-                rest.append(line.strip())
-        push_item(current_func, rest)
-        return items
-
-    def _parse_index(self, section, content):
-        """
-        .. index: default
-           :refguide: something, else, and more
-
-        """
-        def strip_each_in(lst):
-            return [s.strip() for s in lst]
-
-        out = {}
-        section = section.split('::')
-        if len(section) > 1:
-            out['default'] = strip_each_in(section[1].split(','))[0]
-        for line in content:
-            line = line.split(':')
-            if len(line) > 2:
-                out[line[1]] = strip_each_in(line[2].split(','))
-        return out
-
-    def _parse_summary(self):
-        """Grab signature (if given) and summary"""
-        if self._is_at_section():
-            return
-
-        summary = self._doc.read_to_next_empty_line()
-        summary_str = " ".join([s.strip() for s in summary]).strip()
-        if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
-            self['Signature'] = summary_str
-            if not self._is_at_section():
-                self['Summary'] = self._doc.read_to_next_empty_line()
-        else:
-            self['Summary'] = summary
-
-        if not self._is_at_section():
-            self['Extended Summary'] = self._read_to_next_section()
-
-    def _parse(self):
-        self._doc.reset()
-        self._parse_summary()
-
-        for (section,content) in self._read_sections():
-            if not section.startswith('..'):
-                section = ' '.join([s.capitalize() for s in section.split(' ')])
-            if section in ('Parameters', 'Returns', 'Raises', 'Warns',
-                           'Other Parameters', 'Attributes', 'Methods'):
-                self[section] = self._parse_param_list(content)
-            elif section.startswith('.. index::'):
-                self['index'] = self._parse_index(section, content)
-            elif section == 'See Also':
-                self['See Also'] = self._parse_see_also(content)
-            else:
-                self[section] = content
-
-    # string conversion routines
-
-    def _str_header(self, name, symbol='-'):
-        return [name, len(name)*symbol]
-
-    def _str_indent(self, doc, indent=4):
-        out = []
-        for line in doc:
-            out += [' '*indent + line]
-        return out
-
-    def _str_signature(self):
-        if self['Signature']:
-            return [self['Signature'].replace('*','\*')] + ['']
-        else:
-            return ['']
-
-    def _str_summary(self):
-        if self['Summary']:
-            return self['Summary'] + ['']
-        else:
-            return []
-
-    def _str_extended_summary(self):
-        if self['Extended Summary']:
-            return self['Extended Summary'] + ['']
-        else:
-            return []
-
-    def _str_param_list(self, name):
-        out = []
-        if self[name]:
-            out += self._str_header(name)
-            for param,param_type,desc in self[name]:
-                out += ['%s : %s' % (param, param_type)]
-                out += self._str_indent(desc)
-            out += ['']
-        return out
-
-    def _str_section(self, name):
-        out = []
-        if self[name]:
-            out += self._str_header(name)
-            out += self[name]
-            out += ['']
-        return out
-
-    def _str_see_also(self, func_role):
-        if not self['See Also']: return []
-        out = []
-        out += self._str_header("See Also")
-        last_had_desc = True
-        for func, desc, role in self['See Also']:
-            if role:
-                link = ':%s:`%s`' % (role, func)
-            elif func_role:
-                link = ':%s:`%s`' % (func_role, func)
-            else:
-                link = "`%s`_" % func
-            if desc or last_had_desc:
-                out += ['']
-                out += [link]
-            else:
-                out[-1] += ", %s" % link
-            if desc:
-                out += self._str_indent([' '.join(desc)])
-                last_had_desc = True
-            else:
-                last_had_desc = False
-        out += ['']
-        return out
-
-    def _str_index(self):
-        idx = self['index']
-        out = []
-        out += ['.. index:: %s' % idx.get('default','')]
-        for section, references in idx.iteritems():
-            if section == 'default':
-                continue
-            out += ['   :%s: %s' % (section, ', '.join(references))]
-        return out
-
-    def __str__(self, func_role=''):
-        out = []
-        out += self._str_signature()
-        out += self._str_summary()
-        out += self._str_extended_summary()
-        for param_list in ('Parameters', 'Returns', 'Other Parameters',
-                           'Raises', 'Warns'):
-            out += self._str_param_list(param_list)
-        out += self._str_section('Warnings')
-        out += self._str_see_also(func_role)
-        for s in ('Notes','References','Examples'):
-            out += self._str_section(s)
-        for param_list in ('Attributes', 'Methods'):
-            out += self._str_param_list(param_list)
-        out += self._str_index()
-        return '\n'.join(out)
-
-
-def indent(str,indent=4):
-    indent_str = ' '*indent
-    if str is None:
-        return indent_str
-    lines = str.split('\n')
-    return '\n'.join(indent_str + l for l in lines)
-
-def dedent_lines(lines):
-    """Deindent a list of lines maximally"""
-    return textwrap.dedent("\n".join(lines)).split("\n")
-
-def header(text, style='-'):
-    return text + '\n' + style*len(text) + '\n'
-
-
-class FunctionDoc(NumpyDocString):
-    def __init__(self, func, role='func', doc=None, config={}):
-        self._f = func
-        self._role = role # e.g. "func" or "meth"
-
-        if doc is None:
-            if func is None:
-                raise ValueError("No function or docstring given")
-            doc = inspect.getdoc(func) or ''
-        NumpyDocString.__init__(self, doc)
-
-        if not self['Signature'] and func is not None:
-            func, func_name = self.get_func()
-            try:
-                # try to read signature
-                argspec = inspect.getargspec(func)
-                argspec = inspect.formatargspec(*argspec)
-                argspec = argspec.replace('*','\*')
-                signature = '%s%s' % (func_name, argspec)
-            except TypeError, e:
-                signature = '%s()' % func_name
-            self['Signature'] = signature
-
-    def get_func(self):
-        func_name = getattr(self._f, '__name__', self.__class__.__name__)
-        if inspect.isclass(self._f):
-            func = getattr(self._f, '__call__', self._f.__init__)
-        else:
-            func = self._f
-        return func, func_name
-
-    def __str__(self):
-        out = ''
-
-        func, func_name = self.get_func()
-        signature = self['Signature'].replace('*', '\*')
-
-        roles = {'func': 'function',
-                 'meth': 'method'}
-
-        if self._role:
-            if not roles.has_key(self._role):
-                self.warn("Warning: invalid role %s" % self._role)
-            out += '.. %s:: %s\n    \n\n' % (roles.get(self._role,''),
-                                             func_name)
-
-        out += super(FunctionDoc, self).__str__(func_role=self._role)
-        return out
-
-
-class ClassDoc(NumpyDocString):
-
-    extra_public_methods = ['__call__']
-
-    def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc,
-                 config={}):
-        if not inspect.isclass(cls) and cls is not None:
-            raise ValueError("Expected a class or None, but got %r" % cls)
-        self._cls = cls
-
-        if modulename and not modulename.endswith('.'):
-            modulename += '.'
-        self._mod = modulename
-
-        if doc is None:
-            if cls is None:
-                raise ValueError("No class or documentation string given")
-            doc = pydoc.getdoc(cls)
-
-        NumpyDocString.__init__(self, doc)
-
-        if config.get('show_class_members', True):
-            if not self['Methods']:
-                self['Methods'] = [(name, '', '')
-                                   for name in sorted(self.methods)]
-            if not self['Attributes']:
-                self['Attributes'] = [(name, '', '')
-                                      for name in sorted(self.properties)]
-
-    @property
-    def methods(self):
-        if self._cls is None:
-            return []
-        return [name for name,func in inspect.getmembers(self._cls)
-                if ((not name.startswith('_')
-                     or name in self.extra_public_methods)
-                    and callable(func))]
-
-    @property
-    def properties(self):
-        if self._cls is None:
-            return []
-        return [name for name,func in inspect.getmembers(self._cls)
-                if not name.startswith('_') and func is None]
diff --git a/astropy/sphinx/ext/docscrape_sphinx.py b/astropy/sphinx/ext/docscrape_sphinx.py
deleted file mode 100644
index a69919c..0000000
--- a/astropy/sphinx/ext/docscrape_sphinx.py
+++ /dev/null
@@ -1,231 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-import re, inspect, textwrap, pydoc
-import sphinx
-from docscrape import NumpyDocString, FunctionDoc, ClassDoc
-
-class SphinxDocString(NumpyDocString):
-    def __init__(self, docstring, config={}, warn=None):
-        self.use_plots = config.get('use_plots', False)
-        NumpyDocString.__init__(self, docstring, config=config, warn=warn)
-
-    # string conversion routines
-    def _str_header(self, name, symbol='`'):
-        return ['.. rubric:: ' + name, '']
-
-    def _str_field_list(self, name):
-        return [':' + name + ':']
-
-    def _str_indent(self, doc, indent=4):
-        out = []
-        for line in doc:
-            out += [' '*indent + line]
-        return out
-
-    def _str_signature(self):
-        return ['']
-        if self['Signature']:
-            return ['``%s``' % self['Signature']] + ['']
-        else:
-            return ['']
-
-    def _str_summary(self):
-        return self['Summary'] + ['']
-
-    def _str_extended_summary(self):
-        return self['Extended Summary'] + ['']
-
-    def _str_param_list(self, name):
-        out = []
-        if self[name]:
-            out += self._str_field_list(name)
-            out += ['']
-            for param,param_type,desc in self[name]:
-                out += self._str_indent(['**%s** : %s' % (param.strip(),
-                                                          param_type)])
-                out += ['']
-                out += self._str_indent(desc,8)
-                out += ['']
-        return out
-
-    @property
-    def _obj(self):
-        if hasattr(self, '_cls'):
-            return self._cls
-        elif hasattr(self, '_f'):
-            return self._f
-        return None
-
-    def _str_member_list(self, name):
-        """
-        Generate a member listing, autosummary:: table where possible,
-        and a table where not.
-
-        """
-        out = []
-        if self[name]:
-            out += ['.. rubric:: %s' % name, '']
-            prefix = getattr(self, '_name', '')
-
-            if prefix:
-                prefix = '~%s.' % prefix
-
-            autosum = []
-            others = []
-            for param, param_type, desc in self[name]:
-                param = param.strip()
-                if not self._obj or hasattr(self._obj, param):
-                    autosum += ["   %s%s" % (prefix, param)]
-                else:
-                    others.append((param, param_type, desc))
-
-            if autosum:
-                out += ['.. autosummary::', '   :toctree:', '']
-                out += autosum
-
-            if others:
-                maxlen_0 = max([len(x[0]) for x in others])
-                maxlen_1 = max([len(x[1]) for x in others])
-                hdr = "="*maxlen_0 + "  " + "="*maxlen_1 + "  " + "="*10
-                fmt = '%%%ds  %%%ds  ' % (maxlen_0, maxlen_1)
-                n_indent = maxlen_0 + maxlen_1 + 4
-                out += [hdr]
-                for param, param_type, desc in others:
-                    out += [fmt % (param.strip(), param_type)]
-                    out += self._str_indent(desc, n_indent)
-                out += [hdr]
-            out += ['']
-        return out
-
-    def _str_section(self, name):
-        out = []
-        if self[name]:
-            out += self._str_header(name)
-            out += ['']
-            content = textwrap.dedent("\n".join(self[name])).split("\n")
-            out += content
-            out += ['']
-        return out
-
-    def _str_see_also(self, func_role):
-        out = []
-        if self['See Also']:
-            see_also = super(SphinxDocString, self)._str_see_also(func_role)
-            out = ['.. seealso::', '']
-            out += self._str_indent(see_also[2:])
-        return out
-
-    def _str_warnings(self):
-        out = []
-        if self['Warnings']:
-            out = ['.. warning::', '']
-            out += self._str_indent(self['Warnings'])
-        return out
-
-    def _str_index(self):
-        idx = self['index']
-        out = []
-        if len(idx) == 0:
-            return out
-
-        out += ['.. index:: %s' % idx.get('default','')]
-        for section, references in idx.iteritems():
-            if section == 'default':
-                continue
-            elif section == 'refguide':
-                out += ['   single: %s' % (', '.join(references))]
-            else:
-                out += ['   %s: %s' % (section, ','.join(references))]
-        return out
-
-    def _str_references(self):
-        out = []
-        if self['References']:
-            out += self._str_header('References')
-            if isinstance(self['References'], str):
-                self['References'] = [self['References']]
-            out.extend(self['References'])
-            out += ['']
-            # Latex collects all references to a separate bibliography,
-            # so we need to insert links to it
-            if sphinx.__version__ >= "0.6":
-                out += ['.. only:: latex','']
-            else:
-                out += ['.. latexonly::','']
-            items = []
-            for line in self['References']:
-                m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I)
-                if m:
-                    items.append(m.group(1))
-            out += ['   ' + ", ".join(["[%s]_" % item for item in items]), '']
-        return out
-
-    def _str_examples(self):
-        examples_str = "\n".join(self['Examples'])
-
-        if (self.use_plots and 'import matplotlib' in examples_str
-                and 'plot::' not in examples_str):
-            out = []
-            out += self._str_header('Examples')
-            out += ['.. plot::', '']
-            out += self._str_indent(self['Examples'])
-            out += ['']
-            return out
-        else:
-            return self._str_section('Examples')
-
-    def __str__(self, indent=0, func_role="obj"):
-        out = []
-        out += self._str_signature()
-        out += self._str_index() + ['']
-        out += self._str_summary()
-        out += self._str_extended_summary()
-        for param_list in ('Parameters', 'Returns', 'Other Parameters',
-                           'Raises', 'Warns'):
-            out += self._str_param_list(param_list)
-        out += self._str_warnings()
-        out += self._str_see_also(func_role)
-        out += self._str_section('Notes')
-        out += self._str_references()
-        out += self._str_examples()
-        for param_list in ('Attributes', 'Methods'):
-            out += self._str_member_list(param_list)
-        out = self._str_indent(out,indent)
-        return '\n'.join(out)
-
-class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
-    def __init__(self, obj, doc=None, config={}):
-        self.use_plots = config.get('use_plots', False)
-        FunctionDoc.__init__(self, obj, doc=doc, config=config)
-
-class SphinxClassDoc(SphinxDocString, ClassDoc):
-    def __init__(self, obj, doc=None, func_doc=None, config={}):
-        self.use_plots = config.get('use_plots', False)
-        ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config)
-
-class SphinxObjDoc(SphinxDocString):
-    def __init__(self, obj, doc=None, config={}):
-        self._f = obj
-        SphinxDocString.__init__(self, doc, config=config)
-
-def get_doc_object(obj, what=None, doc=None, config={}):
-    if what is None:
-        if inspect.isclass(obj):
-            what = 'class'
-        elif inspect.ismodule(obj):
-            what = 'module'
-        elif callable(obj):
-            what = 'function'
-        else:
-            what = 'object'
-    if what == 'class':
-        return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc,
-                              config=config)
-    elif what in ('function', 'method'):
-        return SphinxFunctionDoc(obj, doc=doc, config=config)
-    else:
-        if doc is None:
-            doc = pydoc.getdoc(obj)
-        return SphinxObjDoc(obj, doc, config=config)
diff --git a/astropy/sphinx/ext/doctest.py b/astropy/sphinx/ext/doctest.py
deleted file mode 100644
index 0ddb4f2..0000000
--- a/astropy/sphinx/ext/doctest.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This is a set of three directives that allow us to insert metadata
-about doctests into the .rst files so the testing framework knows
-which tests to skip.
-
-This is quite different from the doctest extension in Sphinx itself,
-which actually does something.  For astropy, all of the testing is
-centrally managed from py.test and Sphinx is not used for running
-tests.
-"""
-from docutils.nodes import literal_block
-from sphinx.util.compat import Directive
-
-
-class DoctestSkipDirective(Directive):
-    has_content = True
-
-    def run(self):
-        code = '\n'.join(self.content)
-        return [literal_block(code, code)]
-
-
-class DoctestRequiresDirective(DoctestSkipDirective):
-    # This is silly, but we really support an unbounded number of
-    # optional arguments
-    optional_arguments = 64
-
-
-def setup(app):
-    app.add_directive('doctest-requires', DoctestRequiresDirective)
-    app.add_directive('doctest-skip', DoctestSkipDirective)
-    app.add_directive('doctest-skip-all', DoctestSkipDirective)
diff --git a/astropy/sphinx/ext/edit_on_github.py b/astropy/sphinx/ext/edit_on_github.py
deleted file mode 100644
index f2d97ae..0000000
--- a/astropy/sphinx/ext/edit_on_github.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-This extension makes it easy to edit documentation on github.
-
-It adds links associated with each docstring that go to the
-corresponding view source page on Github.  From there, the user can
-push the "Edit" button, edit the docstring, and submit a pull request.
-
-It has the following configuration options (to be set in the project's
-``conf.py``):
-
-* ``edit_on_github_project``
-    The name of the github project, in the form
-    "username/projectname".
-
-* ``edit_on_github_branch``
-    The name of the branch to edit.  If this is a released version,
-    this should be a git tag referring to that version.  For a
-    dev version, it often makes sense for it to be "master".  It
-    may also be a git hash.
-
-* ``edit_on_github_source_root``
-    The location within the source tree of the root of the
-    Python package.  Defaults to "lib".
-
-* ``edit_on_github_doc_root``
-    The location within the source tree of the root of the
-    documentation source.  Defaults to "doc", but it may make sense to
-    set it to "doc/source" if the project uses a separate source
-    directory.
-
-* ``edit_on_github_docstring_message``
-    The phrase displayed in the links to edit a docstring.  Defaults
-    to "[edit on github]".
-
-* ``edit_on_github_page_message``
-    The phrase displayed in the links to edit a RST page.  Defaults
-    to "[edit this page on github]".
-
-* ``edit_on_github_help_message``
-    The phrase displayed as a tooltip on the edit links.  Defaults to
-    "Push the Edit button on the next page"
-
-* ``edit_on_github_skip_regex``
-    When the path to the .rst file matches this regular expression,
-    no "edit this page on github" link will be added.  Defaults to
-    ``"_.*"``.
-"""
-import inspect
-import os
-import re
-import sys
-
-from docutils import nodes
-
-from sphinx import addnodes
-
-
-def import_object(modname, name):
-    """
-    Import the object given by *modname* and *name* and return it.
-    If not found, or the import fails, returns None.
-    """
-    try:
-        __import__(modname)
-        mod = sys.modules[modname]
-        obj = mod
-        for part in name.split('.'):
-            obj = getattr(obj, part)
-        return obj
-    except:
-        return None
-
-
-def get_url_base(app):
-    return  'http://github.com/%s/tree/%s/' % (
-        app.config.edit_on_github_project,
-        app.config.edit_on_github_branch)
-
-
-def doctree_read(app, doctree):
-    # Get the configuration parameters
-    if app.config.edit_on_github_project == 'REQUIRED':
-        raise ValueError(
-            "The edit_on_github_project configuration variable must be "
-            "provided in the conf.py")
-
-    source_root = app.config.edit_on_github_source_root
-    url = get_url_base(app)
-
-    docstring_message = app.config.edit_on_github_docstring_message
-
-    # Handle the docstring-editing links
-    for objnode in doctree.traverse(addnodes.desc):
-        if objnode.get('domain') != 'py':
-            continue
-        names = set()
-        for signode in objnode:
-            if not isinstance(signode, addnodes.desc_signature):
-                continue
-            modname = signode.get('module')
-            if not modname:
-                continue
-            fullname = signode.get('fullname')
-            if fullname in names:
-                # only one link per name, please
-                continue
-            names.add(fullname)
-            obj = import_object(modname, fullname)
-            anchor = None
-            if obj is not None:
-                try:
-                    lines, lineno = inspect.getsourcelines(obj)
-                except:
-                    pass
-                else:
-                    anchor = '#L%d' % lineno
-            if anchor:
-                real_modname = inspect.getmodule(obj).__name__
-                path = '%s%s%s.py%s' % (
-                    url, source_root, real_modname.replace('.', '/'), anchor)
-                onlynode = addnodes.only(expr='html')
-                onlynode += nodes.reference(
-                    reftitle=app.config.edit_on_github_help_message,
-                    refuri=path)
-                onlynode[0] += nodes.inline(
-                    '', '', nodes.raw('', ' ', format='html'),
-                    nodes.Text(docstring_message),
-                    classes=['edit-on-github', 'viewcode-link'])
-                signode += onlynode
-
-
-def html_page_context(app, pagename, templatename, context, doctree):
-    if (templatename == 'page.html' and
-        not re.match(app.config.edit_on_github_skip_regex, pagename)):
-
-        doc_root = app.config.edit_on_github_doc_root
-        if doc_root != '' and not doc_root.endswith('/'):
-            doc_root += '/'
-        doc_path = os.path.relpath(doctree.get('source'), app.builder.srcdir)
-        url = get_url_base(app)
-
-        page_message = app.config.edit_on_github_page_message
-
-        context['edit_on_github'] = url + doc_root + doc_path
-        context['edit_on_github_page_message'] = (
-            app.config.edit_on_github_page_message)
-
-
-def setup(app):
-    app.add_config_value('edit_on_github_project', 'REQUIRED', True)
-    app.add_config_value('edit_on_github_branch', 'master', True)
-    app.add_config_value('edit_on_github_source_root', 'lib', True)
-    app.add_config_value('edit_on_github_doc_root', 'doc', True)
-    app.add_config_value('edit_on_github_docstring_message',
-                         '[edit on github]', True)
-    app.add_config_value('edit_on_github_page_message',
-                         'Edit This Page on Github', True)
-    app.add_config_value('edit_on_github_help_message',
-                         'Push the Edit button on the next page', True)
-    app.add_config_value('edit_on_github_skip_regex',
-                         '_.*', True)
-
-    app.connect('doctree-read', doctree_read)
-    app.connect('html-page-context', html_page_context)
diff --git a/astropy/sphinx/ext/numpydoc.py b/astropy/sphinx/ext/numpydoc.py
deleted file mode 100644
index 6d20698..0000000
--- a/astropy/sphinx/ext/numpydoc.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""
-========
-numpydoc
-========
-
-Sphinx extension that handles docstrings in the Numpy standard format. [1]
-
-It will:
-
-- Convert Parameters etc. sections to field lists.
-- Convert See Also section to a See also entry.
-- Renumber references.
-- Extract the signature from the docstring, if it can't be determined otherwise.
-
-.. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
-
-"""
-
-import sphinx
-
-if sphinx.__version__ < '1.0.1':
-    raise RuntimeError("Sphinx 1.0.1 or newer is required")
-
-import os, re, pydoc
-from docscrape_sphinx import get_doc_object, SphinxDocString
-from sphinx.util.compat import Directive
-import inspect
-
-def mangle_docstrings(app, what, name, obj, options, lines,
-                      reference_offset=[0]):
-
-    cfg = dict(use_plots=app.config.numpydoc_use_plots,
-               show_class_members=app.config.numpydoc_show_class_members)
-
-    if what == 'module':
-        # Strip top title
-        title_re = re.compile(ur'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*',
-                              re.I|re.S)
-        lines[:] = title_re.sub(u'', u"\n".join(lines)).split(u"\n")
-    else:
-        doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg)
-        lines[:] = unicode(doc).split(u"\n")
-
-    if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
-           obj.__name__:
-        if hasattr(obj, '__module__'):
-            v = dict(full_name=u"%s.%s" % (obj.__module__, obj.__name__))
-        else:
-            v = dict(full_name=obj.__name__)
-        lines += [u'', u'.. htmlonly::', '']
-        lines += [u'    %s' % x for x in
-                  (app.config.numpydoc_edit_link % v).split("\n")]
-
-    # replace reference numbers so that there are no duplicates
-    references = []
-    for line in lines:
-        line = line.strip()
-        m = re.match(ur'^.. \[([a-z0-9_.-])\]', line, re.I)
-        if m:
-            references.append(m.group(1))
-
-    # start renaming from the longest string, to avoid overwriting parts
-    references.sort(key=lambda x: -len(x))
-    if references:
-        for i, line in enumerate(lines):
-            for r in references:
-                if re.match(ur'^\d+$', r):
-                    new_r = u"R%d" % (reference_offset[0] + int(r))
-                else:
-                    new_r = u"%s%d" % (r, reference_offset[0])
-                lines[i] = lines[i].replace(u'[%s]_' % r,
-                                            u'[%s]_' % new_r)
-                lines[i] = lines[i].replace(u'.. [%s]' % r,
-                                            u'.. [%s]' % new_r)
-
-    reference_offset[0] += len(references)
-
-def mangle_signature(app, what, name, obj, options, sig, retann):
-    # Do not try to inspect classes that don't define `__init__`
-    if (inspect.isclass(obj) and
-        (not hasattr(obj, '__init__') or
-        'initializes x; see ' in pydoc.getdoc(obj.__init__))):
-        return '', ''
-
-    if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
-    if not hasattr(obj, '__doc__'): return
-
-    doc = SphinxDocString(pydoc.getdoc(obj), warn=app.warn)
-    if doc['Signature']:
-        sig = re.sub(u"^[^(]*", u"", doc['Signature'])
-        return sig, u''
-
-def setup(app, get_doc_object_=get_doc_object):
-    global get_doc_object
-    get_doc_object = get_doc_object_
-
-    app.connect('autodoc-process-docstring', mangle_docstrings)
-    app.connect('autodoc-process-signature', mangle_signature)
-    app.add_config_value('numpydoc_edit_link', None, False)
-    app.add_config_value('numpydoc_use_plots', None, False)
-    app.add_config_value('numpydoc_show_class_members', True, True)
-
-    # Extra mangling domains
-    app.add_domain(NumpyPythonDomain)
-    app.add_domain(NumpyCDomain)
-
-#------------------------------------------------------------------------------
-# Docstring-mangling domains
-#------------------------------------------------------------------------------
-
-from docutils.statemachine import ViewList
-from sphinx.domains.c import CDomain
-from sphinx.domains.python import PythonDomain
-
-class ManglingDomainBase(object):
-    directive_mangling_map = {}
-
-    def __init__(self, *a, **kw):
-        super(ManglingDomainBase, self).__init__(*a, **kw)
-        self.wrap_mangling_directives()
-
-    def wrap_mangling_directives(self):
-        for name, objtype in self.directive_mangling_map.items():
-            self.directives[name] = wrap_mangling_directive(
-                self.directives[name], objtype)
-
-class NumpyPythonDomain(ManglingDomainBase, PythonDomain):
-    name = 'np'
-    directive_mangling_map = {
-        'function': 'function',
-        'class': 'class',
-        'exception': 'class',
-        'method': 'function',
-        'classmethod': 'function',
-        'staticmethod': 'function',
-        'attribute': 'attribute',
-    }
-
-class NumpyCDomain(ManglingDomainBase, CDomain):
-    name = 'np-c'
-    directive_mangling_map = {
-        'function': 'function',
-        'member': 'attribute',
-        'macro': 'function',
-        'type': 'class',
-        'var': 'object',
-    }
-
-def wrap_mangling_directive(base_directive, objtype):
-    class directive(base_directive):
-        def run(self):
-            env = self.state.document.settings.env
-
-            name = None
-            if self.arguments:
-                m = re.match(r'^(.*\s+)?(.*?)(\(.*)?', self.arguments[0])
-                name = m.group(2).strip()
-
-            if not name:
-                name = self.arguments[0]
-
-            lines = list(self.content)
-            mangle_docstrings(env.app, objtype, name, None, None, lines)
-            self.content = ViewList(lines, self.content.parent)
-
-            return base_directive.run(self)
-
-    return directive
-
diff --git a/astropy/sphinx/ext/phantom_import.py b/astropy/sphinx/ext/phantom_import.py
deleted file mode 100644
index 3f3147a..0000000
--- a/astropy/sphinx/ext/phantom_import.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""
-==============
-phantom_import
-==============
-
-Sphinx extension to make directives from ``sphinx.ext.autodoc`` and similar
-extensions to use docstrings loaded from an XML file.
-
-This extension loads an XML file in the Pydocweb format [1] and
-creates a dummy module that contains the specified docstrings. This
-can be used to get the current docstrings from a Pydocweb instance
-without needing to rebuild the documented module.
-
-.. [1] http://code.google.com/p/pydocweb
-
-"""
-import imp, sys, compiler, types, os, inspect, re
-
-def setup(app):
-    app.connect('builder-inited', initialize)
-    app.add_config_value('phantom_import_file', None, True)
-
-def initialize(app):
-    fn = app.config.phantom_import_file
-    if (fn and os.path.isfile(fn)):
-        print "[numpydoc] Phantom importing modules from", fn, "..."
-        import_phantom_module(fn)
-
-#------------------------------------------------------------------------------
-# Creating 'phantom' modules from an XML description
-#------------------------------------------------------------------------------
-def import_phantom_module(xml_file):
-    """
-    Insert a fake Python module to sys.modules, based on a XML file.
-
-    The XML file is expected to conform to Pydocweb DTD. The fake
-    module will contain dummy objects, which guarantee the following:
-
-    - Docstrings are correct.
-    - Class inheritance relationships are correct (if present in XML).
-    - Function argspec is *NOT* correct (even if present in XML).
-      Instead, the function signature is prepended to the function docstring.
-    - Class attributes are *NOT* correct; instead, they are dummy objects.
-
-    Parameters
-    ----------
-    xml_file : str
-        Name of an XML file to read
-    
-    """
-    import lxml.etree as etree
-
-    object_cache = {}
-
-    tree = etree.parse(xml_file)
-    root = tree.getroot()
-
-    # Sort items so that
-    # - Base classes come before classes inherited from them
-    # - Modules come before their contents
-    all_nodes = dict([(n.attrib['id'], n) for n in root])
-    
-    def _get_bases(node, recurse=False):
-        bases = [x.attrib['ref'] for x in node.findall('base')]
-        if recurse:
-            j = 0
-            while True:
-                try:
-                    b = bases[j]
-                except IndexError: break
-                if b in all_nodes:
-                    bases.extend(_get_bases(all_nodes[b]))
-                j += 1
-        return bases
-
-    type_index = ['module', 'class', 'callable', 'object']
-    
-    def base_cmp(a, b):
-        x = cmp(type_index.index(a.tag), type_index.index(b.tag))
-        if x != 0: return x
-
-        if a.tag == 'class' and b.tag == 'class':
-            a_bases = _get_bases(a, recurse=True)
-            b_bases = _get_bases(b, recurse=True)
-            x = cmp(len(a_bases), len(b_bases))
-            if x != 0: return x
-            if a.attrib['id'] in b_bases: return -1
-            if b.attrib['id'] in a_bases: return 1
-        
-        return cmp(a.attrib['id'].count('.'), b.attrib['id'].count('.'))
-
-    nodes = root.getchildren()
-    nodes.sort(base_cmp)
-
-    # Create phantom items
-    for node in nodes:
-        name = node.attrib['id']
-        doc = (node.text or '').decode('string-escape') + "\n"
-        if doc == "\n": doc = ""
-
-        # create parent, if missing
-        parent = name
-        while True:
-            parent = '.'.join(parent.split('.')[:-1])
-            if not parent: break
-            if parent in object_cache: break
-            obj = imp.new_module(parent)
-            object_cache[parent] = obj
-            sys.modules[parent] = obj
-
-        # create object
-        if node.tag == 'module':
-            obj = imp.new_module(name)
-            obj.__doc__ = doc
-            sys.modules[name] = obj
-        elif node.tag == 'class':
-            bases = [object_cache[b] for b in _get_bases(node)
-                     if b in object_cache]
-            bases.append(object)
-            init = lambda self: None
-            init.__doc__ = doc
-            obj = type(name, tuple(bases), {'__doc__': doc, '__init__': init})
-            obj.__name__ = name.split('.')[-1]
-        elif node.tag == 'callable':
-            funcname = node.attrib['id'].split('.')[-1]
-            argspec = node.attrib.get('argspec')
-            if argspec:
-                argspec = re.sub('^[^(]*', '', argspec)
-                doc = "%s%s\n\n%s" % (funcname, argspec, doc)
-            obj = lambda: 0
-            obj.__argspec_is_invalid_ = True
-            obj.func_name = funcname
-            obj.__name__ = name
-            obj.__doc__ = doc
-            if inspect.isclass(object_cache[parent]):
-                obj.__objclass__ = object_cache[parent]
-        else:
-            class Dummy(object): pass
-            obj = Dummy()
-            obj.__name__ = name
-            obj.__doc__ = doc
-            if inspect.isclass(object_cache[parent]):
-                obj.__get__ = lambda: None
-        object_cache[name] = obj
-
-        if parent:
-            if inspect.ismodule(object_cache[parent]):
-                obj.__module__ = parent
-                setattr(object_cache[parent], name.split('.')[-1], obj)
-
-    # Populate items
-    for node in root:
-        obj = object_cache.get(node.attrib['id'])
-        if obj is None: continue
-        for ref in node.findall('ref'):
-            if node.tag == 'class':
-                if ref.attrib['ref'].startswith(node.attrib['id'] + '.'):
-                    setattr(obj, ref.attrib['name'],
-                            object_cache.get(ref.attrib['ref']))
-            else:
-                setattr(obj, ref.attrib['name'],
-                        object_cache.get(ref.attrib['ref']))
diff --git a/astropy/sphinx/ext/smart_resolver.py b/astropy/sphinx/ext/smart_resolver.py
deleted file mode 100644
index e2544ab..0000000
--- a/astropy/sphinx/ext/smart_resolver.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-The classes in the astropy docs are documented by their API location,
-which is not necessarily where they are defined in the source.  This
-causes a problem when certain automated features of the doc build,
-such as the inheritance diagrams or the `Bases` list of a class
-reference a class by its canonical location rather than its "user"
-location.
-
-In the `autodoc-process-docstring` event, a mapping from the actual
-name to the API name is maintained.  Later, in the `missing-reference`
-enent, unresolved references are looked up in this dictionary and
-corrected if possible.
-"""
-
-from docutils.nodes import literal
-
-
-def process_docstring(app, what, name, obj, options, lines):
-    if what in ('class', 'exception'):
-        env = app.env
-        if not hasattr(env, 'class_name_mapping'):
-            env.class_name_mapping = {}
-        mapping = env.class_name_mapping
-        mapping[obj.__module__ + '.' + obj.__name__] = name
-
-
-def missing_reference_handler(app, env, node, contnode):
-    if not hasattr(env, 'class_name_mapping'):
-        env.class_name_mapping = {}
-    mapping = env.class_name_mapping
-    reftype = node['reftype']
-    reftarget = node['reftarget']
-    if reftype in ('obj', 'class', 'exc', 'meth'):
-        reftarget = node['reftarget']
-        suffix = ''
-        if reftarget not in mapping:
-            if '.' in reftarget:
-                front, suffix = reftarget.rsplit('.', 1)
-            else:
-                suffix = reftarget
-
-            if suffix.startswith('_') and not suffix.startswith('__'):
-                # If this is a reference to a hidden class or method,
-                # we can't link to it, but we don't want to have a
-                # nitpick warning.
-                return node[0].deepcopy()
-
-            if reftype in ('obj', 'meth') and '.' in reftarget:
-                if front in mapping:
-                    reftarget = front
-                    suffix = '.' + suffix
-
-        if reftarget in mapping:
-            newtarget = mapping[reftarget] + suffix
-            if not node['refexplicit'] and not '~' in node.rawsource:
-                contnode = literal(text=newtarget)
-            newnode = env.domains['py'].resolve_xref(
-                env, node['refdoc'], app.builder, 'class', newtarget,
-                node, contnode)
-            if newnode is not None:
-                newnode['reftitle'] = reftarget
-            return newnode
-
-
-def setup(app):
-    app.connect('autodoc-process-docstring', process_docstring)
-
-    app.connect('missing-reference', missing_reference_handler)
diff --git a/astropy/sphinx/ext/templates/autosummary_core/base.rst b/astropy/sphinx/ext/templates/autosummary_core/base.rst
deleted file mode 100644
index aa1041b..0000000
--- a/astropy/sphinx/ext/templates/autosummary_core/base.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. 
-   **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-   purposes - it has now been moved to the separate astropy-helpers package,
-   located at https://github.com/astropy/astropy-helpers. Any new development or
-   bug fixes should be done there.
-
-{% if referencefile %}
-.. include:: {{ referencefile }}
-{% endif %}
-
-{{ objname }}
-{{ underline }}
-
-.. currentmodule:: {{ module }}
-
-.. auto{{ objtype }}:: {{ objname }}
diff --git a/astropy/sphinx/ext/templates/autosummary_core/class.rst b/astropy/sphinx/ext/templates/autosummary_core/class.rst
deleted file mode 100644
index 9cbb93f..0000000
--- a/astropy/sphinx/ext/templates/autosummary_core/class.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. 
-   **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-   purposes - it has now been moved to the separate astropy-helpers package,
-   located at https://github.com/astropy/astropy-helpers. Any new development or
-   bug fixes should be done there.
-
-{% if referencefile %}
-.. include:: {{ referencefile }}
-{% endif %}
-
-{{ objname }}
-{{ underline }}
-
-.. currentmodule:: {{ module }}
-
-.. autoclass:: {{ objname }}
-   :show-inheritance:
-
-   {% if '__init__' in methods %}
-     {% set caught_result = methods.remove('__init__') %}
-   {% endif %}
-
-   {% block attributes_summary %}
-   {% if attributes %}
-
-   .. rubric:: Attributes Summary
-
-   .. autosummary::
-   {% for item in attributes %}
-      ~{{ name }}.{{ item }}
-   {%- endfor %}
-
-   {% endif %}
-   {% endblock %}
-
-   {% block methods_summary %}
-   {% if methods %}
-
-   .. rubric:: Methods Summary
-
-   .. autosummary::
-   {% for item in methods %}
-      ~{{ name }}.{{ item }}
-   {%- endfor %}
-
-   {% endif %}
-   {% endblock %}
-
-   {% block attributes_documentation %}
-   {% if attributes %}
-
-   .. rubric:: Attributes Documentation
-
-   {% for item in attributes %}
-   .. autoattribute:: {{ item }}
-   {%- endfor %}
-
-   {% endif %}
-   {% endblock %}
-
-   {% block methods_documentation %}
-   {% if methods %}
-
-   .. rubric:: Methods Documentation
-
-   {% for item in methods %}
-   .. automethod:: {{ item }}
-   {%- endfor %}
-
-   {% endif %}
-   {% endblock %}
diff --git a/astropy/sphinx/ext/templates/autosummary_core/module.rst b/astropy/sphinx/ext/templates/autosummary_core/module.rst
deleted file mode 100644
index b48af08..0000000
--- a/astropy/sphinx/ext/templates/autosummary_core/module.rst
+++ /dev/null
@@ -1,47 +0,0 @@
-.. 
-   **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-   purposes - it has now been moved to the separate astropy-helpers package,
-   located at https://github.com/astropy/astropy-helpers. Any new development or
-   bug fixes should be done there.
-
-{% if referencefile %}
-.. include:: {{ referencefile }}
-{% endif %}
-
-{{ objname }}
-{{ underline }}
-
-.. automodule:: {{ fullname }}
-
-   {% block functions %}
-   {% if functions %}
-   .. rubric:: Functions
-
-   .. autosummary::
-   {% for item in functions %}
-      {{ item }}
-   {%- endfor %}
-   {% endif %}
-   {% endblock %}
-
-   {% block classes %}
-   {% if classes %}
-   .. rubric:: Classes
-
-   .. autosummary::
-   {% for item in classes %}
-      {{ item }}
-   {%- endfor %}
-   {% endif %}
-   {% endblock %}
-
-   {% block exceptions %}
-   {% if exceptions %}
-   .. rubric:: Exceptions
-
-   .. autosummary::
-   {% for item in exceptions %}
-      {{ item }}
-   {%- endfor %}
-   {% endif %}
-   {% endblock %}
diff --git a/astropy/sphinx/ext/tests/__init__.py b/astropy/sphinx/ext/tests/__init__.py
deleted file mode 100644
index bb03ab5..0000000
--- a/astropy/sphinx/ext/tests/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
diff --git a/astropy/sphinx/ext/tests/test_automodapi.py b/astropy/sphinx/ext/tests/test_automodapi.py
deleted file mode 100644
index a4465d3..0000000
--- a/astropy/sphinx/ext/tests/test_automodapi.py
+++ /dev/null
@@ -1,300 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-
-import os
-
-from ....tests.helper import pytest
-pytest.importorskip('sphinx')  # skips these tests if sphinx not present
-
-
-class FakeConfig(object):
-    """
-    Mocks up a sphinx configuration setting construct for automodapi tests
-    """
-    def __init__(self, **kwargs):
-        for k, v in kwargs.iteritems():
-            setattr(self, k, v)
-
-
-class FakeApp(object):
-    """
-    Mocks up a `sphinx.application.Application` object for automodapi tests
-    """
-
-    # Some default config values
-    _defaults = {
-        'automodapi_toctreedirnm': 'api',
-        'automodapi_writereprocessed': False
-    }
-
-    def __init__(self, **configs):
-        config = self._defaults.copy()
-        config.update(configs)
-        self.config = FakeConfig(**config)
-        self.info = []
-        self.warnings = []
-
-    def info(self, msg, loc):
-        self.info.append((msg, loc))
-
-    def warn(self, msg, loc):
-        self.warnings.append((msg, loc))
-
-
-am_replacer_str = """
-This comes before
-
-.. automodapi:: astropy.sphinx.ext.tests.test_automodapi
-{options}
-
-This comes after
-"""
-
-am_replacer_basic_expected = """
-This comes before
-
-astropy.sphinx.ext.tests.test_automodapi Module
------------------------------------------------
-
-.. automodule:: astropy.sphinx.ext.tests.test_automodapi
-
-Functions
-^^^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :functions-only:
-    :toctree: api/
-
-Classes
-^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :classes-only:
-    :toctree: api/
-
-Class Inheritance Diagram
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. automod-diagram:: astropy.sphinx.ext.tests.test_automodapi
-    :private-bases:
-    :parts: 1
-    {empty}
-
-This comes after
-""".format(empty='').replace('/', os.sep)
-# the .format is necessary for editors that remove empty-line whitespace
-
-
-def test_am_replacer_basic():
-    """
-    Tests replacing an ".. automodapi::" with the automodapi no-option
-    template
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    result = automodapi_replace(am_replacer_str.format(options=''), fakeapp)
-
-    assert result == am_replacer_basic_expected
-
-am_replacer_noinh_expected = """
-This comes before
-
-astropy.sphinx.ext.tests.test_automodapi Module
------------------------------------------------
-
-.. automodule:: astropy.sphinx.ext.tests.test_automodapi
-
-Functions
-^^^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :functions-only:
-    :toctree: api/
-
-Classes
-^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :classes-only:
-    :toctree: api/
-
-
-This comes after
-""".format(empty='').replace('/', os.sep)
-
-
-def test_am_replacer_noinh():
-    """
-    Tests replacing an ".. automodapi::" with no-inheritance-diagram
-    option
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    ops = ['', ':no-inheritance-diagram:']
-    ostr = '\n    '.join(ops)
-    result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp)
-
-    assert result == am_replacer_noinh_expected
-
-am_replacer_titleandhdrs_expected = """
-This comes before
-
-astropy.sphinx.ext.tests.test_automodapi Module
-&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-
-.. automodule:: astropy.sphinx.ext.tests.test_automodapi
-
-Functions
-*********
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :functions-only:
-    :toctree: api/
-
-Classes
-*******
-
-.. automodsumm:: astropy.sphinx.ext.tests.test_automodapi
-    :classes-only:
-    :toctree: api/
-
-Class Inheritance Diagram
-*************************
-
-.. automod-diagram:: astropy.sphinx.ext.tests.test_automodapi
-    :private-bases:
-    :parts: 1
-    {empty}
-
-
-This comes after
-""".format(empty='').replace('/', os.sep)
-
-
-def test_am_replacer_titleandhdrs():
-    """
-    Tests replacing an ".. automodapi::" entry with title-setting and header
-    character options.
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    ops = ['', ':title: A new title', ':headings: &*']
-    ostr = '\n    '.join(ops)
-    result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp)
-
-    assert result == am_replacer_titleandhdrs_expected
-
-
-am_replacer_nomain_str = """
-This comes before
-
-.. automodapi:: astropy.sphinx.ext.automodapi
-    :no-main-docstr:
-
-This comes after
-"""
-
-am_replacer_nomain_expected = """
-This comes before
-
-astropy.sphinx.ext.automodapi Module
-------------------------------------
-
-
-
-Functions
-^^^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.automodapi
-    :functions-only:
-    :toctree: api/
-
-
-This comes after
-""".format(empty='').replace('/', os.sep)
-
-
-def test_am_replacer_nomain():
-    """
-    Tests replacing an ".. automodapi::" with "no-main-docstring" .
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    result = automodapi_replace(am_replacer_nomain_str, fakeapp)
-
-    assert result == am_replacer_nomain_expected
-
-
-am_replacer_skip_str = """
-This comes before
-
-.. automodapi:: astropy.sphinx.ext.automodapi
-    :skip: something1
-    :skip: something2
-
-This comes after
-"""
-
-am_replacer_skip_expected = """
-This comes before
-
-astropy.sphinx.ext.automodapi Module
-------------------------------------
-
-.. automodule:: astropy.sphinx.ext.automodapi
-
-Functions
-^^^^^^^^^
-
-.. automodsumm:: astropy.sphinx.ext.automodapi
-    :functions-only:
-    :toctree: api/
-    :skip: something1,something2
-
-
-This comes after
-""".format(empty='').replace('/', os.sep)
-
-
-def test_am_replacer_skip():
-    """
-    Tests using the ":skip: option in an ".. automodapi::" .
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    result = automodapi_replace(am_replacer_skip_str, fakeapp)
-
-    assert result == am_replacer_skip_expected
-
-
-am_replacer_invalidop_str = """
-This comes before
-
-.. automodapi:: astropy.sphinx.ext.automodapi
-    :invalid-option:
-
-This comes after
-"""
-
-
-def test_am_replacer_invalidop():
-    """
-    Tests that a sphinx warning is produced with an invalid option.
-    """
-    from ..automodapi import automodapi_replace
-
-    fakeapp = FakeApp()
-    automodapi_replace(am_replacer_invalidop_str, fakeapp)
-
-    expected_warnings = [('Found additional options invalid-option in '
-                          'automodapi.', None)]
-
-    assert fakeapp.warnings == expected_warnings
diff --git a/astropy/sphinx/ext/tests/test_automodsumm.py b/astropy/sphinx/ext/tests/test_automodsumm.py
deleted file mode 100644
index b4a3cc2..0000000
--- a/astropy/sphinx/ext/tests/test_automodsumm.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-from ....tests.helper import pytest
-pytest.importorskip('sphinx')  # skips these tests if sphinx not present
-
-
-class FakeEnv(object):
-    """
-    Mocks up a sphinx env setting construct for automodapi tests
-    """
-    def __init__(self, **kwargs):
-        for k, v in kwargs.iteritems():
-            setattr(self, k, v)
-
-
-class FakeBuilder(object):
-    """
-    Mocks up a sphinx builder setting construct for automodapi tests
-    """
-    def __init__(self, **kwargs):
-        self.env = FakeEnv(**kwargs)
-
-
-class FakeApp(object):
-    """
-    Mocks up a `sphinx.application.Application` object for automodapi tests
-    """
-    def __init__(self, srcdir, automodapipresent=True):
-        self.builder = FakeBuilder(srcdir=srcdir)
-        self.info = []
-        self.warnings = []
-        self._extensions = []
-        if automodapipresent:
-            self._extensions.append('astropy.sphinx.ext.automodapi')
-
-    def info(self, msg, loc):
-        self.info.append((msg, loc))
-
-    def warn(self, msg, loc):
-        self.warnings.append((msg, loc))
-
-
-ams_to_asmry_str = """
-Before
-
-.. automodsumm:: astropy.sphinx.ext.automodsumm
-    :p:
-
-And After
-"""
-
-ams_to_asmry_expected = """.. currentmodule:: astropy.sphinx.ext.automodsumm
-
-.. autosummary::
-    :p:
-
-    Automoddiagram
-    Automodsumm
-    automodsumm_to_autosummary_lines
-    generate_automodsumm_docs
-    process_automodsumm_generation
-    setup"""
-
-
-def test_ams_to_asmry(tmpdir):
-    from ..automodsumm import automodsumm_to_autosummary_lines
-
-    fi = tmpdir.join('automodsumm.rst')
-    fi.write(ams_to_asmry_str)
-
-    fakeapp = FakeApp(srcdir='')
-    resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp)
-
-    assert '\n'.join(resultlines) == ams_to_asmry_expected
diff --git a/astropy/sphinx/ext/tocdepthfix.py b/astropy/sphinx/ext/tocdepthfix.py
deleted file mode 100644
index ac872e7..0000000
--- a/astropy/sphinx/ext/tocdepthfix.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-from sphinx import addnodes
-
-
-def fix_toc_entries(app, doctree):
-    # Get the docname; I don't know why this isn't just passed in to the
-    # callback
-    # This seems a bit unreliable as it's undocumented, but it's not "private"
-    # either:
-    docname = app.builder.env.temp_data['docname']
-    if app.builder.env.metadata[docname].get('tocdepth', 0) != 0:
-        # We need to reprocess any TOC nodes in the doctree and make sure all
-        # the files listed in any TOCs are noted
-        for treenode in doctree.traverse(addnodes.toctree):
-            app.builder.env.note_toctree(docname, treenode)
-
-
-def setup(app):
-    app.connect('doctree-read', fix_toc_entries)
diff --git a/astropy/sphinx/ext/traitsdoc.py b/astropy/sphinx/ext/traitsdoc.py
deleted file mode 100644
index adfe22a..0000000
--- a/astropy/sphinx/ext/traitsdoc.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-"""
-=========
-traitsdoc
-=========
-
-Sphinx extension that handles docstrings in the Numpy standard format, [1]
-and support Traits [2].
-
-This extension can be used as a replacement for ``numpydoc`` when support
-for Traits is required.
-
-.. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
-.. [2] http://code.enthought.com/projects/traits/
-
-"""
-
-import inspect
-import os
-import pydoc
-
-import docscrape
-import docscrape_sphinx
-from docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString
-
-import numpydoc
-
-import comment_eater
-
-class SphinxTraitsDoc(SphinxClassDoc):
-    def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc):
-        if not inspect.isclass(cls):
-            raise ValueError("Initialise using a class. Got %r" % cls)
-        self._cls = cls
-
-        if modulename and not modulename.endswith('.'):
-            modulename += '.'
-        self._mod = modulename
-        self._name = cls.__name__
-        self._func_doc = func_doc
-
-        docstring = pydoc.getdoc(cls)
-        docstring = docstring.split('\n')
-
-        # De-indent paragraph
-        try:
-            indent = min(len(s) - len(s.lstrip()) for s in docstring
-                         if s.strip())
-        except ValueError:
-            indent = 0
-
-        for n,line in enumerate(docstring):
-            docstring[n] = docstring[n][indent:]
-
-        self._doc = docscrape.Reader(docstring)
-        self._parsed_data = {
-            'Signature': '',
-            'Summary': '',
-            'Description': [],
-            'Extended Summary': [],
-            'Parameters': [],
-            'Returns': [],
-            'Raises': [],
-            'Warns': [],
-            'Other Parameters': [],
-            'Traits': [],
-            'Methods': [],
-            'See Also': [],
-            'Notes': [],
-            'References': '',
-            'Example': '',
-            'Examples': '',
-            'index': {}
-            }
-
-        self._parse()
-
-    def _str_summary(self):
-        return self['Summary'] + ['']
-
-    def _str_extended_summary(self):
-        return self['Description'] + self['Extended Summary'] + ['']
-
-    def __str__(self, indent=0, func_role="func"):
-        out = []
-        out += self._str_signature()
-        out += self._str_index() + ['']
-        out += self._str_summary()
-        out += self._str_extended_summary()
-        for param_list in ('Parameters', 'Traits', 'Methods',
-                           'Returns','Raises'):
-            out += self._str_param_list(param_list)
-        out += self._str_see_also("obj")
-        out += self._str_section('Notes')
-        out += self._str_references()
-        out += self._str_section('Example')
-        out += self._str_section('Examples')
-        out = self._str_indent(out,indent)
-        return '\n'.join(out)
-
-def looks_like_issubclass(obj, classname):
-    """ Return True if the object has a class or superclass with the given class
-    name.
-
-    Ignores old-style classes.
-    """
-    t = obj
-    if t.__name__ == classname:
-        return True
-    for klass in t.__mro__:
-        if klass.__name__ == classname:
-            return True
-    return False
-
-def get_doc_object(obj, what=None, config=None):
-    if what is None:
-        if inspect.isclass(obj):
-            what = 'class'
-        elif inspect.ismodule(obj):
-            what = 'module'
-        elif callable(obj):
-            what = 'function'
-        else:
-            what = 'object'
-    if what == 'class':
-        doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc, config=config)
-        if looks_like_issubclass(obj, 'HasTraits'):
-            for name, trait, comment in comment_eater.get_class_traits(obj):
-                # Exclude private traits.
-                if not name.startswith('_'):
-                    doc['Traits'].append((name, trait, comment.splitlines()))
-        return doc
-    elif what in ('function', 'method'):
-        return SphinxFunctionDoc(obj, '', config=config)
-    else:
-        return SphinxDocString(pydoc.getdoc(obj), config=config)
-
-def setup(app):
-    # init numpydoc
-    numpydoc.setup(app, get_doc_object)
-
diff --git a/astropy/sphinx/ext/viewcode.py b/astropy/sphinx/ext/viewcode.py
deleted file mode 100644
index 171e090..0000000
--- a/astropy/sphinx/ext/viewcode.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# -*- coding: utf-8 -*-
-"""
-    sphinx.ext.viewcode
-    ~~~~~~~~~~~~~~~~~~~
-
-    Add links to module code in Python object descriptions.
-
-    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
-    :license: BSD, see LICENSE for details.
-
-    Patched using patch in https://bitbucket.org/birkenfeld/sphinx/issue/623/extension-viewcode-fails-with-function on 21 Aug 2013 by Kyle H Barbary
-"""
-
-from docutils import nodes
-
-from sphinx import addnodes
-from sphinx.locale import _
-from sphinx.pycode import ModuleAnalyzer
-from sphinx.util.nodes import make_refnode
-
-import sys
-import traceback
-
-
-def doctree_read(app, doctree):
-    env = app.builder.env
-    if not hasattr(env, '_viewcode_modules'):
-        env._viewcode_modules = {}
- 
-    def get_full_modname(modname, attribute):
-        try:
-            __import__(modname)
-        except Exception, error:
-            if not app.quiet:
-                app.info(traceback.format_exc().rstrip())
-            app.warn('viewcode can\'t import %s, failed with error "%s"' %
-                (modname, error))
-            return None
-        module = sys.modules[modname]
-        try:
-            # Allow an attribute to have multiple parts and incidentially allow
-            # repeated .s in the attribute.
-            attr = attribute.split('.')
-            value = module
-            for attr in attribute.split('.'):
-                if attr:
-                    value = getattr(value, attr)
-        except AttributeError:
-            app.warn('Didn\'t find %s in %s' % (attribute, module.__name__))
-            return None
-        else:
-            return getattr(value, '__module__', None)
-
-
-    def has_tag(modname, fullname, docname, refname):
-        entry = env._viewcode_modules.get(modname, None)
-        if entry is None:
-            try:
-                analyzer = ModuleAnalyzer.for_module(modname)
-            except Exception:
-                env._viewcode_modules[modname] = False
-                return
-            analyzer.find_tags()
-            if not isinstance(analyzer.code, unicode):
-                code = analyzer.code.decode(analyzer.encoding)
-            else:
-                code = analyzer.code
-            entry = code, analyzer.tags, {}, refname
-            env._viewcode_modules[modname] = entry
-        elif entry is False:
-            return
-        _, tags, used, _ = entry
-        if fullname in tags:
-            used[fullname] = docname
-            return True
-
-
-    for objnode in doctree.traverse(addnodes.desc):
-        if objnode.get('domain') != 'py':
-            continue
-        names = set()
-        for signode in objnode:
-            if not isinstance(signode, addnodes.desc_signature):
-                continue
-            modname = signode.get('module')
-            fullname = signode.get('fullname')
-            refname = modname
-            if env.config.viewcode_import:
-                modname = get_full_modname(modname, fullname)
-            if not modname:
-                continue
-            if not has_tag(modname, fullname, env.docname, refname):
-                continue
-            if fullname in names:
-                # only one link per name, please
-                continue
-            names.add(fullname)
-            pagename = '_modules/' + modname.replace('.', '/')
-            onlynode = addnodes.only(expr='html')
-            onlynode += addnodes.pending_xref(
-                '', reftype='viewcode', refdomain='std', refexplicit=False,
-                reftarget=pagename, refid=fullname,
-                refdoc=env.docname)
-            onlynode[0] += nodes.inline('', _('[source]'),
-                                        classes=['viewcode-link'])
-            signode += onlynode
-
-
-def missing_reference(app, env, node, contnode):
-    # resolve our "viewcode" reference nodes -- they need special treatment
-    if node['reftype'] == 'viewcode':
-        return make_refnode(app.builder, node['refdoc'], node['reftarget'],
-                            node['refid'], contnode)
-
-
-def collect_pages(app):
-    env = app.builder.env
-    if not hasattr(env, '_viewcode_modules'):
-        return
-    highlighter = app.builder.highlighter
-    urito = app.builder.get_relative_uri
-
-    modnames = set(env._viewcode_modules)
-
-    app.builder.info(' (%d module code pages)' %
-                     len(env._viewcode_modules), nonl=1)
-
-    for modname, entry in env._viewcode_modules.iteritems():
-        if not entry:
-            continue
-        code, tags, used, refname = entry
-        # construct a page name for the highlighted source
-        pagename = '_modules/' + modname.replace('.', '/')
-        # highlight the source using the builder's highlighter
-        highlighted = highlighter.highlight_block(code, 'python', linenos=False)
-        # split the code into lines
-        lines = highlighted.splitlines()
-        # split off wrap markup from the first line of the actual code
-        before, after = lines[0].split('<pre>')
-        lines[0:1] = [before + '<pre>', after]
-        # nothing to do for the last line; it always starts with </pre> anyway
-        # now that we have code lines (starting at index 1), insert anchors for
-        # the collected tags (HACK: this only works if the tag boundaries are
-        # properly nested!)
-        maxindex = len(lines) - 1
-        for name, docname in used.iteritems():
-            type, start, end = tags[name]
-            backlink = urito(pagename, docname) + '#' + refname + '.' + name
-            lines[start] = (
-                '<div class="viewcode-block" id="%s"><a class="viewcode-back" '
-                'href="%s">%s</a>' % (name, backlink, _('[docs]'))
-                + lines[start])
-            lines[min(end - 1, maxindex)] += '</div>'
-        # try to find parents (for submodules)
-        parents = []
-        parent = modname
-        while '.' in parent:
-            parent = parent.rsplit('.', 1)[0]
-            if parent in modnames:
-                parents.append({
-                    'link': urito(pagename, '_modules/' +
-                                  parent.replace('.', '/')),
-                    'title': parent})
-        parents.append({'link': urito(pagename, '_modules/index'),
-                        'title': _('Module code')})
-        parents.reverse()
-        # putting it all together
-        context = {
-            'parents': parents,
-            'title': modname,
-            'body': _('<h1>Source code for %s</h1>') % modname + \
-                    '\n'.join(lines)
-        }
-        yield (pagename, context, 'page.html')
-
-    if not modnames:
-        return
-
-    app.builder.info(' _modules/index')
-    html = ['\n']
-    # the stack logic is needed for using nested lists for submodules
-    stack = ['']
-    for modname in sorted(modnames):
-        if modname.startswith(stack[-1]):
-            stack.append(modname + '.')
-            html.append('<ul>')
-        else:
-            stack.pop()
-            while not modname.startswith(stack[-1]):
-                stack.pop()
-                html.append('</ul>')
-            stack.append(modname + '.')
-        html.append('<li><a href="%s">%s</a></li>\n' % (
-            urito('_modules/index', '_modules/' + modname.replace('.', '/')),
-            modname))
-    html.append('</ul>' * (len(stack) - 1))
-    context = {
-        'title': _('Overview: module code'),
-        'body': _('<h1>All modules for which code is available</h1>') + \
-            ''.join(html),
-    }
-
-    yield ('_modules/index', context, 'page.html')
-
-
-def setup(app):
-    app.add_config_value('viewcode_import', True, False)
-    app.connect('doctree-read', doctree_read)
-    app.connect('html-collect-pages', collect_pages)
-    app.connect('missing-reference', missing_reference)
-    #app.add_config_value('viewcode_include_modules', [], 'env')
-    #app.add_config_value('viewcode_exclude_modules', [], 'env')
diff --git a/astropy/sphinx/setup_package.py b/astropy/sphinx/setup_package.py
deleted file mode 100644
index 35d8c96..0000000
--- a/astropy/sphinx/setup_package.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# **Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-# purposes - it has now been moved to the separate astropy-helpers package,
-# located at https://github.com/astropy/astropy-helpers. Any new development or
-# bug fixes should be done there.
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-
-def get_package_data():
-    # Install the theme files
-    return {
-        'astropy.sphinx': [
-            'ext/templates/*/*',
-            'themes/bootstrap-astropy/*.*',
-            'themes/bootstrap-astropy/static/*.*']}
diff --git a/astropy/sphinx/themes/bootstrap-astropy/README.md b/astropy/sphinx/themes/bootstrap-astropy/README.md
deleted file mode 100644
index 5437b41..0000000
--- a/astropy/sphinx/themes/bootstrap-astropy/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-**Please Note**: ``astropy.sphinx`` exists only for backward-compatibility
-purposes - it has now been moved to the separate astropy-helpers package,
-located at https://github.com/astropy/astropy-helpers. Any new development or
-bug fixes should be done there.
\ No newline at end of file
diff --git a/astropy/sphinx/themes/bootstrap-astropy/layout.html b/astropy/sphinx/themes/bootstrap-astropy/layout.html
deleted file mode 100644
index 99d6196..0000000
--- a/astropy/sphinx/themes/bootstrap-astropy/layout.html
+++ /dev/null
@@ -1,94 +0,0 @@
-{% extends "basic/layout.html" %}
-
-{# Collapsible sidebar script from default/layout.html in Sphinx #}
-{% set script_files = script_files + ['_static/sidebar.js'] %}
-
-{# Add the google webfonts needed for the logo #}
-{% block extrahead %}
-<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,600' rel='stylesheet' type='text/css'>
-{% endblock %}
-
-
-{% block header %}
-<div class="topbar">
-  <a class="brand" title="{{ _('Documentation Home') }}" href="{{ pathto(master_doc) }}"><span id="logotext1">{{ theme_logotext1 }}</span><span id="logotext2">{{ theme_logotext2 }}</span><span id="logotext3">{{ theme_logotext3 }}</span></a>
-  <ul>
-    <li><a class="homelink" title="Astropy Homepage" href="http://www.astropy.org"></a></li>
-    <li><a title="{{ _('General Index') }}" href="{{ pathto('genindex') }}">Index</a></li>
-    <li><a title="{{ _('Module Index') }}" href="{{ pathto('py-modindex') }}">Modules</a></li>
-    <li>
-      {% block sidebarsearch %}
-      {% include "searchbox.html" %}
-      {% endblock %}
-    </li>
-  </ul>
-</div>
-{% endblock %}
-
-{% block relbar1 %}
-<div class="related">
-    <h3>{{ _('Navigation') }}</h3>
-    <ul>
-      {%- if next %}
-      <li class="right">
-	<a href="{{ next.link|e }}" title="{{ next.title|striptags|e }}">
-	  next {{ "»"|safe }}
-	</a>
-      </li>
-      {%- endif %}
-      {%- if prev %}
-      <li class="right">
-	<a href="{{ prev.link|e }}" title="{{ prev.title|striptags|e }}">
-	  {{ "«"|safe }} previous
-	</a>
-	{% if next %}{{ reldelim2 }}{% endif %}
-      </li>
-      {%- endif %}
-      {%- block rootrellink %}
-      <li>
-	<a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>
-	{{ reldelim1 }}
-      </li>
-      {%- endblock %}
-      {%- for parent in parents %}
-      <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
-      {%- endfor %}
-      {# Don't put the title in the relbar for the first (index) page. #}
-      {% if prev %}<li>{{ title }}</li>{% endif %}
-      {%- block relbaritems %} {% endblock %}
-    </ul>
-</div>
-{% endblock %}
-
-{# Silence the bottom relbar. #}
-{% block relbar2 %}{% endblock %}
-
-
-{%- block footer %}
-<footer class="footer">
-  <p class="pull-right">
-    {%- if edit_on_github %}
-    <a href="{{ edit_on_github }}">{{ edit_on_github_page_message }}</a>  
-    {%- endif %}
-    {%- if show_source and has_source and sourcename %}
-    <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-       rel="nofollow">{{ _('Page Source') }}</a>
-    {%- endif %}  
-    <a href="#">Back to Top</a></p>
-  <p>
-    {%- if show_copyright %}
-    {%- if hasdoc('copyright') %}
-    {% trans path=pathto('copyright'), copyright=copyright|e %}© <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}<br/>
-    {%- else %}
-    {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}<br/>
-    {%- endif %}
-    {%- endif %}
-    {%- if show_sphinx %}
-    {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}  
-    {%- endif %}
-    {%- if last_updated %}
-    {% trans last_updated=last_updated|e %}Last built {{ last_updated }}.{% endtrans %} <br/>
-    {%- endif %}
-  </p>
-</footer>
-{%- endblock %}
diff --git a/astropy/stats/__init__.py b/astropy/stats/__init__.py
index cc9626f..a5a1002 100644
--- a/astropy/stats/__init__.py
+++ b/astropy/stats/__init__.py
@@ -12,3 +12,4 @@ astronomers' needs.
 """
 
 from .funcs import *
+from .sigma_clipping import *
diff --git a/astropy/stats/funcs.py b/astropy/stats/funcs.py
index 06517b5..6744e50 100644
--- a/astropy/stats/funcs.py
+++ b/astropy/stats/funcs.py
@@ -16,147 +16,26 @@ import numpy as np
 from ..extern.six.moves import xrange
 
 
-__all__ = ['sigma_clip', 'binom_conf_interval', 'binned_binom_proportion',
+__all__ = ['binom_conf_interval', 'binned_binom_proportion',
            'median_absolute_deviation', 'biweight_location',
-           'biweight_midvariance', 'signal_to_noise_oir_ccd', 'bootstrap']
-
+           'biweight_midvariance', 'signal_to_noise_oir_ccd', 'bootstrap',
+           'mad_std', 'gaussian_fwhm_to_sigma', 'gaussian_sigma_to_fwhm']
 
 __doctest_skip__ = ['binned_binom_proportion']
 __doctest_requires__ = {'binom_conf_interval': ['scipy.special']}
 
 
-def sigma_clip(data, sig=3, iters=1, cenfunc=np.ma.median, varfunc=np.var,
-               axis=None, copy=True):
-    """Perform sigma-clipping on the provided data.
-
-    This performs the sigma clipping algorithm - i.e. the data will be iterated
-    over, each time rejecting points that are more than a specified number of
-    standard deviations discrepant.
-
-    .. note::
-        `scipy.stats.sigmaclip
-        <http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.sigmaclip.html>`_
-        provides a subset of the functionality in this function.
-
-    Parameters
-    ----------
-    data : array-like
-        The data to be sigma-clipped (any shape).
-    sig : float
-        The number of standard deviations (*not* variances) to use as the
-        clipping limit.
-    iters : int or `None`
-        The number of iterations to perform clipping for, or `None` to clip
-        until convergence is achieved (i.e. continue until the last
-        iteration clips nothing).
-    cenfunc : callable
-        The technique to compute the center for the clipping. Must be a
-        callable that takes in a masked array and outputs the central value.
-        Defaults to the median (numpy.median).
-    varfunc : callable
-        The technique to compute the standard deviation about the center. Must
-        be a callable that takes in a masked array and outputs a width
-        estimator::
-
-             deviation**2 > sig**2 * varfunc(deviation)
-
-        Defaults to the variance (numpy.var).
-
-    axis : int or `None`
-        If not `None`, clip along the given axis.  For this case, axis=int will
-        be passed on to cenfunc and varfunc, which are expected to return an
-        array with the axis dimension removed (like the numpy functions).
-        If `None`, clip over all values.  Defaults to `None`.
-    copy : bool
-        If `True`, the data array will be copied.  If `False`, the masked array
-        data will contain the same array as ``data``.  Defaults to `True`.
-
-    Returns
-    -------
-    filtered_data : `numpy.ma.MaskedArray`
-        A masked array with the same shape as ``data`` input, where the points
-        rejected by the algorithm have been masked.
-
-    Notes
-    -----
-     1. The routine works by calculating::
-
-            deviation = data - cenfunc(data [,axis=int])
-
-        and then setting a mask for points outside the range::
-
-            data.mask = deviation**2 > sig**2 * varfunc(deviation)
-
-        It will iterate a given number of times, or until no further points are
-        rejected.
-
-     2. Most numpy functions deal well with masked arrays, but if one would
-        like to have an array with just the good (or bad) values, one can use::
-
-            good_only = filtered_data.data[~filtered_data.mask]
-            bad_only = filtered_data.data[filtered_data.mask]
-
-        However, for multidimensional data, this flattens the array, which may
-        not be what one wants (especially is filtering was done along an axis).
-
-    Examples
-    --------
-
-    This will generate random variates from a Gaussian distribution and return
-    a masked array in which all points that are more than 2 *sample* standard
-    deviation from the median are masked::
-
-        >>> from astropy.stats import sigma_clip
-        >>> from numpy.random import randn
-        >>> randvar = randn(10000)
-        >>> filtered_data = sigma_clip(randvar, 2, 1)
-
-    This will clipping on a similar distribution, but for 3 sigma relative to
-    the sample *mean*, will clip until converged, and does not copy the data::
-
-        >>> from astropy.stats import sigma_clip
-        >>> from numpy.random import randn
-        >>> from numpy import mean
-        >>> randvar = randn(10000)
-        >>> filtered_data = sigma_clip(randvar, 3, None, mean, copy=False)
-
-    This will clip along one axis on a similar distribution with bad points
-    inserted::
-
-        >>> from astropy.stats import sigma_clip
-        >>> from numpy.random import normal
-        >>> from numpy import arange, diag, ones
-        >>> data = arange(5)+normal(0.,0.05,(5,5))+diag(ones(5))
-        >>> filtered_data = sigma_clip(data, axis=0, sig=2.3)
-
-    Note that along the other axis, no points would be masked, as the variance
-    is higher.
-
-    """
-
-    if axis is not None:
-        cenfunc_in = cenfunc
-        varfunc_in = varfunc
-        cenfunc = lambda d: np.expand_dims(cenfunc_in(d, axis=axis), axis=axis)
-        varfunc = lambda d: np.expand_dims(varfunc_in(d, axis=axis), axis=axis)
-
-    filtered_data = np.ma.array(data, copy=copy)
-
-    if iters is None:
-        i = -1
-        lastrej = filtered_data.count() + 1
-        while(filtered_data.count() != lastrej):
-            i += 1
-            lastrej = filtered_data.count()
-            do = filtered_data - cenfunc(filtered_data)
-            filtered_data.mask |= do * do > varfunc(filtered_data) * sig ** 2
-        iters = i + 1
-    else:
-        for i in range(iters):
-            do = filtered_data - cenfunc(filtered_data)
-            filtered_data.mask |= do * do > varfunc(filtered_data) * sig ** 2
+gaussian_sigma_to_fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0))
+"""
+Factor with which to multiply Gaussian 1-sigma standard deviation(s) to
+convert them to full width at half maximum(s).
+"""
 
-    return filtered_data
+gaussian_fwhm_to_sigma = 1. / gaussian_sigma_to_fwhm
+"""
+Factor with which to multiply Gaussian full width at half maximum(s) to
+convert them to 1-sigma standard deviation(s).
+"""
 
 
 # TODO Note scipy dependency
@@ -573,7 +452,7 @@ def median_absolute_deviation(a, axis=None):
 
     Parameters
     ----------
-    a : array_like
+    a : array-like
         Input array or object that can be converted to an array.
     axis : int, optional
         Axis along which the medians are computed. The default (axis=None)
@@ -642,16 +521,16 @@ def biweight_location(a, c=6.0, M=None):
 
     Parameters
     ----------
-    a : array_like
+    a : array-like
         Input array or object that can be converted to an array.
     c : float
         Tuning constant for the biweight estimator.  Default value is 6.0.
     M : float, optional
-        Initial gues for the biweight location.
+        Initial guess for the biweight location.
 
     Returns
     -------
-    biweight_location: float
+    biweight_location : float
         Returns the biweight location for the array elements.
 
     Examples
@@ -685,8 +564,8 @@ def biweight_location(a, c=6.0, M=None):
     # now remove the outlier points
     mask = np.abs(u) < 1
 
-    u = (1 - u**2)**2
-    return M+(d[mask]*u[mask]).sum()/u[mask].sum()
+    u = (1 - u ** 2) ** 2
+    return M + (d[mask] * u[mask]).sum() / u[mask].sum()
 
 
 def biweight_midvariance(a, c=9.0, M=None):
@@ -727,12 +606,12 @@ def biweight_midvariance(a, c=9.0, M=None):
 
     Parameters
     ----------
-    a : array_like
+    a : array-like
         Input array or object that can be converted to an array.
     c : float
         Tuning constant for the biweight estimator.  Default value is 9.0.
     M : float, optional
-        Initial gues for the biweight location.
+        Initial guess for the biweight location.
 
     Returns
     -------
@@ -769,9 +648,9 @@ def biweight_midvariance(a, c=9.0, M=None):
     # now remove the outlier points
     mask = np.abs(u) < 1
 
-    u = u**2
+    u = u ** 2
     n = mask.sum()
-    return n**0.5 * (d[mask] * d[mask] * (1 - u[mask])**4).sum()**0.5\
+    return n ** 0.5 * (d[mask] * d[mask] * (1 - u[mask]) ** 4).sum() ** 0.5\
         / np.abs(((1 - u[mask]) * (1 - 5 * u[mask])).sum())
 
 
@@ -798,10 +677,10 @@ def signal_to_noise_oir_ccd(t, source_eps, sky_eps, dark_eps, rd, npix,
         make sense.
     dark_eps : float
         Number of thermal electrons per second per pixel. If this is given in
-        DN or ADU, then multipy by the gain to get the value in electrons.
+        DN or ADU, then multiply by the gain to get the value in electrons.
     rd : float
         Read noise of the CCD in electrons. If this is given in
-        DN or ADU, then multipy by the gain to get the value in electrons.
+        DN or ADU, then multiply by the gain to get the value in electrons.
     npix : float
         Size of the aperture in pixels
     gain : float
@@ -812,9 +691,9 @@ def signal_to_noise_oir_ccd(t, source_eps, sky_eps, dark_eps, rd, npix,
     SNR : float or numpy.ndarray
         Signal to noise ratio calculated from the inputs
     """
-    signal = t*source_eps*gain
+    signal = t * source_eps * gain
     noise = np.sqrt(t * (source_eps * gain + npix *
-                         (sky_eps * gain + dark_eps)) + npix * rd**2)
+                         (sky_eps * gain + dark_eps)) + npix * rd ** 2)
     return signal / noise
 
 
@@ -830,7 +709,7 @@ def bootstrap(data, bootnum=100, samples=None, bootfunc=None):
     Parameters
     ----------
     data : numpy.ndarray
-        N-D array. The boostrap resampling will be performed on the first
+        N-D array. The bootstrap resampling will be performed on the first
         index, so the first index should access the relevant information
         to be bootstrapped.
     bootnum : int
@@ -871,3 +750,43 @@ def bootstrap(data, bootnum=100, samples=None, bootfunc=None):
             boot[i] = bootfunc(data[bootarr])
 
     return boot
+
+
+def mad_std(data):
+    """
+    Calculate a robust standard deviation using the `median absolute
+    deviation (MAD)
+    <http://en.wikipedia.org/wiki/Median_absolute_deviation>`_.
+
+    The standard deviation estimator is given by:
+
+    .. math::
+
+        \\sigma \\approx \\frac{\\textrm{MAD}}{\Phi^{-1}(3/4)} \\approx 1.4826 \ \\textrm{MAD}
+
+    where :math:`\Phi^{-1}(P)` is the normal inverse cumulative
+    distribution function evaluated at probability :math:`P = 3/4`.
+
+    Parameters
+    ----------
+    data : array-like
+        Data array or object that can be converted to an array.
+
+    Returns
+    -------
+    result : float
+        The robust standard deviation of the data.
+
+    Examples
+    --------
+    >>> from astropy.stats import mad_std
+    >>> from astropy.utils import NumpyRNGContext
+    >>> from numpy.random import normal
+    >>> with NumpyRNGContext(12345):
+    ...     data = normal(5, 2, size=(100, 100))
+    ...     mad_std(data)    # doctest: +FLOAT_CMP
+    2.02327646594
+    """
+
+    # NOTE: 1. / scipy.stats.norm.ppf(0.75) = 1.482602218505602
+    return median_absolute_deviation(data) * 1.482602218505602
diff --git a/astropy/stats/sigma_clipping.py b/astropy/stats/sigma_clipping.py
new file mode 100644
index 0000000..e3dd42a
--- /dev/null
+++ b/astropy/stats/sigma_clipping.py
@@ -0,0 +1,189 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+
+__all__ = ['sigma_clip', 'sigma_clipped_stats']
+
+
+def sigma_clip(data, sig=3, iters=1, cenfunc=np.ma.median, varfunc=np.var,
+               axis=None, copy=True):
+    """Perform sigma-clipping on the provided data.
+
+    This performs the sigma clipping algorithm - i.e. the data will be iterated
+    over, each time rejecting points that are more than a specified number of
+    standard deviations discrepant.
+
+    .. note::
+        `scipy.stats.sigmaclip
+        <http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.sigmaclip.html>`_
+        provides a subset of the functionality in this function.
+
+    Parameters
+    ----------
+    data : array-like
+        The data to be sigma-clipped (any shape).
+    sig : float
+        The number of standard deviations (*not* variances) to use as the
+        clipping limit.
+    iters : int or `None`
+        The number of iterations to perform clipping for, or `None` to clip
+        until convergence is achieved (i.e. continue until the last
+        iteration clips nothing).
+    cenfunc : callable
+        The technique to compute the center for the clipping. Must be a
+        callable that takes in a masked array and outputs the central value.
+        Defaults to the median (numpy.median).
+    varfunc : callable
+        The technique to compute the standard deviation about the center. Must
+        be a callable that takes in a masked array and outputs a width
+        estimator::
+
+             deviation**2 > sig**2 * varfunc(deviation)
+
+        Defaults to the variance (numpy.var).
+
+    axis : int or `None`
+        If not `None`, clip along the given axis.  For this case, axis=int will
+        be passed on to cenfunc and varfunc, which are expected to return an
+        array with the axis dimension removed (like the numpy functions).
+        If `None`, clip over all values.  Defaults to `None`.
+    copy : bool
+        If `True`, the data array will be copied.  If `False`, the masked array
+        data will contain the same array as ``data``.  Defaults to `True`.
+
+    Returns
+    -------
+    filtered_data : `numpy.ma.MaskedArray`
+        A masked array with the same shape as ``data`` input, where the points
+        rejected by the algorithm have been masked.
+
+    Notes
+    -----
+     1. The routine works by calculating::
+
+            deviation = data - cenfunc(data [,axis=int])
+
+        and then setting a mask for points outside the range::
+
+            data.mask = deviation**2 > sig**2 * varfunc(deviation)
+
+        It will iterate a given number of times, or until no further points are
+        rejected.
+
+     2. Most numpy functions deal well with masked arrays, but if one would
+        like to have an array with just the good (or bad) values, one can use::
+
+            good_only = filtered_data.data[~filtered_data.mask]
+            bad_only = filtered_data.data[filtered_data.mask]
+
+        However, for multidimensional data, this flattens the array, which may
+        not be what one wants (especially is filtering was done along an axis).
+
+    Examples
+    --------
+
+    This will generate random variates from a Gaussian distribution and return
+    a masked array in which all points that are more than 2 *sample* standard
+    deviation from the median are masked::
+
+        >>> from astropy.stats import sigma_clip
+        >>> from numpy.random import randn
+        >>> randvar = randn(10000)
+        >>> filtered_data = sigma_clip(randvar, 2, 1)
+
+    This will clipping on a similar distribution, but for 3 sigma relative to
+    the sample *mean*, will clip until converged, and does not copy the data::
+
+        >>> from astropy.stats import sigma_clip
+        >>> from numpy.random import randn
+        >>> from numpy import mean
+        >>> randvar = randn(10000)
+        >>> filtered_data = sigma_clip(randvar, 3, None, mean, copy=False)
+
+    This will clip along one axis on a similar distribution with bad points
+    inserted::
+
+        >>> from astropy.stats import sigma_clip
+        >>> from numpy.random import normal
+        >>> from numpy import arange, diag, ones
+        >>> data = arange(5)+normal(0.,0.05,(5,5))+diag(ones(5))
+        >>> filtered_data = sigma_clip(data, axis=0, sig=2.3)
+
+    Note that along the other axis, no points would be masked, as the variance
+    is higher.
+
+    """
+
+    if axis is not None:
+        cenfunc_in = cenfunc
+        varfunc_in = varfunc
+        cenfunc = lambda d: np.expand_dims(cenfunc_in(d, axis=axis), axis=axis)
+        varfunc = lambda d: np.expand_dims(varfunc_in(d, axis=axis), axis=axis)
+
+    filtered_data = np.ma.array(data, copy=copy)
+
+    if iters is None:
+        i = -1
+        lastrej = filtered_data.count() + 1
+        while filtered_data.count() != lastrej:
+            i += 1
+            lastrej = filtered_data.count()
+            do = filtered_data - cenfunc(filtered_data)
+            filtered_data.mask |= do * do > varfunc(filtered_data) * sig ** 2
+    else:
+        for i in range(iters):
+            do = filtered_data - cenfunc(filtered_data)
+            filtered_data.mask |= do * do > varfunc(filtered_data) * sig ** 2
+
+    return filtered_data
+
+
+def sigma_clipped_stats(data, mask=None, mask_val=None, sigma=3.0, iters=None):
+    """
+    Calculate sigma-clipped statistics from data.
+
+    For example, sigma-clipped statistics can be used to estimate the
+    background and background noise in an image.
+
+    Parameters
+    ----------
+    data : array-like
+        Data array or object that can be converted to an array.
+
+    mask : `numpy.ndarray` (bool), optional
+        A boolean mask with the same shape as ``data``, where a `True`
+        value indicates the corresponding element of ``data`` is masked.
+        Masked pixels are excluded when computing the image statistics.
+
+    mask_val : float, optional
+        An image data value (e.g., ``0.0``) that is ignored when
+        computing the image statistics.  ``mask_val`` will be masked in
+        addition to any input ``mask``.
+
+    sigma : float, optional
+        The number of standard deviations to use as the clipping limit.
+
+    iters : int, optional
+        The number of iterations to perform sigma clipping, or `None` to
+        clip until convergence is achieved (i.e., continue until the
+        last iteration clips nothing) when calculating the image
+        statistics.
+
+    Returns
+    -------
+    mean, median, stddev : float
+        The mean, median, and standard deviation of the sigma-clipped
+        image.
+    """
+
+    if mask is not None:
+        data = np.ma.MaskedArray(data, mask)
+    if mask_val is not None:
+        data = np.ma.masked_values(data, mask_val)
+    data_clip = sigma_clip(data, sig=sigma, iters=iters)
+    goodvals = data_clip.data[~data_clip.mask]
+    return np.mean(goodvals), np.median(goodvals), np.std(goodvals)
diff --git a/astropy/stats/tests/test_funcs.py b/astropy/stats/tests/test_funcs.py
index 62af0ed..06ded3b 100644
--- a/astropy/stats/tests/test_funcs.py
+++ b/astropy/stats/tests/test_funcs.py
@@ -5,65 +5,21 @@ from __future__ import (absolute_import, division, print_function,
 
 import numpy as np
 
-from numpy.random import randn
+from numpy.random import randn, normal
 from numpy.testing import assert_equal
 from numpy.testing.utils import assert_allclose
 
-from ...tests.helper import pytest
-
-from .. import funcs
-from ...utils.misc import NumpyRNGContext
-
 try:
-    from scipy import stats  # used in testing
+    import scipy
 except ImportError:
     HAS_SCIPY = False
 else:
     HAS_SCIPY = True
 
+from ...tests.helper import pytest
 
-def test_sigma_clip():
-    #need to seed the numpy RNG to make sure we don't get some amazingly flukey
-    #random number that breaks one of the tests
-
-    with NumpyRNGContext(12345):
-        # Amazing, I've got the same combination on my luggage!
-        randvar = randn(10000)
-
-        filtered_data = funcs.sigma_clip(randvar, 1, 2)
-
-        assert sum(filtered_data.mask) > 0
-        assert sum(~filtered_data.mask) < randvar.size
-
-        #this is actually a silly thing to do, because it uses the standard
-        #deviation as the variance, but it tests to make sure these arguments
-        #are actually doing something
-        filtered_data2 = funcs.sigma_clip(randvar, 1, 2, varfunc=np.std)
-        assert not np.all(filtered_data.mask == filtered_data2.mask)
-
-        filtered_data3 = funcs.sigma_clip(randvar, 1, 2, cenfunc=np.mean)
-        assert not np.all(filtered_data.mask == filtered_data3.mask)
-
-        # make sure the iters=None method works at all.
-        filtered_data = funcs.sigma_clip(randvar, 3, None)
-
-        # test copying
-        assert filtered_data.data[0] == randvar[0]
-        filtered_data.data[0] += 1.
-        assert filtered_data.data[0] != randvar[0]
-
-        filtered_data = funcs.sigma_clip(randvar, 3, None, copy=False)
-        assert filtered_data.data[0] == randvar[0]
-        filtered_data.data[0] += 1.
-        assert filtered_data.data[0] == randvar[0]
-
-        # test axis
-        data = np.arange(5) + np.random.normal(0., 0.05, (5, 5)) + \
-            np.diag(np.ones(5))
-        filtered_data = funcs.sigma_clip(data, axis=0, sig=2.3)
-        assert filtered_data.count() == 20
-        filtered_data = funcs.sigma_clip(data, axis=1, sig=2.3)
-        assert filtered_data.count() == 25
+from .. import funcs
+from ...utils.misc import NumpyRNGContext
 
 
 def test_median_absolute_deviation():
@@ -142,22 +98,6 @@ def test_biweight_midvariance_small():
 
 
 @pytest.mark.skipif('not HAS_SCIPY')
-def test_compare_to_scipy_sigmaclip():
-    #need to seed the numpy RNG to make sure we don't get some amazingly flukey
-    #random number that breaks one of the tests
-
-    with NumpyRNGContext(12345):
-
-        randvar = randn(10000)
-
-        astropyres = funcs.sigma_clip(randvar, 3, None, np.mean)
-        scipyres = stats.sigmaclip(randvar, 3, 3)[0]
-
-        assert astropyres.count() == len(scipyres)
-        assert_equal(astropyres[~astropyres.mask].data, scipyres)
-
-
- at pytest.mark.skipif('not HAS_SCIPY')
 def test_binom_conf_interval():
 
     # Test Wilson and Jeffreys interval for corner cases:
@@ -196,7 +136,7 @@ def test_binom_conf_interval():
     result = np.array([funcs.binom_conf_interval(kval, n, conf=conf,
                                                  interval='flat')
                        for kval in k]).transpose()
-    assert_allclose(result, table, atol=1.e-3, rtol=0.)    
+    assert_allclose(result, table, atol=1.e-3, rtol=0.)
 
     # Test Wald interval
     result = funcs.binom_conf_interval(0, 5, interval='wald')
@@ -224,7 +164,7 @@ def test_binom_conf_interval():
     for interval in ['wald', 'wilson', 'jeffreys', 'flat']:
         result = funcs.binom_conf_interval(k, n, interval=interval)
         assert result.shape == (2,)
-        
+
     k = np.array([1, 3, 5])
     for interval in ['wald', 'wilson', 'jeffreys', 'flat']:
         result = funcs.binom_conf_interval(k, n, interval=interval)
@@ -295,3 +235,24 @@ def test_bootstrap():
     with NumpyRNGContext(42):
         bootresult = np.mean(funcs.bootstrap(bootarr, 10000, bootfunc=np.mean))
         assert_allclose(np.mean(bootarr), bootresult, atol=0.01)
+
+
+def test_mad_std():
+    with NumpyRNGContext(12345):
+        data = normal(5, 2, size=(100, 100))
+        assert_allclose(funcs.mad_std(data), 2.0, rtol=0.05)
+
+
+def test_gaussian_fwhm_to_sigma():
+    fwhm = (2.0 * np.sqrt(2.0 * np.log(2.0)))
+    assert_allclose(funcs.gaussian_fwhm_to_sigma * fwhm, 1.0, rtol=1.0e-6)
+
+
+def test_gaussian_sigma_to_fwhm():
+    sigma = 1.0 / (2.0 * np.sqrt(2.0 * np.log(2.0)))
+    assert_allclose(funcs.gaussian_sigma_to_fwhm * sigma, 1.0, rtol=1.0e-6)
+
+
+def test_gaussian_sigma_to_fwhm_to_sigma():
+    assert_allclose(funcs.gaussian_fwhm_to_sigma *
+                    funcs.gaussian_sigma_to_fwhm, 1.0)
diff --git a/astropy/stats/tests/test_sigma_clipping.py b/astropy/stats/tests/test_sigma_clipping.py
new file mode 100644
index 0000000..f21a527
--- /dev/null
+++ b/astropy/stats/tests/test_sigma_clipping.py
@@ -0,0 +1,98 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import numpy as np
+
+from numpy.random import randn
+from numpy.testing import assert_equal
+
+try:
+    from scipy import stats  # used in testing
+except ImportError:
+    HAS_SCIPY = False
+else:
+    HAS_SCIPY = True
+
+from ...tests.helper import pytest
+
+from ..sigma_clipping import sigma_clip, sigma_clipped_stats
+from ...utils.misc import NumpyRNGContext
+
+
+def test_sigma_clip():
+    #need to seed the numpy RNG to make sure we don't get some amazingly flukey
+    #random number that breaks one of the tests
+
+    with NumpyRNGContext(12345):
+        # Amazing, I've got the same combination on my luggage!
+        randvar = randn(10000)
+
+        filtered_data = sigma_clip(randvar, 1, 2)
+
+        assert sum(filtered_data.mask) > 0
+        assert sum(~filtered_data.mask) < randvar.size
+
+        #this is actually a silly thing to do, because it uses the standard
+        #deviation as the variance, but it tests to make sure these arguments
+        #are actually doing something
+        filtered_data2 = sigma_clip(randvar, 1, 2, varfunc=np.std)
+        assert not np.all(filtered_data.mask == filtered_data2.mask)
+
+        filtered_data3 = sigma_clip(randvar, 1, 2, cenfunc=np.mean)
+        assert not np.all(filtered_data.mask == filtered_data3.mask)
+
+        # make sure the iters=None method works at all.
+        filtered_data = sigma_clip(randvar, 3, None)
+
+        # test copying
+        assert filtered_data.data[0] == randvar[0]
+        filtered_data.data[0] += 1.
+        assert filtered_data.data[0] != randvar[0]
+
+        filtered_data = sigma_clip(randvar, 3, None, copy=False)
+        assert filtered_data.data[0] == randvar[0]
+        filtered_data.data[0] += 1.
+        assert filtered_data.data[0] == randvar[0]
+
+        # test axis
+        data = np.arange(5) + np.random.normal(0., 0.05, (5, 5)) + \
+            np.diag(np.ones(5))
+        filtered_data = sigma_clip(data, axis=0, sig=2.3)
+        assert filtered_data.count() == 20
+        filtered_data = sigma_clip(data, axis=1, sig=2.3)
+        assert filtered_data.count() == 25
+
+
+ at pytest.mark.skipif('not HAS_SCIPY')
+def test_compare_to_scipy_sigmaclip():
+    #need to seed the numpy RNG to make sure we don't get some amazingly flukey
+    #random number that breaks one of the tests
+
+    with NumpyRNGContext(12345):
+
+        randvar = randn(10000)
+
+        astropyres = sigma_clip(randvar, 3, None, np.mean)
+        scipyres = stats.sigmaclip(randvar, 3, 3)[0]
+
+        assert astropyres.count() == len(scipyres)
+        assert_equal(astropyres[~astropyres.mask].data, scipyres)
+
+
+def test_sigma_clipped_stats():
+    """Test list data with input mask or mask_val (#3268)."""
+    # test list data with mask
+    data = [0, 1]
+    mask = np.array([True, False])
+    result = sigma_clipped_stats(data, mask=mask)
+    assert result[0] == 1.
+    assert result[1] == 1.
+    assert result[2] == 0.
+
+    # test list data with mask_val
+    result2 = sigma_clipped_stats(data, mask_val=0.)
+    assert result2[0] == 1.
+    assert result2[1] == 1.
+    assert result2[2] == 0.
diff --git a/astropy/table/__init__.py b/astropy/table/__init__.py
index 250e1e4..d30d33e 100644
--- a/astropy/table/__init__.py
+++ b/astropy/table/__init__.py
@@ -20,12 +20,12 @@ conf = Conf()
 
 from .column import Column, MaskedColumn
 from .groups import TableGroups, ColumnGroups
-from .table import Table, TableColumns, Row, TableFormatter
-from .np_utils import TableMergeError
-from .operations import join, hstack, vstack
+from .table import Table, QTable, TableColumns, Row, TableFormatter
+from .operations import join, hstack, vstack, unique, TableMergeError
 
 # Import routines that connect readers/writers to astropy.table
 from ..io.ascii import connect
 from ..io.fits import connect
 from ..io.misc import connect
 from ..io.votable import connect
+from . import jsviewer
diff --git a/astropy/table/_np_utils.c b/astropy/table/_np_utils.c
index dd75136..4ae9d01 100644
--- a/astropy/table/_np_utils.c
+++ b/astropy/table/_np_utils.c
@@ -481,7 +481,7 @@ typedef struct {
 } __Pyx_BufFmt_Context;
 
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -490,7 +490,7 @@ typedef struct {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -499,7 +499,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -508,7 +508,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -517,7 +517,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -526,7 +526,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -535,7 +535,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -544,7 +544,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -553,7 +553,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -562,7 +562,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -571,7 +571,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -580,7 +580,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -589,7 +589,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -598,7 +598,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -607,7 +607,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -616,7 +616,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -625,7 +625,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -634,7 +634,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -643,7 +643,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -652,7 +652,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -661,7 +661,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -701,7 +701,7 @@ typedef __pyx_t_5numpy_intp_t __pyx_t_7astropy_5table_9_np_utils_DTYPE_t;
 
 /*--- Type declarations ---*/
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -710,7 +710,7 @@ typedef __pyx_t_5numpy_intp_t __pyx_t_7astropy_5table_9_np_utils_DTYPE_t;
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -719,7 +719,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -728,7 +728,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -1159,8 +1159,8 @@ static char __pyx_k_max_key_idxs[] = "max_key_idxs";
 static char __pyx_k_numpy_lib_recfunctions[] = "numpy.lib.recfunctions";
 static char __pyx_k_astropy_table__np_utils[] = "astropy.table._np_utils";
 static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Users_erik_src_astropy_astropy[] = "/Users/erik/src/astropy/astropy/table/_np_utils.pyx";
 static char __pyx_k_Cython_utilities_for_numpy_stru[] = "\nCython utilities for numpy structured arrays.\n\njoin_inner():  Do the inner-loop cartesian product for np_utils.join() processing.\n               (The \"inner\" is about the inner loop, not inner join).\n";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/table/_np_utils.pyx";
 static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
 static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
@@ -1171,6 +1171,7 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
 static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
 static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
 static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Users_erik_src_astropy_astropy;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s__7;
 static PyObject *__pyx_n_s_astropy_table__np_utils;
@@ -1190,7 +1191,6 @@ static PyObject *__pyx_n_s_idxs;
 static PyObject *__pyx_n_s_ii;
 static PyObject *__pyx_n_s_import;
 static PyObject *__pyx_n_s_int;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
 static PyObject *__pyx_n_s_join_inner;
 static PyObject *__pyx_n_s_jointype;
 static PyObject *__pyx_n_s_key_idxs;
@@ -2480,7 +2480,7 @@ static PyObject *__pyx_pf_7astropy_5table_9_np_utils_join_inner(CYTHON_UNUSED Py
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -2530,7 +2530,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __Pyx_GIVEREF(__pyx_v_info->obj);
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
  *             # of flags
  * 
  *             if info == NULL: return             # <<<<<<<<<<<<<<
@@ -2543,7 +2543,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
  * 
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -2552,7 +2552,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
  *             cdef int copy_shape, i, ndim
  *             cdef int endian_detector = 1
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -2561,7 +2561,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
  *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
  *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
@@ -2570,7 +2570,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
  *             ndim = PyArray_NDIM(self)
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -2580,7 +2580,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
  * 
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 copy_shape = 1             # <<<<<<<<<<<<<<
@@ -2592,7 +2592,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
  *                 copy_shape = 1
  *             else:
  *                 copy_shape = 0             # <<<<<<<<<<<<<<
@@ -2603,7 +2603,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
  *                 copy_shape = 0
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -2617,7 +2617,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L6_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
  * 
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -2629,7 +2629,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L6_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -2643,7 +2643,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
@@ -2657,7 +2657,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     goto __pyx_L9_bool_binop_done;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
@@ -2669,7 +2669,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L9_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -2683,7 +2683,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
@@ -2692,7 +2692,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
  * 
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim             # <<<<<<<<<<<<<<
@@ -2701,7 +2701,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->ndim = __pyx_v_ndim;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
  *             info.buf = PyArray_DATA(self)
  *             info.ndim = ndim
  *             if copy_shape:             # <<<<<<<<<<<<<<
@@ -2711,7 +2711,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = (__pyx_v_copy_shape != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
@@ -2720,7 +2720,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
  *                 # This is allocated as one block, strides first.
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
@@ -2729,7 +2729,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
  *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):             # <<<<<<<<<<<<<<
@@ -2740,7 +2740,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
       __pyx_v_i = __pyx_t_5;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
  *                 info.shape = info.strides + ndim
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
@@ -2749,7 +2749,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
       (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
  *                 for i in range(ndim):
  *                     info.strides[i] = PyArray_STRIDES(self)[i]
  *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
@@ -2762,7 +2762,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
  *                     info.shape[i] = PyArray_DIMS(self)[i]
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
@@ -2771,7 +2771,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
  *             else:
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
@@ -2782,7 +2782,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L11:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
  *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
@@ -2791,7 +2791,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->suboffsets = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
  *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
@@ -2800,7 +2800,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
  *             info.suboffsets = NULL
  *             info.itemsize = PyArray_ITEMSIZE(self)
  *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
@@ -2809,7 +2809,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
  * 
  *             cdef int t
  *             cdef char* f = NULL             # <<<<<<<<<<<<<<
@@ -2818,7 +2818,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_f = NULL;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
  *             cdef int t
  *             cdef char* f = NULL
  *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
@@ -2830,7 +2830,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
  *             cdef int offset
  * 
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
@@ -2839,7 +2839,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
   __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
  *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
  * 
  *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
@@ -2857,7 +2857,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_L15_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
  *             if not hasfields and not copy_shape:
  *                 # do not call releasebuffer
  *                 info.obj = None             # <<<<<<<<<<<<<<
@@ -2873,7 +2873,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
  *             else:
  *                 # need to call releasebuffer
  *                 info.obj = self             # <<<<<<<<<<<<<<
@@ -2888,7 +2888,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   __pyx_L14:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
  *                 info.obj = self
  * 
  *             if not hasfields:             # <<<<<<<<<<<<<<
@@ -2898,7 +2898,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
  * 
  *             if not hasfields:
  *                 t = descr.type_num             # <<<<<<<<<<<<<<
@@ -2908,7 +2908,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_4 = __pyx_v_descr->type_num;
     __pyx_v_t = __pyx_t_4;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
  *             if not hasfields:
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -2928,7 +2928,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L20_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -2946,7 +2946,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_L19_bool_binop_done:;
     if (__pyx_t_1) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -2960,7 +2960,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -2969,7 +2969,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     switch (__pyx_v_t) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
@@ -2980,7 +2980,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_b;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
@@ -2991,7 +2991,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_B;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
@@ -3002,7 +3002,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_h;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
@@ -3013,7 +3013,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_H;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
@@ -3024,7 +3024,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_i;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
@@ -3035,7 +3035,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_I;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
@@ -3046,7 +3046,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_l;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
@@ -3057,7 +3057,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_L;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
@@ -3068,7 +3068,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
@@ -3079,7 +3079,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Q;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
@@ -3090,7 +3090,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_f;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
@@ -3101,7 +3101,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_d;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
@@ -3112,7 +3112,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_g;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
@@ -3123,7 +3123,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zf;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
@@ -3134,7 +3134,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zd;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
@@ -3145,7 +3145,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __pyx_v_f = __pyx_k_Zg;
       break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
@@ -3157,7 +3157,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
       default:
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -3183,7 +3183,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       break;
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f             # <<<<<<<<<<<<<<
@@ -3192,7 +3192,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = __pyx_v_f;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *                 info.format = f
  *                 return             # <<<<<<<<<<<<<<
@@ -3204,7 +3204,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
  *                 return
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
@@ -3213,7 +3213,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_info->format = ((char *)malloc(255));
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
  *             else:
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
@@ -3222,7 +3222,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     (__pyx_v_info->format[0]) = '^';
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
  *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0             # <<<<<<<<<<<<<<
@@ -3231,7 +3231,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  */
     __pyx_v_offset = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
  *                 info.format[0] = c'^' # Native data types, manual alignment
  *                 offset = 0
  *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
@@ -3241,7 +3241,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_f = __pyx_t_7;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
  *                                       info.format + _buffer_format_string_len,
  *                                       &offset)
  *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
@@ -3251,7 +3251,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     (__pyx_v_f[0]) = '\x00';
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
  *         # experimental exception made for __getbuffer__ and __releasebuffer__
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
@@ -3283,7 +3283,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -3307,7 +3307,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
@@ -3317,7 +3317,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
  *         def __releasebuffer__(ndarray self, Py_buffer* info):
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
@@ -3329,7 +3329,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
  *             if PyArray_HASFIELDS(self):
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
@@ -3339,7 +3339,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
@@ -3351,7 +3351,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   }
   __pyx_L4:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
  *                 f[0] = c'\0' # Terminate format string
  * 
  *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
@@ -3363,7 +3363,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -3380,7 +3380,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
  * 
  * cdef inline object PyArray_MultiIterNew1(a):
  *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
@@ -3394,7 +3394,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_cdouble     complex_t
  * 
  * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
@@ -3413,7 +3413,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -3430,7 +3430,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
@@ -3444,7 +3444,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
  *     return PyArray_MultiIterNew(1, <void*>a)
  * 
  * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
@@ -3463,7 +3463,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -3480,7 +3480,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
@@ -3494,7 +3494,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
  *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
  * 
  * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
@@ -3513,7 +3513,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -3530,7 +3530,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
@@ -3544,7 +3544,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
  *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
  * 
  * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
@@ -3563,7 +3563,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -3580,7 +3580,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
@@ -3594,7 +3594,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
  *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
  * 
  * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
@@ -3613,7 +3613,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -3645,7 +3645,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_util_dtypestring", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
  *     cdef int delta_offset
  *     cdef tuple i
  *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
@@ -3654,7 +3654,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_endian_detector = 1;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
  *     cdef tuple i
  *     cdef int endian_detector = 1
  *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
@@ -3663,7 +3663,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
   __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -3685,7 +3685,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
  * 
  *     for childname in descr.names:
  *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
@@ -3698,7 +3698,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
  *     for childname in descr.names:
  *         fields = descr.fields[childname]
  *         child, new_offset = fields             # <<<<<<<<<<<<<<
@@ -3737,7 +3737,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
  *         child, new_offset = fields
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
@@ -3754,7 +3754,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -3768,7 +3768,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
  * 
  *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
@@ -3788,7 +3788,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L8_next_or:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
@@ -3806,7 +3806,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_L7_bool_binop_done:;
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -3820,7 +3820,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
  * 
  *         # Output padding bytes
  *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
@@ -3836,7 +3836,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (!__pyx_t_6) break;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
  *         # Output padding bytes
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
@@ -3845,7 +3845,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       (__pyx_v_f[0]) = 120;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
  *         while offset[0] < new_offset:
  *             f[0] = 120 # "x"; pad byte
  *             f += 1             # <<<<<<<<<<<<<<
@@ -3854,7 +3854,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  */
       __pyx_v_f = (__pyx_v_f + 1);
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
  *             f[0] = 120 # "x"; pad byte
  *             f += 1
  *             offset[0] += 1             # <<<<<<<<<<<<<<
@@ -3865,7 +3865,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
     }
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
  *             offset[0] += 1
  * 
  *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
@@ -3875,7 +3875,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_8 = 0;
     (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
  *         offset[0] += child.itemsize
  * 
  *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
@@ -3885,7 +3885,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_6) {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
  * 
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num             # <<<<<<<<<<<<<<
@@ -3897,7 +3897,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
  *         if not PyDataType_HASFIELDS(child):
  *             t = child.type_num
  *             if end - f < 5:             # <<<<<<<<<<<<<<
@@ -3907,7 +3907,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_6) {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -3921,7 +3921,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
@@ -3939,7 +3939,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
@@ -3957,7 +3957,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
  *             if   t == NPY_BYTE:        f[0] =  98 #"b"
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
@@ -3975,7 +3975,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
  *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
@@ -3993,7 +3993,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
  *             elif t == NPY_SHORT:       f[0] = 104 #"h"
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
@@ -4011,7 +4011,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
  *             elif t == NPY_USHORT:      f[0] =  72 #"H"
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
@@ -4029,7 +4029,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
  *             elif t == NPY_INT:         f[0] = 105 #"i"
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
@@ -4047,7 +4047,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
  *             elif t == NPY_UINT:        f[0] =  73 #"I"
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
@@ -4065,7 +4065,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
  *             elif t == NPY_LONG:        f[0] = 108 #"l"
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
@@ -4083,7 +4083,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
  *             elif t == NPY_ULONG:       f[0] = 76  #"L"
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
@@ -4101,7 +4101,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
  *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
@@ -4119,7 +4119,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
  *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
@@ -4137,7 +4137,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
  *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
@@ -4155,7 +4155,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
  *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
@@ -4175,7 +4175,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
  *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
@@ -4195,7 +4195,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
  *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
@@ -4215,7 +4215,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
         goto __pyx_L15;
       }
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
  *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
  *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
@@ -4234,7 +4234,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       /*else*/ {
 
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
+        /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
  *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
@@ -4257,7 +4257,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       }
       __pyx_L15:;
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
  *             else:
  *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  *             f += 1             # <<<<<<<<<<<<<<
@@ -4269,7 +4269,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     /*else*/ {
 
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
+      /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
  *             # Cython ignores struct boundary information ("T{...}"),
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
@@ -4281,7 +4281,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
     }
     __pyx_L13:;
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
  *     cdef tuple fields
  * 
  *     for childname in descr.names:             # <<<<<<<<<<<<<<
@@ -4291,7 +4291,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
  *             # so don't output it
  *             f = _util_dtypestring(child, f, end, offset)
  *     return f             # <<<<<<<<<<<<<<
@@ -4301,7 +4301,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   __pyx_r = __pyx_v_f;
   goto __pyx_L0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
  *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
  * 
  * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
@@ -4326,7 +4326,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
   return __pyx_r;
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -4341,7 +4341,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
  * cdef inline void set_array_base(ndarray arr, object base):
  *      cdef PyObject* baseptr
  *      if base is None:             # <<<<<<<<<<<<<<
@@ -4352,7 +4352,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
  *      cdef PyObject* baseptr
  *      if base is None:
  *          baseptr = NULL             # <<<<<<<<<<<<<<
@@ -4364,7 +4364,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
  *          baseptr = NULL
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
@@ -4373,7 +4373,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
     Py_INCREF(__pyx_v_base);
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
  *      else:
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
@@ -4384,7 +4384,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   }
   __pyx_L3:;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
  *          Py_INCREF(base) # important to do this before decref below!
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
@@ -4393,7 +4393,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   Py_XDECREF(__pyx_v_arr->base);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
  *          baseptr = <PyObject*>base
  *      Py_XDECREF(arr.base)
  *      arr.base = baseptr             # <<<<<<<<<<<<<<
@@ -4402,7 +4402,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  */
   __pyx_v_arr->base = __pyx_v_baseptr;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
  * 
  * 
  * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
@@ -4414,7 +4414,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   __Pyx_RefNannyFinishContext();
 }
 
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+/* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -4428,7 +4428,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("get_array_base", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
  * 
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:             # <<<<<<<<<<<<<<
@@ -4438,7 +4438,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
  * cdef inline object get_array_base(ndarray arr):
  *     if arr.base is NULL:
  *         return None             # <<<<<<<<<<<<<<
@@ -4452,7 +4452,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
   }
   /*else*/ {
 
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
+    /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
  *         return None
  *     else:
  *         return <object>arr.base             # <<<<<<<<<<<<<<
@@ -4463,7 +4463,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
     goto __pyx_L0;
   }
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
@@ -4506,6 +4506,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
   {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_k_Users_erik_src_astropy_astropy, sizeof(__pyx_k_Users_erik_src_astropy_astropy), 0, 0, 1, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 0, 1, 1},
   {&__pyx_n_s_astropy_table__np_utils, __pyx_k_astropy_table__np_utils, sizeof(__pyx_k_astropy_table__np_utils), 0, 0, 1, 1},
@@ -4525,7 +4526,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_ii, __pyx_k_ii, sizeof(__pyx_k_ii), 0, 0, 1, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
   {&__pyx_n_s_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
   {&__pyx_n_s_join_inner, __pyx_k_join_inner, sizeof(__pyx_k_join_inner), 0, 0, 1, 1},
   {&__pyx_n_s_jointype, __pyx_k_jointype, sizeof(__pyx_k_jointype), 0, 0, 1, 1},
   {&__pyx_n_s_key_idxs, __pyx_k_key_idxs, sizeof(__pyx_k_key_idxs), 0, 0, 1, 1},
@@ -4568,7 +4568,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
  *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
@@ -4579,7 +4579,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple_);
   __Pyx_GIVEREF(__pyx_tuple_);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
@@ -4590,7 +4590,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__2);
   __Pyx_GIVEREF(__pyx_tuple__2);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
  *                 if ((descr.byteorder == c'>' and little_endian) or
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4601,7 +4601,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
  * 
  *         if (end - f) - <int>(new_offset - offset[0]) < 15:
  *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
@@ -4612,7 +4612,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__4);
   __Pyx_GIVEREF(__pyx_tuple__4);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
  *         if ((child.byteorder == c'>' and little_endian) or
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
@@ -4623,7 +4623,7 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
  *             t = child.type_num
  *             if end - f < 5:
  *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
@@ -4644,7 +4644,7 @@ static int __Pyx_InitCachedConstants(void) {
   __pyx_tuple__8 = PyTuple_Pack(24, __pyx_n_s_idxs, __pyx_n_s_idx_sort, __pyx_n_s_len_left, __pyx_n_s_jointype, __pyx_n_s_n_out, __pyx_n_s_max_key_idxs, __pyx_n_s_ii, __pyx_n_s_key_idxs, __pyx_n_s_n_left, __pyx_n_s_n_right, __pyx_n_s_idx0, __pyx_n_s_idx1, __pyx_n_s_idx, __pyx_n_s_i, __pyx_n_s_i_left, __pyx_n_s_i_right, __pyx_n_s_i_out, __pyx_n_s_masked, __pyx_n_s_left_out, __pyx_n_s_right_out, __pyx_n_s_left_mask, __pyx_n_s_right_mask, __pyx_n_s_left_idxs, __pyx_n_s_right_idxs); if (unli [...]
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
-  __pyx_codeobj__9 = (PyObject*)__Pyx_PyCode_New(4, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__8, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_join_inner, 19, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_codeobj__9 = (PyObject*)__Pyx_PyCode_New(4, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__8, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_erik_src_astropy_astropy, __pyx_n_s_join_inner, 19, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -4847,7 +4847,7 @@ PyMODINIT_FUNC PyInit__np_utils(void)
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
+  /* "../../../../opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
  *      arr.base = baseptr
  * 
  * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
diff --git a/astropy/table/column.py b/astropy/table/column.py
index b1edd8a..6e79d30 100644
--- a/astropy/table/column.py
+++ b/astropy/table/column.py
@@ -3,8 +3,6 @@ from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 from ..extern import six
 
-import operator
-
 import weakref
 
 from copy import deepcopy
@@ -14,7 +12,6 @@ import numpy as np
 from numpy import ma
 
 from ..units import Unit, Quantity
-from ..utils import deprecated
 from ..utils.console import color_print
 from ..utils.metadata import MetaData
 from . import groups
@@ -32,7 +29,7 @@ AUTO_COLNAME = ConfigAlias(
 # Create a generic TableFormatter object for use by bare columns with no
 # parent table.
 FORMATTER = pprint.TableFormatter()
-
+INTEGER_TYPES = (int, long, np.integer) if six.PY2 else (int, np.integer)
 
 def _auto_names(n_cols):
     from . import conf
@@ -48,13 +45,137 @@ _comparison_functions = set(
      np.isfinite, np.isinf, np.isnan, np.sign, np.signbit])
 
 
+COLUMN_ATTRS = set(['name', 'unit', 'dtype', 'format', 'description', 'meta', 'parent_table'])
+
+def col_setattr(col, attr, value):
+    """
+    Set one of the column attributes.
+
+    Warning: this function is subject to change or removal.
+    """
+    if attr not in COLUMN_ATTRS:
+        raise AttributeError("attribute must be one of {0}".format(COLUMN_ATTRS))
+
+    # The unit and dtype attributes are considered universal and do NOT get
+    # stored in _astropy_column_attrs.  For BaseColumn instances use the usual setattr.
+    if isinstance(col, BaseColumn):
+        setattr(col, attr, value)
+    else:
+        # If no _astropy_column_attrs or it is None then convert to dict
+        if getattr(col, '_astropy_column_attrs', None) is None:
+            col._astropy_column_attrs = {}
+        if attr == 'parent_table':
+            value = None if value is None else weakref.ref(value)
+        col._astropy_column_attrs[attr] = value
+
+def col_getattr(col, attr, default=None):
+    """
+    Get one of the column attributes
+
+    Warning: this function is subject to change or removal.
+    """
+    if attr not in COLUMN_ATTRS:
+        raise AttributeError("attribute must be one of {0}".format(COLUMN_ATTRS))
+
+    # The unit and dtype attributes are considered universal and do NOT get
+    # stored in _astropy_column_attrs.  For BaseColumn instances use the usual setattr.
+    if (isinstance(col, BaseColumn) or
+            (isinstance(col, Quantity) and attr in ('dtype', 'unit'))):
+        value = getattr(col, attr, default)
+    else:
+        # If col does not have _astropy_column_attrs or it is None (meaning
+        # nothing has been set yet) then return default, otherwise look for
+        # the attribute in the astropy_column_attrs dict.
+        if getattr(col, '_astropy_column_attrs', None) is None:
+            value = default
+        else:
+            value = col._astropy_column_attrs.get(attr, default)
+
+        # Weak ref for parent table
+        if attr == 'parent_table' and callable(value):
+            value = value()
+
+        # Mixins have a default dtype of Object if nothing else was set
+        if attr == 'dtype' and value is None:
+            value = np.dtype('O')
+
+    return value
+
+def _col_update_attrs_from(newcol, col, exclude_attrs=['name', 'parent_table']):
+    """
+    Update _astropy_column_attrs from mixin `col` to `newcol`.  Does nothing
+    for BaseColumn cols
+
+    Warning: this function is subject to change or removal.
+    """
+    if isinstance(newcol, BaseColumn):
+        return
+
+    attrs = COLUMN_ATTRS - set(exclude_attrs)
+    for attr in attrs:
+        val = col_getattr(col, attr)
+        if val is not None:
+            col_setattr(newcol, attr, deepcopy(val))
+
+def col_iter_str_vals(col):
+    """
+    This is a mixin-safe version of Column.iter_str_vals.
+
+    Warning: this function is subject to change or removal.
+    """
+    parent_table = col_getattr(col, 'parent_table')
+    formatter = FORMATTER if parent_table is None else parent_table.formatter
+    _pformat_col_iter = formatter._pformat_col_iter
+    for str_val in _pformat_col_iter(col, -1, False, False, {}):
+        yield str_val
+
+def col_copy(col):
+    """
+    This is a mixin-safe version of Column.copy() (with copy_data=True).
+
+    Warning: this function is subject to change or removal.
+    """
+    if isinstance(col, BaseColumn):
+        return col.copy()
+
+    if hasattr(col, '_astropy_column_attrs'):
+        col_setattr(col, 'parent_table', None)  # Don't copy weakref to parent table
+    newcol = col.copy() if hasattr(col, 'copy') else deepcopy(col)
+
+    # Copy old attributes.  Even deepcopy above may not get this (e.g. pandas).
+    if (not hasattr(newcol, '_astropy_column_attrs') or
+            newcol._astropy_column_attrs is None):
+        _column_attrs = deepcopy(getattr(col, '_astropy_column_attrs', {}))
+        newcol._astropy_column_attrs = _column_attrs
+
+    return newcol
+
+
+class FalseArray(np.ndarray):
+    def __new__(cls, shape):
+        obj = np.zeros(shape, dtype=np.bool).view(cls)
+        return obj
+
+    def __setitem__(self, item, val):
+        val = np.asarray(val)
+        if np.any(val):
+            raise ValueError('Cannot set any element of {0} class to True'
+                             .format(self.__class__.__name__))
+
+    def __setslice__(self, start, stop, val):
+        val = np.asarray(val)
+        if np.any(val):
+            raise ValueError('Cannot set any element of {0} class to True'
+                             .format(self.__class__.__name__))
+
+
 class BaseColumn(np.ndarray):
 
     meta = MetaData()
 
     def __new__(cls, data=None, name=None,
                 dtype=None, shape=(), length=0,
-                description=None, unit=None, format=None, meta=None):
+                description=None, unit=None, format=None, meta=None, copy=False):
 
         if data is None:
             dtype = (np.dtype(dtype).str, shape)
@@ -64,7 +185,7 @@ class BaseColumn(np.ndarray):
             # BaseColumn with none of the expected attributes.  In this case
             # do NOT execute this block which initializes from ``data``
             # attributes.
-            self_data = np.asarray(data.data, dtype=dtype)
+            self_data = np.array(data.data, dtype=dtype, copy=copy)
             if description is None:
                 description = data.description
             if unit is None:
@@ -77,12 +198,19 @@ class BaseColumn(np.ndarray):
                 name = data.name
         elif isinstance(data, Quantity):
             if unit is None:
-                self_data = np.asarray(data, dtype=dtype)
+                self_data = np.array(data, dtype=dtype, copy=copy)
                 unit = data.unit
             else:
-                self_data = np.asarray(data.to(unit), dtype=dtype)
+                self_data = np.array(data.to(unit), dtype=dtype, copy=copy)
+            if description is None:
+                description = col_getattr(data, 'description')
+            if format is None:
+                format = col_getattr(data, 'format')
+            if meta is None:
+                meta = deepcopy(col_getattr(data, 'meta'))
+
         else:
-            self_data = np.asarray(data, dtype=dtype)
+            self_data = np.array(data, dtype=dtype, copy=copy)
 
         self = self_data.view(cls)
         self._name = fix_column_name(name)
@@ -138,7 +266,7 @@ class BaseColumn(np.ndarray):
 
         Returns
         -------
-        col: Column or MaskedColumn
+        col : Column or MaskedColumn
             Copy of the current column (same type as original)
         """
         if data is None:
@@ -196,6 +324,11 @@ class BaseColumn(np.ndarray):
 
         return reconstruct_func, reconstruct_func_args, state
 
+    def __getitem__(self, item):
+        if isinstance(item, INTEGER_TYPES):
+            return self.data[item]  # Return as plain ndarray or ma.MaskedArray
+        else:
+            return super(BaseColumn, self).__getitem__(item)
 
     # avoid == and != to be done based on type of subclass
     # (helped solve #1446; see also __array_wrap__)
@@ -217,10 +350,7 @@ class BaseColumn(np.ndarray):
         # or viewcast e.g. obj.view(Column).  In either case we want to
         # init Column attributes for self from obj if possible.
         self.parent_table = None
-        for attr in ('name', 'unit', 'format', 'description'):
-            val = getattr(obj, attr, None)
-            setattr(self, attr, val)
-        self.meta = deepcopy(getattr(obj, 'meta', {}))
+        self._copy_attrs(obj)
 
     def __array_wrap__(self, out_arr, context=None):
         """
@@ -252,6 +382,9 @@ class BaseColumn(np.ndarray):
 
     @property
     def name(self):
+        """
+        The name of this column.
+        """
         return self._name
 
     @name.setter
@@ -261,9 +394,6 @@ class BaseColumn(np.ndarray):
         if self.parent_table is not None:
             table = self.parent_table
             table.columns._rename_column(self.name, val)
-            table._data.dtype.names = list(table.columns)
-            if table.masked:
-                table._data.mask.dtype.names = list(table.columns)
 
         self._name = val
 
@@ -289,7 +419,8 @@ class BaseColumn(np.ndarray):
         # Iterate over formatted values with no max number of lines, no column
         # name, no unit, and ignoring the returned header info in outs.
         _pformat_col_iter = self._formatter._pformat_col_iter
-        for str_val in _pformat_col_iter(self, -1, False, False, {}):
+        for str_val in _pformat_col_iter(self, -1, show_name=False, show_unit=False,
+                                         show_dtype=False, outs={}):
             yield str_val
 
     def attrs_equal(self, col):
@@ -305,7 +436,7 @@ class BaseColumn(np.ndarray):
 
         Returns
         -------
-        equal: boolean
+        equal : boolean
             True if all attributes are equal
         """
         if not isinstance(col, BaseColumn):
@@ -321,7 +452,8 @@ class BaseColumn(np.ndarray):
     def _formatter(self):
         return FORMATTER if (self.parent_table is None) else self.parent_table.formatter
 
-    def pformat(self, max_lines=None, show_name=True, show_unit=False):
+    def pformat(self, max_lines=None, show_name=True, show_unit=False, show_dtype=False,
+                html=False):
         """Return a list of formatted string representation of column values.
 
         If no value of ``max_lines`` is supplied then the height of the
@@ -342,6 +474,12 @@ class BaseColumn(np.ndarray):
         show_unit : bool
             Include a header row for unit (default=False)
 
+        show_dtype : bool
+            Include column dtype (default=False)
+
+        html : bool
+            Format the output as an HTML table (default=False)
+
         Returns
         -------
         lines : list
@@ -349,10 +487,12 @@ class BaseColumn(np.ndarray):
 
         """
         _pformat_col = self._formatter._pformat_col
-        lines, n_header = _pformat_col(self, max_lines, show_name, show_unit)
+        lines, outs = _pformat_col(self, max_lines, show_name=show_name,
+                                   show_unit=show_unit, show_dtype=show_dtype,
+                                   html=html)
         return lines
 
-    def pprint(self, max_lines=None, show_name=True, show_unit=False):
+    def pprint(self, max_lines=None, show_name=True, show_unit=False, show_dtype=False):
         """Print a formatted string representation of column values.
 
         If no value of ``max_lines`` is supplied then the height of the
@@ -372,9 +512,15 @@ class BaseColumn(np.ndarray):
 
         show_unit : bool
             Include a header row for unit (default=False)
+
+        show_dtype : bool
+            Include column dtype (default=True)
         """
         _pformat_col = self._formatter._pformat_col
-        lines, n_header = _pformat_col(self, max_lines, show_name, show_unit)
+        lines, outs = _pformat_col(self, max_lines, show_name=show_name, show_unit=show_unit,
+                                   show_dtype=show_dtype)
+
+        n_header = outs['n_header']
         for i, line in enumerate(lines):
             if i < n_header:
                 color_print(line, 'red')
@@ -434,21 +580,6 @@ class BaseColumn(np.ndarray):
     def unit(self):
         self._unit = None
 
-    @property
-    @deprecated('0.3', alternative=':attr:`Column.unit`')
-    def units(self):
-        return self.unit
-
-    @units.setter
-    @deprecated('0.3', alternative=':attr:`Column.unit`')
-    def units(self, unit):
-        self.unit = unit
-
-    @units.deleter
-    @deprecated('0.3', alternative=':attr:`Column.unit`')
-    def units(self):
-        del self.unit
-
     def convert_unit_to(self, new_unit, equivalencies=[]):
         """
         Converts the values of the column in-place from the current
@@ -524,6 +655,48 @@ class BaseColumn(np.ndarray):
     def __repr__(self):
         return np.asarray(self).__repr__()
 
+    @property
+    def quantity(self):
+        """
+        A view of this table column as a `~astropy.units.Quantity` object with
+        units given by the Column's `unit` parameter.
+        """
+        # the Quantity initializer is used here because it correctly fails
+        # if the column's values are non-numeric (like strings), while .view
+        # will happily return a quantity with gibberish for numerical values
+        return Quantity(self, copy=False, dtype=self.dtype, order='A')
+
+    def to(self, unit, equivalencies=[], **kwargs):
+        """
+        Converts this table column to a `~astropy.units.Quantity` object with
+        the requested units.
+
+        Parameters
+        ----------
+        unit : `~astropy.units.Unit` or str
+            The unit to convert to (i.e., a valid argument to the
+            :meth:`astropy.units.Quantity.to` method).
+        equivalencies : list of equivalence pairs, optional
+            Equivalencies to use for this conversion.  See
+            :meth:`astropy.units.Quantity.to` for more details.
+
+        Returns
+        -------
+        quantity : `~astropy.units.Quantity`
+            A quantity object with the contents of this column in the units
+            ``unit``.
+        """
+        return self.quantity.to(unit, equivalencies)
+
+    def _copy_attrs(self, obj):
+        """
+        Copy key column attributes from ``obj`` to self
+        """
+        for attr in ('name', 'unit', 'format', 'description'):
+            val = getattr(obj, attr, None)
+            setattr(self, attr, val)
+        self.meta = deepcopy(getattr(obj, 'meta', {}))
+
 
 class Column(BaseColumn):
     """Define a data column for use in a Table object.
@@ -592,29 +765,54 @@ class Column(BaseColumn):
 
     def __new__(cls, data=None, name=None,
                 dtype=None, shape=(), length=0,
-                description=None, unit=None, format=None, meta=None):
+                description=None, unit=None, format=None, meta=None, copy=False):
 
         if isinstance(data, MaskedColumn) and np.any(data.mask):
             raise TypeError("Cannot convert a MaskedColumn with masked value to a Column")
 
         self = super(Column, cls).__new__(cls, data=data, name=name, dtype=dtype,
                                           shape=shape, length=length, description=description,
-                                          unit=unit, format=format, meta=meta)
+                                          unit=unit, format=format, meta=meta, copy=copy)
         return self
 
-    def __repr__(self):
-        unit = None if self.unit is None else six.text_type(self.unit)
-        out = "<{0} name={1} unit={2} format={3} " \
-            "description={4}>\n{5}".format(
-            self.__class__.__name__,
-            repr(self.name), repr(unit),
-            repr(self.format), repr(self.description), repr(self.data))
+    def _base_repr_(self, html=False):
+        descr_vals = [self.__class__.__name__]
+        unit = None if self.unit is None else str(self.unit)
+        shape = None if self.ndim <= 1 else self.shape[1:]
+        for attr, val in (('name', self.name),
+                          ('dtype', self.dtype.name),
+                          ('shape', shape),
+                          ('unit', unit),
+                          ('format', self.format),
+                          ('description', self.description),
+                          ('length', len(self))):
+
+            if val is not None:
+                descr_vals.append('{0}={1}'.format(attr, repr(val)))
+
+        descr = '<' + ' '.join(descr_vals) + '>\n'
+
+        if html:
+            from ..utils.xml.writer import xml_escape
+            descr = xml_escape(descr)
+
+        data_lines, outs = self._formatter._pformat_col(
+            self, show_name=False, show_unit=False, show_length=False, html=html)
+
+        out = descr + '\n'.join(data_lines)
+        if six.PY2 and isinstance(out, six.text_type):
+            out = out.encode('utf-8')
 
         return out
 
+    def _repr_html_(self):
+        return self._base_repr_(html=True)
+
+    def __repr__(self):
+        return self._base_repr_(html=False)
+
     def __unicode__(self):
-        _pformat_col = self._formatter._pformat_col
-        lines, n_header = _pformat_col(self)
+        lines, outs = self._formatter._pformat_col(self)
         return '\n'.join(lines)
     if six.PY3:
         __str__ = __unicode__
@@ -624,13 +822,62 @@ class Column(BaseColumn):
     if six.PY2:
         __str__ = __bytes__
 
+    # Set items using a view of the underlying data, as it gives an
+    # order-of-magnitude speed-up. [#2994]
+    def __setitem__(self, index, value):
+        self.data[index] = value
+
+    # # Set slices using a view of the underlying data, as it gives an
+    # # order-of-magnitude speed-up.  Only gets called in Python 2.  [#3020]
+    def __setslice__(self, start, stop, value):
+        self.data.__setslice__(start, stop, value)
+
+    def insert(self, obj, values):
+        """
+        Insert values before the given indices in the column and return
+        a new `~astropy.table.Column` object.
+
+        Parameters
+        ----------
+        obj : int, slice or sequence of ints
+            Object that defines the index or indices before which ``values`` is
+            inserted.
+        values : array_like
+            Value(s) to insert.  If the type of ``values`` is different
+            from that of quantity, ``values`` is converted to the matching type.
+            ``values`` should be shaped so that it can be broadcast appropriately
+
+        Returns
+        -------
+        out : `~astropy.table.Column`
+            A copy of column with ``values`` and ``mask`` inserted.  Note that the
+            insertion does not occur in-place: a new column is returned.
+        """
+        if self.dtype.kind == 'O':
+            # Even if values is array-like (e.g. [1,2,3]), insert as a single
+            # object.  Numpy.insert instead inserts each element in an array-like
+            # input individually.
+            data = np.insert(self, obj, None, axis=0)
+            data[obj] = values
+        else:
+            # Explicitly convert to dtype of this column.  Needed because numpy 1.7
+            # enforces safe casting by default, so .  This isn't the case for 1.6 or 1.8+.
+            values = np.asarray(values, dtype=self.dtype)
+            data = np.insert(self, obj, values, axis=0)
+        out = data.view(self.__class__)
+        out.__array_finalize__(self)
+        return out
+
     # We do this to make the methods show up in the API docs
     name = BaseColumn.name
+    unit = BaseColumn.unit
     copy = BaseColumn.copy
     more = BaseColumn.more
     pprint = BaseColumn.pprint
     pformat = BaseColumn.pformat
     convert_unit_to = BaseColumn.convert_unit_to
+    quantity = BaseColumn.quantity
+    to = BaseColumn.to
 
 
 class MaskedColumn(Column, ma.MaskedArray):
@@ -707,7 +954,7 @@ class MaskedColumn(Column, ma.MaskedArray):
 
     def __new__(cls, data=None, name=None, mask=None, fill_value=None,
                 dtype=None, shape=(), length=0,
-                description=None, unit=None, format=None, meta=None):
+                description=None, unit=None, format=None, meta=None, copy=False):
 
         if mask is None and hasattr(data, 'mask'):
             mask = data.mask
@@ -723,7 +970,7 @@ class MaskedColumn(Column, ma.MaskedArray):
         # First just pass through all args and kwargs to BaseColumn, then wrap that object
         # with MaskedArray.
         self_data = BaseColumn(data, dtype=dtype, shape=shape, length=length, name=name,
-                               unit=unit, format=format, description=description, meta=meta)
+                               unit=unit, format=format, description=description, meta=meta, copy=copy)
         self = ma.MaskedArray.__new__(cls, data=self_data, mask=mask)
 
         # Note: do not set fill_value in the MaskedArray constructor because this does not
@@ -760,9 +1007,6 @@ class MaskedColumn(Column, ma.MaskedArray):
         if it exists.  Setting one or the other alone doesn't work."""
         val = self._fix_fill_value(val)
 
-        if self.parent_table:
-            self.parent_table._data[self._name].fill_value = val
-
         # Yet another ma bug workaround: If the value of fill_value for a string array is
         # requested but not yet set then it gets created as 'N/A'.  From this point onward
         # any new fill_values are truncated to 3 characters.  Note that this does not
@@ -817,6 +1061,57 @@ class MaskedColumn(Column, ma.MaskedArray):
                          meta=deepcopy(self.meta))
         return out
 
+    def insert(self, obj, values, mask=None):
+        """
+        Insert values along the given axis before the given indices and return
+        a new `~astropy.table.MaskedColumn` object.
+
+        Parameters
+        ----------
+        obj : int, slice or sequence of ints
+            Object that defines the index or indices before which ``values`` is
+            inserted.
+        values : array_like
+            Value(s) to insert.  If the type of ``values`` is different
+            from that of quantity, ``values`` is converted to the matching type.
+            ``values`` should be shaped so that it can be broadcast appropriately
+        mask : boolean array_like
+            Mask value(s) to insert.  If not supplied then False is used.
+
+        Returns
+        -------
+        out : `~astropy.table.MaskedColumn`
+            A copy of column with ``values`` and ``mask`` inserted.  Note that the
+            insertion does not occur in-place: a new masked column is returned.
+        """
+        self_ma = self.data  # self viewed as MaskedArray
+
+        if self.dtype.kind == 'O':
+            # Even if values is array-like (e.g. [1,2,3]), insert as a single
+            # object.  Numpy.insert instead inserts each element in an array-like
+            # input individually.
+            new_data = np.insert(self_ma.data, obj, None, axis=0)
+            new_data[obj] = values
+        else:
+            # Explicitly convert to dtype of this column.  Needed because numpy 1.7
+            # enforces safe casting by default, so .  This isn't the case for 1.6 or 1.8+.
+            values = np.asarray(values, dtype=self.dtype)
+            new_data = np.insert(self_ma.data, obj, values, axis=0)
+
+        if mask is None:
+            if self.dtype.kind == 'O':
+                mask = False
+            else:
+                mask = np.zeros(values.shape, dtype=np.bool)
+        new_mask = np.insert(self_ma.mask, obj, mask, axis=0)
+        new_ma = np.ma.array(new_data, mask=new_mask, copy=False)
+
+        out = new_ma.view(self.__class__)
+        out.parent_table = None
+        out._copy_attrs(self)
+
+        return out
+
     def __getitem__(self, item):
         out = super(MaskedColumn, self).__getitem__(item)
 
@@ -824,13 +1119,19 @@ class MaskedColumn(Column, ma.MaskedArray):
         # the original object attributes are not copied.
         if out.__class__ is self.__class__:
             out.parent_table = None
-            for attr in ('name', 'unit', 'format', 'description'):
-                val = getattr(self, attr, None)
-                setattr(out, attr, val)
-            out.meta = deepcopy(getattr(self, 'meta', {}))
+            out._copy_attrs(self)
 
         return out
 
+    # Set items and slices using MaskedArray method, instead of falling through
+    # to the (faster) Column version which uses an ndarray view.  This doesn't
+    # copy the mask properly. See test_setting_from_masked_column test.
+    def __setitem__(self, index, value):
+        ma.MaskedArray.__setitem__(self, index, value)
+
+    def __setslice__(self, start, stop, value):
+        ma.MaskedArray.__setslice__(self, start, stop, value)
+
     # We do this to make the methods show up in the API docs
     name = BaseColumn.name
     copy = BaseColumn.copy
diff --git a/astropy/table/groups.py b/astropy/table/groups.py
index 62f3ae5..a99bea8 100644
--- a/astropy/table/groups.py
+++ b/astropy/table/groups.py
@@ -107,7 +107,7 @@ def column_group_by(column, keys):
     from .table import Table
 
     if isinstance(keys, Table):
-        keys = keys._data
+        keys = keys.as_array()
 
     if not isinstance(keys, np.ndarray):
         raise TypeError('Keys input must be numpy array, but got {0}'
@@ -216,8 +216,8 @@ class ColumnGroups(BaseGroups):
             return self._keys
 
     def aggregate(self, func):
-        from .column import MaskedColumn
-        
+        from .column import MaskedColumn, col_getattr
+
         i0s, i1s = self.indices[:-1], self.indices[1:]
         par_col = self.parent_column
         masked = isinstance(par_col, MaskedColumn)
@@ -236,10 +236,15 @@ class ColumnGroups(BaseGroups):
                 vals = np.array([func(par_col[i0: i1]) for i0, i1 in izip(i0s, i1s)])
         except Exception:
             raise TypeError("Cannot aggregate column '{0}' with type '{1}'"
-                            .format(par_col.name, par_col.dtype))
-
-        out = par_col.__class__(data=vals, name=par_col.name, description=par_col.description,
-                                unit=par_col.unit, format=par_col.format, meta=par_col.meta)
+                            .format(col_getattr(par_col, 'name'),
+                                    col_getattr(par_col, 'dtype')))
+
+        out = par_col.__class__(data=vals,
+                                name=col_getattr(par_col, 'name'),
+                                description=col_getattr(par_col, 'description'),
+                                unit=col_getattr(par_col, 'unit'),
+                                format=col_getattr(par_col, 'format'),
+                                meta=col_getattr(par_col, 'meta'))
         return out
 
     def filter(self, func):
@@ -316,13 +321,15 @@ class TableGroups(BaseGroups):
         out : Table
             New table with the aggregated rows.
         """
+        from .column import col_getattr
+
         i0s, i1s = self.indices[:-1], self.indices[1:]
         out_cols = []
         parent_table = self.parent_table
 
         for col in six.itervalues(parent_table.columns):
             # For key columns just pick off first in each group since they are identical
-            if col.name in self.key_colnames:
+            if col_getattr(col, 'name') in self.key_colnames:
                 new_col = col.take(i0s)
             else:
                 try:
diff --git a/astropy/table/jsviewer.py b/astropy/table/jsviewer.py
index d55781b..8769255 100644
--- a/astropy/table/jsviewer.py
+++ b/astropy/table/jsviewer.py
@@ -1,8 +1,13 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 # TODO: need to download some images used by the jquery-ui css file:
 # images/ui-icons_888888_256x240.png
+
 import os
+import glob
+
+from .table import Table
 
+from ..io import registry as io_registry
 from .. import config as _config
 from .. import extern
 
@@ -13,13 +18,18 @@ class Conf(_config.ConfigNamespace):
     """
 
     jquery_url = _config.ConfigItem(
-        '',
+        'http://code.jquery.com/jquery-1.11.1.min.js',
         'The URL to the jquery library.')
 
     datatables_url = _config.ConfigItem(
-        '',
+        'http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js',
         'The URL to the jquery datatables library.')
 
+    css_urls = _config.ConfigItem(
+        ['https://code.jquery.com/ui/1.11.1/themes/overcast/jquery-ui.css'],
+        'The URLs to the css file(s) to include.', cfgtype='list')
+
+
 conf = Conf()
 
 
@@ -32,17 +42,18 @@ DATATABLES_URL = _config.ConfigAlias(
     'astropy.table.jsviewer', 'astropy.table.jsviewer')
 
 
-data_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data')
+DATA_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data')
+EXTERN_JS_DIR = os.path.abspath(os.path.join(os.path.dirname(extern.__file__), 'js'))
 
 
-ipynb_js_script = """
+IPYNB_JS_SCRIPT = """
 <script>
     function html_repr_full() {{
         var kernel = IPython.notebook.kernel;
         var button = $("#MakeTableBrowseable{tid}");
         var tablename = button.parents()[4].getElementsByClassName("input_area")[0].innerText;
         tablename = tablename.replace(/\s+/g, '');
-        var command = "print ''.join(" + tablename + ".pformat(html=True, max_lines=1000, max_width=1000, tableid={tid}))";
+        var command = "print ''.join(" + tablename + ".pformat(html=True, max_lines=1000, max_width=1000, table_id={tid}))";
         console.log(command);
         var result = kernel.execute(command, {{'output': callback}}, {{silent:false}});
         console.log(result);
@@ -72,25 +83,23 @@ ipynb_js_script = """
 """
 
 
-commandline_js_script = """
-<script>
-    $(document).ready(function() {{
-        $('#{tid}').dataTable({{
-         "iDisplayLength": {display_length},
-         "aLengthMenu": {display_length_menu},
-         "bJQueryUI": true,
-         "sPaginationType": "full_numbers"
-        }});
-    }} );
-</script>
+HTML_JS_SCRIPT = """
+$(document).ready(function() {{
+    $('#{tid}').dataTable({{
+     "iDisplayLength": {display_length},
+     "aLengthMenu": {display_length_menu},
+     "bJQueryUI": true,
+     "sPaginationType": "full_numbers"
+    }});
+}} );
 """
 
 
 class JSViewer(object):
     def __init__(self,
-                 css_files=['jquery-ui.css', 'demo_page.css', 'demo_table.css'],
+                 use_local_files=False,
                  display_length=50):
-        self.css_urls = ["file://" + os.path.join(data_path, c) for c in css_files]
+        self._use_local_files = use_local_files
         self.display_length_menu = [[10, 25, 50, 100, 500, 1000, -1],
                                     [10, 25, 50, 100, 500, 1000, "All"]]
         self.display_length = display_length
@@ -98,13 +107,20 @@ class JSViewer(object):
             if display_length not in L:
                 L.insert(0, display_length)
 
-    def _jquery_file(self):
-        jquery_url = conf.jquery_url
-        if not jquery_url:
-            jquery_url = 'file://' + os.path.abspath(
-                os.path.join(
-                    os.path.dirname(extern.__file__), 'js', 'jquery-1.11.0.js'))
-        return '<script src="{0}"></script>'.format(jquery_url)
+    @property
+    def jquery_urls(self):
+        if self._use_local_files:
+            return ['file://' + os.path.join(EXTERN_JS_DIR, 'jquery-1.11.0.js'),
+                    'file://' + os.path.join(EXTERN_JS_DIR, 'jquery.dataTables.js')]
+        else:
+            return [conf.jquery_url, conf.datatables_url]
+
+    @property
+    def css_urls(self):
+        if self._use_local_files:
+            return ["file://" + filename for filename in glob.glob(os.path.join(DATA_PATH, '*.css'))]
+        else:
+            return conf.css_urls
 
     def _jstable_file(self):
         # downloaded from http://datatables.net/download/build/
@@ -122,23 +138,39 @@ class JSViewer(object):
             '<link rel="stylesheet" href="{css}" type="text/css">'.format(css=css)
             for css in self.css_urls]
 
-    def ipynb(self, tableid):
+    def ipynb(self, table_id):
         js = self._css_files()
         js.append(self._jstable_file())
-        js.append(ipynb_js_script.format(
+        js.append(IPYNB_JS_SCRIPT.format(
             display_length=self.display_length,
             display_length_menu=self.display_length_menu,
-            tid=tableid,
-            data_path="file://"+data_path))
+            tid=table_id,
+            data_path="file://"+DATA_PATH))
         return js
 
-    def command_line(self, tableid='table0'):
-        js = self._css_files()
-        js.append(self._jquery_file())
-        js.append(self._jstable_file())
+    def html_js(self, table_id='table0'):
+        return HTML_JS_SCRIPT.format(display_length=self.display_length,
+                                     display_length_menu=self.display_length_menu,
+                                     tid=table_id).strip()
 
-        js.append(commandline_js_script.format(
-            display_length=self.display_length,
-            display_length_menu=self.display_length_menu,
-            tid=tableid))
-        return js
+
+def write_table_jsviewer(table, filename, table_id=None,
+                         css="table,th,td,tr,tbody {border: 1px solid black; border-collapse: collapse;}",
+                         max_lines=5000,
+                         jskwargs={}):
+
+    if table_id is None:
+        table_id = 'table{id}'.format(id=id(table))
+
+    jsv = JSViewer(**jskwargs)
+
+    htmldict = {}
+    htmldict['table_id'] = table_id
+    htmldict['css'] = css
+    htmldict['cssfiles'] = jsv.css_urls
+    htmldict['jsfiles'] = jsv.jquery_urls
+    htmldict['js'] =  jsv.html_js(table_id=table_id)
+
+    table.write(filename, format='html', htmldict=htmldict)
+
+io_registry.register_writer('jsviewer', Table, write_table_jsviewer)
diff --git a/astropy/table/np_utils.py b/astropy/table/np_utils.py
index 9af6c2b..32138a5 100644
--- a/astropy/table/np_utils.py
+++ b/astropy/table/np_utils.py
@@ -5,13 +5,14 @@ join():  Perform a database join of two numpy ndarrays.
 hstack(): Horizontally stack a list of numpy ndarrays.
 vstack(): Vertically stack a list of numpy ndarrays.
 
-Some code and inspriration taken from numpy.lib.recfunctions.join_by().
+Some code and inspiration taken from numpy.lib.recfunctions.join_by().
 Redistribution license restrictions apply.
 """
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 from ..extern import six
 from ..extern.six.moves import zip as izip
+from ..utils.decorators import deprecated
 
 from itertools import chain
 import collections
@@ -24,6 +25,10 @@ from ..utils import OrderedDict
 
 __all__ = ['join', 'hstack', 'vstack', 'TableMergeError']
 
+DEPRECATION_MESSAGE = ('The %(func)s %(obj_type)s is deprecated and may '
+                       'be removed in a future version. '
+                       'Contact the Astropy developers if you need '
+                       'continued support for this function.')
 
 class TableMergeError(ValueError):
     pass
@@ -74,7 +79,8 @@ def get_col_name_map(arrays, common_names, uniq_col_name='{col_name}_{table_name
             else:
                 # If name is not one of the common column outputs, and it collides
                 # with the names in one of the other arrays, then rename
-                others = (x for x in arrays if x is not array)
+                others = list(arrays)
+                others.pop(idx)
                 if any(name in other.dtype.names for other in others):
                     out_name = uniq_col_name.format(table_name=table_name, col_name=name)
                 col_name_list.append(out_name)
@@ -162,6 +168,7 @@ def common_dtype(cols):
     return arr_common.dtype.str
 
 
+ at deprecated('1.0', message=DEPRECATION_MESSAGE)
 def join(left, right, keys=None, join_type='inner',
          uniq_col_name='{col_name}_{table_name}',
          table_names=['1', '2'],
@@ -302,6 +309,7 @@ def _check_for_sequence_of_structured_arrays(arrays):
         raise ValueError('`arrays` arg must include at least one array')
 
 
+ at deprecated('1.0', message=DEPRECATION_MESSAGE)
 def vstack(arrays, join_type='inner', col_name_map=None):
     """
     Stack structured arrays vertically (by rows)
@@ -411,6 +419,7 @@ def vstack(arrays, join_type='inner', col_name_map=None):
     return out
 
 
+ at deprecated('1.0', message=DEPRECATION_MESSAGE)
 def hstack(arrays, join_type='exact', uniq_col_name='{col_name}_{table_name}',
            table_names=None, col_name_map=None):
     """
@@ -514,6 +523,7 @@ def hstack(arrays, join_type='exact', uniq_col_name='{col_name}_{table_name}',
     return out
 
 
+ at deprecated('1.0', message=DEPRECATION_MESSAGE)
 def get_groups(table, keys):
     """
     Get groups for numpy structured array on specified keys.
@@ -541,7 +551,7 @@ def get_groups(table, keys):
     table = table.ravel()
     len_table = len(table)
 
-    # oined array dtype as a list of descr (name, type_str, shape) tuples
+    # joined array dtype as a list of descr (name, type_str, shape) tuples
     col_name_map = get_col_name_map([table], keys)
     out_descrs = get_descrs([table], col_name_map)
 
diff --git a/astropy/table/operations.py b/astropy/table/operations.py
index 8399dcd..bda48a6 100644
--- a/astropy/table/operations.py
+++ b/astropy/table/operations.py
@@ -9,18 +9,23 @@ High-level table operations:
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 from ..extern import six
+from ..extern.six.moves import zip
 
 from copy import deepcopy
 import warnings
 import collections
+import itertools
 
 import numpy as np
+from numpy import ma
 
 from ..utils import OrderedDict, metadata
+from .column import col_getattr, col_setattr, _col_update_attrs_from
 
-from . import np_utils
+from . import _np_utils
+from .np_utils import fix_column_name, TableMergeError
 
-__all__ = ['join', 'hstack', 'vstack']
+__all__ = ['join', 'hstack', 'vstack', 'unique']
 
 
 def _merge_col_meta(out, tables, col_name_map, idx_left=0, idx_right=1,
@@ -29,7 +34,7 @@ def _merge_col_meta(out, tables, col_name_map, idx_left=0, idx_right=1,
     Merge column meta data for the ``out`` table.
 
     This merges column meta, which includes attributes unit, format,
-    and description, as well as the actual `meta` atttribute.  It is
+    and description, as well as the actual `meta` attribute.  It is
     assumed that the ``out`` table was created by merging ``tables``.
     The ``col_name_map`` provides the mapping from col name in ``out``
     back to the original name (which may be different).
@@ -39,11 +44,14 @@ def _merge_col_meta(out, tables, col_name_map, idx_left=0, idx_right=1,
     for out_col in six.itervalues(out.columns):
         for idx_table, table in enumerate(tables):
             left_col = out_col
-            right_name = col_name_map[out_col.name][idx_table]
+            right_name = col_name_map[col_getattr(out_col, 'name')][idx_table]
 
             if right_name:
                 right_col = table[right_name]
-                out_col.meta = metadata.merge(left_col.meta, right_col.meta, metadata_conflicts=metadata_conflicts)
+                col_setattr(out_col, 'meta',
+                            metadata.merge(col_getattr(left_col, 'meta', {}),
+                                           col_getattr(right_col, 'meta', {}),
+                                           metadata_conflicts=metadata_conflicts))
                 for attr in attrs:
 
                     # Pick the metadata item that is not None, or they are both
@@ -51,8 +59,8 @@ def _merge_col_meta(out, tables, col_name_map, idx_left=0, idx_right=1,
                     # and if they are different, there is a conflict and we
                     # pick the one on the right (or raise an error).
 
-                    left_attr = getattr(left_col, attr)
-                    right_attr = getattr(right_col, attr)
+                    left_attr = getattr(left_col, attr, None)
+                    right_attr = getattr(right_col, attr, None)
 
                     if left_attr is None:
                         # This may not seem necessary since merge_attr gets set
@@ -65,18 +73,27 @@ def _merge_col_meta(out, tables, col_name_map, idx_left=0, idx_right=1,
                         if metadata_conflicts == 'warn':
                             warnings.warn("In merged column '{0}' the '{1}' attribute does not match "
                                           "({2} != {3}).  Using {3} for merged output"
-                                          .format(out_col.name, attr, left_attr, right_attr),
+                                          .format(col_getattr(out_col, 'name'), attr,
+                                                  left_attr, right_attr),
                                           metadata.MergeConflictWarning)
                         elif metadata_conflicts == 'error':
-                            raise metadata.MergeConflictError('In merged column {0!r} the {1!r} attribute does not match '
-                                          '({2} != {3})'.format(out_col.name, attr, left_attr, right_attr))
+                            raise metadata.MergeConflictError(
+                                'In merged column {0!r} the {1!r} attribute does not match '
+                                '({2} != {3})'.format(col_getattr(out_col, 'name'), attr,
+                                                      left_attr, right_attr))
                         elif metadata_conflicts != 'silent':
-                            raise ValueError('metadata_conflict argument must be one of "silent", "warn", or "error"')
+                            raise ValueError('metadata_conflicts argument must be one of "silent",'
+                                             ' "warn", or "error"')
                         merge_attr = right_attr
                     else:  # left_attr == right_attr
                         merge_attr = right_attr
 
-                    setattr(out_col, attr, merge_attr)
+                    try:
+                        # It may not be allowed to set attributes, for instance `unit`
+                        # in a Quantity column.
+                        setattr(out_col, attr, merge_attr)
+                    except AttributeError:
+                        pass
 
 
 def _merge_table_meta(out, tables, metadata_conflicts='warn'):
@@ -98,7 +115,7 @@ def _get_list_of_tables(tables):
         tables = [tables]
 
     # Make sure each thing is a Table or Row
-    if any(not isinstance(x, (Table, Row)) for x in tables):
+    if any(not isinstance(x, (Table, Row)) for x in tables) or len(tables) == 0:
         raise TypeError('`tables` arg must be a Table or sequence of Tables or Rows')
 
     # Convert any Rows to Tables
@@ -107,6 +124,21 @@ def _get_list_of_tables(tables):
     return tables
 
 
+def _get_out_class(tables):
+    """
+    From a list of table instances get the merged output table class.
+    This is just taken as the deepest subclass.  It is assumed that
+    `tables` is a list of at least one element and that they are all
+    Table (subclass) instances.  This doesn't handle complicated
+    inheritance schemes.
+    """
+    out_class = tables[0].__class__
+    for t in tables[1:]:
+        if issubclass(t.__class__, out_class):
+            out_class = t.__class__
+    return out_class
+
+
 def join(left, right, keys=None, join_type='inner',
          uniq_col_name='{col_name}_{table_name}',
          table_names=['1', '2'], metadata_conflicts='warn'):
@@ -135,6 +167,11 @@ def join(left, right, keys=None, join_type='inner',
             * ``'silent'``: silently pick the last conflicting meta-data value
             * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default)
             * ``'error'``: raise an exception.
+
+    Returns
+    -------
+    joined_table : `~astropy.table.Table` object
+        New table containing the result of the join operation.
     """
     from .table import Table
 
@@ -145,10 +182,8 @@ def join(left, right, keys=None, join_type='inner',
         right = Table(right)
 
     col_name_map = OrderedDict()
-    out_data = np_utils.join(left._data, right._data, keys, join_type,
-                             uniq_col_name, table_names, col_name_map)
-    # Create the output (Table or subclass of Table)
-    out = Table(out_data)
+    out = _join(left, right, keys, join_type,
+                uniq_col_name, table_names, col_name_map)
 
     # Merge the column and table meta data. Table subclasses might override
     # these methods for custom merge behavior.
@@ -162,16 +197,15 @@ def vstack(tables, join_type='outer', metadata_conflicts='warn'):
     """
     Stack tables vertically (along rows)
 
-    A ``join_type`` of 'exact' means that the tables must all
-    have exactly the same column names (though the order can vary).  If
-    ``join_type`` is 'inner' then the intersection of common columns will
-    be output.  A value of 'outer' (default) means the output will have the union of
+    A ``join_type`` of 'exact' means that the tables must all have exactly
+    the same column names (though the order can vary).  If ``join_type``
+    is 'inner' then the intersection of common columns will be output.
+    A value of 'outer' (default) means the output will have the union of
     all columns, with table values being masked where no common values are
     available.
 
     Parameters
     ----------
-
     tables : Table or list of Table objects
         Table(s) to stack along rows (vertically) with the current table
     join_type : str
@@ -182,9 +216,13 @@ def vstack(tables, join_type='outer', metadata_conflicts='warn'):
             * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default)
             * ``'error'``: raise an exception.
 
+    Returns
+    -------
+    stacked_table : `~astropy.table.Table` object
+        New table containing the stacked data from the input tables.
+
     Examples
     --------
-
     To stack two tables along rows do::
 
       >>> from astropy.table import vstack, Table
@@ -208,14 +246,12 @@ def vstack(tables, join_type='outer', metadata_conflicts='warn'):
         5   7
         6   8
     """
-    from .table import Table
-
     tables = _get_list_of_tables(tables)  # validates input
-    arrays = [table._data for table in tables]
+    if len(tables) == 1:
+        return tables[0]  # no point in stacking a single table
     col_name_map = OrderedDict()
 
-    out_data = np_utils.vstack(arrays, join_type, col_name_map)
-    out = Table(out_data)
+    out = _vstack(tables, join_type, col_name_map)
 
     # Merge column and table metadata
     _merge_col_meta(out, tables, col_name_map, metadata_conflicts=metadata_conflicts)
@@ -238,7 +274,6 @@ def hstack(tables, join_type='outer',
 
     Parameters
     ----------
-
     tables : List of Table objects
         Tables to stack along columns (horizontally) with the current table
     join_type : str
@@ -249,18 +284,19 @@ def hstack(tables, join_type='outer',
     table_names : list of str or None
         Two-element list of table names used when generating unique output
         column names.  The default is ['1', '2', ..].
-    col_name_map : empty dict or None
-        If passed as a dict then it will be updated in-place with the
-        mapping of output to input column names.
     metadata_conflicts : str
         How to proceed with metadata conflicts. This should be one of:
             * ``'silent'``: silently pick the last conflicting meta-data value
             * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default)
             * ``'error'``: raise an exception.
 
+    Returns
+    -------
+    stacked_table : `~astropy.table.Table` object
+        New table containing the stacked data from the input tables.
+
     Examples
     --------
-
     To stack two tables horizontally (along columns) do::
 
       >>> from astropy.table import Table, hstack
@@ -282,17 +318,536 @@ def hstack(tables, join_type='outer',
         1   3   5   7
         2   4   6   8
     """
-    from .table import Table
-
     tables = _get_list_of_tables(tables)  # validates input
-    arrays = [table._data for table in tables]
+    if len(tables) == 1:
+        return tables[0]  # no point in stacking a single table
     col_name_map = OrderedDict()
 
-    out_data = np_utils.hstack(arrays, join_type, uniq_col_name, table_names,
-                               col_name_map)
-    out = Table(out_data)
+    out = _hstack(tables, join_type, uniq_col_name, table_names,
+                  col_name_map)
 
     _merge_col_meta(out, tables, col_name_map, metadata_conflicts=metadata_conflicts)
     _merge_table_meta(out, tables, metadata_conflicts=metadata_conflicts)
 
     return out
+
+
+def unique(input_table, keys=None, silent=False):
+    """
+    Returns the unique rows of a table.
+
+    Parameters
+    ----------
+
+    input_table : `~astropy.table.Table` object or a value that
+    will initialize a `~astropy.table.Table` object
+        Input table.
+    keys : str or list of str
+        Name(s) of column(s) used to unique rows.
+        Default is to use all columns.
+    silent : boolean
+        If `True` masked value column(s) are silently removed from
+        ``keys``. If `False` an exception is raised when ``keys`` contains
+        masked value column(s).
+        Default is `False`.
+
+    Returns
+    -------
+    unique_table : `~astropy.table.Table` object
+        Table containing only the unique rays of ``input_table``.
+
+    """
+
+    if keys is None:
+        keys = input_table.colnames
+
+    if input_table.masked:
+        if isinstance(keys, six.string_types):
+            keys = [keys, ]
+        for i, key in enumerate(keys):
+            if np.any(input_table[key].mask):
+                if not silent:
+                    raise ValueError("Cannot unique masked value key columns, "
+                                     "remove column '{0}' from keys and rerun "
+                                     "unique.".format(key))
+                del keys[i]
+        if len(keys) == 0:
+            raise ValueError("No column remained in ``keys``, unique cannot "
+                             "work with masked value key columns.")
+
+    grouped_table = input_table.group_by(keys)
+    unique_table = grouped_table[grouped_table.groups.indices[:-1]]
+
+    return unique_table
+
+
+def _counter(iterable):
+    """
+    Count instances of each unique value in ``iterable``.  Returns a dict
+    with the counts.  Would use collections.Counter but this isn't available in 2.6.
+    """
+    counts = collections.defaultdict(int)
+    for val in iterable:
+        counts[val] += 1
+    return counts
+
+
+def get_col_name_map(arrays, common_names, uniq_col_name='{col_name}_{table_name}',
+                     table_names=None):
+    """
+    Find the column names mapping when merging the list of tables
+    ``arrays``.  It is assumed that col names in ``common_names`` are to be
+    merged into a single column while the rest will be uniquely represented
+    in the output.  The args ``uniq_col_name`` and ``table_names`` specify
+    how to rename columns in case of conflicts.
+
+    Returns a dict mapping each output column name to the input(s).  This takes the form
+    {outname : (col_name_0, col_name_1, ...), ... }.  For key columns all of input names
+    will be present, while for the other non-key columns the value will be (col_name_0,
+    None, ..) or (None, col_name_1, ..) etc.
+    """
+
+    col_name_map = collections.defaultdict(lambda: [None] * len(arrays))
+    col_name_list = []
+
+    if table_names is None:
+        table_names = [six.text_type(ii + 1) for ii in range(len(arrays))]
+
+    for idx, array in enumerate(arrays):
+        table_name = table_names[idx]
+        for name in array.colnames:
+            out_name = name
+
+            if name in common_names:
+                # If name is in the list of common_names then insert into
+                # the column name list, but just once.
+                if name not in col_name_list:
+                    col_name_list.append(name)
+            else:
+                # If name is not one of the common column outputs, and it collides
+                # with the names in one of the other arrays, then rename
+                others = list(arrays)
+                others.pop(idx)
+                if any(name in other.colnames for other in others):
+                    out_name = uniq_col_name.format(table_name=table_name, col_name=name)
+                col_name_list.append(out_name)
+
+            col_name_map[out_name][idx] = name
+
+    # Check for duplicate output column names
+    col_name_count = _counter(col_name_list)
+    repeated_names = [name for name, count in six.iteritems(col_name_count) if count > 1]
+    if repeated_names:
+        raise TableMergeError('Merging column names resulted in duplicates: {0}.  '
+                              'Change uniq_col_name or table_names args to fix this.'
+                              .format(repeated_names))
+
+    # Convert col_name_map to a regular dict with tuple (immutable) values
+    col_name_map = OrderedDict((name, col_name_map[name]) for name in col_name_list)
+
+    return col_name_map
+
+
+def get_descrs(arrays, col_name_map):
+    """
+    Find the dtypes descrs resulting from merging the list of arrays' dtypes,
+    using the column name mapping ``col_name_map``.
+
+    Return a list of descrs for the output.
+    """
+
+    out_descrs = []
+
+    for out_name, in_names in six.iteritems(col_name_map):
+        # List of input arrays that contribute to this output column
+        in_cols = [arr[name] for arr, name in zip(arrays, in_names) if name is not None]
+
+        # List of names of the columns that contribute to this output column.
+        names = [name for name in in_names if name is not None]
+
+        # Output dtype is the superset of all dtypes in in_arrays
+        try:
+            dtype = common_dtype(in_cols)
+        except TableMergeError as tme:
+            # Beautify the error message when we are trying to merge columns with incompatible
+            # types by including the name of the columns that originated the error.
+            raise TableMergeError("The '{0}' columns have incompatible types: {1}"
+                                  .format(names[0], tme._incompat_types))
+
+        # Make sure all input shapes are the same
+        uniq_shapes = set(col.shape[1:] for col in in_cols)
+        if len(uniq_shapes) != 1:
+            raise TableMergeError('Key columns {0!r} have different shape'.format(name))
+        shape = uniq_shapes.pop()
+
+        out_descrs.append((fix_column_name(out_name), dtype, shape))
+
+    return out_descrs
+
+
+def common_dtype(cols):
+    """
+    Use numpy to find the common dtype for a list of columns.
+
+    Only allow columns within the following fundamental numpy data types:
+    np.bool_, np.object_, np.number, np.character, np.void
+    """
+    def dtype(col):
+        return getattr(col, 'dtype', np.dtype('O'))
+
+    np_types = (np.bool_, np.object_, np.number, np.character, np.void)
+    uniq_types = set(tuple(issubclass(dtype(col).type, np_type) for np_type in np_types)
+                     for col in cols)
+    if len(uniq_types) > 1:
+        # Embed into the exception the actual list of incompatible types.
+        incompat_types = [col_getattr(col, 'name') for col in cols]
+        tme = TableMergeError('Columns have incompatible types {0}'
+                              .format(incompat_types))
+        tme._incompat_types = incompat_types
+        raise tme
+
+    arrs = [np.empty(1, dtype=dtype(col)) for col in cols]
+
+    # For string-type arrays need to explicitly fill in non-zero
+    # values or the final arr_common = .. step is unpredictable.
+    for arr in arrs:
+        if arr.dtype.kind in ('S', 'U'):
+            arr[0] = '0' * arr.itemsize
+
+    arr_common = np.array([arr[0] for arr in arrs])
+    return arr_common.dtype.str
+
+
+def _join(left, right, keys=None, join_type='inner',
+         uniq_col_name='{col_name}_{table_name}',
+         table_names=['1', '2'],
+         col_name_map=None):
+    """
+    Perform a join of the left and right Tables on specified keys.
+
+    Parameters
+    ----------
+    left : Table
+        Left side table in the join
+    right : Table
+        Right side table in the join
+    keys : str or list of str
+        Name(s) of column(s) used to match rows of left and right tables.
+        Default is to use all columns which are common to both tables.
+    join_type : str
+        Join type ('inner' | 'outer' | 'left' | 'right'), default is 'inner'
+    uniq_col_name : str or None
+        String generate a unique output column name in case of a conflict.
+        The default is '{col_name}_{table_name}'.
+    table_names : list of str or None
+        Two-element list of table names used when generating unique output
+        column names.  The default is ['1', '2'].
+    col_name_map : empty dict or None
+        If passed as a dict then it will be updated in-place with the
+        mapping of output to input column names.
+
+    Returns
+    -------
+    joined_table : `~astropy.table.Table` object
+        New table containing the result of the join operation.
+    """
+    # Store user-provided col_name_map until the end
+    _col_name_map = col_name_map
+
+    if join_type not in ('inner', 'outer', 'left', 'right'):
+        raise ValueError("The 'join_type' argument should be in 'inner', "
+                         "'outer', 'left' or 'right' (got '{0}' instead)".
+                         format(join_type))
+
+    # If we have a single key, put it in a tuple
+    if keys is None:
+        keys = tuple(name for name in left.colnames if name in right.colnames)
+        if len(keys) == 0:
+            raise TableMergeError('No keys in common between left and right tables')
+    elif isinstance(keys, six.string_types):
+        keys = (keys,)
+
+    # Check the key columns
+    for arr, arr_label in ((left, 'Left'), (right, 'Right')):
+        for name in keys:
+            if name not in arr.colnames:
+                raise TableMergeError('{0} table does not have key column {1!r}'
+                                      .format(arr_label, name))
+            if hasattr(arr[name], 'mask') and np.any(arr[name].mask):
+                raise TableMergeError('{0} key column {1!r} has missing values'
+                                      .format(arr_label, name))
+            if not isinstance(arr[name], np.ndarray):
+                raise ValueError("non-ndarray column '{0}' not allowed as a key column")
+
+    len_left, len_right = len(left), len(right)
+
+    if len_left == 0 or len_right == 0:
+        raise ValueError('input tables for join must both have at least one row')
+
+
+    # Joined array dtype as a list of descr (name, type_str, shape) tuples
+    col_name_map = get_col_name_map([left, right], keys, uniq_col_name, table_names)
+    out_descrs = get_descrs([left, right], col_name_map)
+
+    # Make an array with just the key columns.  This uses a temporary
+    # structured array for efficiency.
+    out_keys_dtype = [descr for descr in out_descrs if descr[0] in keys]
+    out_keys = np.empty(len_left + len_right, dtype=out_keys_dtype)
+    for key in keys:
+        out_keys[key][:len_left] = left[key]
+        out_keys[key][len_left:] = right[key]
+    idx_sort = out_keys.argsort(order=keys)
+    out_keys = out_keys[idx_sort]
+
+    # Get all keys
+    diffs = np.concatenate(([True], out_keys[1:] != out_keys[:-1], [True]))
+    idxs = np.flatnonzero(diffs)
+
+    # Main inner loop in Cython to compute the cartesion product
+    # indices for the given join type
+    int_join_type = {'inner': 0, 'outer': 1, 'left': 2, 'right': 3}[join_type]
+    masked, n_out, left_out, left_mask, right_out, right_mask = \
+        _np_utils.join_inner(idxs, idx_sort, len_left, int_join_type)
+
+    # If either of the inputs are masked then the output is masked
+    if left.masked or right.masked:
+        masked = True
+    masked = bool(masked)
+
+    out = _get_out_class([left, right])(masked=masked)
+
+    for out_name, dtype, shape in out_descrs:
+
+        left_name, right_name = col_name_map[out_name]
+        if left_name and right_name:  # this is a key which comes from left and right
+            out[out_name] = out.ColumnClass(length=n_out, name=out_name, dtype=dtype, shape=shape)
+            out[out_name] = np.where(right_mask,
+                                     left[left_name].take(left_out),
+                                     right[right_name].take(right_out))
+            continue
+        elif left_name:  # out_name came from the left table
+            name, array, array_out, array_mask = left_name, left, left_out, left_mask
+        elif right_name:
+            name, array, array_out, array_mask = right_name, right, right_out, right_mask
+        else:
+            raise TableMergeError('Unexpected column names (maybe one is ""?)')
+
+        # Finally add the joined column to the output table.
+        out[out_name] = array[name][array_out]
+        _col_update_attrs_from(out[out_name], array[name])
+
+        # If the output table is masked then set the output column masking
+        # accordingly.  Check for columns that don't support a mask attribute.
+        if masked:
+            if array.masked:
+                array_mask = array_mask | array[name].mask.take(array_out)
+            try:
+                out[out_name].mask[:] = array_mask
+            except ValueError:
+                raise ValueError("join requires masking column '{0}' but column"
+                                 " type {1} does not support masking"
+                                 .format(out_name, out[out_name].__class__.__name__))
+
+    # If col_name_map supplied as a dict input, then update.
+    if isinstance(_col_name_map, collections.Mapping):
+        _col_name_map.update(col_name_map)
+
+    return out
+
+
+def _vstack(arrays, join_type='inner', col_name_map=None):
+    """
+    Stack Tables vertically (by rows)
+
+    A ``join_type`` of 'exact' (default) means that the arrays must all
+    have exactly the same column names (though the order can vary).  If
+    ``join_type`` is 'inner' then the intersection of common columns will
+    be output.  A value of 'outer' means the output will have the union of
+    all columns, with array values being masked where no common values are
+    available.
+
+    Parameters
+    ----------
+    arrays : list of Tables
+        Tables to stack by rows (vertically)
+    join_type : str
+        Join type ('inner' | 'exact' | 'outer'), default is 'exact'
+    col_name_map : empty dict or None
+        If passed as a dict then it will be updated in-place with the
+        mapping of output to input column names.
+
+    Returns
+    -------
+    stacked_table : `~astropy.table.Table` object
+        New table containing the stacked data from the input tables.
+    """
+    # Store user-provided col_name_map until the end
+    _col_name_map = col_name_map
+
+    # Input validation
+    if join_type not in ('inner', 'exact', 'outer'):
+        raise ValueError("`join_type` arg must be one of 'inner', 'exact' or 'outer'")
+
+    # Trivial case of one input array
+    if len(arrays) == 1:
+        return arrays[0]
+
+    for arr in arrays:
+        if arr.has_mixin_columns:
+            raise NotImplementedError('vstack not available for tables with mixin columns')
+
+    # Start by assuming an outer match where all names go to output
+    names = set(itertools.chain(*[arr.colnames for arr in arrays]))
+    col_name_map = get_col_name_map(arrays, names)
+
+    # If require_match is True then the output must have exactly the same
+    # number of columns as each input array
+    if join_type == 'exact':
+        for names in six.itervalues(col_name_map):
+            if any(x is None for x in names):
+                raise TableMergeError('Inconsistent columns in input arrays '
+                                      "(use 'inner' or 'outer' join_type to "
+                                      "allow non-matching columns)")
+        join_type = 'outer'
+
+    # For an inner join, keep only columns where all input arrays have that column
+    if join_type == 'inner':
+        col_name_map = OrderedDict((name, in_names) for name, in_names in six.iteritems(col_name_map)
+                                   if all(x is not None for x in in_names))
+        if len(col_name_map) == 0:
+            raise TableMergeError('Input arrays have no columns in common')
+
+    # If there are any output columns where one or more input arrays are missing
+    # then the output must be masked.  If any input arrays are masked then
+    # output is masked.
+    masked = any(getattr(arr, 'masked', False) for arr in arrays)
+    for names in six.itervalues(col_name_map):
+        if any(x is None for x in names):
+            masked = True
+            break
+
+    lens = [len(arr) for arr in arrays]
+    n_rows = sum(lens)
+    out = _get_out_class(arrays)(masked=masked)
+    out_descrs = get_descrs(arrays, col_name_map)
+    for out_descr in out_descrs:
+        name = out_descr[0]
+        dtype = out_descr[1:]
+        if masked:
+            out[name] = ma.array(data=np.zeros(n_rows, dtype),
+                                 mask=np.ones(n_rows, ma.make_mask_descr(dtype)))
+        else:
+            out[name] = np.empty(n_rows, dtype=dtype)
+
+    for out_name, in_names in six.iteritems(col_name_map):
+        idx0 = 0
+        for name, array in zip(in_names, arrays):
+            idx1 = idx0 + len(array)
+            if name in array.colnames:
+                out[out_name][idx0:idx1] = array[name]
+            idx0 = idx1
+
+    # If col_name_map supplied as a dict input, then update.
+    if isinstance(_col_name_map, collections.Mapping):
+        _col_name_map.update(col_name_map)
+
+    return out
+
+
+def _hstack(arrays, join_type='exact', uniq_col_name='{col_name}_{table_name}',
+           table_names=None, col_name_map=None):
+    """
+    Stack tables horizontally (by columns)
+
+    A ``join_type`` of 'exact' (default) means that the arrays must all
+    have exactly the same number of rows.  If ``join_type`` is 'inner' then
+    the intersection of rows will be output.  A value of 'outer' means
+    the output will have the union of all rows, with array values being
+    masked where no common values are available.
+
+    Parameters
+    ----------
+    arrays : List of tables
+        Tables to stack by columns (horizontally)
+    join_type : str
+        Join type ('inner' | 'exact' | 'outer'), default is 'exact'
+    uniq_col_name : str or None
+        String generate a unique output column name in case of a conflict.
+        The default is '{col_name}_{table_name}'.
+    table_names : list of str or None
+        Two-element list of table names used when generating unique output
+        column names.  The default is ['1', '2', ..].
+
+    Returns
+    -------
+    stacked_table : `~astropy.table.Table` object
+        New table containing the stacked data from the input tables.
+    """
+
+    # Store user-provided col_name_map until the end
+    _col_name_map = col_name_map
+
+    # Input validation
+    if join_type not in ('inner', 'exact', 'outer'):
+        raise ValueError("join_type arg must be either 'inner', 'exact' or 'outer'")
+
+    if table_names is None:
+        table_names = ['{0}'.format(ii + 1) for ii in range(len(arrays))]
+    if len(arrays) != len(table_names):
+        raise ValueError('Number of arrays must match number of table_names')
+
+    # Trivial case of one input arrays
+    if len(arrays) == 1:
+        return arrays[0]
+
+    col_name_map = get_col_name_map(arrays, [], uniq_col_name, table_names)
+
+    # If require_match is True then all input arrays must have the same length
+    arr_lens = [len(arr) for arr in arrays]
+    if join_type == 'exact':
+        if len(set(arr_lens)) > 1:
+            raise TableMergeError("Inconsistent number of rows in input arrays "
+                                  "(use 'inner' or 'outer' join_type to allow "
+                                  "non-matching rows)")
+        join_type = 'outer'
+
+    # For an inner join, keep only the common rows
+    if join_type == 'inner':
+        min_arr_len = min(arr_lens)
+        if len(set(arr_lens)) > 1:
+            arrays = [arr[:min_arr_len] for arr in arrays]
+        arr_lens = [min_arr_len for arr in arrays]
+
+    # If there are any output rows where one or more input arrays are missing
+    # then the output must be masked.  If any input arrays are masked then
+    # output is masked.
+    masked = any(getattr(arr, 'masked', False) for arr in arrays) or len(set(arr_lens)) > 1
+
+    n_rows = max(arr_lens)
+    out = _get_out_class(arrays)(masked=masked)
+
+    for out_name, in_names in six.iteritems(col_name_map):
+        for name, array, arr_len in zip(in_names, arrays, arr_lens):
+            if name is None:
+                continue
+
+            if n_rows > arr_len:
+                indices = np.arange(n_rows)
+                indices[arr_len:] = 0
+                out[out_name] = array[name][indices]
+                try:
+                    out[out_name].mask[arr_len:] = True
+                except ValueError:
+                    raise ValueError("hstack requires masking column '{0}' but column"
+                                     " type {1} does not support masking"
+                                     .format(out_name, out[out_name].__class__.__name__))
+            else:
+                out[out_name] = array[name][:n_rows]
+
+            _col_update_attrs_from(out[out_name], array[name])
+
+    # If col_name_map supplied as a dict input, then update.
+    if isinstance(_col_name_map, collections.Mapping):
+        _col_name_map.update(col_name_map)
+
+    return out
diff --git a/astropy/table/pprint.py b/astropy/table/pprint.py
index e5f99c9..7709124 100644
--- a/astropy/table/pprint.py
+++ b/astropy/table/pprint.py
@@ -170,8 +170,8 @@ class TableFormatter(object):
             max_lines = lines
         elif max_lines < 0:
             max_lines = sys.maxsize
-        if max_lines < 6:
-            max_lines = 6
+        if max_lines < 8:
+            max_lines = 8
 
         if max_width is None:
             max_width = width
@@ -183,7 +183,8 @@ class TableFormatter(object):
         return max_lines, max_width
 
 
-    def _pformat_col(self, col, max_lines=None, show_name=True, show_unit=None):
+    def _pformat_col(self, col, max_lines=None, show_name=True, show_unit=None,
+                     show_dtype=False, show_length=None, html=False):
         """Return a list of formatted string representation of column values.
 
         Parameters
@@ -199,6 +200,16 @@ class TableFormatter(object):
             for units only if one or more columns has a defined value
             for the unit.
 
+        show_dtype : bool
+            Include column dtype (default=False)
+
+        show_length : bool
+            Include column length at end.  Default is to show this only
+            if the column is not shown completely.
+
+        html : bool
+            Output column as HTML
+
         Returns
         -------
         lines : list
@@ -208,24 +219,56 @@ class TableFormatter(object):
             Number of lines in the header
 
         """
+        if show_unit is None:
+            show_unit = getattr(col, 'unit', None) is not None
+
         outs = {}  # Some values from _pformat_col_iter iterator that are needed here
-        col_strs = list(self._pformat_col_iter(col, max_lines, show_name, show_unit, outs))
-        col_width = max(len(x) for x in col_strs)
+        col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name, show_unit=show_unit,
+                                               show_dtype=show_dtype, show_length=show_length,
+                                               outs=outs)
+        col_strs = list(col_strs_iter)
+
+        if html:
+            from ..utils.xml.writer import xml_escape
+            n_header = outs['n_header']
+            for i, col_str in enumerate(col_strs):
+                # _pformat_col output has a header line '----' which is not needed here
+                if i == n_header - 1:
+                    continue
+                td = 'th' if i < n_header else 'td'
+                val = '<{0}>{1}</{2}>'.format(td, xml_escape(col_str.strip()), td)
+                row = ('<tr>' + val + '</tr>')
+                if i < n_header:
+                    row = ('<thead>' + row + '</thead>')
+                col_strs[i] = row
+
+            if n_header > 0:
+                # Get rid of '---' header line
+                col_strs.pop(n_header - 1)
+            col_strs.insert(0, '<table>')
+            col_strs.append('</table>')
+
+        else:
+            col_width = max(len(x) for x in col_strs) if col_strs else 1
 
-        # Center line content and generate dashed headerline
-        for i in outs['i_centers']:
-            col_strs[i] = col_strs[i].center(col_width)
-        if outs['i_dashes'] is not None:
-            col_strs[outs['i_dashes']] = '-' * col_width
+            # Center line content and generate dashed headerline
+            for i in outs['i_centers']:
+                col_strs[i] = col_strs[i].center(col_width)
+            if outs['i_dashes'] is not None:
+                col_strs[outs['i_dashes']] = '-' * col_width
 
-        # Now bring all the column string values to the same fixed width
-        for i, col_str in enumerate(col_strs):
-            col_strs[i] = col_str.rjust(col_width)
+            # Now bring all the column string values to the same fixed width
+            for i, col_str in enumerate(col_strs):
+                col_strs[i] = col_str.rjust(col_width)
 
-        return col_strs, outs['n_header']
+        if outs['show_length']:
+            col_strs.append('Length = {0} rows'.format(len(col)))
 
+        return col_strs, outs
 
-    def _pformat_col_iter(self, col, max_lines, show_name, show_unit, outs):
+
+    def _pformat_col_iter(self, col, max_lines, show_name, show_unit, outs,
+                          show_dtype=False, show_length=None):
         """Iterator which yields formatted string representation of column values.
 
         Parameters
@@ -241,13 +284,21 @@ class TableFormatter(object):
             for units only if one or more columns has a defined value
             for the unit.
 
+        show_dtype : bool
+            Include column dtype (default=False)
+
+        show_length : bool
+            Include column length at end.  Default is to show this only
+            if the column is not shown completely.
+
         out : dict
             Must be a dict which is used to pass back additional values
             defined within the iterator.
         """
+        from .column import col_getattr
         max_lines, _ = self._get_pprint_size(max_lines, -1)
 
-        multidims = col.shape[1:]
+        multidims = getattr(col, 'shape', [0])[1:]
         if multidims:
             multidim0 = tuple(0 for n in multidims)
             multidim1 = tuple(n - 1 for n in multidims)
@@ -259,7 +310,7 @@ class TableFormatter(object):
         if show_name:
             i_centers.append(n_header)
             # Get column name (or 'None' if not set)
-            col_name = six.text_type(col.name)
+            col_name = six.text_type(col_getattr(col, 'name'))
             if multidims:
                 col_name += ' [{0}]'.format(
                     ','.join(six.text_type(n) for n in multidims))
@@ -268,8 +319,16 @@ class TableFormatter(object):
         if show_unit:
             i_centers.append(n_header)
             n_header += 1
-            yield six.text_type(col.unit or '')
-        if show_unit or show_name:
+            yield six.text_type(getattr(col, 'unit', None) or '')
+        if show_dtype:
+            i_centers.append(n_header)
+            n_header += 1
+            try:
+                dtype = col.dtype.name
+            except AttributeError:
+                dtype = 'object'
+            yield six.text_type(dtype)
+        if show_unit or show_name or show_dtype:
             i_dashes = n_header
             n_header += 1
             yield '---'
@@ -278,9 +337,12 @@ class TableFormatter(object):
         n_print2 = max_lines // 2
         n_rows = len(col)
 
-        format_func = _format_funcs.get(col.format, _auto_format_func)
+        col_format = col_getattr(col, 'format')
+        format_func = _format_funcs.get(col_format, _auto_format_func)
         if len(col) > max_lines:
-            i0 = n_print2
+            if show_length is None:
+                show_length = True
+            i0 = n_print2 - (1 if show_length else 0)
             i1 = n_rows - n_print2 - max_lines % 2
         else:
             i0 = len(col)
@@ -290,28 +352,30 @@ class TableFormatter(object):
         for i in xrange(n_rows):
             if i < i0 or i > i1:
                 if multidims:
-                    # Prevents colums like Column(data=[[(1,)],[(2,)]], name='a')
+                    # Prevents columns like Column(data=[[(1,)],[(2,)]], name='a')
                     # with shape (n,1,...,1) from being printed as if there was
                     # more than one element in a row
                     if trivial_multidims:
-                        col_str = format_func(col.format, col[(i,) + multidim0])
+                        col_str = format_func(col_format, col[(i,) + multidim0])
                     else:
-                        col_str = (format_func(col.format, col[(i,) + multidim0]) +
+                        col_str = (format_func(col_format, col[(i,) + multidim0]) +
                                   ' .. ' +
-                                  format_func(col.format, col[(i,) + multidim1]))
+                                  format_func(col_format, col[(i,) + multidim1]))
                 else:
-                    col_str = format_func(col.format, col[i])
+                    col_str = format_func(col_format, col[i])
                 yield col_str
             elif i == i0:
                 yield '...'
 
+        outs['show_length'] = show_length
         outs['n_header'] = n_header
         outs['i_centers'] = i_centers
         outs['i_dashes'] = i_dashes
 
 
     def _pformat_table(self, table, max_lines=None, max_width=None, show_name=True,
-                       show_unit=None, html=False, tableid=None):
+                       show_unit=None, show_dtype=False,
+                       html=False, tableid=None):
         """Return a list of lines for the formatted string representation of
         the table.
 
@@ -331,6 +395,9 @@ class TableFormatter(object):
             for units only if one or more columns has a defined value
             for the unit.
 
+        show_dtype : bool
+            Include a header row for column dtypes (default=False)
+
         html : bool
             Format the output as an HTML table (default=False)
 
@@ -353,13 +420,18 @@ class TableFormatter(object):
         cols = []
 
         if show_unit is None:
-            show_unit = any([col.unit for col in six.itervalues(table.columns)])
+            show_unit = any([getattr(col, 'unit', None) for col in six.itervalues(table.columns)])
 
         for col in six.itervalues(table.columns):
-            lines, n_header = self._pformat_col(col, max_lines, show_name,
-                                                show_unit)
+            lines, outs = self._pformat_col(col, max_lines, show_name=show_name,
+                                            show_unit=show_unit, show_dtype=show_dtype)
+            if outs['show_length']:
+                lines = lines[:-1]
             cols.append(lines)
 
+        # Use the values for the last column since they are all the same
+        n_header = outs['n_header']
+
         if not cols:
             return []
 
@@ -404,11 +476,11 @@ class TableFormatter(object):
                 row = ' '.join(col[i] for col in cols)
                 rows.append(row)
 
-        return rows, n_header
+        return rows, outs
 
 
     def _more_tabcol(self, tabcol, max_lines=None, max_width=None, show_name=True,
-                     show_unit=None):
+                     show_unit=None, show_dtype=False):
         """Interactive "more" of a table or column.
 
         Parameters
@@ -426,6 +498,9 @@ class TableFormatter(object):
             Include a header row for unit.  Default is to show a row
             for units only if one or more columns has a defined value
             for the unit.
+
+        show_dtype : bool
+            Include a header row for column dtypes (default=False)
         """
         allowed_keys = 'f br<>qhpn'
 
@@ -435,11 +510,14 @@ class TableFormatter(object):
             n_header += 1
         if show_unit:
             n_header += 1
-        if show_name or show_unit:
+        if show_dtype:
+            n_header += 1
+        if show_name or show_unit or show_dtype:
             n_header += 1
 
         # Set up kwargs for pformat call.  Only Table gets max_width.
-        kwargs = dict(max_lines=-1, show_name=show_name, show_unit=show_unit)
+        kwargs = dict(max_lines=-1, show_name=show_name, show_unit=show_unit,
+                      show_dtype=show_dtype)
         if hasattr(tabcol, 'columns'):  # tabcol is a table
             kwargs['max_width'] = max_width
 
diff --git a/astropy/table/row.py b/astropy/table/row.py
index 1c70241..171ac61 100644
--- a/astropy/table/row.py
+++ b/astropy/table/row.py
@@ -10,6 +10,7 @@ import numpy as np
 from numpy import ma
 
 from ..extern import six
+from ..utils import deprecated
 
 class Row(object):
     """A class to represent one row of a Table object.
@@ -34,52 +35,17 @@ class Row(object):
     def __init__(self, table, index):
         self._table = table
         self._index = index
-        try:
-            self._data = table._data[index]
-
-            # MaskedArray __getitem__ has a strange behavior where if a
-            # row mask is all False then it returns a np.void which
-            # has no mask attribute. This makes it impossible to then set
-            # the mask. Here we recast back to mvoid. This was fixed in
-            # Numpy following issue numpy/numpy#483, and the fix should be
-            # included in Numpy 1.8.0.
-            if self._table.masked and isinstance(self._data, np.void):
-                self._data = ma.core.mvoid(self._data,
-                                           mask=self._table._mask[index])
-        except ValueError as err:
-            # Another bug (or maybe same?) that is fixed in 1.8 prevents
-            # accessing a row in masked array if it has object-type members.
-            # >>> x = np.ma.empty(1, dtype=[('a', 'O')])
-            # >>> x['a'] = 1
-            # >>> x['a'].mask = True
-            # >>> x[0]
-            # ValueError: Setting void-array with object members using buffer. [numpy.ma.core]
-            #
-            # All we do here is re-raise with a more informative message
-            if (six.text_type(err).startswith('Setting void-array with object members')
-                    and version.LooseVersion(np.__version__) < version.LooseVersion('1.8')):
-                raise ValueError('Cannot access table row with Object type columns, due to '
-                                 'a bug in numpy {0}.  Please upgrade to numpy 1.8 or newer.'
-                                 .format(np.__version__))
-            else:
-                raise
+
+        n = len(table)
+        if index < -n or index >= n:
+            raise IndexError('index {0} out of range for table with length {1}'
+                             .format(index, len(table)))
 
     def __getitem__(self, item):
-        return self.data[item]
+        return self._table.columns[item][self._index]
 
     def __setitem__(self, item, val):
-        if self._table.masked:
-            # Workaround for astropy/astropy#2734 and numpy/numpy#4866:
-            # Assignment to a masked array containing a recarray object doesn't
-            # work properly when being assigned in [row][colname] order.
-            # Instead go back to the parent table and do [colname][row] order.
-            #
-            # Note also that in the masked case the Row object is not a direct
-            # view of the data so we need to set in the table and in self.data.
-            col = self._table.columns[item]  # works for index or col name
-            col[self._index] = val
-
-        self.data[item] = val
+        self._table.columns[item][self._index] = val
 
     def __eq__(self, other):
         if self._table.masked:
@@ -87,30 +53,33 @@ class Row(object):
             # "Comparing rows in a structured masked array raises exception"
             # No response, so this is still unresolved.
             raise ValueError('Unable to compare rows for masked table due to numpy.ma bug')
-        return self.data == other
+        return self.as_void() == other
 
     def __ne__(self, other):
         if self._table.masked:
             raise ValueError('Unable to compare rows for masked table due to numpy.ma bug')
-        return self.data != other
-
-    @property
-    def _mask(self):
-        return self._data.mask
+        return self.as_void() != other
 
     def __array__(self, dtype=None):
         """Support converting Row to np.array via np.array(table).
 
         Coercion to a different dtype via np.array(table, dtype) is not
         supported and will raise a ValueError.
+
+        If the parent table is masked then the mask information is dropped.
         """
         if dtype is not None:
             raise ValueError('Datatype coercion is not allowed')
 
-        return np.array(self._data)
+        return np.asarray(self.as_void())
 
     def __len__(self):
-        return len(self._data.dtype)
+        return len(self._table.columns)
+
+    def __iter__(self):
+        index = self._index
+        for col in six.itervalues(self._table.columns):
+            yield col[index]
 
     @property
     def table(self):
@@ -121,30 +90,90 @@ class Row(object):
         return self._index
 
     @property
+    @deprecated('0.4', alternative=':attr:`Row.as_void`')
     def data(self):
-        return self._data
+        """
+        Returns a *read-only* copy of the row values in the form of np.void or
+        np.ma.mvoid objects.  This corresponds to the object types returned for
+        row indexing of a pure numpy structured array or masked array. This
+        method is slow and its use is deprecated.
+        """
+        return self.as_void()
+
+    def as_void(self):
+        """
+        Returns a *read-only* copy of the row values in the form of np.void or
+        np.ma.mvoid objects.  This corresponds to the object types returned for
+        row indexing of a pure numpy structured array or masked array. This
+        method is slow and its use is discouraged when possible.
+
+        Returns
+        -------
+        void_row : np.void (unmasked) or np.ma.mvoid (masked)
+            Copy of row values
+        """
+        index = self._index
+        cols = self._table.columns.values()
+        vals = tuple(np.asarray(col)[index] for col in cols)
+        if self._table.masked:
+            # The logic here is a little complicated to work around
+            # bug in numpy < 1.8 (numpy/numpy#483).  Need to build up
+            # a np.ma.mvoid object by hand.
+            from .table import descr
+
+            # Make np.void version of masks.  Use the table dtype but
+            # substitute bool for data type
+            masks = tuple(col.mask[index] if hasattr(col, 'mask') else False
+                          for col in cols)
+            descrs = (descr(col) for col in cols)
+            mask_dtypes = [(name, np.bool, shape) for name, type_, shape in descrs]
+            row_mask = np.array([masks], dtype=mask_dtypes)[0]
+
+            # Make np.void version of values, and then the final mvoid row
+            row_vals = np.array([vals], dtype=self.dtype)[0]
+            try:
+                void_row = np.ma.mvoid(data=row_vals, mask=row_mask)
+            except ValueError as err:
+                # Another bug (or maybe same?) that is fixed in 1.8 prevents
+                # accessing a row in masked array if it has object-type members.
+                # >>> x = np.ma.empty(1, dtype=[('a', 'O')])
+                # >>> x['a'] = 1
+                # >>> x['a'].mask = True
+                # >>> x[0]
+                # ValueError: Setting void-array with object members using buffer. [numpy.ma.core]
+                #
+                # All we do here is re-raise with a more informative message
+                if (six.text_type(err).startswith('Setting void-array with object members')
+                        and version.LooseVersion(np.__version__) < version.LooseVersion('1.8')):
+                    raise ValueError('Cannot convert masked table row with Object type columns '
+                                     'using as_void(), due to a bug in numpy {0}.  Please upgrade '
+                                     'to numpy 1.8 or newer.'
+                                     .format(np.__version__))
+                else:
+                    raise
+        else:
+            void_row = np.array([vals], dtype=self.dtype)[0]
+        return void_row
 
     @property
     def meta(self):
-        return self.table.meta
+        return self._table.meta
 
     @property
     def columns(self):
-        return self.table.columns
+        return self._table.columns
 
     @property
     def colnames(self):
-        return self.table.colnames
+        return self._table.colnames
 
     @property
     def dtype(self):
-        return self.data.dtype
+        return self._table.dtype
 
     def __repr__(self):
         return "<{3} {0} of table\n values={1!r}\n dtype={2}>".format(
-            self.index, self.data, self.dtype, self.__class__.__name__)
+            self.index, self.as_void(), self.dtype, self.__class__.__name__)
 
 
 collections.Sequence.register(Row)
-
-
diff --git a/astropy/table/table.py b/astropy/table/table.py
index e8adfea..f9ae270 100644
--- a/astropy/table/table.py
+++ b/astropy/table/table.py
@@ -5,7 +5,6 @@ from ..extern import six
 from ..extern.six.moves import zip as izip
 from ..extern.six.moves import range as xrange
 
-import warnings
 import re
 
 from copy import deepcopy
@@ -16,14 +15,14 @@ from numpy import ma
 
 from .. import log
 from ..io import registry as io_registry
-from ..units import Quantity
+from ..units import Quantity, Unit
 from ..utils import OrderedDict, isiterable, deprecated
 from ..utils.console import color_print
-from ..utils.exceptions import AstropyDeprecationWarning
 from ..utils.metadata import MetaData
 from . import groups
 from .pprint import TableFormatter
-from .column import BaseColumn, Column, MaskedColumn, _auto_names
+from .column import (BaseColumn, Column, MaskedColumn, _auto_names, FalseArray,
+                     col_getattr, col_setattr, col_copy, _col_update_attrs_from)
 from .row import Row
 from .np_utils import fix_column_name, recarray_fromrecords
 
@@ -41,6 +40,30 @@ __doctest_skip__ = ['Table.read', 'Table.write',
                     ]
 
 
+def descr(col):
+    """Array-interface compliant full description of a column.
+
+    This returns a 3-tuple (name, type, shape) that can always be
+    used in a structured array dtype definition.
+    """
+    col_dtype_str = col.dtype.str if hasattr(col, 'dtype') else 'O'
+    col_shape = col.shape[1:] if hasattr(col, 'shape') else ()
+    return (col_getattr(col, 'name'), col_dtype_str, col_shape)
+
+
+def is_mixin_class(obj):
+    """
+    Abstraction to determine if ``obj`` should be used as a mixin column
+    when input to a table.  This function does not apply to ``Quantity``.
+
+    Parameters
+    ----------
+    obj : object
+        Object being queried for mixin compatibility
+    """
+    return hasattr(obj, '_astropy_column_attrs')
+
+
 class TableColumns(OrderedDict):
     """OrderedDict subclass for a set of columns.
 
@@ -60,9 +83,16 @@ class TableColumns(OrderedDict):
 
     def __init__(self, cols={}):
         if isinstance(cols, (list, tuple)):
-            # check for Columns in the list
-            cols = [((col.name, col) if hasattr(col, 'name') else col)
-                    for col in cols]
+            # `cols` should be a list of two-tuples, but it is allowed to have
+            # columns (BaseColumn or mixins) in the list.
+            newcols = []
+            for col in cols:
+                if (isinstance(col, (BaseColumn, Quantity))
+                        or is_mixin_class(col)):
+                    newcols.append((col_getattr(col, 'name'), col))
+                else:
+                    newcols.append(col)
+            cols = newcols
         super(TableColumns, self).__init__(cols)
 
     def __getitem__(self, item):
@@ -151,11 +181,44 @@ class Table(object):
     TableColumns = TableColumns
     TableFormatter = TableFormatter
 
+    @property
+    @deprecated('0.4', alternative=':attr:`Table.as_array`')
+    def _data(self):
+        """
+        Return a new copy of the table in the form of a structured np.ndarray or
+        np.ma.MaskedArray object (as appropriate).
+
+        Prior to version 1.0 of astropy this private property was a modifiable
+        view of the table data, but since 1.0 it is a copy.
+        """
+        return self.as_array()
+
+    def as_array(self):
+        """
+        Return a new copy of the table in the form of a structured np.ndarray or
+        np.ma.MaskedArray object (as appropriate).
+
+        Returns
+        -------
+        table_array : np.ndarray (unmasked) or np.ma.MaskedArray (masked)
+            Copy of table as a numpy structured array
+        """
+        if len(self.columns) == 0:
+            return None
+
+        cols = self.columns.values()
+        dtype = [descr(col) for col in cols]
+        empty_init = ma.empty if self.masked else np.empty
+        data = empty_init(len(self), dtype=dtype)
+        for col in cols:
+            data[col_getattr(col, 'name')] = col
+
+        return data
+
     def __init__(self, data=None, masked=None, names=None, dtype=None,
                  meta=None, copy=True, rows=None):
 
         # Set up a placeholder empty table
-        self._data = None
         self._set_masked(masked)
         self.columns = self.TableColumns()
         self.meta = meta
@@ -258,16 +321,23 @@ class Table(object):
 
     @property
     def mask(self):
-        return self._data.mask if self.masked else None
+        # Dynamic view of available masks
+        if self.masked:
+            return Table([col.mask for col in self.columns.values()],
+                         names=self.colnames, copy=False)
+        else:
+            return None
 
     @mask.setter
     def mask(self, val):
-        self._data.mask = val
+        self.mask[:] = val
 
     @property
     def _mask(self):
-        """This is needed due to intricacies in numpy.ma, don't remove it."""
-        return self._data.mask
+        """This is needed so that comparison of a masked Table and a
+        MaskedArray works.  The requirement comes from numpy.ma.core
+        so don't remove this property."""
+        return self.as_array().mask
 
     def filled(self, fill_value=None):
         """Return a copy of self, with masked values filled.
@@ -310,39 +380,10 @@ class Table(object):
         # array([(0, 0), (0, 0)],
         #       dtype=[('a', '<i8'), ('b', '<i8')])
 
-        return self._data.data if self.masked else self._data
-
-    def _rebuild_table_column_views(self):
-        """
-        Some table manipulations can corrupt the Column views of self._data.
-        This function will cleanly rebuild the columns and self.columns.
-        This is a slightly subtle operation, see comments.
-        """
-        cols = []
-        for col in six.itervalues(self.columns):
-            # First make a new column based on the name and the original
-            # column.  This step is needed because the table manipulation
-            # may have changed the table masking so that the original data
-            # columns no longer correspond to self.ColumnClass.  This uses
-            # data refs, not copies.
-            newcol = self.ColumnClass(name=col.name, data=col)
-
-            # Now use the copy() method to copy the column and its metadata,
-            # but at the same time set the column data to a view of
-            # self._data[col.name].  Somewhat confusingly in this case
-            # copy() refers to copying the column attributes, but the data
-            # are used by reference.
-            newcol = newcol.copy(data=self._data[col.name])
-
-            # Make column aware of the parent table
-            newcol.parent_table = self
-
-            cols.append(newcol)
-
-        self.columns = self.TableColumns(cols)
+        return self.as_array().data if self.masked else self.as_array()
 
     def _check_names_dtype(self, names, dtype, n_cols):
-        """Make sure that names and dtype are boths iterable and have
+        """Make sure that names and dtype are both iterable and have
         the same length as data.
         """
         for inp_list, inp_str in ((dtype, 'dtype'), (names, 'names')):
@@ -364,12 +405,31 @@ class Table(object):
             if any(np.any(col.mask) for col in cols if isinstance(col, (MaskedColumn, ma.MaskedArray))):
                 self._set_masked(True)
 
+    def _init_from_list_of_dicts(self, data, names, dtype, n_cols, copy):
+        names_from_data = set()
+        for row in data:
+            names_from_data.update(row)
+
+        cols = {}
+        for name in names_from_data:
+            cols[name] = []
+            for i, row in enumerate(data):
+                try:
+                    cols[name].append(row[name])
+                except KeyError:
+                    raise ValueError('Row {0} has no value for column {1}'.format(i, name))
+        if all(name is None for name in names):
+            names = sorted(names_from_data)
+        self._init_from_dict(cols, names, dtype, n_cols, copy)
+        return
+
     def _init_from_list(self, data, names, dtype, n_cols, copy):
         """Initialize table from a list of columns.  A column can be a
-        Column object, np.ndarray, or any other iterable object.
+        Column object, np.ndarray, mixin, or any other iterable object.
         """
-        if not copy:
-            raise ValueError('Cannot use copy=False with a list data input')
+        if data and all(isinstance(row, dict) for row in data):
+            self._init_from_list_of_dicts(data, names, dtype, n_cols, copy)
+            return
 
         # Set self.masked appropriately, then get class to create column instances.
         self._set_masked_from_cols(data)
@@ -377,32 +437,25 @@ class Table(object):
         cols = []
         def_names = _auto_names(n_cols)
 
-        if data and all(isinstance(row, dict) for row in data):
-            names_from_data = set()
-            for row in data:
-                names_from_data.update(row)
-
-            cols = {}
-            for name in names_from_data:
-                cols[name] = []
-                for i, row in enumerate(data):
-                    try:
-                        cols[name].append(row[name])
-                    except KeyError:
-                        raise ValueError('Row {0} has no value for column {1}'.format(i, name))
-            if all(name is None for name in names):
-                names = sorted(names_from_data)
-            self._init_from_dict(cols, names, dtype, n_cols, copy)
-            return
-
         for col, name, def_name, dtype in zip(data, names, def_names, dtype):
             if isinstance(col, (Column, MaskedColumn)):
-                col = self.ColumnClass(name=(name or col.name), data=col, dtype=dtype)
+                col = self.ColumnClass(name=(name or col_getattr(col, 'name')),
+                                       data=col, dtype=dtype,
+                                       copy=copy)
+            elif self._is_mixin_column(col):
+                # Copy the mixin column attributes if they exist since the copy below
+                # may not get this attribute.
+                if copy:
+                    col = col_copy(col)
+
+                col_setattr(col, 'name', name or col_getattr(col, 'name') or def_name)
             elif isinstance(col, np.ndarray) or isiterable(col):
-                col = self.ColumnClass(name=(name or def_name), data=col, dtype=dtype)
+                col = self.ColumnClass(name=(name or def_name), data=col, dtype=dtype,
+                                       copy=copy)
             else:
                 raise ValueError('Elements in list initialization must be '
                                  'either Column or list-like')
+
             cols.append(col)
 
         self._init_from_cols(cols)
@@ -424,17 +477,18 @@ class Table(object):
             self._init_from_list(cols, names, dtype, n_cols, copy)
         else:
             dtype = [(name, col.dtype, col.shape[1:]) for name, col in zip(names, cols)]
-            self._data = data.view(dtype).ravel()
+            newdata = data.view(dtype).ravel()
             columns = self.TableColumns()
 
             for name in names:
-                columns[name] = self.ColumnClass(name=name, data=self._data[name])
-                columns[name].parent_table = self
+                columns[name] = self.ColumnClass(name=name, data=newdata[name])
+                col_setattr(columns[name], 'parent_table', self)
             self.columns = columns
 
     def _init_from_dict(self, data, names, dtype, n_cols, copy):
         """Initialize table from a dictionary of columns"""
 
+        # TODO: is this restriction still needed with no ndarray?
         if not copy:
             raise ValueError('Cannot use copy=False with a dict data input')
 
@@ -445,42 +499,41 @@ class Table(object):
         """Initialize table from an existing Table object """
 
         table = data  # data is really a Table, rename for clarity
-        data_names = table.colnames
         self.meta.clear()
         self.meta.update(deepcopy(table.meta))
-        cols = list(six.itervalues(table.columns))
-
-        # Set self.masked appropriately from cols
-        self._set_masked_from_cols(cols)
+        cols = list(table.columns.values())
 
-        if copy:
-            self._init_from_list(cols, names, dtype, n_cols, copy)
-        else:
-            names = [vals[0] or vals[1] for vals in zip(names, data_names)]
-            dtype = [(name, col.dtype) for name, col in zip(names, cols)]
-            data = table._data.view(dtype)
-
-            self._update_table_from_cols(self, data, cols, names)
+        self._init_from_list(cols, names, dtype, n_cols, copy)
 
     def _init_from_cols(self, cols):
         """Initialize table from a list of Column objects"""
 
-        lengths = set(len(col.data) for col in cols)
+        lengths = set(len(col) for col in cols)
         if len(lengths) != 1:
             raise ValueError('Inconsistent data column lengths: {0}'
                              .format(lengths))
 
+        # Set the table masking
         self._set_masked_from_cols(cols)
-        cols = [self.ColumnClass(name=col.name, data=col) for col in cols]
 
-        names = [col.name for col in cols]
-        dtype = [col.descr for col in cols]
-        empty_init = ma.empty if self.masked else np.empty
-        data = empty_init(lengths.pop(), dtype=dtype)
+        # Make sure that all Column-based objects have class self.ColumnClass
+        newcols = []
         for col in cols:
-            data[col.name] = col.data
+            # Convert any Columns with units to Quantity for a QTable
+            if (isinstance(self, QTable) and isinstance(col, Column)
+                    and getattr(col, 'unit', None) is not None):
+
+                qcol = Quantity(col, unit=col.unit, copy=False)
+                _col_update_attrs_from(qcol, col, exclude_attrs=['unit', 'dtype', 'parent_table'])
 
-        self._update_table_from_cols(self, data, cols, names)
+                newcols.append(qcol)
+                continue
+
+            if isinstance(col, Column) and not col.__class__ is self.ColumnClass:
+                col = self.ColumnClass(col)  # copy attributes and reference data
+            newcols.append(col)
+
+        self._update_table_from_cols(self, newcols)
 
     def _new_from_slice(self, slice_):
         """Create a new table as a referenced slice from self."""
@@ -488,46 +541,71 @@ class Table(object):
         table = self.__class__(masked=self.masked)
         table.meta.clear()
         table.meta.update(deepcopy(self.meta))
-        cols = list(six.itervalues(self.columns))
-        names = [col.name for col in cols]
-        data = self._data[slice_]
+        cols = self.columns.values()
+        names = [col_getattr(col, 'name') for col in cols]
+        newcols = [col[slice_] for col in cols]
+
+        # Mixin column classes are not responsible for copying column attributes
+        # for item/slicing operations.  Do this here in table.
+        for name, col, newcol in zip(names, cols, newcols):
+            if is_mixin_class(col):
+                _col_update_attrs_from(newcol, col, exclude_attrs=['parent_table'])
 
-        self._update_table_from_cols(table, data, cols, names)
+        self._update_table_from_cols(table, newcols)
 
         return table
 
     @staticmethod
-    def _update_table_from_cols(table, data, cols, names):
+    def _update_table_from_cols(table, cols):
         """Update the existing ``table`` so that it represents the given
         ``data`` (a structured ndarray) with ``cols`` and ``names``."""
 
-        columns = table.TableColumns()
-        table._data = data
+        colnames = set(col_getattr(col, 'name') for col in cols)
+        if None in colnames:
+            raise TypeError('Cannot have None for column name')
+        if len(colnames) != len(cols):
+            raise ValueError('Duplicate column names')
+
+        columns = table.TableColumns((col_getattr(col, 'name'), col) for col in cols)
+
+        for col in cols:
+            col_setattr(col, 'parent_table', table)
+            if table.masked and not hasattr(col, 'mask'):
+                col.mask = FalseArray(col.shape)
 
-        for name, col in zip(names, cols):
-            newcol = col.copy(data=data[name], copy_data=False)
-            newcol.name = name
-            newcol.parent_table = table
-            columns[name] = newcol
         table.columns = columns
 
+    def _base_repr_(self, html=False):
+        descr_vals = [self.__class__.__name__]
+        for attr, val in (('masked', self.masked),
+                          ('length', len(self))):
+            descr_vals.append('{0}={1}'.format(attr, repr(val)))
+
+        descr = '<' + ' '.join(descr_vals) + '>\n'
+
+        if html:
+            from ..utils.xml.writer import xml_escape
+            descr = xml_escape(descr)
+
+        tableid = 'table{id}'.format(id=id(self))
+        data_lines, outs = self.formatter._pformat_table(self,
+            tableid=tableid, html=html, max_width=(-1 if html else None),
+            show_name=True, show_unit=None, show_dtype=True)
+
+        out = descr + '\n'.join(data_lines)
+        if six.PY2 and isinstance(out, six.text_type):
+            out = out.encode('utf-8')
+
+        return out
+
+    def _repr_html_(self):
+        return self._base_repr_(html=True)
+
     def __repr__(self):
-        names = ("'{0}'".format(x) for x in self.colnames)
-        if any(col.unit for col in self.columns.values()):
-            units = ("{0}".format(
-                    col.unit if col.unit is None else '\''+str(col.unit)+'\'')
-                    for col in self.columns.values())
-            s = "<{3} rows={0} names=({1}) units=({4})>\n{2}".format(
-                self.__len__(), ','.join(names), repr(self._data), self.__class__.__name__
-                ,','.join(units))
-        else:
-            s = "<{3} rows={0} names=({1})>\n{2}".format(
-                self.__len__(), ','.join(names), repr(self._data), self.__class__.__name__)
-        return s
+        return self._base_repr_(html=False)
 
     def __unicode__(self):
-        lines, n_header = self.formatter._pformat_table(self)
-        return '\n'.join(lines)
+        return '\n'.join(self.pformat())
     if six.PY3:
         __str__ = __unicode__
 
@@ -536,8 +614,30 @@ class Table(object):
     if six.PY2:
         __str__ = __bytes__
 
+    @property
+    def has_mixin_columns(self):
+        """
+        True if table has any mixin columns (defined as columns that are not Column
+        subclasses)
+        """
+        return any(not isinstance(col, BaseColumn) for col in self.columns.values())
+
+    def _is_mixin_column(self, col, quantity_is_mixin=False):
+        """
+        Determine if ``col`` meets the protocol for a mixin Table column for
+        this table.  By definition a BaseColumn instance is not a mixin.
+        """
+        if isinstance(col, BaseColumn):
+            is_mixin = False
+        elif isinstance(col, Quantity):
+            is_mixin = quantity_is_mixin
+        else:
+            is_mixin = is_mixin_class(col)
+
+        return is_mixin
+
     def pprint(self, max_lines=None, max_width=None, show_name=True,
-               show_unit=None):
+               show_unit=None, show_dtype=False):
         """Print a formatted string representation of the table.
 
         If no value of ``max_lines`` is supplied then the height of the
@@ -566,10 +666,16 @@ class Table(object):
             for units only if one or more columns has a defined value
             for the unit.
 
+        show_dtype : bool
+            Include a header row for column dtypes (default=True)
         """
+        lines, outs = self.formatter._pformat_table(self, max_lines, max_width,
+                                                    show_name=show_name, show_unit=show_unit,
+                                                    show_dtype=show_dtype)
+        if outs['show_length']:
+            lines.append('Length = {0} rows'.format(len(self)))
 
-        lines, n_header = self.formatter._pformat_table(self, max_lines, max_width, show_name,
-                                                        show_unit)
+        n_header = outs['n_header']
         for i, line in enumerate(lines):
             if i < n_header:
                 color_print(line, 'red')
@@ -580,13 +686,11 @@ class Table(object):
                         css="table,th,td,tr,tbody {border: 1px solid black; border-collapse: collapse;}",
                         max_lines=5000,
                         jsviewer=False,
-                        jskwargs={},
+                        jskwargs={'use_local_files': True},
                         tableid=None,
                         browser='default'):
         """
-        Render the table in HTML and show it in a web browser.  In order to
-        make a persistent html file, i.e. one that survives refresh, the
-        returned file object must be kept in memory.
+        Render the table in HTML and show it in a web browser.
 
         Parameters
         ----------
@@ -612,48 +716,33 @@ class Table(object):
             ``'safari'`` (for mac, you may need to use ``'open -a
             "/Applications/Google Chrome.app" %s'`` for Chrome).  If
             ``'default'``, will use the system default browser.
-
-        Returns
-        -------
-        file :
-            A `~tempfile.NamedTemporaryFile` object pointing to the
-            html file on disk.
         """
+
+        import os
         import webbrowser
         import tempfile
-        from .jsviewer import JSViewer
 
-        tmp = tempfile.NamedTemporaryFile(suffix='.html')
-
-        if tableid is None:
-            tableid = 'table{id}'.format(id=id(self))
-        linelist = self.pformat(html=True, max_width=np.inf,
-                                max_lines=max_lines, tableid=tableid)
-
-        if jsviewer:
-            jsv = JSViewer(**jskwargs)
-            js = jsv.command_line(tableid=tableid)
-        else:
-            js = []
+        # We can't use NamedTemporaryFile here because it gets deleted as
+        # soon as it gets garbage collected.
 
-        css = ["<style>{0}</style>".format(css)]
-        html = "\n".join(['<!DOCTYPE html>','<html>'] + css + js + linelist + ['</html>'])
+        tmpdir = tempfile.mkdtemp()
+        path = os.path.join(tmpdir, 'table.html')
 
-        try:
-            tmp.write(html)
-        except TypeError:
-            tmp.write(html.encode('utf8'))
-        tmp.flush()
+        with open(path, 'w') as tmp:
 
-        if browser == 'default':
-            webbrowser.open("file://" + tmp.name)
-        else:
-            webbrowser.get(browser).open("file://" + tmp.name)
+            if jsviewer:
+                self.write(tmp, format='jsviewer', css=css, max_lines=max_lines,
+                           jskwargs=jskwargs, table_id=tableid)
+            else:
+                self.write(tmp, format='html')
 
-        return tmp
+            if browser == 'default':
+                webbrowser.open("file://" + path)
+            else:
+                webbrowser.get(browser).open("file://" + path)
 
     def pformat(self, max_lines=None, max_width=None, show_name=True,
-                show_unit=None, html=False, tableid=None):
+                show_unit=None, show_dtype=False, html=False, tableid=None):
         """Return a list of lines for the formatted string representation of
         the table.
 
@@ -683,6 +772,9 @@ class Table(object):
             for units only if one or more columns has a defined value
             for the unit.
 
+        show_dtype : bool
+            Include a header row for column dtypes (default=True)
+
         html : bool
             Format the output as an HTML table (default=False)
 
@@ -697,13 +789,18 @@ class Table(object):
             Formatted table as a list of strings
 
         """
-        lines, n_header = self.formatter._pformat_table(self, max_lines, max_width,
-                                                        show_name, show_unit, html,
-                                                        tableid=tableid)
+        lines, outs = self.formatter._pformat_table(self, max_lines, max_width,
+                                                    show_name=show_name, show_unit=show_unit,
+                                                    show_dtype=show_dtype, html=html,
+                                                    tableid=tableid)
+
+        if outs['show_length']:
+            lines.append('Length = {0} rows'.format(len(self)))
+
         return lines
 
     def more(self, max_lines=None, max_width=None, show_name=True,
-             show_unit=None):
+             show_unit=None, show_dtype=False):
         """Interactively browse table with a paging interface.
 
         Supported keys::
@@ -733,15 +830,12 @@ class Table(object):
             Include a header row for unit.  Default is to show a row
             for units only if one or more columns has a defined value
             for the unit.
-        """
-        self.formatter._more_tabcol(self, max_lines, max_width, show_name,
-                                    show_unit)
 
-    def _repr_html_(self):
-        # Since the user cannot provide input, need a sensible default
-        tableid = 'table{id}'.format(id=id(self))
-        lines = self.pformat(html=True, tableid=tableid, max_width=-1)
-        return ''.join(lines)
+        show_dtype : bool
+            Include a header row for column dtypes (default=True)
+        """
+        self.formatter._more_tabcol(self, max_lines, max_width, show_name=show_name,
+                                    show_unit=show_unit, show_dtype=show_dtype)
 
     def __getitem__(self, item):
         if isinstance(item, six.string_types):
@@ -777,8 +871,8 @@ class Table(object):
         if isinstance(item, six.string_types) and item not in self.colnames:
             NewColumn = self.MaskedColumn if self.masked else self.Column
 
-            # Make sure value is an ndarray so we can get the dtype
-            if not isinstance(value, np.ndarray):
+            # Make sure value has a dtype.  If not make it into a numpy array
+            if not hasattr(value, 'dtype') and not self._is_mixin_column(value):
                 value = np.asarray(value)
 
             # Make new column and assign the value.  If the table currently
@@ -788,13 +882,14 @@ class Table(object):
             # define a new column with the right length and shape and then
             # set it from value.  This allows for broadcasting, e.g. t['a']
             # = 1.
-            if isinstance(value, BaseColumn):
-                new_column = value.copy(copy_data=False)
-                new_column.name = item
+            name = item
+            if isinstance(value, BaseColumn) or self._is_mixin_column(value):
+                new_column = col_copy(value)
+                col_setattr(new_column, 'name', name)
             elif len(self) == 0:
-                new_column = NewColumn(name=item, data=value)
+                new_column = NewColumn(value, name=name)
             else:
-                new_column = NewColumn(name=item, length=len(self), dtype=value.dtype,
+                new_column = NewColumn(name=name, length=len(self), dtype=value.dtype,
                                        shape=value.shape[1:])
                 new_column[:] = value
 
@@ -802,14 +897,55 @@ class Table(object):
                     new_column.unit = value.unit
 
             # Now add new column to the table
-            self.add_column(new_column)
+            self.add_columns([new_column], copy=False)
 
-        elif isinstance(value, Row):
-            # Value is another row
-            self._data[item] = value.data
         else:
-            # Otherwise just delegate to the numpy item setter.
-            self._data[item] = value
+            n_cols = len(self.columns)
+
+            if isinstance(item, six.string_types):
+                # Set an existing column
+                self.columns[item][:] = value
+
+            elif isinstance(item, (int, np.integer)):
+                # Set the corresponding row assuming value is an iterable.
+                if not hasattr(value, '__len__'):
+                    raise TypeError('Right side value must be iterable')
+
+                if len(value) != n_cols:
+                    raise ValueError('Right side value needs {0} elements (one for each column)'
+                                     .format(n_cols))
+
+                for col, val in izip(self.columns.values(), value):
+                    col[item] = val
+
+            elif (isinstance(item, slice) or
+                  isinstance(item, np.ndarray) or
+                  isinstance(item, list) or
+                  (isinstance(item, tuple) and  # output from np.where
+                   all(isinstance(x, np.ndarray) for x in item))):
+
+                if isinstance(value, Table):
+                    vals = (col for col in value.columns.values())
+
+                elif isinstance(value, np.ndarray) and value.dtype.names:
+                    vals = (value[name] for name in value.dtype.names)
+
+                elif np.isscalar(value):
+                    import itertools
+                    vals = itertools.repeat(value, n_cols)
+
+                else:  # Assume this is an iterable that will work
+                    if len(value) != n_cols:
+                        raise ValueError('Right side value needs {0} elements (one for each column)'
+                                         .format(n_cols))
+                    vals = value
+
+                for col, val in izip(self.columns.values(), vals):
+                    col[item] = val
+
+            else:
+                raise ValueError('Illegal type {0} for table item access'
+                                 .format(type(item)))
 
     def __delitem__(self, item):
         if isinstance(item, six.string_types):
@@ -817,22 +953,6 @@ class Table(object):
         elif isinstance(item, tuple):
             self.remove_columns(item)
 
-    def __iter__(self):
-        self._iter_index = 0
-        return self
-
-    def __next__(self):
-        """Python 3 iterator"""
-        if self._iter_index < len(self._data):
-            val = self[self._iter_index]
-            self._iter_index += 1
-            return val
-        else:
-            raise StopIteration
-
-    if six.PY2:
-        next = __next__
-
     def field(self, item):
         """Return column[item] for recarray compatibility."""
         return self.columns[item]
@@ -886,7 +1006,7 @@ class Table(object):
 
     @property
     def dtype(self):
-        return self._data.dtype
+        return np.dtype([descr(col) for col in self.columns.values()])
 
     @property
     def colnames(self):
@@ -896,16 +1016,15 @@ class Table(object):
         return list(self.columns.keys())
 
     def __len__(self):
-        if self._data is None:
+        if len(self.columns) == 0:
             return 0
-        else:
-            return len(self._data)
 
-    def create_mask(self):
-        if isinstance(self._data, ma.MaskedArray):
-            raise Exception("data array is already masked")
-        else:
-            self._data = ma.array(self._data)
+        lengths = set(len(col) for col in self.columns.values())
+        if len(lengths) != 1:
+            len_strs = [' {0} : {1}'.format(name, len(col)) for name, col in self.columns.items()]
+            raise ValueError('Column length mismatch:\n{0}'.format('\n'.join(len_strs)))
+
+        return lengths.pop()
 
     def index_column(self, name):
         """
@@ -999,7 +1118,7 @@ class Table(object):
             index = len(self.columns)
         self.add_columns([col], [index])
 
-    def add_columns(self, cols, indexes=None):
+    def add_columns(self, cols, indexes=None, copy=True):
         """
         Add a list of new Column objects ``cols`` to the table.  If a
         corresponding list of ``indexes`` is supplied then insert column before
@@ -1012,6 +1131,8 @@ class Table(object):
             Column objects to add.
         indexes : list of ints or `None`
             Insert column before this position or at end (default)
+        copy : bool
+            Make a copy of the new columns (default=True)
 
         Examples
         --------
@@ -1056,7 +1177,10 @@ class Table(object):
         elif len(indexes) != len(cols):
             raise ValueError('Number of indexes must match number of cols')
 
-        if self._data is None:
+        if copy:
+            cols = [col_copy(col) for col in cols]
+
+        if len(self.columns) == 0:
             # No existing table data, init from cols
             newcols = cols
         else:
@@ -1151,17 +1275,16 @@ class Table(object):
               2 0.2   y
               3 0.3   z
         """
-        try:
-            table = np.delete(self._data, row_specifier, axis=0)
-        except (ValueError, IndexError):
-            # Numpy <= 1.7 raises ValueError while Numpy >= 1.8 raises IndexError
-            raise IndexError('Removing row(s) {0} from table with {1} rows failed'
-                             .format(row_specifier, len(self._data)))
-        self._data = table
+        keep_mask = np.ones(len(self), dtype=np.bool)
+        keep_mask[row_specifier] = False
 
-        # after updating the row data, the column views will be out of date
-        # and should be updated:
-        self._rebuild_table_column_views()
+        columns = self.TableColumns()
+        for name, col in self.columns.items():
+            newcol = col[keep_mask]
+            col_setattr(newcol, 'parent_table', self)
+            columns[name] = newcol
+
+        self.columns = columns
 
         # Revert groups to default (ungrouped) state
         if hasattr(self, '_groups'):
@@ -1264,24 +1387,6 @@ class Table(object):
         for name in names:
             self.columns.pop(name)
 
-        newdtype = [(name, self._data.dtype[name]) for name in self._data.dtype.names
-                    if name not in names]
-        newdtype = np.dtype(newdtype)
-
-        if newdtype:
-            if self.masked:
-                table = np.ma.empty(self._data.shape, dtype=newdtype)
-            else:
-                table = np.empty(self._data.shape, dtype=newdtype)
-
-            for field in newdtype.fields:
-                table[field] = self._data[field]
-                if self.masked:
-                    table[field].fill_value = self._data[field].fill_value
-        else:
-            table = None
-
-        self._data = table
 
     def _convert_string_dtype(self, in_kind, out_kind, python3_only):
         """
@@ -1426,6 +1531,8 @@ class Table(object):
 
           table[name].name = new_name
 
+        TODO: this won't work for mixins
+
         Parameters
         ----------
         name : str
@@ -1457,7 +1564,10 @@ class Table(object):
         if name not in self.keys():
             raise KeyError("Column {0} does not exist".format(name))
 
-        self.columns[name].name = new_name
+        if not isinstance(self.columns[name], BaseColumn):
+            raise NotImplementedError('cannot rename a mixin column')
+
+        col_setattr(self.columns[name], 'name', new_name)
 
     def add_row(self, vals=None, mask=None):
         """Add a new row to the end of the table.
@@ -1510,25 +1620,56 @@ class Table(object):
              2   5   8
              3   6   9
         """
+        self.insert_row(len(self), vals, mask)
+
+    def insert_row(self, index, vals=None, mask=None):
+        """Add a new row before the given ``index`` position in the table.
+
+        The ``vals`` argument can be:
+
+        sequence (e.g. tuple or list)
+            Column values in the same order as table columns.
+        mapping (e.g. dict)
+            Keys corresponding to column names.  Missing values will be
+            filled with np.zeros for the column dtype.
+        `None`
+            All values filled with np.zeros for the column dtype.
+
+        The ``mask`` attribute should give (if desired) the mask for the
+        values. The type of the mask should match that of the values, i.e. if
+        ``vals`` is an iterable, then ``mask`` should also be an iterable
+        with the same length, and if ``vals`` is a mapping, then ``mask``
+        should be a dictionary.
+
+        Parameters
+        ----------
+        vals : tuple, list, dict or `None`
+            Use the specified values in the new row
+        mask : tuple, list, dict or `None`
+            Use the specified mask values in the new row
+        """
+        colnames = self.colnames
+
+        N = len(self)
+        if index < -N or index > N:
+            raise IndexError("Index {0} is out of bounds for table with length {1}"
+                             .format(index, N))
+        if index < 0:
+            index += N
 
         def _is_mapping(obj):
             """Minimal checker for mapping (dict-like) interface for obj"""
             attrs = ('__getitem__', '__len__', '__iter__', 'keys', 'values', 'items')
             return all(hasattr(obj, attr) for attr in attrs)
 
-        newlen = len(self._data) + 1
-
-        if vals is None:
-            vals = np.zeros(1, dtype=self._data.dtype)[0]
-
         if mask is not None and not self.masked:
+            # Possibly issue upgrade warning and update self.ColumnClass.  This
+            # does not change the existing columns.
             self._set_masked(True)
 
-        # Create a table with one row to test the operation on
-        test_data = (ma.zeros if self.masked else np.zeros)(1, dtype=self._data.dtype)
-
-        if _is_mapping(vals):
-
+        if _is_mapping(vals) or vals is None:
+            # From the vals and/or mask mappings create the corresponding lists
+            # that have entries for each table column.
             if mask is not None and not _is_mapping(mask):
                 raise TypeError("Mismatch between type of vals and mask")
 
@@ -1537,64 +1678,86 @@ class Table(object):
             if mask is not None and set(vals.keys()) != set(mask.keys()):
                 raise ValueError('keys in mask should match keys in vals')
 
-            if self.masked:
-                # We set the mask to True regardless of whether a mask value
-                # is specified or not - that is, any cell where a new row
-                # value is not specified should be treated as missing.
-                test_data.mask[-1] = (True,) * len(test_data.dtype)
-
-            # First we copy the values
-            for name, val in six.iteritems(vals):
-                try:
-                    test_data[name][-1] = val
-                except IndexError:
-                    raise ValueError("No column {0} in table".format(name))
-                if mask:
-                    test_data[name].mask[-1] = mask[name]
-
-        elif isiterable(vals):
-
+            if vals and any(name not in colnames for name in vals):
+                raise ValueError('Keys in vals must all be valid column names')
+
+            vals_list = []
+            mask_list = []
+
+            for name in colnames:
+                if vals and name in vals:
+                    vals_list.append(vals[name])
+                    mask_list.append(False if mask is None else mask[name])
+                else:
+                    col = self[name]
+                    if hasattr(col, 'dtype'):
+                        # Make a placeholder zero element of the right type which is masked.
+                        # This assumes the appropriate insert() method will broadcast a
+                        # numpy scalar to the right shape.
+                        vals_list.append(np.zeros(shape=(), dtype=col.dtype))
+
+                        # For masked table any unsupplied values are masked by default.
+                        mask_list.append(self.masked and vals is not None)
+                    else:
+                        raise ValueError("Value must be supplied for column '{0}'".format(name))
+
+            vals = vals_list
+            mask = mask_list
+
+        if isiterable(vals):
             if mask is not None and (not isiterable(mask) or _is_mapping(mask)):
                 raise TypeError("Mismatch between type of vals and mask")
 
             if len(self.columns) != len(vals):
                 raise ValueError('Mismatch between number of vals and columns')
 
-            if not isinstance(vals, tuple):
-                vals = tuple(vals)
-
-            test_data[-1] = vals
-
             if mask is not None:
-
                 if len(self.columns) != len(mask):
                     raise ValueError('Mismatch between number of masks and columns')
-
-                if not isinstance(mask, tuple):
-                    mask = tuple(mask)
-
-                test_data.mask[-1] = mask
+            else:
+                mask = [False] * len(self.columns)
 
         else:
             raise TypeError('Vals must be an iterable or mapping or None')
 
-        # If no errors have been raised, then the table can be resized
-        if self.masked:
-            if newlen == 1:
-                self._data = ma.empty(1, dtype=self._data.dtype)
-            else:
-                self._data = ma.resize(self._data, (newlen,))
-        else:
-            self._data.resize((newlen,), refcheck=False)
+        columns = self.TableColumns()
+        try:
+            # Insert val at index for each column
+            for name, col, val, mask_ in izip(colnames, self.columns.values(), vals, mask):
+                # If the new row caused a change in self.ColumnClass then
+                # Column-based classes need to be converted first.  This is
+                # typical for adding a row with mask values to an unmasked table.
+                if isinstance(col, Column) and not isinstance(col, self.ColumnClass):
+                    col = self.ColumnClass(col, copy=False)
+
+                newcol = col.insert(index, val)
+                if not isinstance(newcol, BaseColumn):
+                    _col_update_attrs_from(newcol, col)
+                    col_setattr(newcol, 'name', name)
+                    if self.masked:
+                        newcol.mask = FalseArray(newcol.shape)
+
+                if len(newcol) != N + 1:
+                    raise ValueError('Incorrect length for column {0} after inserting {1}'
+                                     ' (expected {2}, got {3})'
+                                     .format(name, val, len(newcol), N + 1))
+                col_setattr(newcol, 'parent_table', self)
+
+                # Set mask if needed
+                if self.masked:
+                    newcol.mask[index] = mask_
 
-        # Assign the new row
-        self._data[-1:] = test_data
+                columns[name] = newcol
 
-        self._rebuild_table_column_views()
+        except Exception as err:
+            raise ValueError("Unable to insert row because of exception in column '{0}':\n{1}"
+                             .format(name, err))
+        else:
+            self.columns = columns
 
-        # Revert groups to default (ungrouped) state
-        if hasattr(self, '_groups'):
-            del self._groups
+            # Revert groups to default (ungrouped) state
+            if hasattr(self, '_groups'):
+                del self._groups
 
     def argsort(self, keys=None, kind=None):
         """
@@ -1623,7 +1786,10 @@ class Table(object):
         if kind:
             kwargs['kind'] = kind
 
-        data = self._data
+        if keys:
+            data = self[keys].as_array()
+        else:
+            data = self.as_array()
 
         if _BROKEN_UNICODE_TABLE_SORT and keys is not None and any(
                 data.dtype[i].kind == 'U' for i in xrange(len(data.dtype))):
@@ -1667,17 +1833,9 @@ class Table(object):
         if type(keys) is not list:
             keys = [keys]
 
-        data = self._data
-
-        if _BROKEN_UNICODE_TABLE_SORT and any(
-                data.dtype[i].kind == 'U' for i in xrange(len(data.dtype))):
-            # Use an alternate sort implementation that uses argsort
-            ordering = self.argsort(keys=keys)
-            data[:] = data[ordering]
-        else:
-            data.sort(order=keys)
-
-        self._rebuild_table_column_views()
+        indexes = self.argsort(keys)
+        for col in self.columns.values():
+            col[:] = col.take(indexes, axis=0)
 
     def reverse(self):
         '''
@@ -1707,8 +1865,8 @@ class Table(object):
                    Jo  Miller  15
                   Max  Miller  12
         '''
-        self._data[:] = self._data[::-1].copy()
-        self._rebuild_table_column_views()
+        for col in self.columns.values():
+            col[:] = col[::-1]
 
     @classmethod
     def read(cls, *args, **kwargs):
@@ -1801,24 +1959,24 @@ class Table(object):
     def __eq__(self, other):
 
         if isinstance(other, Table):
-            other = other._data
+            other = other.as_array()
 
         if self.masked:
             if isinstance(other, np.ma.MaskedArray):
-                result = self._data == other
+                result = self.as_array() == other
             else:
                 # If mask is True, then by definition the row doesn't match
                 # because the other array is not masked.
                 false_mask = np.zeros(1, dtype=[(n, bool) for n in self.dtype.names])
-                result = (self._data.data == other) & (self.mask == false_mask)
+                result = (self.as_array().data == other) & (self.mask == false_mask)
         else:
             if isinstance(other, np.ma.MaskedArray):
                 # If mask is True, then by definition the row doesn't match
                 # because the other array is not masked.
                 false_mask = np.zeros(1, dtype=[(n, bool) for n in other.dtype.names])
-                result = (self._data == other.data) & (other.mask == false_mask)
+                result = (self.as_array() == other.data) & (other.mask == false_mask)
             else:
-                result = self._data == other
+                result = self.as_array() == other
 
         return result
 
@@ -1856,4 +2014,49 @@ class Table(object):
         out : `Table`
             New table with groups set
         """
+        if self.has_mixin_columns:
+            raise NotImplementedError('group_by not available for tables with mixin columns')
+
         return groups.table_group_by(self, keys)
+
+
+class QTable(Table):
+    """A class to represent tables of heterogeneous data.
+
+    `QTable` provides a class for heterogeneous tabular data which can be
+    easily modified, for instance adding columns or new rows.
+
+    The `QTable` class is identical to `Table` except that columns with an
+    associated ``unit`` attribute are converted to `~astropy.units.Quantity`
+    objects.
+
+    Parameters
+    ----------
+    data : numpy ndarray, dict, list, or Table, optional
+        Data to initialize table.
+    masked : bool, optional
+        Specify whether the table is masked.
+    names : list, optional
+        Specify column names
+    dtype : list, optional
+        Specify column data types
+    meta : dict, optional
+        Metadata associated with the table.
+    copy : bool, optional
+        Copy the input data (default=True).
+    rows : numpy ndarray, list of lists, optional
+        Row-oriented data for table instead of ``data`` argument
+
+    """
+    def __init__(self, data=None, masked=None, names=None, dtype=None,
+                 meta=None, copy=True, rows=None):
+        super(QTable, self).__init__(data, masked, names, dtype, meta, copy, rows)
+
+    def _is_mixin_column(self, col):
+        """
+        Determine if ``col`` meets the protocol for a mixin Table column for
+        this table.  By definition a BaseColumn instance is not a mixin.
+
+        If ``col`` is a string then it refers to a column name in this table.
+        """
+        return super(QTable, self)._is_mixin_column(col, quantity_is_mixin=True)
diff --git a/astropy/table/table_helpers.py b/astropy/table/table_helpers.py
new file mode 100644
index 0000000..9d4c0ce
--- /dev/null
+++ b/astropy/table/table_helpers.py
@@ -0,0 +1,169 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Helper functions for table development, mostly creating useful
+tables for testing.
+"""
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from itertools import cycle
+import string
+import numpy as np
+
+from .table import Table, Column, col_setattr, col_getattr
+from ..extern.six.moves import zip, range
+
+class TimingTables(object):
+    """
+    Object which contains two tables and various other attributes that
+    are useful for timing and other API tests.
+    """
+    def __init__(self, size=1000, masked=False):
+        self.masked = masked
+
+        # Initialize table
+        self.table = Table(masked=self.masked)
+
+        # Create column with mixed types
+        np.random.seed(12345)
+        self.table['i'] = np.arange(size)
+        self.table['a'] = np.random.random(size)  # float
+        self.table['b'] = np.random.random(size) > 0.5  # bool
+        self.table['c'] = np.random.random((size,10))  # 2d column
+        self.table['d'] = np.random.choice(np.array(list(string.ascii_letters)),size)
+
+        self.extra_row = {'a':1.2, 'b':True, 'c':np.repeat(1, 10), 'd':'Z'}
+        self.extra_column = np.random.randint(0, 100, size)
+        self.row_indices = np.where(self.table['a'] > 0.9)[0]
+        self.table_grouped = self.table.group_by('d')
+
+        # Another table for testing joining
+        self.other_table = Table(masked=self.masked)
+        self.other_table['i'] = np.arange(1,size,3)
+        self.other_table['f'] = np.random.random()
+        self.other_table.sort('f')
+
+        # Another table for testing hstack
+        self.other_table_2 = Table(masked=self.masked)
+        self.other_table_2['g'] = np.random.random(size)
+        self.other_table_2['h'] = np.random.random((size, 10))
+
+        self.bool_mask = self.table['a'] > 0.6
+
+
+def simple_table(size=3, cols=None, kinds='ifS', masked=False):
+    """
+    Return a simple table for testing.
+
+    Example
+    --------
+    ::
+
+      >>> from astropy.table.table_helpers import simple_table
+      >>> print(simple_table(3, 6, masked=True, kinds='ifOS'))
+       a   b     c      d   e   f
+      --- --- -------- --- --- ---
+       -- 1.0 {'c': 2}  --   5 5.0
+        2 2.0       --   e   6  --
+        3  -- {'e': 4}   f  -- 7.0
+
+    Parameters
+    ----------
+    size : int
+        Number of table rows
+    cols : int, default=number of kinds
+        Number of table columns
+    kinds : str
+        String consisting of the column dtype.kinds.  This string
+        will be cycled through to generate the column dtype.
+        The allowed values are 'i', 'f', 'S', 'O'.
+
+    Returns
+    -------
+    out : `Table`
+        New table with appropriate characteristics
+    """
+    if cols is None:
+        cols = len(kinds)
+    if cols > 26:
+        raise ValueError("Max 26 columns in SimpleTable")
+
+    columns = []
+    names = [chr(ord('a') + ii) for ii in range(cols)]
+    letters = np.array([c for c in string.ascii_letters])
+    for jj, kind in zip(range(cols), cycle(kinds)):
+        if kind == 'i':
+            data = np.arange(1, size + 1, dtype=int) + jj
+        elif kind == 'f':
+            data = np.arange(size, dtype=float) + jj
+        elif kind == 'S':
+            indices = (np.arange(size) + jj) % len(letters)
+            data = letters[indices]
+        elif kind == 'O':
+            indices = (np.arange(size) + jj) % len(letters)
+            vals = letters[indices]
+            data = [{val: index} for val, index in zip(vals, indices)]
+        else:
+            raise ValueError('Unknown data kind')
+        columns.append(Column(data, dtype=kind))
+
+    table = Table(columns, names=names, masked=masked)
+    if masked:
+        for ii, col in enumerate(table.columns.values()):
+            mask = np.array((np.arange(size) + ii) % 3, dtype=bool)
+            col.mask = ~mask
+
+    return table
+
+
+def complex_table():
+    """
+    Return a masked table from the io.votable test set that has a wide variety
+    of stressing types.
+    """
+    from ..utils.data import get_pkg_data_filename
+    from ..io.votable.table import parse
+    import warnings
+
+
+    with warnings.catch_warnings():
+        warnings.simplefilter("ignore")
+        votable = parse(get_pkg_data_filename('../io/votable/tests/data/regression.xml'),
+                        pedantic=False)
+    first_table = votable.get_first_table()
+    table = first_table.to_table()
+
+    return table
+
+class ArrayWrapper(object):
+    """
+    Minimal mixin using a simple wrapper around a numpy array
+    """
+    _astropy_column_attrs = None
+
+    def __init__(self, data):
+        self.data = np.array(data)
+        col_setattr(self, 'dtype', self.data.dtype)
+
+    def __getitem__(self, item):
+        if isinstance(item, (int, np.integer)):
+            out = self.data[item]
+        else:
+            out = self.__class__(self.data[item])
+        return out
+
+    def __setitem__(self, item, value):
+        self.data[item] = value
+
+    def __len__(self):
+        return len(self.data)
+
+    @property
+    def shape(self):
+        return self.data.shape
+
+    def __repr__(self):
+        return ("<{0} name='{1}' data={2}>"
+                .format(self.__class__.__name__, col_getattr(self, 'name'), self.data))
diff --git a/astropy/table/tests/conftest.py b/astropy/table/tests/conftest.py
index b6e6262..b82c1bd 100644
--- a/astropy/table/tests/conftest.py
+++ b/astropy/table/tests/conftest.py
@@ -14,10 +14,23 @@ place to put fixtures that are shared between modules.  These fixtures
 can not be defined in a module by a different name and still be shared
 between modules.
 """
+from copy import deepcopy
+
+try:
+    import pandas
+except ImportError:
+    HAS_PANDAS = False
+else:
+    HAS_PANDAS = True
 
 from ...tests.helper import pytest
 from ... import table
+from ...table import table_helpers
+from ... import time
+from ... import units as u
+from ... import coordinates
 from .. import pprint
+from ...utils import OrderedDict
 
 
 @pytest.fixture(params=[table.Column, table.MaskedColumn])
@@ -124,3 +137,33 @@ def table_type(request):
         return MaskedTable
     except AttributeError:
         return table.Table
+
+
+# Stuff for testing mixin columns
+
+MIXIN_COLS = {'quantity': [0, 1, 2, 3] * u.m,
+              'time': time.Time([2000, 2001, 2002, 2003], format='jyear'),
+              'skycoord': coordinates.SkyCoord(ra=[0, 1, 2, 3] * u.deg,
+                                               dec=[0, 1, 2, 3] * u.deg),
+              'arraywrap': table_helpers.ArrayWrapper([0, 1, 2, 3])
+              }
+if HAS_PANDAS:
+    MIXIN_COLS['pandas'] = pandas.Series([0, 1, 2, 3])
+
+ at pytest.fixture(params=sorted(MIXIN_COLS))
+def mixin_cols(request):
+    """
+    Fixture to return a set of columns for mixin testing which includes
+    an index column 'i', two string cols 'a', 'b' (for joins etc), and
+    one of the available mixin column types.
+    """
+    cols = OrderedDict()
+    mixin_cols = deepcopy(MIXIN_COLS)
+    if HAS_PANDAS:
+        mixin_cols['pandas']._astropy_column_attrs = None
+    cols['i'] = table.Column([0, 1, 2, 3], name='i')
+    cols['a'] = table.Column(['a', 'b', 'b', 'c'], name='a')
+    cols['b'] = table.Column(['b', 'c', 'a', 'd'], name='b')
+    cols['m'] = mixin_cols[request.param]
+
+    return cols
diff --git a/astropy/table/tests/test_column.py b/astropy/table/tests/test_column.py
index a29a2fb..dd1668c 100644
--- a/astropy/table/tests/test_column.py
+++ b/astropy/table/tests/test_column.py
@@ -4,23 +4,18 @@
 
 import operator
 
-from distutils import version
-
 import numpy as np
 
-from ...tests.helper import pytest, catch_warnings, assert_follows_unicode_guidelines
-from ...utils.exceptions import AstropyDeprecationWarning
+from ...tests.helper import pytest, assert_follows_unicode_guidelines
 from ... import table
 from ... import units as u
+from ...extern import six
 
 NUMPY_LT_1P8 = [int(x) for x in np.__version__.split('.')[:2]] < [1, 8]
 
 
 class TestColumn():
 
-    def test_1(self, Column):
-        Column(name='a')
-
     def test_subclass(self, Column):
         c = Column(name='a')
         assert isinstance(c, np.ndarray)
@@ -75,24 +70,23 @@ class TestColumn():
                     assert result.dtype.str == '|b1'
 
     def test_view(self, Column):
-        c = np.array([1, 2, 3]).view(Column)
-        if Column == table.MaskedColumn:
-            assert repr(c) == ('<MaskedColumn name=None unit=None format=None description=None>\n'
-                               'masked_array(data = [1 2 3],\n'
-                               '             mask = False,\n'
-                               '       fill_value = 999999)\n')
-        else:
-            assert repr(c) == ('<Column name=None unit=None format=None description=None>\n'
-                               'array([1, 2, 3])')
+        c = np.array([1, 2, 3], dtype=np.int64).view(Column)
+        assert repr(c) == "<{0} dtype='int64' length=3>\n1\n2\n3".format(Column.__name__)
 
     def test_format(self, Column):
         """Show that the formatted output from str() works"""
         from ... import conf
-        with conf.set_temp('max_lines', 7):
+        with conf.set_temp('max_lines', 8):
             c1 = Column(np.arange(2000), name='a', dtype=float,
                         format='%6.2f')
-            assert str(c1) == ('   a   \n-------\n   0.00\n'
-                               '   1.00\n    ...\n1998.00\n1999.00')
+            assert str(c1).splitlines() == ['   a   ',
+                                            '-------',
+                                            '   0.00',
+                                            '   1.00',
+                                            '    ...',
+                                            '1998.00',
+                                            '1999.00',
+                                            'Length = 2000 rows']
 
     def test_convert_numpy_array(self, Column):
         d = Column([1, 2, 3], name='a', dtype='i8')
@@ -152,12 +146,12 @@ class TestColumn():
 
     def test_quantity_init(self, Column):
 
-        c = Column(data=np.array([1,2,3]) * u.m)
-        assert np.all(c.data == np.array([1,2,3]))
+        c = Column(data=np.array([1, 2, 3]) * u.m)
+        assert np.all(c.data == np.array([1, 2, 3]))
         assert np.all(c.unit == u.m)
 
-        c = Column(data=np.array([1,2,3]) * u.m, unit=u.cm)
-        assert np.all(c.data == np.array([100,200,300]))
+        c = Column(data=np.array([1, 2, 3]) * u.m, unit=u.cm)
+        assert np.all(c.data == np.array([100, 200, 300]))
         assert np.all(c.unit == u.cm)
 
     def test_attrs_survive_getitem_after_change(self, Column):
@@ -188,6 +182,164 @@ class TestColumn():
         for attr in ('name', 'unit', 'format', 'description', 'meta'):
             assert not hasattr(val, attr)
 
+    def test_to_quantity(self, Column):
+        d = Column([1, 2, 3], name='a', dtype="f8", unit="m")
+
+        assert np.all(d.quantity == ([1, 2, 3.] * u.m))
+        assert np.all(d.quantity.value == ([1, 2, 3.] * u.m).value)
+        assert np.all(d.quantity == d.to('m'))
+        assert np.all(d.quantity.value == d.to('m').value)
+
+        np.testing.assert_allclose(d.to(u.km).value, ([.001, .002, .003] * u.km).value)
+        np.testing.assert_allclose(d.to('km').value, ([.001, .002, .003] * u.km).value)
+
+        np.testing.assert_allclose(d.to(u.MHz,u.equivalencies.spectral()).value,
+                                   [299.792458, 149.896229,  99.93081933])
+
+        d_nounit = Column([1, 2, 3], name='a', dtype="f8", unit=None)
+        with pytest.raises(u.UnitsError):
+            d_nounit.to(u.km)
+        assert np.all(d_nounit.to(u.dimensionless_unscaled) == np.array([1, 2, 3]))
+
+        #make sure the correct copy/no copy behavior is happening
+        q = [1, 3, 5]*u.km
+
+        # to should always make a copy
+        d.to(u.km)[:] = q
+        np.testing.assert_allclose(d, [1, 2, 3])
+
+        # explcit copying of the quantity should not change the column
+        d.quantity.copy()[:] = q
+        np.testing.assert_allclose(d, [1, 2, 3])
+
+        # but quantity directly is a "view", accessing the underlying column
+        d.quantity[:] = q
+        np.testing.assert_allclose(d, [1000, 3000, 5000])
+
+        #view should also work for integers
+        d2 = Column([1, 2, 3], name='a', dtype=int, unit="m")
+        d2.quantity[:] = q
+        np.testing.assert_allclose(d2, [1000, 3000, 5000])
+
+        #but it should fail for strings or other non-numeric tables
+        d3 = Column(['arg', 'name', 'stuff'], name='a', unit="m")
+        with pytest.raises(TypeError):
+            d3.quantity
+
+    def test_item_access_type(self, Column):
+        """
+        Tests for #3095, which forces integer item access to always return a plain
+        ndarray or MaskedArray, even in the case of a multi-dim column.
+        """
+        integer_types = (int, long, np.int) if six.PY2 else (int, np.int)
+
+        for int_type in integer_types:
+            c = Column([[1, 2], [3, 4]])
+            i0 = int_type(0)
+            i1 = int_type(1)
+            assert np.all(c[i0] == [1, 2])
+            assert type(c[i0]) == (np.ma.MaskedArray if hasattr(Column, 'mask') else np.ndarray)
+            assert c[i0].shape == (2,)
+
+            c01 = c[i0:i1]
+            assert np.all(c01 == [[1, 2]])
+            assert isinstance(c01, Column)
+            assert c01.shape == (1, 2)
+
+            c = Column([1, 2])
+            assert np.all(c[i0] == 1)
+            assert isinstance(c[i0], np.integer)
+            assert c[i0].shape == ()
+
+            c01 = c[i0:i1]
+            assert np.all(c01 == [1])
+            assert isinstance(c01, Column)
+            assert c01.shape == (1,)
+
+    def test_insert_basic(self, Column):
+        c = Column([0, 1, 2], name='a', dtype=int, unit='mJy', format='%i',
+                   description='test column', meta={'c': 8, 'd': 12})
+
+        # Basic insert
+        c1 = c.insert(1, 100)
+        assert np.all(c1 == [0, 100, 1, 2])
+        assert c1.attrs_equal(c)
+        assert type(c) is type(c1)
+        if hasattr(c1, 'mask'):
+            assert c1.data.shape == c1.mask.shape
+
+        c1 = c.insert(-1, 100)
+        assert np.all(c1 == [0, 1, 100, 2])
+
+        c1 = c.insert(3, 100)
+        assert np.all(c1 == [0, 1, 2, 100])
+
+        c1 = c.insert(-3, 100)
+        assert np.all(c1 == [100, 0, 1, 2])
+
+        c1 = c.insert(1, [100, 200, 300])
+        if hasattr(c1, 'mask'):
+            assert c1.data.shape == c1.mask.shape
+
+        # Out of bounds index
+        with pytest.raises((ValueError, IndexError)):
+            c1 = c.insert(-4, 100)
+        with pytest.raises((ValueError,IndexError)):
+            c1 = c.insert(4, 100)
+
+    def test_insert_multidim(self, Column):
+        c = Column([[1, 2],
+                    [3, 4]], name='a', dtype=int)
+
+        # Basic insert
+        c1 = c.insert(1, [100, 200])
+        assert np.all(c1 == [[1, 2], [100, 200], [3, 4]])
+
+        # Broadcast
+        c1 = c.insert(1, 100)
+        assert np.all(c1 == [[1, 2], [100, 100], [3, 4]])
+
+        # Wrong shape
+        with pytest.raises(ValueError):
+            c1 = c.insert(1, [100, 200, 300])
+
+    def test_insert_object(self, Column):
+        c = Column(['a', 1, None], name='a', dtype=object)
+
+        # Basic insert
+        c1 = c.insert(1, [100, 200])
+        assert np.all(c1 == ['a', [100, 200], 1, None])
+
+    def test_insert_masked(self):
+        c = table.MaskedColumn([0, 1, 2], name='a', mask=[False, True, False])
+
+        # Basic insert
+        c1 = c.insert(1, 100)
+        assert np.all(c1.data.data == [0, 100, 1, 2])
+        assert np.all(c1.data.mask == [False, False, True, False])
+        assert type(c) is type(c1)
+
+        for mask in (False, True):
+            c1 = c.insert(1, 100, mask=mask)
+            assert np.all(c1.data.data == [0, 100, 1, 2])
+            assert np.all(c1.data.mask == [False, mask, True, False])
+
+    def test_insert_masked_multidim(self):
+        c = table.MaskedColumn([[1, 2],
+                                [3, 4]], name='a', dtype=int)
+
+        c1 = c.insert(1, [100, 200], mask=True)
+        assert np.all(c1.data.data == [[1, 2], [100, 200], [3, 4]])
+        assert np.all(c1.data.mask == [[False, False], [True, True], [False, False]])
+
+        c1 = c.insert(1, [100, 200], mask=[True, False])
+        assert np.all(c1.data.data == [[1, 2], [100, 200], [3, 4]])
+        assert np.all(c1.data.mask == [[False, False], [True, False], [False, False]])
+
+        with pytest.raises(ValueError):
+            c1 = c.insert(1, [100, 200], mask=[True, False, True])
+
+
 class TestAttrEqual():
     """Bunch of tests originally from ATpy that test the attrs_equal method."""
 
diff --git a/astropy/table/tests/test_groups.py b/astropy/table/tests/test_groups.py
index ef2df93..80d7bd7 100644
--- a/astropy/table/tests/test_groups.py
+++ b/astropy/table/tests/test_groups.py
@@ -42,7 +42,7 @@ def test_column_group_by():
         assert np.all(t1ag.groups.indices == np.array([0, 1, 3, 4, 5, 7, 8]))
 
         # Group by a numpy structured array
-        t1ag = t1a.group_by(t1['a', 'b']._data)
+        t1ag = t1a.group_by(t1['a', 'b'].as_array())
         assert np.all(t1ag.groups.indices == np.array([0, 1, 3, 4, 5, 7, 8]))
 
 
@@ -101,7 +101,7 @@ def test_table_group_by():
         assert tg.pformat() == tg2.pformat()
 
         # Group by a structured array
-        tg2 = t1.group_by(t1['a', 'b']._data)
+        tg2 = t1.group_by(t1['a', 'b'].as_array())
         assert tg.pformat() == tg2.pformat()
 
         # Group by a simple ndarray
@@ -388,7 +388,7 @@ def test_groups_keys_meta():
     assert tg.groups[1].groups.keys.meta['grouped_by_table_cols'] is False
 
     # Group by external numpy array
-    tg = T1.group_by(T1['a', 'b']._data)
+    tg = T1.group_by(T1['a', 'b'].as_array())
     assert not hasattr(tg.groups.keys, 'meta')
     assert not hasattr(tg['c'].groups.keys, 'meta')
 
diff --git a/astropy/table/tests/test_init_table.py b/astropy/table/tests/test_init_table.py
index a84bb16..e263c5c 100644
--- a/astropy/table/tests/test_init_table.py
+++ b/astropy/table/tests/test_init_table.py
@@ -115,16 +115,14 @@ class TestInitFromNdarrayHomo(BaseInitFromListLike):
         assert t.colnames == ['col0', 'col1', 'col2']
 
     def test_ndarray_ref(self, table_type):
-        """Init with ndarray and copy=False and show that ValueError is raised
+        """Init with ndarray and copy=False and show that this is a reference
         to input ndarray"""
         self._setup(table_type)
         t = table_type(self.data, copy=False)
         t['col1'][1] = 0
-        assert t._data['col1'][1] == 0
+        assert t.as_array()['col1'][1] == 0
         assert t['col1'][1] == 0
         assert self.data[1][1] == 0
-        # NOTE: assert np.all(t._data == self.data) fails because when
-        # homogenous array is viewcast to structured then the == is False
 
     def test_partial_names_dtype(self, table_type):
         self._setup(table_type)
@@ -225,10 +223,11 @@ class TestInitFromColsList(BaseInitFromListLike):
         assert all(t[name].name == name for name in t.colnames)
 
     def test_ref(self, table_type):
+        """Test that initializing from a list of columns can be done by reference"""
         self._setup(table_type)
-        with pytest.raises(ValueError):
-            table_type(self.data, copy=False)
-
+        t = table_type(self.data, copy=False)
+        t['x'][0] = 100
+        assert self.data[0][0] == 100
 
 @pytest.mark.usefixtures('table_type')
 class TestInitFromNdarrayStruct(BaseInitFromDictLike):
@@ -243,11 +242,12 @@ class TestInitFromNdarrayStruct(BaseInitFromDictLike):
         to input ndarray"""
         self._setup(table_type)
         t = table_type(self.data, copy=False)
-        assert np.all(t._data == self.data)
-        t['x'][1] = 0
-        assert t._data['x'][1] == 0
+
+        t['x'][1] = 0  # Column-wise assignment
+        t[0]['y'] = 0  # Row-wise assignment
         assert self.data['x'][1] == 0
-        assert np.all(t._data == self.data)
+        assert self.data['y'][0] == 0
+        assert np.all(np.array(t) == self.data)
         assert all(t[name].name == name for name in t.colnames)
 
     def test_partial_names_dtype(self, table_type):
@@ -342,11 +342,10 @@ class TestInitFromTable(BaseInitFromDictLike):
     def test_table_ref(self, table_type):
         self._setup(table_type)
         t = table_type(self.data, copy=False)
-        assert np.all(t._data == self.data._data)
         t['x'][1] = 0
-        assert t._data['x'][1] == 0
-        assert self.data._data['x'][1] == 0
-        assert np.all(t._data == self.data._data)
+        assert t['x'][1] == 0
+        assert self.data['x'][1] == 0
+        assert np.all(t.as_array() == self.data.as_array())
         assert all(t[name].name == name for name in t.colnames)
 
     def test_partial_names_dtype(self, table_type):
@@ -372,21 +371,21 @@ class TestInitFromTable(BaseInitFromDictLike):
         t = table_type(self.data)
         t2 = table_type(t.columns['z', 'x', 'y'])
         assert t2.colnames == ['z', 'x', 'y']
-        assert t2._data.dtype.names == ('z', 'x', 'y')
+        assert t2.dtype.names == ('z', 'x', 'y')
 
     def test_init_from_columns_slice(self, table_type):
         self._setup(table_type)
         t = table_type(self.data)
         t2 = table_type(t.columns[0:2])
         assert t2.colnames == ['x', 'y']
-        assert t2._data.dtype.names == ('x', 'y')
+        assert t2.dtype.names == ('x', 'y')
 
     def test_init_from_columns_mix(self, table_type):
         self._setup(table_type)
         t = table_type(self.data)
         t2 = table_type([t.columns[0], t.columns['z']])
         assert t2.colnames == ['x', 'z']
-        assert t2._data.dtype.names == ('x', 'z')
+        assert t2.dtype.names == ('x', 'z')
 
 
 @pytest.mark.usefixtures('table_type')
diff --git a/astropy/table/tests/test_item_access.py b/astropy/table/tests/test_item_access.py
index 631cee9..c66aca9 100644
--- a/astropy/table/tests/test_item_access.py
+++ b/astropy/table/tests/test_item_access.py
@@ -160,7 +160,7 @@ class TestTableItems(BaseTestItems):
         assert t2['c'].attrs_equal(table_data.COLS[2])
         t2['a'][0] = 0
 
-        assert np.all(self.t._data == table_data.DATA)
+        assert np.all(self.t.as_array() == table_data.DATA)
         assert np.any(t2['a'] != table_data.DATA['a'][slice])
         assert t2.masked == self.t.masked
         assert t2._column_class == self.t._column_class
@@ -179,7 +179,7 @@ class TestTableItems(BaseTestItems):
         assert t2['c'].attrs_equal(table_data.COLS[2])
         t2['a'][0] = 0
 
-        assert np.all(self.t._data == table_data.DATA)
+        assert np.all(self.t.as_array() == table_data.DATA)
         assert np.any(t2['a'] != table_data.DATA['a'][slice])
         assert t2.masked == self.t.masked
         assert t2._column_class == self.t._column_class
@@ -199,7 +199,7 @@ class TestTableItems(BaseTestItems):
             assert t2['a'].attrs_equal(table_data.COLS[0])
             assert t2['c'].attrs_equal(table_data.COLS[2])
             t2['a'][0] = 0
-            assert np.all(self.t._data == table_data.DATA)
+            assert np.all(self.t.as_array() == table_data.DATA)
             assert np.any(t2['a'] != table_data.DATA['a'])
             assert t2.masked == self.t.masked
             assert t2._column_class == self.t._column_class
diff --git a/astropy/table/tests/test_jsviewer.py b/astropy/table/tests/test_jsviewer.py
new file mode 100644
index 0000000..ad3b872
--- /dev/null
+++ b/astropy/table/tests/test_jsviewer.py
@@ -0,0 +1,65 @@
+from ..table import Table
+
+REFERENCE = """
+<html>
+ <head>
+  <meta charset="utf-8"/>
+  <meta content="text/html;charset=UTF-8" http-equiv="Content-type"/>
+  <style>
+table,th,td,tr,tbody {border: 1px solid black; border-collapse: collapse;}  </style>
+  <link href="https://code.jquery.com/ui/1.11.1/themes/overcast/jquery-ui.css" rel="stylesheet" type="text/css"/>
+  <script src="http://code.jquery.com/jquery-1.11.1.min.js">
+  </script>
+  <script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js">
+  </script>
+ </head>
+ <body>
+  <script>
+$(document).ready(function() {
+    $('#test').dataTable({
+     "iDisplayLength": 50,
+     "aLengthMenu": [[10, 25, 50, 100, 500, 1000, -1], [10, 25, 50, 100, 500, 1000, 'All']],
+     "bJQueryUI": true,
+     "sPaginationType": "full_numbers"
+    });
+} );  </script>
+  <table id="test">
+   <thead>
+    <tr>
+     <th>a</th>
+     <th>b</th>
+    </tr>
+   </thead>
+   <tr>
+    <td>1</td>
+    <td>a</td>
+   </tr>
+   <tr>
+    <td>2</td>
+    <td>b</td>
+   </tr>
+   <tr>
+    <td>3</td>
+    <td>c</td>
+   </tr>
+  </table>
+ </body>
+</html>
+"""
+
+
+def test_write_jsviewer(tmpdir):
+
+    t = Table()
+    t['a'] = [1,2,3]
+    t['b'] = ['a','b','c']
+    t['a'].unit = 'm'
+
+    tmpfile = tmpdir.join('test.html').strpath
+
+    t.write(tmpfile, format='jsviewer', table_id='test')
+
+    with open(tmpfile) as f:
+        content = f.read()
+
+    assert content.strip() == REFERENCE.strip()
diff --git a/astropy/table/tests/test_masked.py b/astropy/table/tests/test_masked.py
index f8d1b79..07079f0 100644
--- a/astropy/table/tests/test_masked.py
+++ b/astropy/table/tests/test_masked.py
@@ -128,7 +128,6 @@ class TestFillValue(SetupData):
         self.t['b'].fill_value = 1
         assert self.t['b'].fill_value == 1
         assert np.all(self.t['b'].filled() == [1, 1, 1])
-        assert self.t._data['b'].fill_value == 1
 
     def test_data_attribute_fill_and_mask(self):
         """Check that .data attribute preserves fill_value and mask"""
@@ -376,3 +375,25 @@ class TestAddRow(object):
         assert np.all(t['a'].mask == np.array([0, 0, 0], bool))
         assert np.all(np.array(t['b']) == np.array([4, 5, 6]))
         assert np.all(t['b'].mask == np.array([0, 0, 1], bool))
+
+
+def test_setting_from_masked_column():
+    """Test issue in #2997"""
+    mask_b =  np.array([True, True, False, False])
+    for select in (mask_b, slice(0, 2)):
+        t = Table(masked=True)
+        t['a'] = Column([1, 2, 3, 4])
+        t['b'] = MaskedColumn([11, 22, 33, 44], mask=mask_b)
+        t['c'] = MaskedColumn([111, 222, 333, 444], mask=[True, False, True, False])
+
+        t['b'][select] = t['c'][select]
+        assert t['b'][1] == t[1]['b']
+        assert t['b'][0] is np.ma.masked  # Original state since t['c'][0] is masked
+        assert t['b'][1] == 222  # New from t['c'] since t['c'][1] is unmasked
+        assert t['b'][2] == 33
+        assert t['b'][3] == 44
+        assert np.all(t['b'].mask == t.mask['b'])  # Avoid t.mask in general, this is for testing
+
+        mask_before_add = t.mask.copy()
+        t['d'] = np.arange(len(t))
+        assert np.all(t.mask['b'] == mask_before_add['b'])
diff --git a/astropy/table/tests/test_mixin.py b/astropy/table/tests/test_mixin.py
new file mode 100644
index 0000000..ee2a2d0
--- /dev/null
+++ b/astropy/table/tests/test_mixin.py
@@ -0,0 +1,376 @@
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from io import StringIO
+
+try:
+    import h5py
+except ImportError:
+    HAS_H5PY = False
+else:
+    HAS_H5PY = True
+
+try:
+    import yaml
+    HAS_YAML = True
+except ImportError:
+    HAS_YAML = False
+
+import numpy as np
+
+from ...tests.helper import pytest
+from ...table import Table, QTable, join, hstack, vstack
+from ..column import col_setattr, col_getattr
+from ... import units as u
+from ... import coordinates
+from .. import table_helpers
+from .conftest import MIXIN_COLS
+
+
+def test_attributes(mixin_cols):
+    """
+    Required attributes for a column can be set.
+    """
+    m = mixin_cols['m']
+    col_setattr(m, 'name', 'a')
+    assert col_getattr(m, 'name') == 'a'
+
+    col_setattr(m, 'description', 'a')
+    assert col_getattr(m, 'description') == 'a'
+
+    if not isinstance(m, u.Quantity):
+        col_setattr(m, 'unit', u.m)
+    assert col_getattr(m, 'unit') is u.m
+
+    col_setattr(m, 'format', 'a')
+    assert col_getattr(m, 'format') == 'a'
+
+    col_setattr(m, 'meta', {'a': 1})
+    assert col_getattr(m, 'meta') == {'a': 1}
+
+    with pytest.raises(AttributeError):
+        col_setattr(m, 'bad_attr', 1)
+
+    with pytest.raises(AttributeError):
+        col_getattr(m, 'bad_attr')
+
+
+def check_mixin_type(table, table_col, in_col):
+    if isinstance(in_col, u.Quantity) and type(table) is not QTable:
+        assert type(table_col) is table.ColumnClass
+    else:
+        assert type(table_col) is type(in_col)
+
+    # Make sure in_col got copied and creating table did not touch it
+    assert col_getattr(in_col, 'name') is None
+
+def test_make_table(table_types, mixin_cols):
+    """
+    Make a table with the columns in mixin_cols, which is an ordered dict of
+    three cols: 'a' and 'b' are table_types.Column type, and 'm' is a mixin.
+    """
+    t = table_types.Table(mixin_cols)
+    check_mixin_type(t, t['m'], mixin_cols['m'])
+
+    cols = list(mixin_cols.values())
+    t = table_types.Table(cols, names=('a', 'b', 'c', 'm'))
+    check_mixin_type(t, t['m'], mixin_cols['m'])
+
+    t = table_types.Table(cols)
+    check_mixin_type(t, t['col3'], mixin_cols['m'])
+
+
+def test_io_ascii_write():
+    """
+    Test that table with mixin column can be written by io.ascii for
+    every pure Python writer.  No validation of the output is done,
+    this just confirms no exceptions.
+    """
+    from ...io.ascii.connect import _get_connectors_table
+    t = QTable(MIXIN_COLS)
+    for fmt in _get_connectors_table():
+        if fmt['Format'] == 'ascii.ecsv' and not HAS_YAML:
+            continue
+        if fmt['Write'] and '.fast_' not in fmt['Format']:
+            out = StringIO()
+            t.write(out, format=fmt['Format'])
+
+
+def test_io_write_fail(mixin_cols):
+    """
+    Test that table with mixin column cannot be written by io.votable,
+    io.fits, and io.misc.hdf5
+    every pure Python writer.  No validation of the output is done,
+    this just confirms no exceptions.
+    """
+    t = QTable(mixin_cols)
+    for fmt in ('fits', 'votable', 'hdf5'):
+        if fmt == 'hdf5' and not HAS_H5PY:
+            continue
+        out = StringIO()
+        with pytest.raises(ValueError) as err:
+            t.write(out, format=fmt)
+        assert 'cannot write table with mixin column(s)' in str(err.value)
+
+
+def test_join(table_types):
+    """
+    Join tables with mixin cols.  Use column "i" as proxy for what the
+    result should be for each mixin.
+    """
+    t1 = table_types.Table()
+    t1['a'] = table_types.Column(['a', 'b', 'b', 'c'])
+    t1['i'] = table_types.Column([0, 1, 2, 3])
+    for name, col in MIXIN_COLS.items():
+        t1[name] = col
+
+    t2 = table_types.Table(t1)
+    t2['a'] = ['b', 'c', 'a', 'd']
+
+    for name, col in MIXIN_COLS.items():
+        col_setattr(t1[name], 'description', name)
+        col_setattr(t2[name], 'description', name + '2')
+
+    for join_type in ('inner', 'left'):
+        t12 = join(t1, t2, keys='a', join_type=join_type)
+        idx1 = t12['i_1']
+        idx2 = t12['i_2']
+        for name, col in MIXIN_COLS.items():
+            name1 = name + '_1'
+            name2 = name + '_2'
+            assert_table_name_col_equal(t12, name1, col[idx1])
+            assert_table_name_col_equal(t12, name2, col[idx2])
+            assert col_getattr(t12[name1], 'description') == name
+            assert col_getattr(t12[name2], 'description') == name + '2'
+
+    for join_type in ('outer', 'right'):
+        with pytest.raises(ValueError) as exc:
+            t12 = join(t1, t2, keys='a', join_type=join_type)
+        assert 'join requires masking column' in str(exc.value)
+
+    with pytest.raises(ValueError) as exc:
+        t12 = join(t1, t2, keys=['a', 'skycoord'])
+    assert 'not allowed as a key column' in str(exc.value)
+
+    # Join does work for a mixin which is a subclass of np.ndarray
+    t12 = join(t1, t2, keys=['quantity'])
+    assert np.all(t12['a_1'] == t1['a'])
+
+def test_hstack(table_types):
+    """
+    Hstack tables with mixin cols.  Use column "i" as proxy for what the
+    result should be for each mixin.
+    """
+    t1 = table_types.Table()
+    t1['i'] = table_types.Column([0, 1, 2, 3])
+    for name, col in MIXIN_COLS.items():
+        t1[name] = col
+        col_setattr(t1[name], 'description', name)
+        col_setattr(t1[name], 'meta', {'a': 1})
+
+    for join_type in ('inner', 'outer'):
+        for chop in (True, False):
+            t2 = table_types.Table(t1)
+            if chop:
+                t2 = t2[:-1]
+                if join_type == 'outer':
+                    with pytest.raises(ValueError) as exc:
+                        t12 = hstack([t1, t2], join_type=join_type)
+                    assert 'hstack requires masking column' in str(exc.value)
+                    continue
+
+            t12 = hstack([t1, t2], join_type=join_type)
+            idx1 = t12['i_1']
+            idx2 = t12['i_2']
+            for name, col in MIXIN_COLS.items():
+                name1 = name + '_1'
+                name2 = name + '_2'
+                assert_table_name_col_equal(t12, name1, col[idx1])
+                assert_table_name_col_equal(t12, name2, col[idx2])
+                for attr in ('description', 'meta'):
+                    assert col_getattr(t1[name], attr) == col_getattr(t12[name1], attr)
+                    assert col_getattr(t2[name], attr) == col_getattr(t12[name2], attr)
+
+
+def assert_table_name_col_equal(t, name, col):
+    """
+    Assert all(t[name] == col), with special handling for known mixin cols.
+    """
+    if isinstance(col, coordinates.SkyCoord):
+        assert np.all(t[name].ra == col.ra)
+        assert np.all(t[name].dec == col.dec)
+    elif isinstance(col, u.Quantity):
+        if type(t) is QTable:
+            assert np.all(t[name].value == col.value)
+    elif isinstance(col, table_helpers.ArrayWrapper):
+        assert np.all(t[name].data == col.data)
+    else:
+        assert np.all(t[name] == col)
+
+def test_get_items(mixin_cols):
+    """
+    Test that slicing / indexing table gives right values and col attrs inherit
+    """
+    attrs = ('name', 'unit', 'dtype', 'format', 'description', 'meta')
+    m = mixin_cols['m']
+    col_setattr(m, 'name', 'm')
+    col_setattr(m, 'format', '{0}')
+    col_setattr(m, 'description', 'd')
+    col_setattr(m, 'meta', {'a': 1})
+    t = QTable([m])
+    for item in ([1, 3], np.array([0, 2]), slice(1, 3)):
+        t2 = t[item]
+        assert_table_name_col_equal(t2, 'm', m[item])
+        for attr in attrs:
+            assert col_getattr(t2['m'], attr) == col_getattr(m, attr)
+
+def test_add_column(mixin_cols):
+    """
+    Test that adding a column preserves values and attributes
+    """
+    attrs = ('name', 'unit', 'dtype', 'format', 'description', 'meta')
+    m = mixin_cols['m']
+    assert col_getattr(m, 'name') is None
+
+    # Make sure adding column in various ways doesn't touch
+    t = QTable([m], names=['a'])
+    assert col_getattr(m, 'name') is None
+
+    t['new'] = m
+    assert col_getattr(m, 'name') is None
+
+    col_setattr(m, 'name', 'm')
+    col_setattr(m, 'format', '{0}')
+    col_setattr(m, 'description', 'd')
+    col_setattr(m, 'meta', {'a': 1})
+    t = QTable([m])
+
+    # Add columns m2 and m3 by two different methods and test expected equality
+    t['m2'] = m
+    col_setattr(m, 'name', 'm3')
+    t.add_columns([m], copy=True)
+    col_setattr(m, 'name', 'm4')
+    t.add_columns([m], copy=False)
+    for name in ('m2', 'm3', 'm4'):
+        assert_table_name_col_equal(t, 'm', t[name])
+        for attr in attrs:
+            if attr != 'name':
+                assert col_getattr(t['m'], attr) == col_getattr(t[name], attr)
+
+def test_vstack():
+    """
+    Vstack tables with mixin cols.
+    """
+    t1 = QTable(MIXIN_COLS)
+    t2 = QTable(MIXIN_COLS)
+    with pytest.raises(NotImplementedError):
+        vstack([t1, t2])
+
+def test_insert_row(mixin_cols):
+    """
+    Test inserting a row, which only works for BaseColumn and Quantity
+    """
+    t = QTable(mixin_cols)
+    col_setattr(t['m'], 'description', 'd')
+    if isinstance(t['m'], u.Quantity):
+        t.insert_row(1, t[-1])
+        assert t[1] == t[-1]
+        assert col_getattr(t['m'], 'description') == 'd'
+    else:
+        with pytest.raises(ValueError) as exc:
+            t.insert_row(1, t[-1])
+        assert "Unable to insert row" in str(exc.value)
+
+def test_insert_row_bad_unit():
+    """
+    Insert a row into a QTable with the wrong unit
+    """
+    t = QTable([[1] * u.m])
+    with pytest.raises(ValueError) as exc:
+        t.insert_row(0, (2 * u.m / u.s,))
+    assert "'m / s' (speed) and 'm' (length) are not convertible" in str(exc.value)
+
+def test_convert_np_array(mixin_cols):
+    """
+    Test that converting to numpy array creates an object dtype and that
+    each instance in the array has the expected type.
+    """
+    t = QTable(mixin_cols)
+    ta = t.as_array()
+    m = mixin_cols['m']
+    dtype_kind = m.dtype.kind if hasattr(m, 'dtype') else 'O'
+    assert ta['m'].dtype.kind == dtype_kind
+
+def test_assignment_and_copy():
+    """
+    Test that assignment of an int, slice, and fancy index works.
+    Along the way test that copying table works.
+    """
+    for name in ('quantity', 'arraywrap'):
+        m = MIXIN_COLS[name]
+        t0 = QTable([m], names=['m'])
+        for i0, i1 in ((1, 2),
+                       (slice(0, 2), slice(1, 3)),
+                       (np.array([1, 2]), np.array([2, 3]))):
+            t = t0.copy()
+            t['m'][i0] = m[i1]
+            if name == 'arraywrap':
+                assert np.all(t['m'].data[i0] == m.data[i1])
+                assert np.all(t0['m'].data[i0] == m.data[i0])
+                assert np.all(t0['m'].data[i0] != t['m'].data[i0])
+            else:
+                assert np.all(t['m'][i0] == m[i1])
+                assert np.all(t0['m'][i0] == m[i0])
+                assert np.all(t0['m'][i0] != t['m'][i0])
+
+def test_grouping():
+    """
+    Test grouping with mixin columns.  Raises not yet implemented error.
+    """
+    t = QTable(MIXIN_COLS)
+    t['index'] = ['a', 'b', 'b', 'c']
+    with pytest.raises(NotImplementedError):
+        t.group_by('index')
+
+def test_conversion_qtable_table():
+    """
+    Test that a table round trips from QTable => Table => QTable
+    """
+    qt = QTable(MIXIN_COLS)
+    names = qt.colnames
+    for name in names:
+        col_setattr(qt[name], 'description', name)
+
+    t = Table(qt)
+    for name in names:
+        assert col_getattr(t[name], 'description') == name
+        if name == 'quantity':
+            assert np.all(t['quantity'] == qt['quantity'].value)
+            assert np.all(t['quantity'].unit is qt['quantity'].unit)
+            assert isinstance(t['quantity'], t.ColumnClass)
+        else:
+            assert_table_name_col_equal(t, name, qt[name])
+
+    qt2 = QTable(qt)
+    for name in names:
+        assert col_getattr(qt2[name], 'description') == name
+        assert_table_name_col_equal(qt2, name, qt[name])
+
+ at pytest.mark.xfail
+def test_column_rename():
+    qt = QTable(MIXIN_COLS)
+    names = qt.colnames
+    for name in names:
+        qt.rename_column(name, name + '2')
+    assert qt.colnames == [name + '2' for name in names]
+
+
+def test_setitem_as_column_name():
+    """
+    Test for mixin-related regression described in #3321.
+    """
+    t = Table()
+    t['a'] = ['x', 'y']
+    t['b'] = 'b'  # Previously was failing with KeyError
+    assert np.all(t['a'] == ['x', 'y'])
+    assert np.all(t['b'] == ['b', 'b'])
diff --git a/astropy/table/tests/test_operations.py b/astropy/table/tests/test_operations.py
index 99eb66f..97dcc40 100644
--- a/astropy/table/tests/test_operations.py
+++ b/astropy/table/tests/test_operations.py
@@ -2,18 +2,14 @@
 
 # TEST_UNICODE_LITERALS
 
-from distutils import version
-import warnings
-
 import numpy as np
 
 from ...tests.helper import pytest, catch_warnings
-from ...table import Table
+from ...table import Table, TableMergeError
 from ...utils import OrderedDict, metadata
 from ...utils.metadata import MergeConflictError
-from .. import np_utils
 from ... import table
-from ... import log
+
 
 def sort_eq(list1, list2):
     return sorted(list1) == sorted(list2)
@@ -131,7 +127,7 @@ class TestJoin():
         # Check that the common keys are 'a', 'b'
         t12a = table.join(t1, t2, join_type='outer')
         t12b = table.join(t1, t2, join_type='outer', keys=['a', 'b'])
-        assert np.all(t12a._data == t12b._data)
+        assert np.all(t12a.as_array() == t12b.as_array())
 
     def test_both_unmasked_single_key_inner(self):
         t1 = self.t1
@@ -200,7 +196,7 @@ class TestJoin():
 
         # Result should match non-masked result
         t12 = table.join(t1, t2)
-        assert np.all(t12._data == np.array(t1m2._data))
+        assert np.all(t12.as_array() == np.array(t1m2))
 
         # Mask out some values in left table and make sure they propagate
         t1m['b'].mask[1] = True
@@ -236,7 +232,7 @@ class TestJoin():
 
         # Result should match non-masked result
         t12 = table.join(t1, t2)
-        assert np.all(t12._data == np.array(t1m2m._data))
+        assert np.all(t12.as_array() == np.array(t1m2m))
 
         # Mask out some values in both tables and make sure they propagate
         t1m['b'].mask[1] = True
@@ -270,14 +266,14 @@ class TestJoin():
         t1 = self.t1
         t2 = self.t2
         t1['b_1'] = 1  # Add a new column b_1 that will conflict with auto-rename
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.join(t1, t2, keys='a')
 
     def test_missing_keys(self):
         """Merge on a key column that doesn't exist"""
         t1 = self.t1
         t2 = self.t2
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.join(t1, t2, keys=['a', 'not there'])
 
     def test_bad_join_type(self):
@@ -295,7 +291,7 @@ class TestJoin():
         del t1['b']
         del t2['a']
         del t2['b']
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.join(t1, t2)
 
     def test_masked_key_column(self):
@@ -304,7 +300,7 @@ class TestJoin():
         t2 = Table(self.t2, masked=True)
         table.join(t1, t2)  # OK
         t2['a'].mask[0] = True
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.join(t1, t2)
 
     def test_col_meta_merge(self):
@@ -449,6 +445,8 @@ class TestVStack():
 
     def test_bad_input_type(self):
         with pytest.raises(TypeError):
+            table.vstack([])
+        with pytest.raises(TypeError):
             table.vstack(1)
         with pytest.raises(TypeError):
             table.vstack([self.t2, 1])
@@ -499,15 +497,15 @@ class TestVStack():
                                   '  1 bar']
 
     def test_stack_incompatible(self):
-        with pytest.raises(np_utils.TableMergeError) as excinfo:
+        with pytest.raises(TableMergeError) as excinfo:
             table.vstack([self.t1, self.t3], join_type='inner')
         assert "The 'b' columns have incompatible types:" in str(excinfo)
 
-        with pytest.raises(np_utils.TableMergeError) as excinfo:
+        with pytest.raises(TableMergeError) as excinfo:
             table.vstack([self.t1, self.t3], join_type='outer')
         assert "The 'b' columns have incompatible types:" in str(excinfo)
 
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.vstack([self.t1, self.t2], join_type='exact')
 
     def test_vstack_one_masked(self):
@@ -575,6 +573,11 @@ class TestVStack():
             assert ("In merged column 'a' the 'unit' attribute does not match (m != km)"
                     in str(warning_lines[1].message))
 
+    def test_vstack_one_table(self):
+        """Regression test for issue #3313"""
+        assert (self.t1 == table.vstack(self.t1)).all()
+        assert (self.t1 == table.vstack([self.t1])).all()
+
 
 class TestHStack():
 
@@ -608,6 +611,17 @@ class TestHStack():
                                        ('a', 1),
                                        ('e', 1)])
 
+    def test_stack_same_table(self):
+        """
+        From #2995, test that hstack'ing references to the same table has the
+        expected output.
+        """
+        out = table.hstack([self.t1, self.t1])
+        assert out.pformat() == ['a_1 b_1 a_2 b_2',
+                                 '--- --- --- ---',
+                                 '  0 foo   0 foo',
+                                 '  1 bar   1 bar']
+
     def test_stack_rows(self):
         out = table.hstack([self.t1[0], self.t2[1]])
         assert out.pformat() == ['a_1 b_1 a_2 b_2  c ',
@@ -646,6 +660,8 @@ class TestHStack():
 
     def test_bad_input_type(self):
         with pytest.raises(TypeError):
+            table.hstack([])
+        with pytest.raises(TypeError):
             table.hstack(1)
         with pytest.raises(TypeError):
             table.hstack([self.t2, 1])
@@ -688,7 +704,7 @@ class TestHStack():
     def test_stack_incompatible(self):
         # For join_type exact, which will fail here because n_rows
         # does not match
-        with pytest.raises(np_utils.TableMergeError):
+        with pytest.raises(TableMergeError):
             table.hstack([self.t1, self.t3], join_type='exact')
 
     def test_hstack_one_masked(self):
@@ -742,3 +758,63 @@ class TestHStack():
             # Make sure we got a copy of meta, not ref
             t1['b'].meta['b'] = None
             assert out['b'].meta['b'] == [1, 2]
+
+    def test_hstack_one_table(self):
+        """Regression test for issue #3313"""
+        assert (self.t1 == table.hstack(self.t1)).all()
+        assert (self.t1 == table.hstack([self.t1])).all()
+
+
+def test_unique():
+    t = table.Table.read([' a b  c  d',
+                          ' 2 b 7.0 0',
+                          ' 1 c 3.0 5',
+                          ' 2 b 6.0 2',
+                          ' 2 a 4.0 3',
+                          ' 1 a 1.0 7',
+                          ' 2 b 5.0 1',
+                          ' 0 a 0.0 4',
+                          ' 1 a 2.0 6',
+                          ' 1 c 3.0 5',
+                          ], format='ascii')
+
+    tu = table.Table(np.sort(t[:-1]))
+
+    t_all = table.unique(t)
+    assert sort_eq(t_all.pformat(), tu.pformat())
+
+    key1 = 'a'
+    t1 = table.unique(t, key1)
+    assert sort_eq(t1.pformat(), [' a   b   c   d ',
+                                  '--- --- --- ---',
+                                  '  0   a 0.0   4',
+                                  '  1   c 3.0   5',
+                                  '  2   b 7.0   0'])
+
+    key2 = ['a', 'b']
+    t2 = table.unique(t, key2)
+    assert sort_eq(t2.pformat(), [' a   b   c   d ',
+                                  '--- --- --- ---',
+                                  '  0   a 0.0   4',
+                                  '  1   a 1.0   7',
+                                  '  1   c 3.0   5',
+                                  '  2   a 4.0   3',
+                                  '  2   b 7.0   0'])
+
+    t1_m = table.Table(t1, masked=True)
+    t1_m['a'].mask[1] = True
+
+    with pytest.raises(ValueError) as e:
+        t1_mu = table.unique(t1_m)
+    assert e.value.args[0] == ("Cannot unique masked value key columns, remove "
+                               "column 'a' from keys and rerun unique.")
+
+    t1_mu = table.unique(t1_m, silent=True)
+    assert t1_mu.pformat() == [' a   b   c   d ',
+                               '--- --- --- ---',
+                               '  0   a 0.0   4',
+                               '  2   b 7.0   0',
+                               ' --   c 3.0   5']
+
+    with pytest.raises(ValueError) as e:
+        t1_mu = table.unique(t1_m, silent=True, keys='a')
diff --git a/astropy/table/tests/test_pprint.py b/astropy/table/tests/test_pprint.py
index 47fba7d..9a73cf8 100644
--- a/astropy/table/tests/test_pprint.py
+++ b/astropy/table/tests/test_pprint.py
@@ -10,8 +10,8 @@ from ...table import Table
 from ...extern.six import PY3
 from ...utils import console
 
-BIG_WIDE_ARR = np.arange(2000, dtype=np.float).reshape(100, 20)
-SMALL_ARR = np.arange(12, dtype=np.int).reshape(4, 3)
+BIG_WIDE_ARR = np.arange(2000, dtype=np.float64).reshape(100, 20)
+SMALL_ARR = np.arange(18, dtype=np.int64).reshape(6, 3)
 
 
 @pytest.mark.usefixtures('table_type')
@@ -20,14 +20,13 @@ class TestMultiD():
     def test_multidim(self, table_type):
         """Test printing with multidimensional column"""
         arr = [np.array([[1, 2],
-                         [10, 20]]),
+                         [10, 20]], dtype=np.int64),
                np.array([[3, 4],
-                         [30, 40]]),
+                         [30, 40]], dtype=np.int64),
                np.array([[5, 6],
-                         [50, 60]])]
+                         [50, 60]], dtype=np.int64)]
         t = table_type(arr)
         lines = t.pformat()
-        print(lines)
         assert lines == ['col0 [2] col1 [2] col2 [2]',
                          '-------- -------- --------',
                          '  1 .. 2   3 .. 4   5 .. 6',
@@ -39,14 +38,17 @@ class TestMultiD():
                          '<tr><td>1 .. 2</td><td>3 .. 4</td><td>5 .. 6</td></tr>',
                          '<tr><td>10 .. 20</td><td>30 .. 40</td><td>50 .. 60</td></tr>',
                          '</table>']
-        assert t._repr_html_() == ('<table id="table{tid}"><thead><tr><th>col0 [2]</th><th>col1 [2]</th><th>col2 [2]'.format(tid=id(t)) +
-                                   '</th></tr></thead><tr><td>1 .. 2</td><td>3 .. 4</td><td>5 .. 6</td>'
-                                   '</tr><tr><td>10 .. 20</td><td>30 .. 40</td><td>50 .. 60</td>'
-                                   '</tr></table>')
+        assert t._repr_html_().splitlines() == [
+            '<{0} masked={1} length=2>'.format(table_type.__name__, t.masked),
+            '<table id="table{tid}">'.format(tid=id(t)),
+            '<thead><tr><th>col0 [2]</th><th>col1 [2]</th><th>col2 [2]</th></tr></thead>',
+            '<thead><tr><th>int64</th><th>int64</th><th>int64</th></tr></thead>',
+            '<tr><td>1 .. 2</td><td>3 .. 4</td><td>5 .. 6</td></tr>',
+            '<tr><td>10 .. 20</td><td>30 .. 40</td><td>50 .. 60</td></tr>',
+            '</table>']
 
         t = table_type([arr])
         lines = t.pformat()
-        print(lines)
         assert lines == ['col0 [2,2]',
                          '----------',
                          '   1 .. 20',
@@ -56,14 +58,13 @@ class TestMultiD():
     def test_fake_multidim(self, table_type):
         """Test printing with 'fake' multidimensional column"""
         arr = [np.array([[(1,)],
-                         [(10,)]]),
+                         [(10,)]], dtype=np.int64),
                np.array([[(3,)],
-                         [(30,)]]),
+                         [(30,)]], dtype=np.int64),
                np.array([[(5,)],
-                         [(50,)]])]
+                         [(50,)]], dtype=np.int64)]
         t = table_type(arr)
         lines = t.pformat()
-        print(lines)
         assert lines == ['col0 [1,1] col1 [1,1] col2 [1,1]',
                          '---------- ---------- ----------',
                          '         1          3          5',
@@ -75,13 +76,16 @@ class TestMultiD():
                          '<tr><td>1</td><td>3</td><td>5</td></tr>',
                          '<tr><td>10</td><td>30</td><td>50</td></tr>',
                          '</table>']
-        assert t._repr_html_() == ('<table id="table{tid}"><thead><tr><th>col0 [1,1]</th><th>col1 [1,1]</th><th>col2'.format(tid=id(t)) +
-                                   ' [1,1]</th></tr></thead><tr><td>1</td><td>3</td><td>5</td>'
-                                   '</tr><tr><td>10</td><td>30</td><td>50</td></tr></table>')
+        assert t._repr_html_().splitlines() == [
+            '<{0} masked={1} length=2>'.format(table_type.__name__, t.masked),
+            '<table id="table{id}">'.format(id=id(t)),
+            '<thead><tr><th>col0 [1,1]</th><th>col1 [1,1]</th><th>col2 [1,1]</th></tr></thead>',
+            '<thead><tr><th>int64</th><th>int64</th><th>int64</th></tr></thead>',
+            '<tr><td>1</td><td>3</td><td>5</td></tr>', u'<tr><td>10</td><td>30</td><td>50</td></tr>',
+            '</table>']
 
         t = table_type([arr])
         lines = t.pformat()
-        print(lines)
         assert lines == ['col0 [2,1,1]',
                          '------------',
                          '     1 .. 10',
@@ -90,12 +94,16 @@ class TestMultiD():
 
 
 def test_html_escaping():
-    t = table.Table([('<script>alert("gotcha");</script>', 2, 3)])
-    assert t._repr_html_() == (
-        '<table id="table{id}"><thead><tr><th>col0</th></tr></thead>'.format(id=id(t)) +
-        '<tr><td><script>alert("gotcha");</script></td>'
-        '</tr><tr><td>2</td></tr><tr><td>3</td></tr></table>')
-
+    t = table.Table([(str('<script>alert("gotcha");</script>'), 2, 3)])
+    assert t._repr_html_().splitlines() == [
+        '<Table masked=False length=3>',
+        '<table id="table{id}">'.format(id=id(t)),
+        '<thead><tr><th>col0</th></tr></thead>',
+        '<thead><tr><th>{0}</th></tr></thead>'.format('str1056' if PY3 else 'string264'),
+        '<tr><td><script>alert("gotcha");</script></td></tr>',
+        '<tr><td>2</td></tr>',
+        '<tr><td>3</td></tr>',
+        '</table>']
 
 @pytest.mark.usefixtures('table_type')
 class TestPprint():
@@ -113,14 +121,12 @@ class TestPprint():
         """Try getting screen size but fail to defaults because testing doesn't
         have access to screen (fcntl.ioctl fails).
         """
-        from ... import conf
-
         self._setup(table_type)
-        arr = np.arange(4000, dtype=np.float).reshape(100, 40)
+        arr = np.arange(4000, dtype=np.float64).reshape(100, 40)
         lines = table_type(arr).pformat()
         nlines, width = console.terminal_size()
         assert len(lines) == nlines
-        for line in lines:
+        for line in lines[:-1]:  # skip last "Length = .. rows" line
             assert (len(line) > width - 10 and
                     len(line) <= width)
 
@@ -132,10 +138,10 @@ class TestPprint():
                          '    km2                  ... kg s / m2',
                          '------------ ----------- ... ---------',
                          '0.000000e+00    1.000000 ...      19.0',
-                         '2.000000e+01   21.000000 ...      39.0',
                          '         ...         ... ...       ...',
                          '1.960000e+03 1961.000000 ...    1979.0',
-                         '1.980000e+03 1981.000000 ...    1999.0']
+                         '1.980000e+03 1981.000000 ...    1999.0',
+                         'Length = 100 rows']
 
     def test_format2(self, table_type):
         """Basic test of formatting, unit header row excluded"""
@@ -145,25 +151,24 @@ class TestPprint():
                          '------------ ----------- ... ------',
                          '0.000000e+00    1.000000 ...   19.0',
                          '2.000000e+01   21.000000 ...   39.0',
-                         '4.000000e+01   41.000000 ...   59.0',
                          '         ...         ... ...    ...',
                          '1.960000e+03 1961.000000 ... 1979.0',
-                         '1.980000e+03 1981.000000 ... 1999.0']
+                         '1.980000e+03 1981.000000 ... 1999.0',
+                         'Length = 100 rows']
 
     def test_format3(self, table_type):
         """Include the unit header row"""
         self._setup(table_type)
         lines = self.tb.pformat(max_lines=8, max_width=40, show_unit=True)
 
-        print(lines)
         assert lines == ['    col0         col1    ...   col19  ',
                          '    km2                  ... kg s / m2',
                          '------------ ----------- ... ---------',
                          '0.000000e+00    1.000000 ...      19.0',
-                         '2.000000e+01   21.000000 ...      39.0',
                          '         ...         ... ...       ...',
                          '1.960000e+03 1961.000000 ...    1979.0',
-                         '1.980000e+03 1981.000000 ...    1999.0']
+                         '1.980000e+03 1981.000000 ...    1999.0',
+                         'Length = 100 rows']
 
     def test_format4(self, table_type):
         """Do not include the name header row"""
@@ -173,10 +178,10 @@ class TestPprint():
                          '------------ ----------- ... ---------',
                          '0.000000e+00    1.000000 ...      19.0',
                          '2.000000e+01   21.000000 ...      39.0',
-                         '4.000000e+01   41.000000 ...      59.0',
                          '         ...         ... ...       ...',
                          '1.960000e+03 1961.000000 ...    1979.0',
-                         '1.980000e+03 1981.000000 ...    1999.0']
+                         '1.980000e+03 1981.000000 ...    1999.0',
+                         'Length = 100 rows']
 
     def test_noclip(self, table_type):
         """Basic table print"""
@@ -187,10 +192,12 @@ class TestPprint():
                          '   0    1    2',
                          '   3    4    5',
                          '   6    7    8',
-                         '   9   10   11']
+                         '   9   10   11',
+                         '  12   13   14',
+                         '  15   16   17']
 
     def test_clip1(self, table_type):
-        """max lines below hard limit of 6
+        """max lines below hard limit of 8
         """
         self._setup(table_type)
         lines = self.ts.pformat(max_lines=3, max_width=-1)
@@ -199,22 +206,27 @@ class TestPprint():
                          '   0    1    2',
                          '   3    4    5',
                          '   6    7    8',
-                         '   9   10   11']
+                         '   9   10   11',
+                         '  12   13   14',
+                         '  15   16   17']
 
     def test_clip2(self, table_type):
-        """max lines below hard limit of 6 and output longer than 6
+        """max lines below hard limit of 8 and output longer than 8
         """
         self._setup(table_type)
-        lines = self.ts.pformat(max_lines=3, max_width=-1, show_unit=True)
-        assert lines == ['col0 col1 col2',
-                         '              ',
-                         '---- ---- ----',
-                         '   0    1    2',
-                         ' ...  ...  ...',
-                         '   9   10   11']
+        lines = self.ts.pformat(max_lines=3, max_width=-1, show_unit=True, show_dtype=True)
+        assert lines == [' col0  col1  col2',
+                         '                 ',
+                         'int64 int64 int64',
+                         '----- ----- -----',
+                         '    0     1     2',
+                         '  ...   ...   ...',
+                         '   15    16    17',
+                         'Length = 6 rows']
+
 
     def test_clip3(self, table_type):
-        """Max lines below hard limit of 6 and max width below hard limit
+        """Max lines below hard limit of 8 and max width below hard limit
         of 10
         """
         self._setup(table_type)
@@ -224,14 +236,16 @@ class TestPprint():
                          '---- ...',
                          '   0 ...',
                          ' ... ...',
-                         '   9 ...']
+                         '  12 ...',
+                         '  15 ...',
+                         'Length = 6 rows']
 
     def test_clip4(self, table_type):
         """Test a range of max_lines"""
         self._setup(table_type)
-        for max_lines in range(130):
+        for max_lines in (0, 1, 4, 5, 6, 7, 8, 100, 101, 102, 103, 104, 130):
             lines = self.tb.pformat(max_lines=max_lines, show_unit=False)
-            assert len(lines) == max(6, min(102, max_lines))
+            assert len(lines) == max(8, min(102, max_lines))
 
 
 
@@ -270,13 +284,26 @@ class TestFormat():
 
     def test_column_format_with_threshold(self, table_type):
         from ... import conf
-        with conf.set_temp('max_lines', 6):
+        with conf.set_temp('max_lines', 8):
             t = table_type([np.arange(20)], names=['a'])
             t['a'].format = '%{0:}'
-            assert str(t['a']) == ' a \n---\n %0\n %1\n...\n%19'
+            assert str(t['a']).splitlines() == [' a ',
+                                                '---',
+                                                ' %0',
+                                                ' %1',
+                                                '...',
+                                                '%18',
+                                                '%19',
+                                                'Length = 20 rows']
             t['a'].format = '{ %4.2f }'
-            assert str(t['a']) == '    a    \n---------\n { 0.00 }\n' \
-                                  ' { 1.00 }\n      ...\n{ 19.00 }'
+            assert str(t['a']).splitlines() == ['    a    ',
+                                                '---------',
+                                                ' { 0.00 }',
+                                                ' { 1.00 }',
+                                                '      ...',
+                                                '{ 18.00 }',
+                                                '{ 19.00 }',
+                                                'Length = 20 rows']
 
     def test_column_format_func(self, table_type):
         # run most of functions twice
@@ -364,18 +391,30 @@ class TestFormatWithMaskedElements():
         t['a'].format = '%4.2f {0:}'
         assert str(t['a']) == '   a   \n-------\n     --\n%4.2f 2\n     --'
 
-    def test_column_format_with_threshold(self):
+    def test_column_format_with_threshold(self, table_type):
         from ... import conf
-        with conf.set_temp('max_lines', 7):
-            t = Table([np.arange(20)], names=['a'], masked=True)
+        with conf.set_temp('max_lines', 8):
+            t = table_type([np.arange(20)], names=['a'])
+            t['a'].format = '%{0:}'
             t['a'].mask[0] = True
             t['a'].mask[-1] = True
-            t['a'].format = '%{0:}'
-            assert str(t['a']) == ' a \n---\n --\n %1\n...\n%18\n --'
+            assert str(t['a']).splitlines() == [' a ',
+                                                '---',
+                                                ' --',
+                                                ' %1',
+                                                '...',
+                                                '%18',
+                                                ' --',
+                                                'Length = 20 rows']
             t['a'].format = '{ %4.2f }'
-            assert str(t['a']) == '    a    \n---------\n       --\n' \
-                                  ' { 1.00 }\n      ...\n{ 18.00 }\n' \
-                                  '       --'
+            assert str(t['a']).splitlines() == ['    a    ',
+                                                '---------',
+                                                '       --',
+                                                ' { 1.00 }',
+                                                '      ...',
+                                                '{ 18.00 }',
+                                                '       --',
+                                                'Length = 20 rows']
 
     def test_column_format_func(self):
         # run most of functions twice
diff --git a/astropy/table/tests/test_row.py b/astropy/table/tests/test_row.py
index 3f3c888..150ebc5 100644
--- a/astropy/table/tests/test_row.py
+++ b/astropy/table/tests/test_row.py
@@ -25,10 +25,10 @@ def test_masked_row_with_object_col():
     if numpy_lt_1p8:
         with pytest.raises(ValueError):
             t['col0'].mask = False
-            t[0]
+            t[0].as_void()
         with pytest.raises(ValueError):
             t['col0'].mask = True
-            t[0]
+            t[0].as_void()
     else:
         t['col0'].mask = False
         assert t[0]['col0'] == 1
@@ -92,7 +92,7 @@ class TestRow():
     def test_left_equal(self, table_types):
         """Compare a table row to the corresponding structured array row"""
         self._setup(table_types)
-        np_t = self.t._data.copy()
+        np_t = self.t.as_array()
         if table_types.Table is MaskedTable:
             with pytest.raises(ValueError):
                 self.t[0] == np_t[0]
@@ -103,7 +103,7 @@ class TestRow():
     def test_left_not_equal(self, table_types):
         """Compare a table row to the corresponding structured array row"""
         self._setup(table_types)
-        np_t = self.t._data.copy()
+        np_t = self.t.as_array()
         np_t['a'] = [0, 0, 0]
         if table_types.Table is MaskedTable:
             with pytest.raises(ValueError):
@@ -115,7 +115,7 @@ class TestRow():
     def test_right_equal(self, table_types):
         """Test right equal"""
         self._setup(table_types)
-        np_t = self.t._data.copy()
+        np_t = self.t.as_array()
         if table_types.Table is MaskedTable:
             with pytest.raises(ValueError):
                 self.t[0] == np_t[0]
@@ -129,14 +129,14 @@ class TestRow():
 
         np_data = np.array(d)
         if table_types.Table is not MaskedTable:
-            assert np.all(np_data == d._data)
-        assert not np_data is d._data
+            assert np.all(np_data == d.as_void())
+        assert not np_data is d.as_void()
         assert d.colnames == list(np_data.dtype.names)
 
         np_data = np.array(d, copy=False)
         if table_types.Table is not MaskedTable:
-            assert np.all(np_data == d._data)
-        assert not np_data is d._data
+            assert np.all(np_data == d.as_void())
+        assert not np_data is d.as_void()
         assert d.colnames == list(np_data.dtype.names)
 
         with pytest.raises(ValueError):
@@ -148,3 +148,62 @@ class TestRow():
         table = self.t
         row = table[0]
         assert format(row, "").startswith("<{0} 0 of table".format(row.__class__.__name__))
+
+    def test_data_and_as_void(self, table_types):
+        """Test the deprecated data property and as_void() method"""
+        self._setup(table_types)
+        table = self.t
+        row = table[0]
+
+        # row.data is now deprecated because it is slow, generic and abusable
+        with catch_warnings(AstropyDeprecationWarning) as warning_lines:
+            row_data = row.data
+            assert isinstance(row_data, (np.void, np.ma.mvoid))
+
+            assert warning_lines[0].category == AstropyDeprecationWarning
+            assert ("The data function is deprecated" in str(warning_lines[0].message))
+
+        # If masked then with no masks, issue numpy/numpy#483 should come into play.
+        # Make sure as_void() code is working.
+        row_void = row.as_void()
+        if table.masked:
+            assert isinstance(row_void, np.ma.mvoid)
+        else:
+            assert isinstance(row_void, np.void)
+        assert row_void['a'] == 1
+        assert row_void['b'] == 4
+
+        # Confirm row is a view of table but row_void is not.
+        table['a'][0] = -100
+        assert row['a'] == -100
+        assert row_void['a'] == 1
+
+        # Make sure it works for a table that has masked elements
+        if table.masked:
+            table['a'].mask = True
+
+            # row_void is not a view, need to re-make
+            assert row_void['a'] == 1
+            row_void = row.as_void()  # but row is a view
+            assert row['a'] is np.ma.masked
+
+    def test_row_and_as_void_with_objects(self, table_types):
+        """Test the deprecated data property and as_void() method"""
+        t = table_types.Table([[{'a': 1}, {'b': 2}]], names=('a',))
+        assert t[0][0] == {'a': 1}
+        assert t[0]['a'] == {'a': 1}
+        if numpy_lt_1p8 and t.masked:
+            # With numpy < 1.8 there is a bug setting mvoid with
+            # an object.
+            with pytest.raises(ValueError):
+                t[0].as_void()
+        else:
+            assert t[0].as_void()[0] == {'a': 1}
+            assert t[0].as_void()['a'] == {'a': 1}
+
+    def test_bounds_checking(self, table_types):
+        """Row gives index error upon creation for out-of-bounds index"""
+        self._setup(table_types)
+        for ibad in (-5, -4, 3, 4):
+            with pytest.raises(IndexError):
+                self.t[ibad]
diff --git a/astropy/table/tests/test_subclass.py b/astropy/table/tests/test_subclass.py
index f73c9b1..2c39aca 100644
--- a/astropy/table/tests/test_subclass.py
+++ b/astropy/table/tests/test_subclass.py
@@ -8,14 +8,14 @@ from .. import pprint
 
 class MyRow(table.Row):
     def __str__(self):
-        return str(self.data)
+        return str(self.as_void())
 
 
 class MyColumn(table.Column):
     pass
 
 
-class MyMaskedColumn(table.Column):
+class MyMaskedColumn(table.MaskedColumn):
     pass
 
 
@@ -58,4 +58,38 @@ def test_simple_subclass():
     assert str(row) == '(1, 3)'
     assert isinstance(t['col0'], MyMaskedColumn)
     assert isinstance(t.formatter, MyTableFormatter)
-    
+
+
+class ParamsRow(table.Row):
+    """
+    Row class that allows access to an arbitrary dict of parameters
+    stored as a dict object in the ``params`` column.
+    """
+    def __getitem__(self, item):
+        if item not in self.colnames:
+            return super(ParamsRow, self).__getitem__('params')[item]
+        else:
+            return super(ParamsRow, self).__getitem__(item)
+
+    def keys(self):
+        out = [name for name in self.colnames if name != 'params']
+        params = [key.lower() for key in sorted(self['params'])]
+        return out + params
+
+    def values(self):
+        return [self[key] for key in self.keys()]
+
+
+class ParamsTable(table.Table):
+    Row = ParamsRow
+
+def test_params_table():
+    t = ParamsTable(names=['a', 'b', 'params'], dtype=['i', 'f', 'O'])
+    t.add_row((1, 2.0, {'x': 1.5, 'y': 2.5}))
+    t.add_row((2, 3.0, {'z': 'hello', 'id': 123123}))
+    assert t['params'][0] == {'x': 1.5, 'y': 2.5}
+    assert t[0]['params'] == {'x': 1.5, 'y': 2.5}
+    assert t[0]['y'] == 2.5
+    assert t[1]['id'] == 123123
+    assert list(t[1].keys()) == ['a', 'b', 'id', 'z']
+    assert list(t[1].values()) == [2, 3.0, 123123, 'hello']
diff --git a/astropy/table/tests/test_table.py b/astropy/table/tests/test_table.py
index 5ae6195..76141f2 100644
--- a/astropy/table/tests/test_table.py
+++ b/astropy/table/tests/test_table.py
@@ -5,10 +5,6 @@
 
 import copy
 import gc
-import platform
-import sys
-
-from distutils import version
 
 import numpy as np
 
@@ -94,7 +90,7 @@ class TestSetTableColumn(SetupData):
         assert t[0][1] == 5
 
     def test_set_row_fail_1(self, table_types):
-        """Set a row from an incorrectly-sized set of values"""
+        """Set a row from an incorrectly-sized or typed set of values"""
         self._setup(table_types)
         t = table_types.Table([self.a, self.b])
         with pytest.raises(ValueError):
@@ -511,6 +507,13 @@ class TestAddRow(SetupData):
             return self._c
 
     @property
+    def d(self):
+        if self._column_type is not None:
+            if not hasattr(self, '_d'):
+                self._d = self._column_type(name='d', data=[[1, 2], [3, 4], [5, 6]])
+            return self._d
+
+    @property
     def t(self):
         if self._table_type is not None:
             if not hasattr(self, '_t'):
@@ -519,39 +522,41 @@ class TestAddRow(SetupData):
 
     def test_add_none_to_empty_table(self, table_types):
         self._setup(table_types)
-        t = table_types.Table(names=('a', 'b', 'c'), dtype=('i', 'S4', 'O'))
+        t = table_types.Table(names=('a', 'b', 'c'), dtype=('(2,)i', 'S4', 'O'))
         t.add_row()
-        assert t['a'][0] == 0
+        assert np.all(t['a'][0] == [0, 0])
         assert t['b'][0] == b''
         assert t['c'][0] == 0
         t.add_row()
-        assert t['a'][1] == 0
+        assert np.all(t['a'][1] == [0, 0])
         assert t['b'][1] == b''
         assert t['c'][1] == 0
 
     def test_add_stuff_to_empty_table(self, table_types):
         self._setup(table_types)
-        t = table_types.Table(names=('a', 'b', 'obj'), dtype=('i', 'S8', 'O'))
-        t.add_row([1, 'hello', 'world'])
-        assert t['a'][0] == 1
+        t = table_types.Table(names=('a', 'b', 'obj'), dtype=('(2,)i', 'S8', 'O'))
+        t.add_row([[1, 2], 'hello', 'world'])
+        assert np.all(t['a'][0] == [1, 2])
         assert t['b'][0] == b'hello'
         assert t['obj'][0] == 'world'
         # Make sure it is not repeating last row but instead
         # adding zeros (as documented)
         t.add_row()
-        assert t['a'][1] == 0
+        assert np.all(t['a'][1] == [0, 0])
         assert t['b'][1] == b''
         assert t['obj'][1] == 0
 
     def test_add_table_row(self, table_types):
         self._setup(table_types)
         t = self.t
-        t2 = table_types.Table([self.a, self.b, self.c])
+        t['d'] = self.d
+        t2 = table_types.Table([self.a, self.b, self.c, self.d])
         t.add_row(t2[0])
         assert len(t) == 4
         assert np.all(t['a'] == np.array([1, 2, 3, 1]))
         assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 4.0]))
         assert np.all(t['c'] == np.array(['7', '8', '9', '7']))
+        assert np.all(t['d'] == np.array([[1, 2], [3, 4], [5, 6], [1, 2]]))
 
     def test_add_table_row_obj(self, table_types):
         self._setup(table_types)
@@ -619,17 +624,6 @@ class TestAddRow(SetupData):
         with pytest.raises(TypeError):
             t.add_row(1)
 
-    def test_add_without_own_fails(self, table_types):
-        """Add row to a table that doesn't own the data"""
-        self._setup(table_types)
-        data = np.array([(1, 2, 3),
-                         (3, 4, 5)],
-                        dtype='i4')
-        t = table_types.Table(data, copy=False)
-        if not t.masked:
-            with pytest.raises(ValueError):
-                t.add_row([6, 7, 8])
-
     def test_add_row_failures(self, table_types):
         self._setup(table_types)
         t = self.t
@@ -640,14 +634,40 @@ class TestAddRow(SetupData):
         except ValueError:
             pass
         assert len(t) == 3
-        assert np.all(t._data == t_copy._data)
+        assert np.all(t.as_array() == t_copy.as_array())
         # Wrong data type
         try:
             t.add_row(['one',2,3])
         except ValueError:
             pass
         assert len(t) == 3
-        assert np.all(t._data == t_copy._data)
+        assert np.all(t.as_array() == t_copy.as_array())
+
+    def test_insert_table_row(self, table_types):
+        """
+        Light testing of Table.insert_row() method.  The deep testing is done via
+        the add_row() tests which calls insert_row(index=len(self), ...), so
+        here just test that the added index parameter is handled correctly.
+        """
+        self._setup(table_types)
+        row = (10, 40.0, 'x', [10, 20])
+        for index in range(-3, 4):
+            indices = np.insert(np.arange(3), index, 3)
+            t = table_types.Table([self.a, self.b, self.c, self.d])
+            t2 = t.copy()
+            t.add_row(row)  # By now we know this works
+            t2.insert_row(index, row)
+            for name in t.colnames:
+                if t[name].dtype.kind == 'f':
+                    assert np.allclose(t[name][indices], t2[name])
+                else:
+                    assert np.all(t[name][indices] == t2[name])
+
+        for index in (-4, 4):
+            t = table_types.Table([self.a, self.b, self.c, self.d])
+            with pytest.raises(IndexError):
+                t.insert_row(index, row)
+
 
 @pytest.mark.usefixtures('table_types')
 class TestTableColumn(SetupData):
@@ -657,7 +677,7 @@ class TestTableColumn(SetupData):
         t = self.t
         a = t.columns['a']
         a[2] = 10
-        assert t._data['a'][2] == 10
+        assert t['a'][2] == 10
 
 
 @pytest.mark.usefixtures('table_types')
@@ -709,14 +729,14 @@ class TestRemove(SetupData):
         self._setup(table_types)
         self.t.remove_columns('a')
         assert self.t.columns.keys() == []
-        assert self.t._data is None
+        assert self.t.as_array() is None
 
     def test_2(self, table_types):
         self._setup(table_types)
         self.t.add_column(self.b)
         self.t.remove_columns('a')
         assert self.t.columns.keys() == ['b']
-        assert self.t._data.dtype.names == ('b',)
+        assert self.t.dtype.names == ('b',)
         assert np.all(self.t['b'] == np.array([4, 5, 6]))
 
     def test_3(self, table_types):
@@ -785,7 +805,7 @@ class TestRemove(SetupData):
         self._setup(table_types)
         del self.t['a']
         assert self.t.columns.keys() == []
-        assert self.t._data is None
+        assert self.t.as_array() is None
 
     def test_delitem2(self, table_types):
         self._setup(table_types)
@@ -811,14 +831,14 @@ class TestKeep(SetupData):
         t = table_types.Table([self.a, self.b])
         t.keep_columns([])
         assert t.columns.keys() == []
-        assert t._data is None
+        assert t.as_array() is None
 
     def test_2(self, table_types):
         self._setup(table_types)
         t = table_types.Table([self.a, self.b])
         t.keep_columns('b')
         assert t.columns.keys() == ['b']
-        assert t._data.dtype.names == ('b',)
+        assert t.dtype.names == ('b',)
         assert np.all(t['b'] == np.array([4, 5, 6]))
 
 
@@ -830,7 +850,7 @@ class TestRename(SetupData):
         t = table_types.Table([self.a])
         t.rename_column('a', 'b')
         assert t.columns.keys() == ['b']
-        assert t._data.dtype.names == ('b',)
+        assert t.dtype.names == ('b',)
         assert np.all(t['b'] == np.array([1, 2, 3]))
 
     def test_2(self, table_types):
@@ -839,9 +859,9 @@ class TestRename(SetupData):
         t.rename_column('a', 'c')
         t.rename_column('b', 'a')
         assert t.columns.keys() == ['c', 'a']
-        assert t._data.dtype.names == ('c', 'a')
+        assert t.dtype.names == ('c', 'a')
         if t.masked:
-            assert t._data.mask.dtype.names == ('c', 'a')
+            assert t.mask.dtype.names == ('c', 'a')
         assert np.all(t['c'] == np.array([1, 2, 3]))
         assert np.all(t['a'] == np.array([4, 5, 6]))
 
@@ -851,7 +871,7 @@ class TestRename(SetupData):
         t['a'].name = 'c'
         t['b'].name = 'a'
         assert t.columns.keys() == ['c', 'a']
-        assert t._data.dtype.names == ('c', 'a')
+        assert t.dtype.names == ('c', 'a')
         assert np.all(t['c'] == np.array([1, 2, 3]))
         assert np.all(t['a'] == np.array([4, 5, 6]))
 
@@ -863,14 +883,21 @@ class TestSort():
         t = table_types.Table()
         t.add_column(table_types.Column(name='a', data=[2, 1, 3]))
         t.add_column(table_types.Column(name='b', data=[6, 5, 4]))
+        t.add_column(table_types.Column(name='c', data=[(1, 2), (3, 4), (4, 5)]))
         assert np.all(t['a'] == np.array([2, 1, 3]))
         assert np.all(t['b'] == np.array([6, 5, 4]))
         t.sort('a')
         assert np.all(t['a'] == np.array([1, 2, 3]))
         assert np.all(t['b'] == np.array([5, 6, 4]))
+        assert np.all(t['c'] == np.array([[3, 4],
+                                          [1, 2],
+                                          [4, 5]]))
         t.sort('b')
         assert np.all(t['a'] == np.array([3, 1, 2]))
         assert np.all(t['b'] == np.array([4, 5, 6]))
+        assert np.all(t['c'] == np.array([[4, 5],
+                                          [3, 4],
+                                          [1, 2]]))
 
     def test_single_big(self, table_types):
         """Sort a big-ish table with a non-trivial sort order"""
@@ -927,9 +954,14 @@ class TestSort():
         t = table_types.Table()
         t.add_column(table_types.Column(name='a', data=[2, 1, 3, 2, 3, 1]))
         t.add_column(table_types.Column(name='b', data=[6, 5, 4, 3, 5, 4]))
-        assert np.all(t.argsort() == t._data.argsort())
-        assert np.all(t.argsort('a') == t._data.argsort(order=['a']))
-        assert np.all(t.argsort(['a', 'b']) == t._data.argsort(order=['a', 'b']))
+        assert np.all(t.argsort() == t.as_array().argsort())
+        i0 = t.argsort('a')
+        i1 = t.as_array().argsort(order=['a'])
+        assert np.all(t['a'][i0] == t['a'][i1])
+        i0 = t.argsort(['a', 'b'])
+        i1 = t.as_array().argsort(order=['a', 'b'])
+        assert np.all(t['a'][i0] == t['a'][i1])
+        assert np.all(t['b'][i0] == t['b'][i1])
 
     def test_argsort_bytes(self, table_types):
         t = table_types.Table()
@@ -958,23 +990,23 @@ class TestSort():
         """
         t = table_types.Table([[1]], names=('a',))
         assert t.colnames == ['a']
-        assert t._data.dtype.names == ('a',)
+        assert t.dtype.names == ('a',)
 
         t.add_row((2,))
         assert t.colnames == ['a']
-        assert t._data.dtype.names == ('a',)
+        assert t.dtype.names == ('a',)
 
         t.rename_column('a', 'b')
         assert t.colnames == ['b']
-        assert t._data.dtype.names == ('b',)
+        assert t.dtype.names == ('b',)
 
         t.sort('b')
         assert t.colnames == ['b']
-        assert t._data.dtype.names == ('b',)
+        assert t.dtype.names == ('b',)
 
         t.rename_column('b', 'c')
         assert t.colnames == ['c']
-        assert t._data.dtype.names == ('c',)
+        assert t.dtype.names == ('c',)
 
 
 @pytest.mark.usefixtures('table_types')
@@ -1013,14 +1045,13 @@ class TestConvertNumpyArray():
 
         np_data = np.array(d)
         if table_types.Table is not MaskedTable:
-            assert np.all(np_data == d._data)
-        assert not np_data is d._data
+            assert np.all(np_data == d.as_array())
+        assert not np_data is d.as_array()
         assert d.colnames == list(np_data.dtype.names)
 
         np_data = np.array(d, copy=False)
         if table_types.Table is not MaskedTable:
-            assert np.all(np_data == d._data)
-            assert np_data is d._data
+            assert np.all(np_data == d.as_array())
         assert d.colnames == list(np_data.dtype.names)
 
         with pytest.raises(ValueError):
@@ -1029,13 +1060,14 @@ class TestConvertNumpyArray():
 
 def _assert_copies(t, t2, deep=True):
     assert t.colnames == t2.colnames
-    np.testing.assert_array_equal(t._data, t2._data)
+    np.testing.assert_array_equal(t.as_array(), t2.as_array())
     assert t.meta == t2.meta
 
-    if deep:
-        assert not np.may_share_memory(t._data, t2._data)
-    else:
-        assert np.may_share_memory(t._data, t2._data)
+    for col, col2 in zip(t.columns.values(), t2.columns.values()):
+        if deep:
+            assert not np.may_share_memory(col, col2)
+        else:
+            assert np.may_share_memory(col, col2)
 
 
 def test_copy():
@@ -1122,8 +1154,8 @@ def test_equality():
     assert np.all((t != t2) == np.array([0,0,1,0,1,0,1,0], dtype=bool))
 
     # Check that comparing to a structured array works
-    assert np.all((t == t2._data) == np.array([1,1,0,1,0,1,0,1], dtype=bool))
-    assert np.all((t._data == t2) == np.array([1,1,0,1,0,1,0,1], dtype=bool))
+    assert np.all((t == t2.as_array()) == np.array([1,1,0,1,0,1,0,1], dtype=bool))
+    assert np.all((t.as_array() == t2) == np.array([1,1,0,1,0,1,0,1], dtype=bool))
 
 
 def test_equality_masked():
@@ -1176,7 +1208,7 @@ def test_equality_masked():
     assert np.all((t != t2) == np.array([1,0,1,0,1,0,1,0], dtype=bool))
 
     # Check that comparing to a structured array works
-    assert np.all((t == t2._data) == np.array([0,1,0,1,0,1,0,1], dtype=bool))
+    assert np.all((t == t2.as_array()) == np.array([0,1,0,1,0,1,0,1], dtype=bool))
 
 
 @pytest.mark.xfail
@@ -1212,7 +1244,7 @@ def test_equality_masked_bug():
                            ' 1 a 1.0 7',
                           ], format='ascii')
 
-    assert np.all((t._data == t2) == np.array([0,1,0,1,0,1,0,1], dtype=bool))
+    assert np.all((t.as_array() == t2) == np.array([0,1,0,1,0,1,0,1], dtype=bool))
 
 
 # Check that the meta descriptor is working as expected. The MetaBaseTest class
@@ -1240,9 +1272,11 @@ def test_unicode_column_names(table_types):
 
 
 def test_unicode_content():
+    # If we don't have unicode literals then return
     if isinstance('', bytes):
         return
 
+    # Define unicode literals
     string_a = 'астрономическая питона'
     string_b = 'миллиарды световых лет'
 
@@ -1251,7 +1285,6 @@ def test_unicode_content():
          [string_b, 3]],
         names=('a', 'b'))
 
-    assert repr(string_a) in repr(a)
     assert string_a in six.text_type(a)
     # This only works because the coding of this file is utf-8, which
     # matches the default encoding of Table.__str__
@@ -1320,3 +1353,14 @@ def test_table_deletion():
     gc.collect()
 
     assert the_id in deleted
+
+def test_nested_iteration():
+    """
+    Regression test for issue 3358 where nested iteration over a single table fails.
+    """
+    t = table.Table([[0, 1]], names=['a'])
+    out = []
+    for r1 in t:
+        for r2 in t:
+            out.append((r1['a'], r2['a']))
+    assert out == [(0, 0), (0, 1), (1, 0), (1, 1)]
diff --git a/astropy/tests/helper.py b/astropy/tests/helper.py
index f523141..9eba79a 100644
--- a/astropy/tests/helper.py
+++ b/astropy/tests/helper.py
@@ -1,6 +1,6 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 """
-This module prvoides the tools used to internally run the astropy test suite
+This module provides the tools used to internally run the astropy test suite
 from the installed astropy.  It makes use of the `pytest` testing framework.
 """
 from __future__ import (absolute_import, division, print_function,
@@ -17,7 +17,6 @@ import zlib
 import functools
 import multiprocessing
 import os
-import subprocess
 import shutil
 import tempfile
 import types
@@ -31,10 +30,10 @@ try:
 except ImportError:
     pass
 
-from distutils.core import Command
-
 from .. import test
-from ..utils.exceptions import AstropyWarning
+from ..utils.exceptions import (AstropyWarning,
+                                AstropyDeprecationWarning,
+                                AstropyPendingDeprecationWarning)
 from ..config import configuration
 
 if os.environ.get('ASTROPY_USE_SYSTEM_PYTEST') or '_pytest' in sys.modules:
@@ -60,12 +59,6 @@ else:
     importer = extern_pytest.DictImporter(unpacked_sources)
     sys.meta_path.insert(0, importer)
 
-    # On Python 3.1, we need to forcibly import the py.test-"bundled"
-    # argparse before importing py.test, since it isn't in the
-    # standard library, and py.test's workaround doesn't appear to
-    # work with the "absolute imports" of Python 3.x.
-    if six.PY3 and sys.version_info[1] <= 1:
-        argparse = importer.load_module(str('argparse'))
     pytest = importer.load_module(str('pytest'))
 
 
@@ -152,24 +145,34 @@ class TestRunner(object):
 
         if test_path:
             base, ext = os.path.splitext(test_path)
-            if ext == '.py':
-                test_path = os.path.abspath(test_path)
-                all_args.append(test_path)
-            elif ext == '.rst':
+
+            if ext in ('.rst', ''):
                 if docs_path is None:
                     # This shouldn't happen from "python setup.py test"
                     raise ValueError(
-                        "Can not test .rst files without a docs_path specified.")
-                else:
+                        "Can not test .rst files without a docs_path "
+                        "specified.")
+
+                abs_docs_path = os.path.abspath(docs_path)
+                abs_test_path = os.path.abspath(
+                    os.path.join(abs_docs_path, os.pardir, test_path))
+
+                common = os.path.commonprefix((abs_docs_path, abs_test_path))
+
+                if os.path.exists(abs_test_path) and common == abs_docs_path:
                     # Since we aren't testing any Python files within
                     # the astropy tree, we need to forcibly load the
                     # astropy py.test plugins, and then turn on the
                     # doctest_rst plugin.
-                    all_args.extend(['-p', 'astropy.tests.pytest_plugins', '--doctest-rst'])
-                    test_path = os.path.join(docs_path, '..', test_path)
-                    all_args.append(test_path)
-            else:
-                raise ValueError("Test file path must be to a .py or .rst file")
+                    all_args.extend(['-p', 'astropy.tests.pytest_plugins',
+                                     '--doctest-rst'])
+                    test_path = abs_test_path
+
+            if not (os.path.isdir(test_path) or ext in ('.py', '.rst')):
+                raise ValueError("Test path must be a directory or a path to "
+                                 "a .py or .rst file")
+
+            all_args.append(test_path)
         else:
             all_args.append(package_path)
             if docs_path is not None and not skip_docs:
@@ -210,15 +213,17 @@ class TestRunner(object):
 
         # check for opened files after each test
         if open_files:
+            if parallel != 0:
+                raise SystemError(
+                    "open file detection may not be used in conjunction with "
+                    "parallel testing.")
+
             try:
-                subproc = subprocess.Popen(
-                    ['lsof -F0 -n -p {0}'.format(os.getpid())],
-                    shell=True, stdout=subprocess.PIPE)
-                output = subproc.communicate()[0].strip()
-            except subprocess.CalledProcessError:
+                import psutil
+            except ImportError:
                 raise SystemError(
-                    "open file detection requested, but could not "
-                    "successfully run the 'lsof' command")
+                    "open file detection requested, but psutil package "
+                    "is not installed.")
 
             all_args.append('--open-files')
 
@@ -369,15 +374,19 @@ class raises(object):
 
 
 _deprecations_as_exceptions = False
+_include_astropy_deprecations = True
 
-
-def enable_deprecations_as_exceptions():
+def enable_deprecations_as_exceptions(include_astropy_deprecations=True):
     """
     Turn on the feature that turns deprecations into exceptions.
     """
+
     global _deprecations_as_exceptions
     _deprecations_as_exceptions = True
 
+    global _include_astropy_deprecations
+    _include_astropy_deprecations = include_astropy_deprecations
+
 
 def treat_deprecations_as_exceptions():
     """
@@ -425,6 +434,11 @@ def treat_deprecations_as_exceptions():
     # Now, turn DeprecationWarnings into exceptions
     warnings.filterwarnings("error", ".*", DeprecationWarning)
 
+    # Only turn astropy deprecation warnings into exceptions if requested
+    if _include_astropy_deprecations:
+        warnings.filterwarnings("error", ".*", AstropyDeprecationWarning)
+        warnings.filterwarnings("error", ".*", AstropyPendingDeprecationWarning)
+
     if sys.version_info[:2] == (2, 6):
         # py.test's warning.showwarning does not include the line argument
         # on Python 2.6, so we need to explicitly ignore this warning.
@@ -540,190 +554,90 @@ def assert_follows_unicode_guidelines(
             assert eval(repr_x, roundtrip) == x
 
 
-##############################################################################
-# Note: the following class exists only for backward-compatibility purposes. #
-#       It has been moved to the separate astropy-helpers package, located   #
-#       at https://github.com/astropy/astropy-helpers. Any new development   #
-#       or bug fixes should be done there                                    #
-##############################################################################
-
-
-class astropy_test(Command, object):
-    user_options = [
-        ('package=', 'P',
-         "The name of a specific package to test, e.g. 'io.fits' or 'utils'.  "
-         "If nothing is specified, all default tests are run."),
-        ('test-path=', 't',
-         'Specify a test location by path.  If a relative path to a '
-         '.py file, it is relative to the built package.  If a relative '
-         'path to a .rst file, it is relative to the docs directory '
-         '(see --docs-path).  May also be an absolute path.'),
-        ('verbose-results', 'V',
-         'Turn on verbose output from pytest.'),
-        ('plugins=', 'p',
-         'Plugins to enable when running pytest.'),
-        ('pastebin=', 'b',
-         "Enable pytest pastebin output. Either 'all' or 'failed'."),
-        ('args=', 'a',
-         'Additional arguments to be passed to pytest.'),
-        ('remote-data', 'R', 'Run tests that download remote data.'),
-        ('pep8', '8',
-         'Enable PEP8 checking and disable regular tests. '
-         'Requires the pytest-pep8 plugin.'),
-        ('pdb', 'd',
-         'Start the interactive Python debugger on errors.'),
-        ('coverage', 'c',
-         'Create a coverage report. Requires the coverage package.'),
-        ('open-files', 'o', 'Fail if any tests leave files open.'),
-        ('parallel=', 'j',
-         'Run the tests in parallel on the specified number of '
-         'CPUs.  If negative, all the cores on the machine will be '
-         'used.  Requires the pytest-xdist plugin.'),
-        ('docs-path=', None,
-         'The path to the documentation .rst files.  If not provided, and '
-         'the current directory contains a directory called "docs", that '
-         'will be used.'),
-        ('skip-docs', None,
-         "Don't test the documentation .rst files.")
-    ]
-
-    user_options = _fix_user_options(user_options)
-
-    package_name = None
-
-    def initialize_options(self):
-        self.package = None
-        self.test_path = None
-        self.verbose_results = False
-        self.plugins = None
-        self.pastebin = None
-        self.args = None
-        self.remote_data = False
-        self.pep8 = False
-        self.pdb = False
-        self.coverage = False
-        self.open_files = False
-        self.parallel = 0
-        self.docs_path = None
-        self.skip_docs = False
-
-    def finalize_options(self):
-        # Normally we would validate the options here, but that's handled in
-        # run_tests
-        pass
+ at pytest.fixture(params=[0, 1, -1])
+def pickle_protocol(request):
+    """
+    Fixture to run all the tests for protocols 0 and 1, and -1 (most advanced).
+    (Originally from astropy.table.tests.test_pickle)
+    """
+    return request.param
 
-    def run(self):
-        self.reinitialize_command('build', inplace=False)
-        self.run_command('build')
-        build_cmd = self.get_finalized_command('build')
-        new_path = os.path.abspath(build_cmd.build_lib)
 
-        if self.docs_path is None:
-            if os.path.exists('docs'):
-                self.docs_path = os.path.abspath('docs')
+def generic_recursive_equality_test(a, b, class_history):
+    """
+    Check if the attributes of a and b are equal. Then,
+    check if the attributes of the attributes are equal.
+    """
+    dict_a = a.__dict__
+    dict_b = b.__dict__
+    for key in dict_a:
+        assert key in dict_b,\
+          "Did not pickle {0}".format(key)
+        if hasattr(dict_a[key], '__eq__'):
+            eq = (dict_a[key] == dict_b[key])
+            if '__iter__' in dir(eq):
+                eq = (False not in eq)
+            assert eq, "Value of {0} changed by pickling".format(key)
+
+        if hasattr(dict_a[key], '__dict__'):
+            if dict_a[key].__class__ in class_history:
+                #attempt to prevent infinite recursion
+                pass
+            else:
+                new_class_history = [dict_a[key].__class__]
+                new_class_history.extend(class_history)
+                generic_recursive_equality_test(dict_a[key],
+                                                dict_b[key],
+                                                new_class_history)
 
-        # Copy the build to a temporary directory for the purposes of testing
-        # - this avoids creating pyc and __pycache__ directories inside the
-        # build directory
-        tmp_dir = tempfile.mkdtemp(prefix='astropy-test-')
-        testing_path = os.path.join(tmp_dir, os.path.basename(new_path))
-        shutil.copytree(new_path, testing_path)
-        shutil.copy('setup.cfg', testing_path)
 
-        cmd_pre = ''
-        cmd_post = ''
+def check_pickling_recovery(original, protocol):
+    """
+    Try to pickle an object. If successful, make sure
+    the object's attributes survived pickling and unpickling.
+    """
+    f = pickle.dumps(original, protocol=protocol)
+    unpickled = pickle.loads(f)
+    class_history = [original.__class__]
+    generic_recursive_equality_test(original, unpickled,
+                                    class_history)
 
+
+def assert_quantity_allclose(actual, desired, rtol=1.e-7, atol=None, err_msg='', verbose=True):
+    """
+    Raise an assertion if two objects are not equal up to desired tolerance.
+
+    This is a :class:`~astropy.units.Quantity`-aware version of
+    :func:`numpy.testing.assert_allclose`.
+    """
+
+    import numpy as np
+    from .. import units as u
+
+    actual = u.Quantity(actual, subok=True, copy=False)
+
+    desired = u.Quantity(desired, subok=True, copy=False)
+    try:
+        desired = desired.to(actual.unit)
+    except u.UnitsError:
+        raise u.UnitsError("Units for 'desired' ({0}) and 'actual' ({1}) are not convertible".format(desired.unit, actual.unit))
+
+    if atol is None:
+        # by default, we assume an absolute tolerance of 0
+        atol = u.Quantity(0)
+    else:
+        atol = u.Quantity(atol, subok=True, copy=False)
         try:
-            if self.coverage:
-                if self.parallel != 0:
-                    raise ValueError(
-                        "--coverage can not be used with --parallel")
-
-                try:
-                    import coverage
-                except ImportError:
-                    raise ImportError(
-                        "--coverage requires that the coverage package is "
-                        "installed.")
-
-                # Don't use get_pkg_data_filename here, because it
-                # requires importing astropy.config and thus screwing
-                # up coverage results for those packages.
-                coveragerc = os.path.join(
-                    testing_path, self.package_name, 'tests', 'coveragerc')
-
-                # We create a coveragerc that is specific to the version
-                # of Python we're running, so that we can mark branches
-                # as being specifically for Python 2 or Python 3
-                with open(coveragerc, 'rb') as fd:
-                    coveragerc_content = fd.read().decode('utf-8')
-                if six.PY3:
-                    ignore_python_version = '2'
-                elif six.PY2:
-                    ignore_python_version = '3'
-                coveragerc_content = coveragerc_content.replace(
-                    "{ignore_python_version}", ignore_python_version).replace(
-                        "{packagename}", self.package_name)
-                tmp_coveragerc = os.path.join(tmp_dir, 'coveragerc')
-                with open(tmp_coveragerc, 'wb') as tmp:
-                    tmp.write(coveragerc_content.encode('utf-8'))
-
-                cmd_pre = (
-                    'import coverage; '
-                    'cov = coverage.coverage(data_file="{0}", config_file="{1}"); '
-                    'cov.start();'.format(
-                        os.path.abspath(".coverage"), tmp_coveragerc))
-                cmd_post = (
-                    'cov.stop(); '
-                    'from astropy.tests.helper import _save_coverage; '
-                    '_save_coverage(cov, result, "{0}", "{1}");'.format(
-                        os.path.abspath('.'), testing_path))
-
-            if six.PY3:
-                set_flag = "import builtins; builtins._ASTROPY_TEST_ = True"
-            elif six.PY2:
-                set_flag = "import __builtin__; __builtin__._ASTROPY_TEST_ = True"
-
-            cmd = ('{cmd_pre}{0}; import {1.package_name}, sys; result = ('
-                   '{1.package_name}.test('
-                   'package={1.package!r}, '
-                   'test_path={1.test_path!r}, '
-                   'args={1.args!r}, '
-                   'plugins={1.plugins!r}, '
-                   'verbose={1.verbose_results!r}, '
-                   'pastebin={1.pastebin!r}, '
-                   'remote_data={1.remote_data!r}, '
-                   'pep8={1.pep8!r}, '
-                   'pdb={1.pdb!r}, '
-                   'open_files={1.open_files!r}, '
-                   'parallel={1.parallel!r}, '
-                   'docs_path={1.docs_path!r}, '
-                   'skip_docs={1.skip_docs!r})); '
-                   '{cmd_post}'
-                   'sys.exit(result)')
-            cmd = cmd.format(set_flag, self, cmd_pre=cmd_pre, cmd_post=cmd_post)
-
-            # Run the tests in a subprocess--this is necessary since
-            # new extension modules may have appeared, and this is the
-            # easiest way to set up a new environment
-
-            # On Python 3.x prior to 3.3, the creation of .pyc files
-            # is not atomic.  py.test jumps through some hoops to make
-            # this work by parsing import statements and carefully
-            # importing files atomically.  However, it can't detect
-            # when __import__ is used, so its carefulness still fails.
-            # The solution here (admittedly a bit of a hack), is to
-            # turn off the generation of .pyc files altogether by
-            # passing the `-B` switch to `python`.  This does mean
-            # that each core will have to compile .py file to bytecode
-            # itself, rather than getting lucky and borrowing the work
-            # already done by another core.  Compilation is an
-            # insignificant fraction of total testing time, though, so
-            # it's probably not worth worrying about.
-            retcode = subprocess.call([sys.executable, '-B', '-c', cmd],
-                                      cwd=testing_path, close_fds=False)
-        finally:
-            # Remove temporary directory
-            shutil.rmtree(tmp_dir)
+            atol = atol.to(actual.unit)
+        except u.UnitsError:
+            raise u.UnitsError("Units for 'atol' ({0}) and 'actual' ({1}) are not convertible".format(atol.unit, actual.unit))
+
+    rtol =  u.Quantity(rtol, subok=True, copy=False)
+    try:
+        rtol = rtol.to(u.dimensionless_unscaled)
+    except:
+        raise u.UnitsError("`rtol` should be dimensionless")
 
-        raise SystemExit(retcode)
+    np.testing.assert_allclose(actual.value, desired.value,
+                               rtol=rtol.value, atol=atol.value,
+                               err_msg=err_msg, verbose=verbose)
diff --git a/astropy/tests/output_checker.py b/astropy/tests/output_checker.py
index 3f257f1..4751d9f 100644
--- a/astropy/tests/output_checker.py
+++ b/astropy/tests/output_checker.py
@@ -50,7 +50,7 @@ class AstropyOutputChecker(doctest.OutputChecker):
         # floats in the 'want' string may contain ellipses
         want_floats = got_floats + r'(\.{3})?'
 
-        front_sep = r'\s|[+*,(<-]'
+        front_sep = r'\s|[+*,(<=-]'
         back_sep = front_sep + r'|[)>j]'
 
         fbeg = r'^%s(?=%s|$)' % (got_floats, back_sep)
diff --git a/astropy/tests/pytest_plugins.py b/astropy/tests/pytest_plugins.py
index ce8f3d8..7342fb5 100644
--- a/astropy/tests/pytest_plugins.py
+++ b/astropy/tests/pytest_plugins.py
@@ -20,16 +20,20 @@ import locale
 import math
 import os
 import re
-import shutil
-import subprocess
 import sys
-import tempfile
 import types
 
 from .helper import (
     pytest, treat_deprecations_as_exceptions, enable_deprecations_as_exceptions)
 from .disable_internet import turn_off_internet, turn_on_internet
 from .output_checker import AstropyOutputChecker, FIX, FLOAT_CMP
+from ..utils import OrderedDict
+
+# Needed for Python 2.6 compatibility
+try:
+    import importlib.machinery as importlib_machinery
+except ImportError:
+    importlib_machinery = None
 
 # these pytest hooks allow us to mark tests and run the marked tests with
 # specific command line options.
@@ -382,44 +386,26 @@ class DocTestFinderPlus(doctest.DocTestFinder):
 
 # Open file detection.
 #
-# This works by calling out to lsof to get the list of open files held
-# by the process both before and after the test.  If something is
+# This works by calling out to psutil to get the list of open files
+# held by the process both before and after the test.  If something is
 # still open after the test that wasn't open before the test, an
 # AssertionError is raised.
 #
 # This is not thread-safe.  We're not currently running our tests
 # multi-threaded, but that is worth noting.
 
-SUPPORTS_OPEN_FILE_DETECTION = (
-    sys.platform in ('linux', 'linux2', 'darwin'))
-
 
 def _get_open_file_list():
-    fsencoding = sys.getfilesystemencoding()
-
-    sproc = subprocess.Popen(
-        ['lsof -F0 -n -p {0}'.format(os.getpid())],
-        shell=True, stdout=subprocess.PIPE)
-    output = sproc.communicate()[0].strip()
+    import psutil
     files = []
-    for line in output.split(b'\n'):
-        columns = line.split(b'\0')
-        mapping = {}
-        for column in columns:
-            if len(column) >= 2:
-                mapping[column[0:1]] = column[1:]
-
-        if (mapping.get(b'f') and
-            mapping.get(b'a', b' ') != b' ' and
-                mapping.get(b't') == b'REG'):
-            # Ignore extension modules -- they may be imported by a
-            # test but are never again closed by the runtime.  That's
-            # ok.
-            for suffix, mode, filetype in imp.get_suffixes():
-                if mapping[b'n'].decode(fsencoding).endswith(suffix):
-                    break
-            else:
-                files.append(mapping[b'n'])
+    p = psutil.Process()
+
+    if importlib_machinery is not None:
+        suffixes = tuple(importlib_machinery.all_suffixes())
+    else:
+        suffixes = tuple(info[0] for info in imp.get_suffixes())
+
+    files = [x.path for x in p.open_files() if not x.path.endswith(suffixes)]
 
     return set(files)
 
@@ -427,7 +413,7 @@ def _get_open_file_list():
 def pytest_runtest_setup(item):
     # Store a list of the currently opened files so we can compare
     # against them when the test is done.
-    if SUPPORTS_OPEN_FILE_DETECTION and item.config.getvalue('open_files'):
+    if item.config.getvalue('open_files'):
         item.open_files = _get_open_file_list()
 
     if ('remote_data' in item.keywords and
@@ -435,42 +421,46 @@ def pytest_runtest_setup(item):
         pytest.skip("need --remote-data option to run")
 
 
-if SUPPORTS_OPEN_FILE_DETECTION:
-    def pytest_runtest_teardown(item, nextitem):
-        # a "skipped" test will not have been called with
-        # pytest_runtest_setup, so therefore won't have an
-        # "open_files" member
-        if (not item.config.getvalue('open_files') or
-                not hasattr(item, 'open_files')):
-            return
+def pytest_runtest_teardown(item, nextitem):
+    # a "skipped" test will not have been called with
+    # pytest_runtest_setup, so therefore won't have an
+    # "open_files" member
+    if (not item.config.getvalue('open_files') or
+            not hasattr(item, 'open_files')):
+        return
 
-        start_open_files = item.open_files
-        del item.open_files
+    start_open_files = item.open_files
+    del item.open_files
 
-        open_files = _get_open_file_list()
+    open_files = _get_open_file_list()
 
-        # This works in tandem with the test_open_file_detection test to
-        # ensure that it creates one extra open file.
-        if item.name == 'test_open_file_detection':
-            assert len(start_open_files) + 1 == len(open_files)
-            return
+    # This works in tandem with the test_open_file_detection test to
+    # ensure that it creates one extra open file.
+    if item.name == 'test_open_file_detection':
+        assert len(start_open_files) + 1 == len(open_files)
+        return
+
+    not_closed = set()
+    for filename in open_files:
+        # astropy.log files are allowed to continue to exist
+        # between test runs
+        if os.path.basename(filename) == 'astropy.log':
+            continue
+
+        if filename not in start_open_files:
+            not_closed.add(filename)
 
-        not_closed = set()
-        for filename in open_files:
-            # astropy.log files are allowed to continue to exist
-            # between test runs
-            if os.path.basename(filename) == 'astropy.log':
-                continue
+    if len(not_closed):
+        msg = ['File(s) not closed:']
+        for name in not_closed:
+            msg.append('  {0}'.format(name))
+        raise AssertionError('\n'.join(msg))
 
-            if filename not in start_open_files:
-                not_closed.add(filename)
 
-        if len(not_closed):
-            msg = ['File(s) not closed:']
-            for name in not_closed:
-                msg.append('  {0}'.format(
-                    name.decode(sys.getfilesystemencoding())))
-            raise AssertionError('\n'.join(msg))
+PYTEST_HEADER_MODULES = OrderedDict([('Numpy', 'numpy'),
+                                     ('Scipy', 'scipy'),
+                                     ('Matplotlib', 'matplotlib'),
+                                     ('h5py', 'h5py')])
 
 
 def pytest_report_header(config):
@@ -506,26 +496,17 @@ def pytest_report_header(config):
     s += "float info: dig: {0.dig}, mant_dig: {0.dig}\n\n".format(
         sys.float_info)
 
-    import numpy
-    s += "Numpy: {0}\n".format(numpy.__version__)
-
-    try:
-        import scipy
-        s += "Scipy: {0}\n".format(scipy.__version__)
-    except:
-        s += "Scipy: not available\n"
-
-    try:
-        import matplotlib
-        s += "Matplotlib: {0}\n".format(matplotlib.__version__)
-    except:
-        s += "Matplotlib: not available\n"
-
-    try:
-        import h5py.version
-        s += "h5py: {0}\n".format(h5py.version.version)
-    except:
-        s += "h5py: not available\n"
+    for module_display, module_name in six.iteritems(PYTEST_HEADER_MODULES):
+        try:
+            module = __import__(module_name)
+        except ImportError:
+            s += "{0}: not available\n".format(module_display)
+        else:
+            try:
+                version = module.__version__
+            except AttributeError:
+                version = 'unknown (no __version__ attribute)'
+            s += "{0}: {1}\n".format(module_display, version)
 
     special_opts = ["remote_data", "pep8"]
     opts = []
diff --git a/astropy/tests/tests/run_after_2to3.py b/astropy/tests/tests/run_after_2to3.py
deleted file mode 100644
index 9bb80ed..0000000
--- a/astropy/tests/tests/run_after_2to3.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-from __future__ import (absolute_import, division, print_function,
-                        unicode_literals)
-
-
-# This module is not a test module, but is used as part of the
-# test_run_after_2to3 test in test_run_tests.py
-def test_run_after_2to3():
-    try:
-        1 / 0
-    except ZeroDivisionError as e:
-        pass
diff --git a/astropy/tests/tests/test_quantity_helpers.py b/astropy/tests/tests/test_quantity_helpers.py
new file mode 100644
index 0000000..bbe8cee
--- /dev/null
+++ b/astropy/tests/tests/test_quantity_helpers.py
@@ -0,0 +1,39 @@
+from ... import units as u
+
+from ..helper import assert_quantity_allclose, pytest
+
+
+def test_assert_quantity_allclose():
+
+    assert_quantity_allclose([1,2], [1,2])
+
+    assert_quantity_allclose([1,2] * u.m, [100,200] * u.cm)
+
+    assert_quantity_allclose([1,2] * u.m, [101,201] * u.cm, atol=2 * u.cm)
+
+    with pytest.raises(AssertionError):
+        assert_quantity_allclose([1,2] * u.m, [90,200] * u.cm)
+
+    with pytest.raises(AssertionError):
+        assert_quantity_allclose([1,2] * u.m, [101,201] * u.cm, atol=0.5 * u.cm)
+
+    with pytest.raises(u.UnitsError) as exc:
+        assert_quantity_allclose([1,2] * u.m, [100,200])
+    assert exc.value.args[0] == "Units for 'desired' () and 'actual' (m) are not convertible"
+
+    with pytest.raises(u.UnitsError) as exc:
+        assert_quantity_allclose([1,2], [100,200] * u.cm)
+    assert exc.value.args[0] == "Units for 'desired' (cm) and 'actual' () are not convertible"
+
+    with pytest.raises(u.UnitsError) as exc:
+        assert_quantity_allclose([1,2] * u.m, [100,200] * u.cm, atol=0.3)
+    assert exc.value.args[0] == "Units for 'atol' () and 'actual' (m) are not convertible"
+
+    with pytest.raises(u.UnitsError) as exc:
+        assert_quantity_allclose([1,2], [1, 2], atol=0.3 * u.m)
+    assert exc.value.args[0] == "Units for 'atol' (m) and 'actual' () are not convertible"
+
+    with pytest.raises(u.UnitsError) as exc:
+        assert_quantity_allclose([1,2], [1, 2], rtol=0.3 * u.m)
+    assert exc.value.args[0] == "`rtol` should be dimensionless"
+
diff --git a/astropy/tests/tests/test_run_tests.py b/astropy/tests/tests/test_run_tests.py
index 2bb23f4..4b71660 100644
--- a/astropy/tests/tests/test_run_tests.py
+++ b/astropy/tests/tests/test_run_tests.py
@@ -31,15 +31,6 @@ def test_pastebin_keyword():
         _get_test_runner().run_tests(pastebin='not_an_option')
 
 
-# tests that tests are only run in Python 3 out of the 2to3'd build (otherwise
-# a syntax error would occur)
-try:
-    from .run_after_2to3 import test_run_after_2to3
-except SyntaxError:
-    def test_run_after_2to3():
-        helper.pytest.fail("Not running the 2to3'd tests!")
-
-
 # TODO: Temporarily disabled, as this seems to non-deterministically fail
 # def test_deprecation_warning():
 #     with pytest.raises(DeprecationWarning):
diff --git a/astropy/time/core.py b/astropy/time/core.py
index 266f66a..888f71c 100644
--- a/astropy/time/core.py
+++ b/astropy/time/core.py
@@ -10,22 +10,21 @@ from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
 import fnmatch
-import itertools
 import time
 
 from datetime import datetime
 
 import numpy as np
-import functools
 
 from .. import units as u
-from ..utils import deprecated, deprecated_attribute
-from ..utils.exceptions import AstropyBackwardsIncompatibleChangeWarning
+from .. import _erfa as erfa
 from ..utils.compat.misc import override__dir__
 from ..extern import six
 
+
 __all__ = ['Time', 'TimeDelta', 'TimeFormat', 'TimeJD', 'TimeMJD',
            'TimeFromEpoch', 'TimeUnix', 'TimeCxcSec', 'TimeGPS',
+           'TimeDecimalYear',
            'TimePlotDate', 'TimeDatetime', 'TimeString',
            'TimeISO', 'TimeISOT', 'TimeYearDayTime', 'TimeEpochDate',
            'TimeBesselianEpoch', 'TimeJulianEpoch', 'TimeDeltaFormat',
@@ -44,9 +43,6 @@ except ImportError:
     if not _ASTROPY_SETUP_:
         raise
 
-MJD_ZERO = 2400000.5
-SECS_PER_DAY = 86400
-
 # These both get filled in at end after TimeFormat subclasses defined
 TIME_FORMATS = {}
 TIME_DELTA_FORMATS = {}
@@ -75,21 +71,23 @@ TIME_DELTA_TYPES = dict((scale, scales)
                         for scales in (GEOCENTRIC_SCALES, BARYCENTRIC_SCALES,
                                        ROTATIONAL_SCALES) for scale in scales)
 TIME_DELTA_SCALES = TIME_DELTA_TYPES.keys()
-# TODO: access these from erfa.h??
-# L_G = 1 - d(TT)/d(TCG) -> d(TT)/d(TCG) = 1-L_G
-# d(TCG)/d(TT) = 1/(1-L_G) = 1 + (1-(1-L_G))/(1-L_G) = 1 + L_G/(1-L_G)
-ERFA_ELG = 6.969290134e-10
-# L_B = 1 - d(TDB)/d(TCB)
-ERFA_ELB = 1.550519768e-8
+# For time scale changes, we need L_G and L_B, which are stored in erfam.h as
+#   /* L_G = 1 - d(TT)/d(TCG) */
+#   define ERFA_ELG (6.969290134e-10)
+#   /* L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0 */
+#   define ERFA_ELB (1.550519768e-8)
+# These are exposed in erfa as erfa.ELG and erfa.ELB.
+# Implied: d(TT)/d(TCG) = 1-L_G
+# and      d(TCG)/d(TT) = 1/(1-L_G) = 1 + (1-(1-L_G))/(1-L_G) = 1 + L_G/(1-L_G)
 # scale offsets as second = first + first * scale_offset[(first,second)]
 SCALE_OFFSETS = {('tt', 'tai'): None,
                  ('tai', 'tt'): None,
-                 ('tcg', 'tt'): -ERFA_ELG,
-                 ('tt', 'tcg'): ERFA_ELG / (1. - ERFA_ELG),
-                 ('tcg', 'tai'): -ERFA_ELG,
-                 ('tai', 'tcg'): ERFA_ELG / (1. - ERFA_ELG),
-                 ('tcb', 'tdb'): -ERFA_ELB,
-                 ('tdb', 'tcb'): ERFA_ELB / (1. - ERFA_ELB)}
+                 ('tcg', 'tt'): -erfa.ELG,
+                 ('tt', 'tcg'): erfa.ELG / (1. - erfa.ELG),
+                 ('tcg', 'tai'): -erfa.ELG,
+                 ('tai', 'tcg'): erfa.ELG / (1. - erfa.ELG),
+                 ('tcb', 'tdb'): -erfa.ELB,
+                 ('tdb', 'tcb'): erfa.ELB / (1. - erfa.ELB)}
 
 # triple-level dictionary, yay!
 SIDEREAL_TIME_MODELS = {
@@ -104,23 +102,6 @@ SIDEREAL_TIME_MODELS = {
         'IAU1994': {'function': erfa_time.gst94, 'scales': ('ut1',)}}}
 
 
-# TODO: remove in version beyond 0.4
-# with longitude and latitude swapped to get them in the right order,
-# insist that these are given as keyword arguments
-def kwargs_after_scale(func):
-    @functools.wraps(func)
-    def new_func(*args, **kwargs):
-        if len(args) > 5:
-            AstropyBackwardsIncompatibleChangeWarning(
-                'lon and lat have been replaced with location in version 0.4. '
-                'Code should be changed to set the location explicitly using '
-                'a keyword argument: location=EarthLocation(...), or via a '
-                'shortcut with a tuple: location=(lon, lat, [height]) or '
-                'location=(x, y, z)')
-        return func(*args, **kwargs)
-    return new_func
-
-
 class Time(object):
     """
     Represent and manipulate times and dates for astronomy.
@@ -158,9 +139,6 @@ class Time(object):
         Make a copy of the input values
     """
 
-    is_scalar = deprecated_attribute(name='is_scalar', since='0.3',
-                                     alternative='isscalar')
-
     _precision = 3  # Precision when for seconds as floating point
     _in_subfmt = '*'  # Select subformat for inputting string times
     _out_subfmt = '*'  # Select subformat for outputting string times
@@ -175,10 +153,13 @@ class Time(object):
     # gets called over the __mul__ of Numpy arrays.
     __array_priority__ = 20000
 
-    @kwargs_after_scale
+    # Declare that Time can be used as a Table column by defining the
+    # attribute where column attributes will be stored.
+    _astropy_column_attrs = None
+
     def __new__(cls, val, val2=None, format=None, scale=None,
                 precision=None, in_subfmt=None, out_subfmt=None,
-                location=None, copy=False, **kwargs):
+                location=None, copy=False):
 
         if isinstance(val, cls):
             self = val.replicate(format=format, copy=copy)
@@ -190,19 +171,9 @@ class Time(object):
     def __getnewargs__(self):
         return (self._time,)
 
-    @kwargs_after_scale
     def __init__(self, val, val2=None, format=None, scale=None,
                  precision=None, in_subfmt=None, out_subfmt=None,
-                 location=None, copy=False, **kwargs):
-
-        if 'lon' in kwargs or 'lat' in kwargs:
-            AstropyBackwardsIncompatibleChangeWarning(
-                'lon and lat have been replaced with location in version 0.4. '
-                'Code should be changed to set the location explicitly using '
-                'a keyword argument: location=(lon, lat, [height]) or '
-                'location=(x, y, z)')
-            if location is None:
-                location = (kwargs.pop('lon', None), kwargs.pop('lat', None))
+                 location=None, copy=False):
 
         if location is not None:
             from ..coordinates import EarthLocation
@@ -226,12 +197,18 @@ class Time(object):
         else:
             self._init_from_vals(val, val2, format, scale, copy)
 
-        if (self.location is not None and self.location.shape and
-                len(self.location) != (1 if self.isscalar else len(self))):
-            raise ValueError('Have {0} times but {1} locations.  Should '
-                             'either give a single location or one for each '
-                             'time'.format(1 if self.isscalar else len(self),
-                                           len(self.location)))
+        if self.location:
+            try:
+                # check the two can be broadcast together
+                b = np.broadcast(self.location, self._time.jd1)
+                # and insist there are not more locations than times
+                assert b.size == self.size
+            except:
+                raise ValueError('The location with shape {0} cannot be '
+                                 'broadcast against time with shape {1}. '
+                                 'Typically, either give a single location or '
+                                 'one for each time.'
+                                 .format(self.location.shape, self.shape))
 
     def _init_from_vals(self, val, val2, format, scale, copy):
         """
@@ -240,37 +217,17 @@ class Time(object):
         some basic input validation.
         """
 
-        # check whether input is some form of list of Time objects,
-        # since these should be treated separately
-        try:
-            val0 = val[0]
-        except:
-            isiterable_of_times = False
-        else:
-            isiterable_of_times = isinstance(val0, self.__class__)
+        # Coerce val into an array
+        val = _make_array(val, copy)
 
-        if isiterable_of_times:
-            if val2 is not None:
-                raise ValueError(
-                    'non-None second value for list of {0!r} objects'
-                    .format(self.__class__.__name__))
-            self.isscalar = False
-        else:
-            # Coerce val into a 1-d array
-            val, val_ndim = _make_1d_array(val, copy)
-
-            self.isscalar = (val_ndim == 0)
-
-            # If val2 is not None, ensure consistency
-            if val2 is not None:
-                val2, val2_ndim = _make_1d_array(val2, copy)
-
-                if val_ndim != val2_ndim:
-                    raise ValueError('Input val and val2 must have same '
-                                     'dimensions')
-
-                if len(val) != len(val2):
-                    raise ValueError('Input val and val2 must match in length')
+        # If val2 is not None, ensure consistency
+        if val2 is not None:
+            val2 = _make_array(val2, copy)
+            try:
+                np.broadcast(val, val2)
+            except ValueError:
+                raise ValueError('Input val and val2 have inconsistent shape; '
+                                 'they cannot be broadcast together.')
 
         if scale is not None:
             if not (isinstance(scale, six.string_types) and
@@ -293,8 +250,7 @@ class Time(object):
         guess available formats and stop when one matches.
         """
 
-        if format is None and (isinstance(val[0], self.__class__) or
-                               val.dtype.kind in ('S', 'U', 'O')):
+        if format is None and val.dtype.kind in ('S', 'U', 'O'):
             formats = [(name, cls) for name, cls in self.FORMATS.items()
                        if issubclass(cls, TimeUnique)]
             err_msg = ('any of the formats where the format keyword is '
@@ -452,15 +408,20 @@ class Time(object):
             raise ValueError('out_subfmt attribute must be a string')
         self._out_subfmt = val
 
-    def _shaped_like_input(self, values):
-        if self.isscalar:
-            value0 = values[0]
-            try:
-                return value0.tolist()
-            except AttributeError:
-                return value0
-        else:
-            return values
+    @property
+    def shape(self):
+        return self._time.jd1.shape
+
+    @property
+    def size(self):
+        return self._time.jd1.size
+
+    @property
+    def isscalar(self):
+        return self.shape == ()
+
+    def _shaped_like_input(self, value):
+        return value if self._time.jd1.shape else value.item()
 
     @property
     def jd1(self):
@@ -481,27 +442,6 @@ class Time(object):
         """Time value(s) in current format"""
         return self._shaped_like_input(self._time.value)
 
-    @property
-    @deprecated("0.3", name="val", alternative="value")
-    def val(self):
-        return self.value
-
-    @property
-    @deprecated("0.3", name="vals", alternative="value")
-    def vals(self):
-        """Time values in current format as a numpy array."""
-        return self.value
-
-    @property
-    @deprecated("0.4", name="lon", alternative="location.longitude")
-    def lon(self):
-        return self.location.longitude
-
-    @property
-    @deprecated("0.4", name="lat", alternative="location.latitude")
-    def lat(self):
-        return self.location.latitude
-
     def sidereal_time(self, kind, longitude=None, model=None):
         """Calculate sidereal time.
 
@@ -568,7 +508,7 @@ class Time(object):
         'mean', sorted(SIDEREAL_TIME_MODELS['mean'].keys()))
 
     def _erfa_sidereal_time(self, model):
-        """Caculate a sidereal time using a IAU precession/nutation model."""
+        """Calculate a sidereal time using a IAU precession/nutation model."""
 
         from ..coordinates import Longitude
 
@@ -579,8 +519,7 @@ class Time(object):
 
         sidereal_time = erfa_function(*erfa_parameters)
 
-        return Longitude(self._shaped_like_input(sidereal_time),
-                         u.radian).to(u.hourangle)
+        return Longitude(sidereal_time, u.radian).to(u.hourangle)
 
     def copy(self, format=None):
         """
@@ -602,7 +541,7 @@ class Time(object):
 
         Returns
         -------
-        tm: Time object
+        tm : Time object
             Copy of this object
         """
         return self.replicate(format, copy=True)
@@ -633,7 +572,7 @@ class Time(object):
 
         Returns
         -------
-        tm: Time object
+        tm : Time object
             Replica of this object
         """
         # To avoid recalculating integer day + fraction, no longer just
@@ -647,7 +586,7 @@ class Time(object):
                           self.scale, self.precision,
                           self.in_subfmt, self.out_subfmt, from_jd=True)
         # Optional or non-arg attributes
-        attrs = ('isscalar', '_delta_ut1_utc', '_delta_tdb_tt',
+        attrs = ('_delta_ut1_utc', '_delta_tdb_tt',
                  'location', 'precision', 'in_subfmt', 'out_subfmt')
         for attr in attrs:
             try:
@@ -707,19 +646,14 @@ class Time(object):
             raise TypeError('scalar {0!r} object is not subscriptable.'.format(
                 self.__class__.__name__))
         tm = self.replicate()
-        jd1 = self._time.jd1[item]
-        tm.isscalar = jd1.ndim == 0
-
-        def keepasarray(x):
-            return np.atleast_1d(x) if isinstance(x, np.float) else x
-        tm._time.jd1 = keepasarray(jd1)
-        tm._time.jd2 = keepasarray(self._time.jd2[item])
+        tm._time.jd1 = self._time.jd1[item]
+        tm._time.jd2 = self._time.jd2[item]
         attrs = ('_delta_ut1_utc', '_delta_tdb_tt', 'location')
         for attr in attrs:
             val = getattr(self, attr, None)
             if val is not None:
                 try:
-                    setattr(tm, attr, keepasarray(val[item]))
+                    setattr(tm, attr, val[item])
                 except IndexError:  # location may be scalar (same for all)
                     continue
 
@@ -738,14 +672,7 @@ class Time(object):
             tm = self.replicate(format=attr)
             if hasattr(self.FORMATS[attr], 'epoch_scale'):
                 tm._set_scale(self.FORMATS[attr].epoch_scale)
-            if self.isscalar:
-                out = tm._time.value[0]
-                # convert to native python for non-object dtypes
-                if tm._time.value.dtype.kind != 'O':
-                    out = out.tolist()
-            else:
-                out = tm.value
-            return out
+            return tm.value
 
         elif attr in TIME_SCALES:  # allowed ones done above (self.SCALES)
             if self.scale is None:
@@ -767,18 +694,20 @@ class Time(object):
         result.update(self.FORMATS)
         return result
 
-    def _match_len(self, val):
+    def _match_shape(self, val):
         """
         Ensure that `val` is matched to length of self.  If val has length 1
-        then broadcast, otherwise cast to double and make sure length matches.
+        then broadcast, otherwise cast to double and make sure shape matches.
         """
-        val, ndim = _make_1d_array(val, copy=True)  # be conservative and copy
-        if len(val) == 1:
-            oval = val
-            val = np.empty(len(self._time), dtype=np.double)
-            val[:] = oval
-        elif len(val) != len(self._time):
-            raise ValueError('Attribute length must match Time object length')
+        val = _make_array(val, copy=True)  # be conservative and copy
+        try:
+            # check the two can be broadcast together
+            b = np.broadcast(val, self._time.jd1)
+            # and insist there are not more attributes than times
+            assert b.size == self.size
+        except:
+            raise ValueError('Attribute shape must match that of Time object')
+
         return val
 
     def get_delta_ut1_utc(self, iers_table=None, return_status=False):
@@ -797,9 +726,9 @@ class Time(object):
 
         Returns
         -------
-        ut1_utc: float or float array
+        ut1_utc : float or float array
             UT1-UTC, interpolated in IERS Table
-        status: int or int array
+        status : int or int array
             Status values (if ``return_status=`True```)::
             ``astropy.utils.iers.FROM_IERS_B``
             ``astropy.utils.iers.FROM_IERS_A``
@@ -881,7 +810,7 @@ class Time(object):
         return self._delta_ut1_utc
 
     def _set_delta_ut1_utc(self, val):
-        self._delta_ut1_utc = self._match_len(val)
+        self._delta_ut1_utc = self._match_shape(val)
 
     # Note can't use @property because _get_delta_tdb_tt is explicitly
     # called with the optional jd1 and jd2 args.
@@ -922,14 +851,13 @@ class Time(object):
             rxy = np.hypot(location.x, location.y)
             z = location.z
             self._delta_tdb_tt = erfa_time.d_tdb_tt(
-                jd1, jd2, ut, np.atleast_1d(lon.to(u.radian).value),
-                np.atleast_1d(rxy.to(u.km).value),
-                np.atleast_1d(z.to(u.km).value))
+                jd1, jd2, ut, lon.to(u.radian).value,
+                rxy.to(u.km).value, z.to(u.km).value)
 
         return self._delta_tdb_tt
 
     def _set_delta_tdb_tt(self, val):
-        self._delta_tdb_tt = self._match_len(val)
+        self._delta_tdb_tt = self._match_shape(val)
 
     # Note can't use @property because _get_delta_tdb_tt is explicitly
     # called with the optional jd1 and jd2 args.
@@ -980,7 +908,6 @@ class Time(object):
         jd2 = out._time.jd2 - other._time.jd2
 
         out._time.jd1, out._time.jd2 = day_frac(jd1, jd2)
-        out.isscalar = self.isscalar and other.isscalar
 
         if other_is_delta and out.scale != self.scale:
             return getattr(out, self.scale)
@@ -1021,7 +948,6 @@ class Time(object):
         jd2 = out._time.jd2 + other._time.jd2
 
         out._time.jd1, out._time.jd2 = day_frac(jd1, jd2)
-        out.isscalar = self.isscalar and other.isscalar
 
         if out.scale != self.scale:
             return getattr(out, self.scale)
@@ -1201,7 +1127,6 @@ class TimeDelta(Time):
         jd2 = self._time.jd2 + other._time.jd2
 
         out._time.jd1, out._time.jd2 = day_frac(jd1, jd2)
-        out.isscalar = self.isscalar and other.isscalar
 
         return out
 
@@ -1234,7 +1159,6 @@ class TimeDelta(Time):
         jd2 = self._time.jd2 - other._time.jd2
 
         out._time.jd1, out._time.jd2 = day_frac(jd1, jd2)
-        out.isscalar = self.isscalar and other.isscalar
 
         return out
 
@@ -1317,11 +1241,28 @@ class TimeDelta(Time):
         return other / self.to(u.day)
 
     def to(self, *args, **kwargs):
-        return u.Quantity(self._shaped_like_input(self._time.jd1 +
-                                                  self._time.jd2),
+        return u.Quantity(self._time.jd1 + self._time.jd2,
                           u.day).to(*args, **kwargs)
 
 
+class TimeFormatMeta(type):
+    """
+    Metaclass that adds `TimeFormat` and `TimeDeltaFormat` to the
+    `TIME_FORMATS` and `TIME_DELTA_FORMATS` registries, respectively.
+    """
+
+    _registry = TIME_FORMATS
+
+    def __new__(mcls, name, bases, members):
+        cls = super(TimeFormatMeta, mcls).__new__(mcls, name, bases, members)
+
+        if 'name' in members:
+            mcls._registry[cls.name] = cls
+
+        return cls
+
+
+ at six.add_metaclass(TimeFormatMeta)
 class TimeFormat(object):
     """
     Base class for time representations.
@@ -1469,11 +1410,74 @@ class TimeMJD(TimeFormat):
         # first one is probably biggest.
         self._check_scale(self._scale)  # Validate scale.
         self.jd1, self.jd2 = day_frac(val1, val2)
-        self.jd1 += MJD_ZERO
+        self.jd1 += erfa.DJM0  # erfa.DJM0=2400000.5 (from erfam.h)
+
+    @property
+    def value(self):
+        return (self.jd1 - erfa.DJM0) + self.jd2
+
+
+class TimeDecimalYear(TimeFormat):
+    """
+    Time as a decimal year, with integer values corresponding to midnight
+    of the first day of each year.  For example 2000.5 corresponds to the
+    ISO time '2000-07-02 00:00:00'.
+    """
+    name = 'decimalyear'
+
+    def set_jds(self, val1, val2):
+        self._check_scale(self._scale)  # Validate scale.
+
+        sum12, err12 = two_sum(val1, val2)
+        iy_start = np.trunc(sum12).astype(np.int)
+        extra, y_frac = two_sum(sum12, -iy_start)
+        y_frac += extra + err12
+
+        val = (val1 + val2).astype(np.double)
+        iy_start = np.trunc(val).astype(np.int)
+
+        imon = np.ones_like(iy_start)
+        iday = np.ones_like(iy_start)
+        ihr = np.zeros_like(iy_start)
+        imin = np.zeros_like(iy_start)
+        isec = np.zeros_like(y_frac)
+
+        # Possible enhancement: use np.unique to only compute start, stop
+        # for unique values of iy_start.
+        jd1_start, jd2_start = erfa_time.dtf_jd(
+            self.scale.upper().encode('utf8'), iy_start, imon, iday, ihr, imin, isec)
+        jd1_end, jd2_end = erfa_time.dtf_jd(
+            self.scale.upper().encode('utf8'), iy_start + 1, imon, iday, ihr, imin, isec)
+
+        t_start = Time(jd1_start, jd2_start, scale=self.scale, format='jd')
+        t_end = Time(jd1_end, jd2_end, scale=self.scale, format='jd')
+        t_frac = t_start + (t_end - t_start) * y_frac
+
+        self.jd1, self.jd2 = day_frac(t_frac.jd1, t_frac.jd2)
 
     @property
     def value(self):
-        return (self.jd1 - MJD_ZERO) + self.jd2
+        iy_start, ims, ids, ihmsfs = erfa_time.jd_dtf(self.scale.upper().encode('utf8'),
+                                                 0,  # precision=0
+                                                 self.jd1, self.jd2)
+        imon = np.ones_like(iy_start)
+        iday = np.ones_like(iy_start)
+        ihr = np.zeros_like(iy_start)
+        imin = np.zeros_like(iy_start)
+        isec = np.zeros_like(self.jd1)
+
+        # Possible enhancement: use np.unique to only compute start, stop
+        # for unique values of iy_start.
+        jd1_start, jd2_start = erfa_time.dtf_jd(
+            self.scale.upper().encode('utf8'), iy_start, imon, iday, ihr, imin, isec)
+        jd1_end, jd2_end = erfa_time.dtf_jd(
+            self.scale.upper().encode('utf8'), iy_start + 1, imon, iday, ihr, imin, isec)
+
+        dt = (self.jd1 - jd1_start) + (self.jd2 - jd2_start)
+        dt_end = (jd1_end - jd1_start) + (jd2_end - jd2_start)
+        decimalyear = iy_start + dt / dt_end
+
+        return decimalyear
 
 
 class TimeFromEpoch(TimeFormat):
@@ -1531,8 +1535,8 @@ class TimeFromEpoch(TimeFormat):
                                   .format(self.name, self.epoch_scale,
                                           self.scale, err))
 
-        self.jd1 = tm.jd1
-        self.jd2 = tm.jd2
+        self.jd1 = tm._time.jd1
+        self.jd2 = tm._time.jd2
 
     @property
     def value(self):
@@ -1555,7 +1559,7 @@ class TimeUnix(TimeFromEpoch):
     per UTC day.
     """
     name = 'unix'
-    unit = 1.0 / SECS_PER_DAY  # in days (1 day == 86400 seconds)
+    unit = 1.0 / erfa.DAYSEC  # in days (1 day == 86400 seconds)
     epoch_val = '1970-01-01 00:00:00'
     epoch_val2 = None
     epoch_scale = 'utc'
@@ -1568,7 +1572,7 @@ class TimeCxcSec(TimeFromEpoch):
     For example, 63072064.184 is midnight on January 1, 2000.
     """
     name = 'cxcsec'
-    unit = 1.0 / SECS_PER_DAY  # in days (1 day == 86400 seconds)
+    unit = 1.0 / erfa.DAYSEC  # in days (1 day == 86400 seconds)
     epoch_val = '1998-01-01 00:00:00'
     epoch_val2 = None
     epoch_scale = 'tt'
@@ -1589,7 +1593,7 @@ class TimeGPS(TimeFromEpoch):
     For details, see http://tycho.usno.navy.mil/gpstt.html
     """
     name = 'gps'
-    unit = 1.0 / SECS_PER_DAY  # in days (1 day == 86400 seconds)
+    unit = 1.0 / erfa.DAYSEC  # in days (1 day == 86400 seconds)
     epoch_val = '1980-01-06 00:00:19'
     # above epoch is the same as Time('1980-01-06 00:00:00', scale='utc').tai
     epoch_val2 = None
@@ -1647,16 +1651,23 @@ class TimeAstropyTime(TimeUnique):
         Use __new__ instead of __init__ to output a class instance that
         is the same as the class of the first Time object in the list.
         """
-
-        if not all(isinstance(val, Time) for val in val1):
-            raise TypeError('Input values for {0} class must be datetime '
-                            'objects'.format(cls.name))
+        val1_0 = val1.flat[0]
+        if not (isinstance(val1_0, Time) and all(type(val) is type(val1_0)
+                                                 for val in val1.flat)):
+            raise TypeError('Input values for {0} class must all be same '
+                            'astropy Time type.'.format(cls.name))
 
         if scale is None:
-            scale = val1[0].scale
-        jd1 = np.concatenate([getattr(val, scale)._time.jd1 for val in val1])
-        jd2 = np.concatenate([getattr(val, scale)._time.jd2 for val in val1])
-        OutTimeFormat = val1[0]._time.__class__
+            scale = val1_0.scale
+        if val1.shape:
+            vals = [getattr(val, scale)._time for val in val1]
+            jd1 = np.concatenate([np.atleast_1d(val.jd1) for val in vals])
+            jd2 = np.concatenate([np.atleast_1d(val.jd2) for val in vals])
+        else:
+            val = getattr(val1_0, scale)._time
+            jd1, jd2 = val.jd1, val.jd2
+
+        OutTimeFormat = val1_0._time.__class__
         self = OutTimeFormat(jd1, jd2, scale, precision, in_subfmt, out_subfmt,
                              from_jd=True)
 
@@ -1681,7 +1692,7 @@ class TimeDatetime(TimeUnique):
     def _check_val_type(self, val1, val2):
         # Note: don't care about val2 for this class
         try:
-            assert all(isinstance(val, datetime) for val in val1)
+            assert all(isinstance(val, datetime) for val in val1.flat)
         except:
             raise TypeError('Input values for {0} class must be '
                             'datetime objects'.format(self.name))
@@ -1689,25 +1700,25 @@ class TimeDatetime(TimeUnique):
 
     def set_jds(self, val1, val2):
         """Convert datetime object contained in val1 to jd1, jd2"""
-        n_times = len(val1)
-        iy = np.empty(n_times, dtype=np.intc)
-        im = np.empty(n_times, dtype=np.intc)
-        id = np.empty(n_times, dtype=np.intc)
-        ihr = np.empty(n_times, dtype=np.intc)
-        imin = np.empty(n_times, dtype=np.intc)
-        dsec = np.empty(n_times, dtype=np.double)
-
-        # Iterate through the datetime objects
-        for i, val in enumerate(val1):
-            iy[i] = val.year
-            im[i] = val.month
-            id[i] = val.day
-            ihr[i] = val.hour
-            imin[i] = val.minute
-            dsec[i] = val.second + val.microsecond / 1e6
+        # Iterate through the datetime objects, getting year, month, etc.
+        iterator = np.nditer([val1, None, None, None, None, None, None],
+                             flags=['refs_ok'],
+                             op_dtypes=[np.object] + 5*[np.intc] + [np.double])
+        for val, iy, im, id, ihr, imin, dsec in iterator:
+            dt = val.item()
+
+            if dt.tzinfo is not None:
+                dt = (dt - dt.utcoffset()).replace(tzinfo=None)
+
+            iy[...] = dt.year
+            im[...] = dt.month
+            id[...] = dt.day
+            ihr[...] = dt.hour
+            imin[...] = dt.minute
+            dsec[...] = dt.second + dt.microsecond / 1e6
 
         self.jd1, self.jd2 = erfa_time.dtf_jd(
-            self.scale.upper().encode('utf8'), iy, im, id, ihr, imin, dsec)
+            self.scale.upper().encode('utf8'), *iterator.operands[1:])
 
     @property
     def value(self):
@@ -1715,21 +1726,22 @@ class TimeDatetime(TimeUnique):
                                                  .encode('utf8'),
                                                  6,  # precision=6 for microsec
                                                  self.jd1, self.jd2)
+        ihrs = ihmsfs[..., 0]
+        imins = ihmsfs[..., 1]
+        isecs = ihmsfs[..., 2]
+        ifracs = ihmsfs[..., 3]
+        iterator = np.nditer([iys, ims, ids, ihrs, imins, isecs, ifracs, None],
+                             flags=['refs_ok'],
+                             op_dtypes=7*[iys.dtype] + [np.object])
+        for iy, im, id, ihr, imin, isec, ifracsec, out in iterator:
+            out[...] = datetime(iy, im, id, ihr, imin, isec, ifracsec)
 
-        out = np.empty(len(self), dtype=np.object)
-        idxs = itertools.count()
-        for idx, iy, im, id, ihmsf in six.moves.zip(idxs, iys, ims, ids,
-                                                    ihmsfs):
-            ihr, imin, isec, ifracsec = ihmsf
-            out[idx] = datetime(int(iy), int(im), int(id),
-                                int(ihr), int(imin), int(isec), int(ifracsec))
-
-        return out
+        return iterator.operands[-1]
 
 
 class TimeString(TimeUnique):
     """
-    Base class for string-like time represetations.
+    Base class for string-like time representations.
 
     This class assumes that anything following the last decimal point to the
     right is a fraction of a second.
@@ -1747,27 +1759,21 @@ class TimeString(TimeUnique):
 
     def set_jds(self, val1, val2):
         """Parse the time strings contained in val1 and set jd1, jd2"""
-        n_times = len(val1)  # val1,2 already checked to have same len
-        iy = np.empty(n_times, dtype=np.intc)
-        im = np.empty(n_times, dtype=np.intc)
-        id = np.empty(n_times, dtype=np.intc)
-        ihr = np.empty(n_times, dtype=np.intc)
-        imin = np.empty(n_times, dtype=np.intc)
-        dsec = np.empty(n_times, dtype=np.double)
-
         # Select subformats based on current self.in_subfmt
         subfmts = self._select_subfmts(self.in_subfmt)
 
-        for i, timestr in enumerate(val1):
-            # Assume that anything following "." on the right side is a
-            # floating fraction of a second.
-
+        iterator = np.nditer([val1, None, None, None, None, None, None],
+                             op_dtypes=[val1.dtype] + 5*[np.intc] + [np.double])
+        for val, iy, im, id, ihr, imin, dsec in iterator:
+            timestr = val.item()
             # Handle trailing 'Z' for UTC time
             if timestr.endswith('Z'):
                 if self.scale != 'utc':
                     raise ValueError("Time input terminating in 'Z' must have scale='UTC'")
                 timestr = timestr[:-1]
 
+            # Assume that anything following "." on the right side is a
+            # floating fraction of a second.
             try:
                 idot = timestr.rindex('.')
             except:
@@ -1782,19 +1788,19 @@ class TimeString(TimeUnique):
                 except ValueError:
                     pass
                 else:
-                    iy[i] = tm.tm_year
-                    im[i] = tm.tm_mon
-                    id[i] = tm.tm_mday
-                    ihr[i] = tm.tm_hour
-                    imin[i] = tm.tm_min
-                    dsec[i] = tm.tm_sec + fracsec
+                    iy[...] = tm.tm_year
+                    im[...] = tm.tm_mon
+                    id[...] = tm.tm_mday
+                    ihr[...] = tm.tm_hour
+                    imin[...] = tm.tm_min
+                    dsec[...] = tm.tm_sec + fracsec
                     break
             else:
                 raise ValueError('Time {0} does not match {1} format'
                                  .format(timestr, self.name))
 
         self.jd1, self.jd2 = erfa_time.dtf_jd(
-            self.scale.upper().encode('utf8'), iy, im, id, ihr, imin, dsec)
+            self.scale.upper().encode('utf8'), *iterator.operands[1:])
 
     def str_kwargs(self):
         """
@@ -1815,8 +1821,12 @@ class TimeString(TimeUnique):
             has_yday = False
             yday = None
 
-        for iy, im, id, ihmsf in six.moves.zip(iys, ims, ids, ihmsfs):
-            ihr, imin, isec, ifracsec = ihmsf
+        ihrs = ihmsfs[..., 0]
+        imins = ihmsfs[..., 1]
+        isecs = ihmsfs[..., 2]
+        ifracs = ihmsfs[..., 3]
+        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
+                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
             if has_yday:
                 yday = datetime(iy, im, id).timetuple().tm_yday
 
@@ -1841,7 +1851,7 @@ class TimeString(TimeUnique):
         for kwargs in self.str_kwargs():
             outs.append(str(str_fmt.format(**kwargs)))
 
-        return np.array(outs)
+        return np.array(outs).reshape(self.jd1.shape)
 
     def _select_subfmts(self, pattern):
         """
@@ -1967,7 +1977,7 @@ class TimeBesselianEpoch(TimeEpochDate):
 class TimeJulianEpoch(TimeEpochDate):
     """Julian Epoch year as floating point value(s) like 2000.0"""
     name = 'jyear'
-    unit = 365.25  # Length of the Julian year, for conversion to quantities
+    unit = erfa.DJY  # 365.25, the Julian year, for conversion to quantities
     epoch_to_jd = 'julian_epoch_jd'
     jd_to_epoch = 'jd_julian_epoch'
 
@@ -1978,10 +1988,10 @@ class TimeEpochDateString(TimeString):
     such as 'B1950.0' or 'J2000.0' respectively.
     """
     def set_jds(self, val1, val2):
-        years = np.empty(len(val1), dtype=np.double)
         epoch_prefix = self.epoch_prefix
-
-        for i, time_str in enumerate(val1):
+        iterator = np.nditer([val1, None], op_dtypes=[val1.dtype, np.double])
+        for val, years in iterator:
+            time_str = val.item()
             try:
                 epoch_type, year_str = time_str[0], time_str[1:]
                 year = float(year_str)
@@ -1991,11 +2001,11 @@ class TimeEpochDateString(TimeString):
                 raise ValueError('Time {0} does not match {1} format'
                                  .format(time_str, self.name))
             else:
-                years[i] = year
+                years[...] = year
 
         self._check_scale(self._scale)  # validate scale.
         epoch_to_jd = getattr(erfa_time, self.epoch_to_jd)
-        self.jd1, self.jd2 = epoch_to_jd(years)
+        self.jd1, self.jd2 = epoch_to_jd(iterator.operands[-1])
 
     @property
     def value(self):
@@ -2003,8 +2013,8 @@ class TimeEpochDateString(TimeString):
         years = jd_to_epoch(self.jd1, self.jd2)
         # Use old-style format since it is a factor of 2 faster
         str_fmt = self.epoch_prefix + '%.' + str(self.precision) + 'f'
-        outs = [str_fmt % year for year in years]
-        return np.array(outs)
+        outs = [str_fmt % year for year in years.flat]
+        return np.array(outs).reshape(self.jd1.shape)
 
 
 class TimeBesselianEpochString(TimeEpochDateString):
@@ -2023,6 +2033,11 @@ class TimeJulianEpochString(TimeEpochDateString):
     epoch_prefix = 'J'
 
 
+class TimeDeltaFormatMeta(TimeFormatMeta):
+    _registry = TIME_DELTA_FORMATS
+
+
+ at six.add_metaclass(TimeDeltaFormatMeta)
 class TimeDeltaFormat(TimeFormat):
     """Base class for time delta representations"""
 
@@ -2049,7 +2064,7 @@ class TimeDeltaFormat(TimeFormat):
 class TimeDeltaSec(TimeDeltaFormat):
     """Time delta in SI seconds"""
     name = 'sec'
-    unit = 1. / SECS_PER_DAY  # for quantity input
+    unit = 1. / erfa.DAYSEC  # for quantity input
 
 
 class TimeDeltaJD(TimeDeltaFormat):
@@ -2062,46 +2077,24 @@ class ScaleValueError(Exception):
     pass
 
 
-# Set module constant with names of all available time formats
-for name, val in list(six.iteritems(locals())):
-    try:
-        is_timeformat = issubclass(val, TimeFormat)
-        is_timedeltaformat = issubclass(val, TimeDeltaFormat)
-    except:
-        pass
-    else:
-        if hasattr(val, 'name'):
-            if is_timedeltaformat:
-                TIME_DELTA_FORMATS[val.name] = val
-            elif is_timeformat:
-                TIME_FORMATS[val.name] = val
-
-
-def _make_1d_array(val, copy=False):
+def _make_array(val, copy=False):
     """
-    Take ``val`` and convert/reshape to a 1-d array.  If ``copy`` is `True`
+    Take ``val`` and convert/reshape to an array.  If ``copy`` is `True`
     then copy input values.
 
     Returns
     -------
-    val, val_ndim: ndarray, int
-        Array version of ``val`` and the number of dims in original.
+    val : ndarray
+        Array version of ``val``.
     """
     val = np.array(val, copy=copy, subok=True)
-    val_ndim = val.ndim  # remember original ndim
-    if val.ndim == 0:
-        val = np.atleast_1d(val)
-    elif val_ndim > 1:
-        # Maybe lift this restriction later to allow multi-dim in/out?
-        raise TypeError('Input val must be zero or one dimensional')
-
     # Allow only float64, string or object arrays as input
     # (object is for datetime, maybe add more specific test later?)
     # This also ensures the right byteorder for float64 (closes #2942).
     if not (val.dtype == np.float64 or val.dtype.kind in 'OSUa'):
         val = np.asanyarray(val, dtype=np.float64)
 
-    return val, val_ndim
+    return val
 
 
 def day_frac(val1, val2, factor=1., divisor=1.):
@@ -2117,7 +2110,7 @@ def day_frac(val1, val2, factor=1., divisor=1.):
 
     Returns
     -------
-    day, frac: float64
+    day, frac : float64
         Integer and fractional part of val1 + val2.
     """
     # Add val1 and val2 exactly, returning the result as two float64s.
@@ -2158,7 +2151,7 @@ def two_sum(a, b):
 
     Returns
     -------
-    sum, err: float64
+    sum, err : float64
         Approximate sum of a + b and the exact floating point error
     """
     x = a + b
@@ -2172,7 +2165,7 @@ def two_sum(a, b):
 def two_product(a, b):
     """
     Multiple ``a`` and ``b`` exactly, returning the result as two float64s.
-    The first is the approximate prodcut (with some floating point error)
+    The first is the approximate product (with some floating point error)
     and the second is the error of the float64 product.
 
     Uses the procedure of Shewchuk, 1997,
@@ -2181,7 +2174,7 @@ def two_product(a, b):
 
     Returns
     -------
-    prod, err: float64
+    prod, err : float64
         Approximate product a * b and the exact floating point error
     """
     x = a * b
diff --git a/astropy/time/erfa_time.c b/astropy/time/erfa_time.c
deleted file mode 100644
index 87bc13b..0000000
--- a/astropy/time/erfa_time.c
+++ /dev/null
@@ -1,20866 +0,0 @@
-/* Generated by Cython 0.21.1 */
-
-#define PY_SSIZE_T_CLEAN
-#ifndef CYTHON_USE_PYLONG_INTERNALS
-#ifdef PYLONG_BITS_IN_DIGIT
-#define CYTHON_USE_PYLONG_INTERNALS 0
-#else
-#include "pyconfig.h"
-#ifdef PYLONG_BITS_IN_DIGIT
-#define CYTHON_USE_PYLONG_INTERNALS 1
-#else
-#define CYTHON_USE_PYLONG_INTERNALS 0
-#endif
-#endif
-#endif
-#include "Python.h"
-#ifndef Py_PYTHON_H
-    #error Python headers needed to compile C extensions, please install development version of Python.
-#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
-    #error Cython requires Python 2.6+ or Python 3.2+.
-#else
-#define CYTHON_ABI "0_21_1"
-#include <stddef.h>
-#ifndef offsetof
-#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
-#endif
-#if !defined(WIN32) && !defined(MS_WINDOWS)
-  #ifndef __stdcall
-    #define __stdcall
-  #endif
-  #ifndef __cdecl
-    #define __cdecl
-  #endif
-  #ifndef __fastcall
-    #define __fastcall
-  #endif
-#endif
-#ifndef DL_IMPORT
-  #define DL_IMPORT(t) t
-#endif
-#ifndef DL_EXPORT
-  #define DL_EXPORT(t) t
-#endif
-#ifndef PY_LONG_LONG
-  #define PY_LONG_LONG LONG_LONG
-#endif
-#ifndef Py_HUGE_VAL
-  #define Py_HUGE_VAL HUGE_VAL
-#endif
-#ifdef PYPY_VERSION
-#define CYTHON_COMPILING_IN_PYPY 1
-#define CYTHON_COMPILING_IN_CPYTHON 0
-#else
-#define CYTHON_COMPILING_IN_PYPY 0
-#define CYTHON_COMPILING_IN_CPYTHON 1
-#endif
-#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
-#define Py_OptimizeFlag 0
-#endif
-#define __PYX_BUILD_PY_SSIZE_T "n"
-#define CYTHON_FORMAT_SSIZE_T "z"
-#if PY_MAJOR_VERSION < 3
-  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
-          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
-  #define __Pyx_DefaultClassType PyClass_Type
-#else
-  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
-          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
-  #define __Pyx_DefaultClassType PyType_Type
-#endif
-#if PY_MAJOR_VERSION >= 3
-  #define Py_TPFLAGS_CHECKTYPES 0
-  #define Py_TPFLAGS_HAVE_INDEX 0
-  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#endif
-#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
-  #define Py_TPFLAGS_HAVE_FINALIZE 0
-#endif
-#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
-  #define CYTHON_PEP393_ENABLED 1
-  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
-                                              0 : _PyUnicode_Ready((PyObject *)(op)))
-  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
-  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
-  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
-  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
-  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
-#else
-  #define CYTHON_PEP393_ENABLED 0
-  #define __Pyx_PyUnicode_READY(op)       (0)
-  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
-  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
-  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
-  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
-  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
-#endif
-#if CYTHON_COMPILING_IN_PYPY
-  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
-  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
-  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
-#else
-  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
-  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
-      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
-  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
-#endif
-#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
-#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
-#if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
-#else
-  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
-#endif
-#if PY_MAJOR_VERSION >= 3
-  #define PyBaseString_Type            PyUnicode_Type
-  #define PyStringObject               PyUnicodeObject
-  #define PyString_Type                PyUnicode_Type
-  #define PyString_Check               PyUnicode_Check
-  #define PyString_CheckExact          PyUnicode_CheckExact
-#endif
-#if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
-  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
-#else
-  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
-  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
-#endif
-#ifndef PySet_CheckExact
-  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
-#endif
-#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
-#if PY_MAJOR_VERSION >= 3
-  #define PyIntObject                  PyLongObject
-  #define PyInt_Type                   PyLong_Type
-  #define PyInt_Check(op)              PyLong_Check(op)
-  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
-  #define PyInt_FromString             PyLong_FromString
-  #define PyInt_FromUnicode            PyLong_FromUnicode
-  #define PyInt_FromLong               PyLong_FromLong
-  #define PyInt_FromSize_t             PyLong_FromSize_t
-  #define PyInt_FromSsize_t            PyLong_FromSsize_t
-  #define PyInt_AsLong                 PyLong_AsLong
-  #define PyInt_AS_LONG                PyLong_AS_LONG
-  #define PyInt_AsSsize_t              PyLong_AsSsize_t
-  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
-  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
-  #define PyNumber_Int                 PyNumber_Long
-#endif
-#if PY_MAJOR_VERSION >= 3
-  #define PyBoolObject                 PyLongObject
-#endif
-#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
-  #ifndef PyUnicode_InternFromString
-    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
-  #endif
-#endif
-#if PY_VERSION_HEX < 0x030200A4
-  typedef long Py_hash_t;
-  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
-  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
-#else
-  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
-  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
-#endif
-#if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
-#else
-  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
-#endif
-#ifndef CYTHON_INLINE
-  #if defined(__GNUC__)
-    #define CYTHON_INLINE __inline__
-  #elif defined(_MSC_VER)
-    #define CYTHON_INLINE __inline
-  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-    #define CYTHON_INLINE inline
-  #else
-    #define CYTHON_INLINE
-  #endif
-#endif
-#ifndef CYTHON_RESTRICT
-  #if defined(__GNUC__)
-    #define CYTHON_RESTRICT __restrict__
-  #elif defined(_MSC_VER) && _MSC_VER >= 1400
-    #define CYTHON_RESTRICT __restrict
-  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-    #define CYTHON_RESTRICT restrict
-  #else
-    #define CYTHON_RESTRICT
-  #endif
-#endif
-#ifdef NAN
-#define __PYX_NAN() ((float) NAN)
-#else
-static CYTHON_INLINE float __PYX_NAN() {
-  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
-   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
-   a quiet NaN. */
-  float value;
-  memset(&value, 0xFF, sizeof(value));
-  return value;
-}
-#endif
-#ifdef __cplusplus
-template<typename T>
-void __Pyx_call_destructor(T* x) {
-    x->~T();
-}
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
-  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
-#else
-  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
-  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
-#endif
-
-#ifndef __PYX_EXTERN_C
-  #ifdef __cplusplus
-    #define __PYX_EXTERN_C extern "C"
-  #else
-    #define __PYX_EXTERN_C extern
-  #endif
-#endif
-
-#if defined(WIN32) || defined(MS_WINDOWS)
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#define __PYX_HAVE__astropy__time__erfa_time
-#define __PYX_HAVE_API__astropy__time__erfa_time
-#include "string.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "numpy/arrayobject.h"
-#include "numpy/ufuncobject.h"
-#include "erfa.h"
-#ifdef _OPENMP
-#include <omp.h>
-#endif /* _OPENMP */
-
-#ifdef PYREX_WITHOUT_ASSERTIONS
-#define CYTHON_WITHOUT_ASSERTIONS
-#endif
-
-#ifndef CYTHON_UNUSED
-# if defined(__GNUC__)
-#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#     define CYTHON_UNUSED __attribute__ ((__unused__))
-#   else
-#     define CYTHON_UNUSED
-#   endif
-# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
-#   define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-#   define CYTHON_UNUSED
-# endif
-#endif
-typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
-                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
-
-#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
-#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
-#define __PYX_DEFAULT_STRING_ENCODING ""
-#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
-#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
-#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
-    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
-    (sizeof(type) > sizeof(Py_ssize_t) &&               \
-          likely(v < (type)PY_SSIZE_T_MAX ||            \
-                 v == (type)PY_SSIZE_T_MAX)  &&         \
-          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
-                                v == (type)PY_SSIZE_T_MIN)))  ||  \
-    (sizeof(type) == sizeof(Py_ssize_t) &&              \
-          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
-                               v == (type)PY_SSIZE_T_MAX)))  )
-static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
-static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
-#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
-#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
-#define __Pyx_PyBytes_FromString        PyBytes_FromString
-#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
-static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
-#if PY_MAJOR_VERSION < 3
-    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
-    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
-#else
-    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
-    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
-#endif
-#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
-#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
-#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((const char*)s)
-#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((const char*)s)
-#define __Pyx_PyByteArray_FromUString(s)   __Pyx_PyByteArray_FromString((const char*)s)
-#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((const char*)s)
-#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
-#if PY_MAJOR_VERSION < 3
-static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
-{
-    const Py_UNICODE *u_end = u;
-    while (*u_end++) ;
-    return (size_t)(u_end - u - 1);
-}
-#else
-#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
-#endif
-#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
-#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
-#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
-#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
-#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
-#if CYTHON_COMPILING_IN_CPYTHON
-#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
-#else
-#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
-#endif
-#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
-#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
-static int __Pyx_sys_getdefaultencoding_not_ascii;
-static int __Pyx_init_sys_getdefaultencoding_params(void) {
-    PyObject* sys;
-    PyObject* default_encoding = NULL;
-    PyObject* ascii_chars_u = NULL;
-    PyObject* ascii_chars_b = NULL;
-    const char* default_encoding_c;
-    sys = PyImport_ImportModule("sys");
-    if (!sys) goto bad;
-    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
-    Py_DECREF(sys);
-    if (!default_encoding) goto bad;
-    default_encoding_c = PyBytes_AsString(default_encoding);
-    if (!default_encoding_c) goto bad;
-    if (strcmp(default_encoding_c, "ascii") == 0) {
-        __Pyx_sys_getdefaultencoding_not_ascii = 0;
-    } else {
-        char ascii_chars[128];
-        int c;
-        for (c = 0; c < 128; c++) {
-            ascii_chars[c] = c;
-        }
-        __Pyx_sys_getdefaultencoding_not_ascii = 1;
-        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
-        if (!ascii_chars_u) goto bad;
-        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
-        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
-            PyErr_Format(
-                PyExc_ValueError,
-                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
-                default_encoding_c);
-            goto bad;
-        }
-        Py_DECREF(ascii_chars_u);
-        Py_DECREF(ascii_chars_b);
-    }
-    Py_DECREF(default_encoding);
-    return 0;
-bad:
-    Py_XDECREF(default_encoding);
-    Py_XDECREF(ascii_chars_u);
-    Py_XDECREF(ascii_chars_b);
-    return -1;
-}
-#endif
-#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
-#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
-#else
-#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
-#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
-static char* __PYX_DEFAULT_STRING_ENCODING;
-static int __Pyx_init_sys_getdefaultencoding_params(void) {
-    PyObject* sys;
-    PyObject* default_encoding = NULL;
-    char* default_encoding_c;
-    sys = PyImport_ImportModule("sys");
-    if (!sys) goto bad;
-    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
-    Py_DECREF(sys);
-    if (!default_encoding) goto bad;
-    default_encoding_c = PyBytes_AsString(default_encoding);
-    if (!default_encoding_c) goto bad;
-    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
-    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
-    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
-    Py_DECREF(default_encoding);
-    return 0;
-bad:
-    Py_XDECREF(default_encoding);
-    return -1;
-}
-#endif
-#endif
-
-
-/* Test for GCC > 2.95 */
-#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
-  #define likely(x)   __builtin_expect(!!(x), 1)
-  #define unlikely(x) __builtin_expect(!!(x), 0)
-#else /* !__GNUC__ or GCC < 2.95 */
-  #define likely(x)   (x)
-  #define unlikely(x) (x)
-#endif /* __GNUC__ */
-
-static PyObject *__pyx_m;
-static PyObject *__pyx_d;
-static PyObject *__pyx_b;
-static PyObject *__pyx_empty_tuple;
-static PyObject *__pyx_empty_bytes;
-static int __pyx_lineno;
-static int __pyx_clineno = 0;
-static const char * __pyx_cfilenm= __FILE__;
-static const char *__pyx_filename;
-
-#if !defined(CYTHON_CCOMPLEX)
-  #if defined(__cplusplus)
-    #define CYTHON_CCOMPLEX 1
-  #elif defined(_Complex_I)
-    #define CYTHON_CCOMPLEX 1
-  #else
-    #define CYTHON_CCOMPLEX 0
-  #endif
-#endif
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    #include <complex>
-  #else
-    #include <complex.h>
-  #endif
-#endif
-#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
-  #undef _Complex_I
-  #define _Complex_I 1.0fj
-#endif
-
-
-static const char *__pyx_f[] = {
-  "astropy/time/erfa_time.pyx",
-  "__init__.pxd",
-  "type.pxd",
-};
-#define IS_UNSIGNED(type) (((type) -1) > 0)
-struct __Pyx_StructField_;
-#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
-typedef struct {
-  const char* name;
-  struct __Pyx_StructField_* fields;
-  size_t size;
-  size_t arraysize[8];
-  int ndim;
-  char typegroup;
-  char is_unsigned;
-  int flags;
-} __Pyx_TypeInfo;
-typedef struct __Pyx_StructField_ {
-  __Pyx_TypeInfo* type;
-  const char* name;
-  size_t offset;
-} __Pyx_StructField;
-typedef struct {
-  __Pyx_StructField* field;
-  size_t parent_offset;
-} __Pyx_BufFmt_StackElem;
-typedef struct {
-  __Pyx_StructField root;
-  __Pyx_BufFmt_StackElem* head;
-  size_t fmt_offset;
-  size_t new_count, enc_count;
-  size_t struct_alignment;
-  int is_complex;
-  char enc_type;
-  char new_packmode;
-  char enc_packmode;
-  char is_valid_array;
-} __Pyx_BufFmt_Context;
-
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":723
- * # in Cython to enable them only on the right systems.
- * 
- * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
- * ctypedef npy_int16      int16_t
- * ctypedef npy_int32      int32_t
- */
-typedef npy_int8 __pyx_t_5numpy_int8_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":724
- * 
- * ctypedef npy_int8       int8_t
- * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
- * ctypedef npy_int32      int32_t
- * ctypedef npy_int64      int64_t
- */
-typedef npy_int16 __pyx_t_5numpy_int16_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725
- * ctypedef npy_int8       int8_t
- * ctypedef npy_int16      int16_t
- * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
- * ctypedef npy_int64      int64_t
- * #ctypedef npy_int96      int96_t
- */
-typedef npy_int32 __pyx_t_5numpy_int32_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726
- * ctypedef npy_int16      int16_t
- * ctypedef npy_int32      int32_t
- * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
- * #ctypedef npy_int96      int96_t
- * #ctypedef npy_int128     int128_t
- */
-typedef npy_int64 __pyx_t_5numpy_int64_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":730
- * #ctypedef npy_int128     int128_t
- * 
- * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
- * ctypedef npy_uint16     uint16_t
- * ctypedef npy_uint32     uint32_t
- */
-typedef npy_uint8 __pyx_t_5numpy_uint8_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":731
- * 
- * ctypedef npy_uint8      uint8_t
- * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
- * ctypedef npy_uint32     uint32_t
- * ctypedef npy_uint64     uint64_t
- */
-typedef npy_uint16 __pyx_t_5numpy_uint16_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732
- * ctypedef npy_uint8      uint8_t
- * ctypedef npy_uint16     uint16_t
- * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
- * ctypedef npy_uint64     uint64_t
- * #ctypedef npy_uint96     uint96_t
- */
-typedef npy_uint32 __pyx_t_5numpy_uint32_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733
- * ctypedef npy_uint16     uint16_t
- * ctypedef npy_uint32     uint32_t
- * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
- * #ctypedef npy_uint96     uint96_t
- * #ctypedef npy_uint128    uint128_t
- */
-typedef npy_uint64 __pyx_t_5numpy_uint64_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":737
- * #ctypedef npy_uint128    uint128_t
- * 
- * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
- * ctypedef npy_float64    float64_t
- * #ctypedef npy_float80    float80_t
- */
-typedef npy_float32 __pyx_t_5numpy_float32_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":738
- * 
- * ctypedef npy_float32    float32_t
- * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
- * #ctypedef npy_float80    float80_t
- * #ctypedef npy_float128   float128_t
- */
-typedef npy_float64 __pyx_t_5numpy_float64_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":747
- * # The int types are mapped a bit surprising --
- * # numpy.int corresponds to 'l' and numpy.long to 'q'
- * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
- * ctypedef npy_longlong   long_t
- * ctypedef npy_longlong   longlong_t
- */
-typedef npy_long __pyx_t_5numpy_int_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":748
- * # numpy.int corresponds to 'l' and numpy.long to 'q'
- * ctypedef npy_long       int_t
- * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
- * ctypedef npy_longlong   longlong_t
- * 
- */
-typedef npy_longlong __pyx_t_5numpy_long_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749
- * ctypedef npy_long       int_t
- * ctypedef npy_longlong   long_t
- * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
- * 
- * ctypedef npy_ulong      uint_t
- */
-typedef npy_longlong __pyx_t_5numpy_longlong_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751
- * ctypedef npy_longlong   longlong_t
- * 
- * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
- * ctypedef npy_ulonglong  ulong_t
- * ctypedef npy_ulonglong  ulonglong_t
- */
-typedef npy_ulong __pyx_t_5numpy_uint_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752
- * 
- * ctypedef npy_ulong      uint_t
- * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
- * ctypedef npy_ulonglong  ulonglong_t
- * 
- */
-typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753
- * ctypedef npy_ulong      uint_t
- * ctypedef npy_ulonglong  ulong_t
- * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
- * 
- * ctypedef npy_intp       intp_t
- */
-typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755
- * ctypedef npy_ulonglong  ulonglong_t
- * 
- * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
- * ctypedef npy_uintp      uintp_t
- * 
- */
-typedef npy_intp __pyx_t_5numpy_intp_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756
- * 
- * ctypedef npy_intp       intp_t
- * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
- * 
- * ctypedef npy_double     float_t
- */
-typedef npy_uintp __pyx_t_5numpy_uintp_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758
- * ctypedef npy_uintp      uintp_t
- * 
- * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
- * ctypedef npy_double     double_t
- * ctypedef npy_longdouble longdouble_t
- */
-typedef npy_double __pyx_t_5numpy_float_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759
- * 
- * ctypedef npy_double     float_t
- * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
- * ctypedef npy_longdouble longdouble_t
- * 
- */
-typedef npy_double __pyx_t_5numpy_double_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760
- * ctypedef npy_double     float_t
- * ctypedef npy_double     double_t
- * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
- * 
- * ctypedef npy_cfloat      cfloat_t
- */
-typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
-
-/* "astropy/time/erfa_time.pyx":9
- * import cython
- * 
- * ctypedef np.double_t DOUBLE_T             # <<<<<<<<<<<<<<
- * 
- * cdef extern from "erfa.h":
- */
-typedef __pyx_t_5numpy_double_t __pyx_t_7astropy_4time_9erfa_time_DOUBLE_T;
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    typedef ::std::complex< float > __pyx_t_float_complex;
-  #else
-    typedef float _Complex __pyx_t_float_complex;
-  #endif
-#else
-    typedef struct { float real, imag; } __pyx_t_float_complex;
-#endif
-
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    typedef ::std::complex< double > __pyx_t_double_complex;
-  #else
-    typedef double _Complex __pyx_t_double_complex;
-  #endif
-#else
-    typedef struct { double real, imag; } __pyx_t_double_complex;
-#endif
-
-
-/*--- Type declarations ---*/
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762
- * ctypedef npy_longdouble longdouble_t
- * 
- * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
- * ctypedef npy_cdouble     cdouble_t
- * ctypedef npy_clongdouble clongdouble_t
- */
-typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763
- * 
- * ctypedef npy_cfloat      cfloat_t
- * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
- * ctypedef npy_clongdouble clongdouble_t
- * 
- */
-typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764
- * ctypedef npy_cfloat      cfloat_t
- * ctypedef npy_cdouble     cdouble_t
- * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
- * 
- * ctypedef npy_cdouble     complex_t
- */
-typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766
- * ctypedef npy_clongdouble clongdouble_t
- * 
- * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew1(a):
- */
-typedef npy_cdouble __pyx_t_5numpy_complex_t;
-#ifndef CYTHON_REFNANNY
-  #define CYTHON_REFNANNY 0
-#endif
-#if CYTHON_REFNANNY
-  typedef struct {
-    void (*INCREF)(void*, PyObject*, int);
-    void (*DECREF)(void*, PyObject*, int);
-    void (*GOTREF)(void*, PyObject*, int);
-    void (*GIVEREF)(void*, PyObject*, int);
-    void* (*SetupContext)(const char*, int, const char*);
-    void (*FinishContext)(void**);
-  } __Pyx_RefNannyAPIStruct;
-  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
-  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
-  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
-#ifdef WITH_THREAD
-  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
-          if (acquire_gil) { \
-              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
-              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
-              PyGILState_Release(__pyx_gilstate_save); \
-          } else { \
-              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
-          }
-#else
-  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
-          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
-#endif
-  #define __Pyx_RefNannyFinishContext() \
-          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
-  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
-  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
-  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
-  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
-  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
-  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
-  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
-  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
-#else
-  #define __Pyx_RefNannyDeclarations
-  #define __Pyx_RefNannySetupContext(name, acquire_gil)
-  #define __Pyx_RefNannyFinishContext()
-  #define __Pyx_INCREF(r) Py_INCREF(r)
-  #define __Pyx_DECREF(r) Py_DECREF(r)
-  #define __Pyx_GOTREF(r)
-  #define __Pyx_GIVEREF(r)
-  #define __Pyx_XINCREF(r) Py_XINCREF(r)
-  #define __Pyx_XDECREF(r) Py_XDECREF(r)
-  #define __Pyx_XGOTREF(r)
-  #define __Pyx_XGIVEREF(r)
-#endif
-#define __Pyx_XDECREF_SET(r, v) do {                            \
-        PyObject *tmp = (PyObject *) r;                         \
-        r = v; __Pyx_XDECREF(tmp);                              \
-    } while (0)
-#define __Pyx_DECREF_SET(r, v) do {                             \
-        PyObject *tmp = (PyObject *) r;                         \
-        r = v; __Pyx_DECREF(tmp);                               \
-    } while (0)
-#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
-#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
-
-#if CYTHON_COMPILING_IN_CPYTHON
-static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
-    PyTypeObject* tp = Py_TYPE(obj);
-    if (likely(tp->tp_getattro))
-        return tp->tp_getattro(obj, attr_name);
-#if PY_MAJOR_VERSION < 3
-    if (likely(tp->tp_getattr))
-        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
-#endif
-    return PyObject_GetAttr(obj, attr_name);
-}
-#else
-#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
-#endif
-
-static PyObject *__Pyx_GetBuiltinName(PyObject *name);
-
-static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
-    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
-
-static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
-
-static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
-    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
-    const char* function_name);
-
-static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
-    int result = PySequence_Contains(seq, item);
-    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
-}
-
-static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
-
-#if CYTHON_COMPILING_IN_CPYTHON
-static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
-#else
-#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
-#endif
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
-
-static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
-    const char *name, int exact);
-
-static CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
-    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
-static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
-
-#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
-static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
-
-#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)
-#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
-    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
-    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
-    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
-               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
-#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
-    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
-    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
-    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
-                                                              int wraparound, int boundscheck);
-#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
-    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
-    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
-    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
-                                                              int wraparound, int boundscheck);
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
-                                                     int is_list, int wraparound, int boundscheck);
-
-static void __Pyx_RaiseBufferIndexError(int axis);
-
-#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
-    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
-    __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
-    (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
-               __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
-static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
-static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
-                                               int is_list, int wraparound, int boundscheck);
-
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
-
-static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
-
-static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
-
-static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
-
-typedef struct {
-    int code_line;
-    PyCodeObject* code_object;
-} __Pyx_CodeObjectCacheEntry;
-struct __Pyx_CodeObjectCache {
-    int count;
-    int max_count;
-    __Pyx_CodeObjectCacheEntry* entries;
-};
-static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
-static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
-static PyCodeObject *__pyx_find_code_object(int code_line);
-static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
-
-static void __Pyx_AddTraceback(const char *funcname, int c_line,
-                               int py_line, const char *filename);
-
-typedef struct {
-  Py_ssize_t shape, strides, suboffsets;
-} __Pyx_Buf_DimInfo;
-typedef struct {
-  size_t refcount;
-  Py_buffer pybuffer;
-} __Pyx_Buffer;
-typedef struct {
-  __Pyx_Buffer *rcbuffer;
-  char *data;
-  __Pyx_Buf_DimInfo diminfo[8];
-} __Pyx_LocalBuf_ND;
-
-#if PY_MAJOR_VERSION < 3
-    static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
-    static void __Pyx_ReleaseBuffer(Py_buffer *view);
-#else
-    #define __Pyx_GetBuffer PyObject_GetBuffer
-    #define __Pyx_ReleaseBuffer PyBuffer_Release
-#endif
-
-
-static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
-static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
-
-static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
-
-static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
-
-static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
-
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    #define __Pyx_CREAL(z) ((z).real())
-    #define __Pyx_CIMAG(z) ((z).imag())
-  #else
-    #define __Pyx_CREAL(z) (__real__(z))
-    #define __Pyx_CIMAG(z) (__imag__(z))
-  #endif
-#else
-    #define __Pyx_CREAL(z) ((z).real)
-    #define __Pyx_CIMAG(z) ((z).imag)
-#endif
-#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
-    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
-    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
-#else
-    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
-    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
-#endif
-
-static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
-
-#if CYTHON_CCOMPLEX
-    #define __Pyx_c_eqf(a, b)   ((a)==(b))
-    #define __Pyx_c_sumf(a, b)  ((a)+(b))
-    #define __Pyx_c_difff(a, b) ((a)-(b))
-    #define __Pyx_c_prodf(a, b) ((a)*(b))
-    #define __Pyx_c_quotf(a, b) ((a)/(b))
-    #define __Pyx_c_negf(a)     (-(a))
-  #ifdef __cplusplus
-    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
-    #define __Pyx_c_conjf(z)    (::std::conj(z))
-    #if 1
-        #define __Pyx_c_absf(z)     (::std::abs(z))
-        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
-    #endif
-  #else
-    #define __Pyx_c_is_zerof(z) ((z)==0)
-    #define __Pyx_c_conjf(z)    (conjf(z))
-    #if 1
-        #define __Pyx_c_absf(z)     (cabsf(z))
-        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
-    #endif
- #endif
-#else
-    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
-    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
-    #if 1
-        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
-        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
-    #endif
-#endif
-
-static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
-
-#if CYTHON_CCOMPLEX
-    #define __Pyx_c_eq(a, b)   ((a)==(b))
-    #define __Pyx_c_sum(a, b)  ((a)+(b))
-    #define __Pyx_c_diff(a, b) ((a)-(b))
-    #define __Pyx_c_prod(a, b) ((a)*(b))
-    #define __Pyx_c_quot(a, b) ((a)/(b))
-    #define __Pyx_c_neg(a)     (-(a))
-  #ifdef __cplusplus
-    #define __Pyx_c_is_zero(z) ((z)==(double)0)
-    #define __Pyx_c_conj(z)    (::std::conj(z))
-    #if 1
-        #define __Pyx_c_abs(z)     (::std::abs(z))
-        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
-    #endif
-  #else
-    #define __Pyx_c_is_zero(z) ((z)==0)
-    #define __Pyx_c_conj(z)    (conj(z))
-    #if 1
-        #define __Pyx_c_abs(z)     (cabs(z))
-        #define __Pyx_c_pow(a, b)  (cpow(a, b))
-    #endif
- #endif
-#else
-    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
-    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
-    #if 1
-        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
-        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
-    #endif
-#endif
-
-static int __Pyx_check_binary_version(void);
-
-#if !defined(__Pyx_PyIdentifier_FromString)
-#if PY_MAJOR_VERSION < 3
-  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
-#else
-  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
-#endif
-#endif
-
-static PyObject *__Pyx_ImportModule(const char *name);
-
-static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
-
-
-/* Module declarations from 'cpython.buffer' */
-
-/* Module declarations from 'cpython.ref' */
-
-/* Module declarations from 'libc.string' */
-
-/* Module declarations from 'libc.stdio' */
-
-/* Module declarations from 'cpython.object' */
-
-/* Module declarations from '__builtin__' */
-
-/* Module declarations from 'cpython.type' */
-static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
-
-/* Module declarations from 'libc.stdlib' */
-
-/* Module declarations from 'numpy' */
-
-/* Module declarations from 'numpy' */
-static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
-static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
-static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
-static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
-static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
-static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
-
-/* Module declarations from 'cython' */
-
-/* Module declarations from 'astropy.time.erfa_time' */
-static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 };
-static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
-#define __Pyx_MODULE_NAME "astropy.time.erfa_time"
-int __pyx_module_is_main_astropy__time__erfa_time = 0;
-
-/* Implementation of 'astropy.time.erfa_time' */
-static PyObject *__pyx_builtin_ValueError;
-static PyObject *__pyx_builtin_range;
-static PyObject *__pyx_builtin_ord;
-static PyObject *__pyx_builtin_RuntimeError;
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_check_return(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_ret, PyObject *__pyx_v_func_name, PyObject *__pyx_v_warns, PyObject *__pyx_v_errors); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_2cal2jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_djm0, PyArrayObject *__pyx_v_djm); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_4d_tai_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_fd); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_6jd_dtf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_scale, PyObject *__pyx_v_ndp, PyArrayObject *__pyx_v_d1, PyArrayObject *__pyx_v_d2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_8dtf_jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_scale, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_ihr, PyArrayObject *__pyx_v_imn, PyArrayObject *__pyx_v_sec); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_10tai_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_12tcb_tdb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_14tcg_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_16tdb_tcb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_18tt_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_20tt_tcg(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_22utc_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_24tai_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_26tai_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_28ut1_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_30tt_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_32ut1_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_34tdb_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_36tt_tdb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_38ut1_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_40utc_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_42d_tdb_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_ut, PyArrayObject *__pyx_v_elong, PyArrayObject *__pyx_v_u, PyArrayObject *__pyx_v_v); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_44era_af2a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sign, PyObject *__pyx_v_ideg, PyObject *__pyx_v_iamin, PyObject *__pyx_v_asec); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_46era_gd2gc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_n, PyObject *__pyx_v_elong, PyObject *__pyx_v_phi, PyObject *__pyx_v_height); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_48era_gc2gd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_n, PyObject *__pyx_v_xyz); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_50jd_julian_epoch(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_jd1, PyArrayObject *__pyx_v_jd2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_52julian_epoch_jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_epd); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_54jd_besselian_epoch(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_jd1, PyArrayObject *__pyx_v_jd2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_56besselian_epoch_jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_epd); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_58gmst00(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_60gmst06(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_62gmst82(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_64gst00a(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_66gst00b(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_68gst06a(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2); /* proto */
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_70gst94(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12); /* proto */
-static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
-static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
-static char __pyx_k_B[] = "B";
-static char __pyx_k_H[] = "H";
-static char __pyx_k_I[] = "I";
-static char __pyx_k_L[] = "L";
-static char __pyx_k_O[] = "O";
-static char __pyx_k_Q[] = "Q";
-static char __pyx_k_b[] = "b";
-static char __pyx_k_d[] = "d";
-static char __pyx_k_f[] = "f";
-static char __pyx_k_g[] = "g";
-static char __pyx_k_h[] = "h";
-static char __pyx_k_i[] = "i";
-static char __pyx_k_j[] = "j";
-static char __pyx_k_l[] = "l";
-static char __pyx_k_n[] = "n";
-static char __pyx_k_q[] = "q";
-static char __pyx_k_s[] = "s";
-static char __pyx_k_u[] = "u";
-static char __pyx_k_v[] = "v";
-static char __pyx_k_Zd[] = "Zd";
-static char __pyx_k_Zf[] = "Zf";
-static char __pyx_k_Zg[] = "Zg";
-static char __pyx_k_d1[] = "d1";
-static char __pyx_k_d2[] = "d2";
-static char __pyx_k_dt[] = "dt";
-static char __pyx_k_fd[] = "fd";
-static char __pyx_k_id[] = "id";
-static char __pyx_k_im[] = "im";
-static char __pyx_k_iy[] = "iy";
-static char __pyx_k_np[] = "np";
-static char __pyx_k_ut[] = "ut";
-static char __pyx_k_0_1[] = "{0}: {1}";
-static char __pyx_k_djm[] = "djm";
-static char __pyx_k_epd[] = "epd";
-static char __pyx_k_gst[] = "gst";
-static char __pyx_k_ihr[] = "ihr";
-static char __pyx_k_imn[] = "imn";
-static char __pyx_k_in1[] = "in1";
-static char __pyx_k_in2[] = "in2";
-static char __pyx_k_jd1[] = "jd1";
-static char __pyx_k_jd2[] = "jd2";
-static char __pyx_k_ndp[] = "ndp";
-static char __pyx_k_ord[] = "ord";
-static char __pyx_k_out[] = "out";
-static char __pyx_k_phi[] = "phi";
-static char __pyx_k_rad[] = "rad";
-static char __pyx_k_ret[] = "ret";
-static char __pyx_k_sec[] = "sec";
-static char __pyx_k_tt1[] = "tt1";
-static char __pyx_k_tt2[] = "tt2";
-static char __pyx_k_xyz[] = "xyz";
-static char __pyx_k_asec[] = "asec";
-static char __pyx_k_djm0[] = "djm0";
-static char __pyx_k_errs[] = "errs";
-static char __pyx_k_gmst[] = "gmst";
-static char __pyx_k_ideg[] = "ideg";
-static char __pyx_k_intc[] = "intc";
-static char __pyx_k_main[] = "__main__";
-static char __pyx_k_out1[] = "out1";
-static char __pyx_k_out2[] = "out2";
-static char __pyx_k_sign[] = "sign";
-static char __pyx_k_test[] = "__test__";
-static char __pyx_k_ut11[] = "ut11";
-static char __pyx_k_ut12[] = "ut12";
-static char __pyx_k_warn[] = "warn";
-static char __pyx_k_dtype[] = "dtype";
-static char __pyx_k_elong[] = "elong";
-static char __pyx_k_empty[] = "empty";
-static char __pyx_k_gst94[] = "gst94";
-static char __pyx_k_iamin[] = "iamin";
-static char __pyx_k_ihmsf[] = "ihmsf";
-static char __pyx_k_numpy[] = "numpy";
-static char __pyx_k_range[] = "range";
-static char __pyx_k_scale[] = "scale";
-static char __pyx_k_shape[] = "shape";
-static char __pyx_k_warns[] = "warns";
-static char __pyx_k_cal2jd[] = "cal2jd";
-static char __pyx_k_double[] = "double";
-static char __pyx_k_dtf_jd[] = "dtf_jd";
-static char __pyx_k_eraDat[] = "eraDat";
-static char __pyx_k_errors[] = "errors";
-static char __pyx_k_format[] = "format";
-static char __pyx_k_gmst00[] = "gmst00";
-static char __pyx_k_gmst06[] = "gmst06";
-static char __pyx_k_gmst82[] = "gmst82";
-static char __pyx_k_gst00a[] = "gst00a";
-static char __pyx_k_gst00b[] = "gst00b";
-static char __pyx_k_gst06a[] = "gst06a";
-static char __pyx_k_height[] = "height";
-static char __pyx_k_import[] = "__import__";
-static char __pyx_k_jd_dtf[] = "jd_dtf";
-static char __pyx_k_nitems[] = "nitems";
-static char __pyx_k_tai_tt[] = "tai_tt";
-static char __pyx_k_tcg_tt[] = "tcg_tt";
-static char __pyx_k_tdb_tt[] = "tdb_tt";
-static char __pyx_k_tt_tai[] = "tt_tai";
-static char __pyx_k_tt_tcg[] = "tt_tcg";
-static char __pyx_k_tt_tdb[] = "tt_tdb";
-static char __pyx_k_tt_ut1[] = "tt_ut1";
-static char __pyx_k_ut1_tt[] = "ut1_tt";
-static char __pyx_k_DUBIOUS[] = "DUBIOUS";
-static char __pyx_k_bad_day[] = "bad day";
-static char __pyx_k_eraAf2a[] = "eraAf2a";
-static char __pyx_k_tai_ut1[] = "tai_ut1";
-static char __pyx_k_tai_utc[] = "tai_utc";
-static char __pyx_k_tcb_tdb[] = "tcb_tdb";
-static char __pyx_k_tdb_tcb[] = "tdb_tcb";
-static char __pyx_k_ut1_tai[] = "ut1_tai";
-static char __pyx_k_ut1_utc[] = "ut1_utc";
-static char __pyx_k_utc_tai[] = "utc_tai";
-static char __pyx_k_utc_ut1[] = "utc_ut1";
-static char __pyx_k_bad_hour[] = "bad hour";
-static char __pyx_k_bad_year[] = "bad year";
-static char __pyx_k_d_tdb_tt[] = "d_tdb_tt";
-static char __pyx_k_eraD2dtf[] = "eraD2dtf";
-static char __pyx_k_eraDtf2d[] = "eraDtf2d";
-static char __pyx_k_eraGd2gc[] = "eraGd2gc";
-static char __pyx_k_eraTaitt[] = "eraTaitt";
-static char __pyx_k_eraTcgtt[] = "eraTcgtt";
-static char __pyx_k_eraTdbtt[] = "eraTdbtt";
-static char __pyx_k_eraTttai[] = "eraTttai";
-static char __pyx_k_eraTttcg[] = "eraTttcg";
-static char __pyx_k_eraTttdb[] = "eraTttdb";
-static char __pyx_k_eraTtut1[] = "eraTtut1";
-static char __pyx_k_eraUt1tt[] = "eraUt1tt";
-static char __pyx_k_era_af2a[] = "era_af2a";
-static char __pyx_k_warnings[] = "warnings";
-static char __pyx_k_xyz_item[] = "xyz_item";
-static char __pyx_k_bad_month[] = "bad month";
-static char __pyx_k_d_tai_utc[] = "d_tai_utc";
-static char __pyx_k_eraCal2jd[] = "eraCal2jd";
-static char __pyx_k_eraTaiut1[] = "eraTaiut1";
-static char __pyx_k_eraTaiutc[] = "eraTaiutc";
-static char __pyx_k_eraTcbtdb[] = "eraTcbtdb";
-static char __pyx_k_eraTdbtcb[] = "eraTdbtcb";
-static char __pyx_k_eraUt1tai[] = "eraUt1tai";
-static char __pyx_k_eraUt1utc[] = "eraUt1utc";
-static char __pyx_k_eraUtctai[] = "eraUtctai";
-static char __pyx_k_eraUtcut1[] = "eraUtcut1";
-static char __pyx_k_era_gc2gd[] = "era_gc2gd";
-static char __pyx_k_era_gd2gc[] = "era_gd2gc";
-static char __pyx_k_func_name[] = "func_name";
-static char __pyx_k_ValueError[] = "ValueError";
-static char __pyx_k_bad_minute[] = "bad minute";
-static char __pyx_k_RuntimeError[] = "RuntimeError";
-static char __pyx_k_bad_second_0[] = "bad second (< 0)";
-static char __pyx_k_check_return[] = "check_return";
-static char __pyx_k_illegal_case[] = "illegal case";
-static char __pyx_k_Bad_input_year[] = "Bad input year";
-static char __pyx_k_Bad_input_month[] = "Bad input month";
-static char __pyx_k_jd_julian_epoch[] = "jd_julian_epoch";
-static char __pyx_k_julian_epoch_jd[] = "julian_epoch_jd";
-static char __pyx_k_utils_exceptions[] = "utils.exceptions";
-static char __pyx_k_unacceptable_date[] = "unacceptable date";
-static char __pyx_k_AstropyUserWarning[] = "AstropyUserWarning";
-static char __pyx_k_besselian_epoch_jd[] = "besselian_epoch_jd";
-static char __pyx_k_illegal_identifier[] = "illegal identifier";
-static char __pyx_k_jd_besselian_epoch[] = "jd_besselian_epoch";
-static char __pyx_k_bad_fraction_of_day[] = "bad fraction of day";
-static char __pyx_k_astropy_time_erfa_time[] = "astropy.time.erfa_time";
-static char __pyx_k_iamin_outside_range_0_59[] = "iamin outside range 0-59";
-static char __pyx_k_ideg_outside_range_0_359[] = "ideg outside range 0-359";
-static char __pyx_k_time_is_after_end_of_day[] = "time is after end of day";
-static char __pyx_k_bad_month_must_be_1_to_12[] = "bad month (must be 1 to 12)";
-static char __pyx_k_asec_outside_range_0_59_999[] = "asec outside range 0-59.999...";
-static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
-static char __pyx_k_time_is_after_end_of_day_and[] = "time is after end of day and ";
-static char __pyx_k_Bad_input_day_JD_still_computed[] = "Bad input day (JD still computed)";
-static char __pyx_k_Unexpected_return_code_0_from_1[] = "Unexpected return code {0} from {1}";
-static char __pyx_k_internal_1_root_src_astropy_ast[] = "/internal/1/root/src/astropy/astropy/astropy/time/erfa_time.pyx";
-static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
-static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
-static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
-static char __pyx_k_bad_day_must_be_within_normal_ca[] = "bad day (must be within normal calendar date for a month)";
-static char __pyx_k_dubious_year_for_UTC_before_1960[] = "dubious year for UTC (before 1960.0 or 5 years beyond last known leap second)";
-static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
-static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
-static PyObject *__pyx_kp_s_0_1;
-static PyObject *__pyx_n_s_AstropyUserWarning;
-static PyObject *__pyx_kp_s_Bad_input_day_JD_still_computed;
-static PyObject *__pyx_kp_s_Bad_input_month;
-static PyObject *__pyx_kp_s_Bad_input_year;
-static PyObject *__pyx_n_s_DUBIOUS;
-static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
-static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
-static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
-static PyObject *__pyx_n_s_RuntimeError;
-static PyObject *__pyx_kp_s_Unexpected_return_code_0_from_1;
-static PyObject *__pyx_n_s_ValueError;
-static PyObject *__pyx_n_s_asec;
-static PyObject *__pyx_kp_s_asec_outside_range_0_59_999;
-static PyObject *__pyx_n_s_astropy_time_erfa_time;
-static PyObject *__pyx_kp_s_bad_day;
-static PyObject *__pyx_kp_s_bad_day_must_be_within_normal_ca;
-static PyObject *__pyx_kp_s_bad_fraction_of_day;
-static PyObject *__pyx_kp_s_bad_hour;
-static PyObject *__pyx_kp_s_bad_minute;
-static PyObject *__pyx_kp_s_bad_month;
-static PyObject *__pyx_kp_s_bad_month_must_be_1_to_12;
-static PyObject *__pyx_kp_s_bad_second_0;
-static PyObject *__pyx_kp_s_bad_year;
-static PyObject *__pyx_n_s_besselian_epoch_jd;
-static PyObject *__pyx_n_s_cal2jd;
-static PyObject *__pyx_n_s_check_return;
-static PyObject *__pyx_n_s_d1;
-static PyObject *__pyx_n_s_d2;
-static PyObject *__pyx_n_s_d_tai_utc;
-static PyObject *__pyx_n_s_d_tdb_tt;
-static PyObject *__pyx_n_s_djm;
-static PyObject *__pyx_n_s_djm0;
-static PyObject *__pyx_n_s_double;
-static PyObject *__pyx_n_s_dt;
-static PyObject *__pyx_n_s_dtf_jd;
-static PyObject *__pyx_n_s_dtype;
-static PyObject *__pyx_kp_s_dubious_year_for_UTC_before_1960;
-static PyObject *__pyx_n_s_elong;
-static PyObject *__pyx_n_s_empty;
-static PyObject *__pyx_n_s_epd;
-static PyObject *__pyx_n_s_eraAf2a;
-static PyObject *__pyx_n_s_eraCal2jd;
-static PyObject *__pyx_n_s_eraD2dtf;
-static PyObject *__pyx_n_s_eraDat;
-static PyObject *__pyx_n_s_eraDtf2d;
-static PyObject *__pyx_n_s_eraGd2gc;
-static PyObject *__pyx_n_s_eraTaitt;
-static PyObject *__pyx_n_s_eraTaiut1;
-static PyObject *__pyx_n_s_eraTaiutc;
-static PyObject *__pyx_n_s_eraTcbtdb;
-static PyObject *__pyx_n_s_eraTcgtt;
-static PyObject *__pyx_n_s_eraTdbtcb;
-static PyObject *__pyx_n_s_eraTdbtt;
-static PyObject *__pyx_n_s_eraTttai;
-static PyObject *__pyx_n_s_eraTttcg;
-static PyObject *__pyx_n_s_eraTttdb;
-static PyObject *__pyx_n_s_eraTtut1;
-static PyObject *__pyx_n_s_eraUt1tai;
-static PyObject *__pyx_n_s_eraUt1tt;
-static PyObject *__pyx_n_s_eraUt1utc;
-static PyObject *__pyx_n_s_eraUtctai;
-static PyObject *__pyx_n_s_eraUtcut1;
-static PyObject *__pyx_n_s_era_af2a;
-static PyObject *__pyx_n_s_era_gc2gd;
-static PyObject *__pyx_n_s_era_gd2gc;
-static PyObject *__pyx_n_s_errors;
-static PyObject *__pyx_n_s_errs;
-static PyObject *__pyx_n_s_fd;
-static PyObject *__pyx_n_s_format;
-static PyObject *__pyx_n_s_func_name;
-static PyObject *__pyx_n_s_gmst;
-static PyObject *__pyx_n_s_gmst00;
-static PyObject *__pyx_n_s_gmst06;
-static PyObject *__pyx_n_s_gmst82;
-static PyObject *__pyx_n_s_gst;
-static PyObject *__pyx_n_s_gst00a;
-static PyObject *__pyx_n_s_gst00b;
-static PyObject *__pyx_n_s_gst06a;
-static PyObject *__pyx_n_s_gst94;
-static PyObject *__pyx_n_s_height;
-static PyObject *__pyx_n_s_i;
-static PyObject *__pyx_n_s_iamin;
-static PyObject *__pyx_kp_s_iamin_outside_range_0_59;
-static PyObject *__pyx_n_s_id;
-static PyObject *__pyx_n_s_ideg;
-static PyObject *__pyx_kp_s_ideg_outside_range_0_359;
-static PyObject *__pyx_n_s_ihmsf;
-static PyObject *__pyx_n_s_ihr;
-static PyObject *__pyx_kp_s_illegal_case;
-static PyObject *__pyx_kp_s_illegal_identifier;
-static PyObject *__pyx_n_s_im;
-static PyObject *__pyx_n_s_imn;
-static PyObject *__pyx_n_s_import;
-static PyObject *__pyx_n_s_in1;
-static PyObject *__pyx_n_s_in2;
-static PyObject *__pyx_n_s_intc;
-static PyObject *__pyx_kp_s_internal_1_root_src_astropy_ast;
-static PyObject *__pyx_n_s_iy;
-static PyObject *__pyx_n_s_j;
-static PyObject *__pyx_n_s_jd1;
-static PyObject *__pyx_n_s_jd2;
-static PyObject *__pyx_n_s_jd_besselian_epoch;
-static PyObject *__pyx_n_s_jd_dtf;
-static PyObject *__pyx_n_s_jd_julian_epoch;
-static PyObject *__pyx_n_s_julian_epoch_jd;
-static PyObject *__pyx_n_s_main;
-static PyObject *__pyx_n_s_n;
-static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
-static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
-static PyObject *__pyx_n_s_ndp;
-static PyObject *__pyx_n_s_nitems;
-static PyObject *__pyx_n_s_np;
-static PyObject *__pyx_n_s_numpy;
-static PyObject *__pyx_n_s_ord;
-static PyObject *__pyx_n_s_out;
-static PyObject *__pyx_n_s_out1;
-static PyObject *__pyx_n_s_out2;
-static PyObject *__pyx_n_s_phi;
-static PyObject *__pyx_n_s_rad;
-static PyObject *__pyx_n_s_range;
-static PyObject *__pyx_n_s_ret;
-static PyObject *__pyx_n_s_s;
-static PyObject *__pyx_n_s_scale;
-static PyObject *__pyx_n_s_sec;
-static PyObject *__pyx_n_s_shape;
-static PyObject *__pyx_n_s_sign;
-static PyObject *__pyx_n_s_tai_tt;
-static PyObject *__pyx_n_s_tai_ut1;
-static PyObject *__pyx_n_s_tai_utc;
-static PyObject *__pyx_n_s_tcb_tdb;
-static PyObject *__pyx_n_s_tcg_tt;
-static PyObject *__pyx_n_s_tdb_tcb;
-static PyObject *__pyx_n_s_tdb_tt;
-static PyObject *__pyx_n_s_test;
-static PyObject *__pyx_kp_s_time_is_after_end_of_day;
-static PyObject *__pyx_kp_s_time_is_after_end_of_day_and;
-static PyObject *__pyx_n_s_tt1;
-static PyObject *__pyx_n_s_tt2;
-static PyObject *__pyx_n_s_tt_tai;
-static PyObject *__pyx_n_s_tt_tcg;
-static PyObject *__pyx_n_s_tt_tdb;
-static PyObject *__pyx_n_s_tt_ut1;
-static PyObject *__pyx_n_s_u;
-static PyObject *__pyx_kp_s_unacceptable_date;
-static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
-static PyObject *__pyx_n_s_ut;
-static PyObject *__pyx_n_s_ut11;
-static PyObject *__pyx_n_s_ut12;
-static PyObject *__pyx_n_s_ut1_tai;
-static PyObject *__pyx_n_s_ut1_tt;
-static PyObject *__pyx_n_s_ut1_utc;
-static PyObject *__pyx_n_s_utc_tai;
-static PyObject *__pyx_n_s_utc_ut1;
-static PyObject *__pyx_n_s_utils_exceptions;
-static PyObject *__pyx_n_s_v;
-static PyObject *__pyx_n_s_warn;
-static PyObject *__pyx_n_s_warnings;
-static PyObject *__pyx_n_s_warns;
-static PyObject *__pyx_n_s_xyz;
-static PyObject *__pyx_n_s_xyz_item;
-static PyObject *__pyx_int_0;
-static PyObject *__pyx_int_1;
-static PyObject *__pyx_int_2;
-static PyObject *__pyx_int_3;
-static PyObject *__pyx_int_4;
-static PyObject *__pyx_int_neg_1;
-static PyObject *__pyx_int_neg_2;
-static PyObject *__pyx_int_neg_3;
-static PyObject *__pyx_int_neg_4;
-static PyObject *__pyx_int_neg_5;
-static PyObject *__pyx_int_neg_6;
-static PyObject *__pyx_k_;
-static PyObject *__pyx_k__2;
-static PyObject *__pyx_tuple__3;
-static PyObject *__pyx_tuple__4;
-static PyObject *__pyx_tuple__5;
-static PyObject *__pyx_tuple__6;
-static PyObject *__pyx_tuple__7;
-static PyObject *__pyx_tuple__8;
-static PyObject *__pyx_tuple__9;
-static PyObject *__pyx_tuple__10;
-static PyObject *__pyx_tuple__12;
-static PyObject *__pyx_tuple__14;
-static PyObject *__pyx_tuple__16;
-static PyObject *__pyx_tuple__18;
-static PyObject *__pyx_tuple__20;
-static PyObject *__pyx_tuple__22;
-static PyObject *__pyx_tuple__24;
-static PyObject *__pyx_tuple__26;
-static PyObject *__pyx_tuple__28;
-static PyObject *__pyx_tuple__30;
-static PyObject *__pyx_tuple__32;
-static PyObject *__pyx_tuple__34;
-static PyObject *__pyx_tuple__36;
-static PyObject *__pyx_tuple__38;
-static PyObject *__pyx_tuple__40;
-static PyObject *__pyx_tuple__42;
-static PyObject *__pyx_tuple__44;
-static PyObject *__pyx_tuple__46;
-static PyObject *__pyx_tuple__48;
-static PyObject *__pyx_tuple__50;
-static PyObject *__pyx_tuple__52;
-static PyObject *__pyx_tuple__54;
-static PyObject *__pyx_tuple__56;
-static PyObject *__pyx_tuple__58;
-static PyObject *__pyx_tuple__60;
-static PyObject *__pyx_tuple__62;
-static PyObject *__pyx_tuple__64;
-static PyObject *__pyx_tuple__66;
-static PyObject *__pyx_tuple__68;
-static PyObject *__pyx_tuple__70;
-static PyObject *__pyx_tuple__72;
-static PyObject *__pyx_tuple__74;
-static PyObject *__pyx_tuple__76;
-static PyObject *__pyx_tuple__78;
-static PyObject *__pyx_tuple__80;
-static PyObject *__pyx_codeobj__11;
-static PyObject *__pyx_codeobj__13;
-static PyObject *__pyx_codeobj__15;
-static PyObject *__pyx_codeobj__17;
-static PyObject *__pyx_codeobj__19;
-static PyObject *__pyx_codeobj__21;
-static PyObject *__pyx_codeobj__23;
-static PyObject *__pyx_codeobj__25;
-static PyObject *__pyx_codeobj__27;
-static PyObject *__pyx_codeobj__29;
-static PyObject *__pyx_codeobj__31;
-static PyObject *__pyx_codeobj__33;
-static PyObject *__pyx_codeobj__35;
-static PyObject *__pyx_codeobj__37;
-static PyObject *__pyx_codeobj__39;
-static PyObject *__pyx_codeobj__41;
-static PyObject *__pyx_codeobj__43;
-static PyObject *__pyx_codeobj__45;
-static PyObject *__pyx_codeobj__47;
-static PyObject *__pyx_codeobj__49;
-static PyObject *__pyx_codeobj__51;
-static PyObject *__pyx_codeobj__53;
-static PyObject *__pyx_codeobj__55;
-static PyObject *__pyx_codeobj__57;
-static PyObject *__pyx_codeobj__59;
-static PyObject *__pyx_codeobj__61;
-static PyObject *__pyx_codeobj__63;
-static PyObject *__pyx_codeobj__65;
-static PyObject *__pyx_codeobj__67;
-static PyObject *__pyx_codeobj__69;
-static PyObject *__pyx_codeobj__71;
-static PyObject *__pyx_codeobj__73;
-static PyObject *__pyx_codeobj__75;
-static PyObject *__pyx_codeobj__77;
-static PyObject *__pyx_codeobj__79;
-static PyObject *__pyx_codeobj__81;
-
-/* "astropy/time/erfa_time.pyx":64
- *           'beyond last known leap second)'
- * 
- * def check_return(ret, func_name, warns={}, errors={}):             # <<<<<<<<<<<<<<
- *     """Check the return value from an era routine"""
- *     if ret in warns:
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_1check_return(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_check_return[] = "Check the return value from an era routine";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_1check_return = {"check_return", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_1check_return, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_check_return};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_1check_return(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_ret = 0;
-  PyObject *__pyx_v_func_name = 0;
-  PyObject *__pyx_v_warns = 0;
-  PyObject *__pyx_v_errors = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("check_return (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ret,&__pyx_n_s_func_name,&__pyx_n_s_warns,&__pyx_n_s_errors,0};
-    PyObject* values[4] = {0,0,0,0};
-    values[2] = __pyx_k_;
-    values[3] = __pyx_k__2;
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ret)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_func_name)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("check_return", 0, 2, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_warns);
-          if (value) { values[2] = value; kw_args--; }
-        }
-        case  3:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_errors);
-          if (value) { values[3] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "check_return") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-    }
-    __pyx_v_ret = values[0];
-    __pyx_v_func_name = values[1];
-    __pyx_v_warns = values[2];
-    __pyx_v_errors = values[3];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("check_return", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.check_return", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_check_return(__pyx_self, __pyx_v_ret, __pyx_v_func_name, __pyx_v_warns, __pyx_v_errors);
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_check_return(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_ret, PyObject *__pyx_v_func_name, PyObject *__pyx_v_warns, PyObject *__pyx_v_errors) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
-  Py_ssize_t __pyx_t_9;
-  PyObject *__pyx_t_10 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("check_return", 0);
-
-  /* "astropy/time/erfa_time.pyx":66
- * def check_return(ret, func_name, warns={}, errors={}):
- *     """Check the return value from an era routine"""
- *     if ret in warns:             # <<<<<<<<<<<<<<
- *         warnings.warn('{0}: {1}'.format(func_name, warns[ret]), AstropyUserWarning)
- *     elif ret in errors:
- */
-  __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_ret, __pyx_v_warns, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = (__pyx_t_1 != 0);
-  if (__pyx_t_2) {
-
-    /* "astropy/time/erfa_time.pyx":67
- *     """Check the return value from an era routine"""
- *     if ret in warns:
- *         warnings.warn('{0}: {1}'.format(func_name, warns[ret]), AstropyUserWarning)             # <<<<<<<<<<<<<<
- *     elif ret in errors:
- *         raise ValueError('{0}: {1}'.format(func_name, errors[ret]))
- */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_warnings); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_warn); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_0_1, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = PyObject_GetItem(__pyx_v_warns, __pyx_v_ret); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_8 = NULL;
-    __pyx_t_9 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_8);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_9 = 1;
-      }
-    }
-    __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    if (__pyx_t_8) {
-      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
-    }
-    __Pyx_INCREF(__pyx_v_func_name);
-    PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_v_func_name);
-    __Pyx_GIVEREF(__pyx_v_func_name);
-    PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_7);
-    __Pyx_GIVEREF(__pyx_t_7);
-    __pyx_t_7 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_AstropyUserWarning); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_10 = NULL;
-    __pyx_t_9 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_10)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_10);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_9 = 1;
-      }
-    }
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    if (__pyx_t_10) {
-      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_9, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_9, __pyx_t_6);
-    __Pyx_GIVEREF(__pyx_t_6);
-    __pyx_t_4 = 0;
-    __pyx_t_6 = 0;
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    goto __pyx_L3;
-  }
-
-  /* "astropy/time/erfa_time.pyx":68
- *     if ret in warns:
- *         warnings.warn('{0}: {1}'.format(func_name, warns[ret]), AstropyUserWarning)
- *     elif ret in errors:             # <<<<<<<<<<<<<<
- *         raise ValueError('{0}: {1}'.format(func_name, errors[ret]))
- *     elif ret != 0:
- */
-  __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_v_ret, __pyx_v_errors, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = (__pyx_t_2 != 0);
-  if (__pyx_t_1) {
-
-    /* "astropy/time/erfa_time.pyx":69
- *         warnings.warn('{0}: {1}'.format(func_name, warns[ret]), AstropyUserWarning)
- *     elif ret in errors:
- *         raise ValueError('{0}: {1}'.format(func_name, errors[ret]))             # <<<<<<<<<<<<<<
- *     elif ret != 0:
- *         raise ValueError('Unexpected return code {0} from {1}'
- */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_0_1, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = PyObject_GetItem(__pyx_v_errors, __pyx_v_ret); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_6 = NULL;
-    __pyx_t_9 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_6)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_6);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_9 = 1;
-      }
-    }
-    __pyx_t_4 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    if (__pyx_t_6) {
-      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_INCREF(__pyx_v_func_name);
-    PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_9, __pyx_v_func_name);
-    __Pyx_GIVEREF(__pyx_v_func_name);
-    PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_9, __pyx_t_7);
-    __Pyx_GIVEREF(__pyx_t_7);
-    __pyx_t_7 = 0;
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __pyx_t_3 = 0;
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-
-  /* "astropy/time/erfa_time.pyx":70
- *     elif ret in errors:
- *         raise ValueError('{0}: {1}'.format(func_name, errors[ret]))
- *     elif ret != 0:             # <<<<<<<<<<<<<<
- *         raise ValueError('Unexpected return code {0} from {1}'
- *                          .format(repr(ret), func_name))
- */
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_ret, __pyx_int_0, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__pyx_t_1) {
-
-    /* "astropy/time/erfa_time.pyx":72
- *     elif ret != 0:
- *         raise ValueError('Unexpected return code {0} from {1}'
- *                          .format(repr(ret), func_name))             # <<<<<<<<<<<<<<
- * 
- * 
- */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unexpected_return_code_0_from_1, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = PyObject_Repr(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_7 = NULL;
-    __pyx_t_9 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_9 = 1;
-      }
-    }
-    __pyx_t_6 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    if (__pyx_t_7) {
-      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_9, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_v_func_name);
-    PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_9, __pyx_v_func_name);
-    __Pyx_GIVEREF(__pyx_v_func_name);
-    __pyx_t_4 = 0;
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-
-    /* "astropy/time/erfa_time.pyx":71
- *         raise ValueError('{0}: {1}'.format(func_name, errors[ret]))
- *     elif ret != 0:
- *         raise ValueError('Unexpected return code {0} from {1}'             # <<<<<<<<<<<<<<
- *                          .format(repr(ret), func_name))
- * 
- */
-    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __pyx_t_3 = 0;
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_L3:;
-
-  /* "astropy/time/erfa_time.pyx":64
- *           'beyond last known leap second)'
- * 
- * def check_return(ret, func_name, warns={}, errors={}):             # <<<<<<<<<<<<<<
- *     """Check the return value from an era routine"""
- *     if ret in warns:
- */
-
-  /* function exit code */
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_XDECREF(__pyx_t_10);
-  __Pyx_AddTraceback("astropy.time.erfa_time.check_return", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":77
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def cal2jd(             # <<<<<<<<<<<<<<
- *     np.ndarray[int, ndim=1] iy,
- *     np.ndarray[int, ndim=1] im,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_3cal2jd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_2cal2jd[] = "\n    int eraCal2jd(int iy, int im, int id, double *djm0, double *djm)\n    Calendar date to high-precision JD.\n\n    **  Given:\n    **     iy,im,id  int     year, month, day in Gregorian calendar (Note 1)\n    **\n    **  Returned:\n    **     djm0      double  MJD zero-point: always 2400000.5\n    **     djm       double  Modified Julian Date for 0 hrs\n    **\n    **  Returned (function value):\n    **               int    [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_3cal2jd = {"cal2jd", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_3cal2jd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_2cal2jd};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_3cal2jd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_iy = 0;
-  PyArrayObject *__pyx_v_im = 0;
-  PyArrayObject *__pyx_v_id = 0;
-  PyArrayObject *__pyx_v_djm0 = 0;
-  PyArrayObject *__pyx_v_djm = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("cal2jd (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_iy,&__pyx_n_s_im,&__pyx_n_s_id,&__pyx_n_s_djm0,&__pyx_n_s_djm,0};
-    PyObject* values[5] = {0,0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_iy)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_im)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("cal2jd", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_id)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("cal2jd", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_djm0)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("cal2jd", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  4:
-        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_djm)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("cal2jd", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "cal2jd") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-    }
-    __pyx_v_iy = ((PyArrayObject *)values[0]);
-    __pyx_v_im = ((PyArrayObject *)values[1]);
-    __pyx_v_id = ((PyArrayObject *)values[2]);
-    __pyx_v_djm0 = ((PyArrayObject *)values[3]);
-    __pyx_v_djm = ((PyArrayObject *)values[4]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("cal2jd", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.cal2jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_iy), __pyx_ptype_5numpy_ndarray, 1, "iy", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_im), __pyx_ptype_5numpy_ndarray, 1, "im", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_id), __pyx_ptype_5numpy_ndarray, 1, "id", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_djm0), __pyx_ptype_5numpy_ndarray, 1, "djm0", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_djm), __pyx_ptype_5numpy_ndarray, 1, "djm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_2cal2jd(__pyx_self, __pyx_v_iy, __pyx_v_im, __pyx_v_id, __pyx_v_djm0, __pyx_v_djm);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_2cal2jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_djm0, PyArrayObject *__pyx_v_djm) {
-  unsigned int __pyx_v_i;
-  unsigned int __pyx_v_n;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_djm;
-  __Pyx_Buffer __pyx_pybuffer_djm;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_djm0;
-  __Pyx_Buffer __pyx_pybuffer_djm0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_id;
-  __Pyx_Buffer __pyx_pybuffer_id;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_im;
-  __Pyx_Buffer __pyx_pybuffer_im;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_iy;
-  __Pyx_Buffer __pyx_pybuffer_iy;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  unsigned int __pyx_t_2;
-  unsigned int __pyx_t_3;
-  unsigned int __pyx_t_4;
-  unsigned int __pyx_t_5;
-  unsigned int __pyx_t_6;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  PyObject *__pyx_t_9 = NULL;
-  PyObject *__pyx_t_10 = NULL;
-  PyObject *__pyx_t_11 = NULL;
-  Py_ssize_t __pyx_t_12;
-  PyObject *__pyx_t_13 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("cal2jd", 0);
-  __pyx_pybuffer_iy.pybuffer.buf = NULL;
-  __pyx_pybuffer_iy.refcount = 0;
-  __pyx_pybuffernd_iy.data = NULL;
-  __pyx_pybuffernd_iy.rcbuffer = &__pyx_pybuffer_iy;
-  __pyx_pybuffer_im.pybuffer.buf = NULL;
-  __pyx_pybuffer_im.refcount = 0;
-  __pyx_pybuffernd_im.data = NULL;
-  __pyx_pybuffernd_im.rcbuffer = &__pyx_pybuffer_im;
-  __pyx_pybuffer_id.pybuffer.buf = NULL;
-  __pyx_pybuffer_id.refcount = 0;
-  __pyx_pybuffernd_id.data = NULL;
-  __pyx_pybuffernd_id.rcbuffer = &__pyx_pybuffer_id;
-  __pyx_pybuffer_djm0.pybuffer.buf = NULL;
-  __pyx_pybuffer_djm0.refcount = 0;
-  __pyx_pybuffernd_djm0.data = NULL;
-  __pyx_pybuffernd_djm0.rcbuffer = &__pyx_pybuffer_djm0;
-  __pyx_pybuffer_djm.pybuffer.buf = NULL;
-  __pyx_pybuffer_djm.refcount = 0;
-  __pyx_pybuffernd_djm.data = NULL;
-  __pyx_pybuffernd_djm.rcbuffer = &__pyx_pybuffer_djm;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_iy.rcbuffer->pybuffer, (PyObject*)__pyx_v_iy, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_iy.diminfo[0].strides = __pyx_pybuffernd_iy.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_iy.diminfo[0].shape = __pyx_pybuffernd_iy.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_im.rcbuffer->pybuffer, (PyObject*)__pyx_v_im, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_im.diminfo[0].strides = __pyx_pybuffernd_im.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_im.diminfo[0].shape = __pyx_pybuffernd_im.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_id.rcbuffer->pybuffer, (PyObject*)__pyx_v_id, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_id.diminfo[0].strides = __pyx_pybuffernd_id.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_id.diminfo[0].shape = __pyx_pybuffernd_id.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_djm0.rcbuffer->pybuffer, (PyObject*)__pyx_v_djm0, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_djm0.diminfo[0].strides = __pyx_pybuffernd_djm0.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_djm0.diminfo[0].shape = __pyx_pybuffernd_djm0.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_djm.rcbuffer->pybuffer, (PyObject*)__pyx_v_djm, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_djm.diminfo[0].strides = __pyx_pybuffernd_djm.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_djm.diminfo[0].shape = __pyx_pybuffernd_djm.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":117
- *     """
- *     cdef unsigned int i
- *     cdef unsigned n = iy.shape[0]             # <<<<<<<<<<<<<<
- *     warns = {-3: 'Bad input day (JD still computed)'}
- *     errs = {-1: 'Bad input year',
- */
-  __pyx_v_n = (__pyx_v_iy->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":118
- *     cdef unsigned int i
- *     cdef unsigned n = iy.shape[0]
- *     warns = {-3: 'Bad input day (JD still computed)'}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'Bad input year',
- *              -2: 'Bad input month'}
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_3, __pyx_kp_s_Bad_input_day_JD_still_computed) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_warns = ((PyObject*)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":119
- *     cdef unsigned n = iy.shape[0]
- *     warns = {-3: 'Bad input day (JD still computed)'}
- *     errs = {-1: 'Bad input year',             # <<<<<<<<<<<<<<
- *              -2: 'Bad input month'}
- *     for i in range(n):
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_1, __pyx_kp_s_Bad_input_year) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_2, __pyx_kp_s_Bad_input_month) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":121
- *     errs = {-1: 'Bad input year',
- *              -2: 'Bad input month'}
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraCal2jd( iy[i], im[i], id[i], &djm0[i], &djm[i])
- *         check_return(ret, 'eraCal2jd', warns, errs)
- */
-  __pyx_t_2 = __pyx_v_n;
-  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
-    __pyx_v_i = __pyx_t_3;
-
-    /* "astropy/time/erfa_time.pyx":122
- *              -2: 'Bad input month'}
- *     for i in range(n):
- *         ret = eraCal2jd( iy[i], im[i], id[i], &djm0[i], &djm[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraCal2jd', warns, errs)
- *     return
- */
-    __pyx_t_4 = __pyx_v_i;
-    __pyx_t_5 = __pyx_v_i;
-    __pyx_t_6 = __pyx_v_i;
-    __pyx_t_7 = __pyx_v_i;
-    __pyx_t_8 = __pyx_v_i;
-    __pyx_v_ret = eraCal2jd((*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_iy.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_iy.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_im.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_im.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_id.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_id.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_djm0.rcbuffer->pybuffer.buf [...]
-
-    /* "astropy/time/erfa_time.pyx":123
- *     for i in range(n):
- *         ret = eraCal2jd( iy[i], im[i], id[i], &djm0[i], &djm[i])
- *         check_return(ret, 'eraCal2jd', warns, errs)             # <<<<<<<<<<<<<<
- *     return
- * 
- */
-    __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_10 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_11 = NULL;
-    __pyx_t_12 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
-      __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_9);
-      if (likely(__pyx_t_11)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
-        __Pyx_INCREF(__pyx_t_11);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_9, function);
-        __pyx_t_12 = 1;
-      }
-    }
-    __pyx_t_13 = PyTuple_New(4+__pyx_t_12); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_13);
-    if (__pyx_t_11) {
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_10);
-    __Pyx_GIVEREF(__pyx_t_10);
-    __Pyx_INCREF(__pyx_n_s_eraCal2jd);
-    PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_n_s_eraCal2jd);
-    __Pyx_GIVEREF(__pyx_n_s_eraCal2jd);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_13, 2+__pyx_t_12, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_13, 3+__pyx_t_12, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_10 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":124
- *         ret = eraCal2jd( iy[i], im[i], id[i], &djm0[i], &djm[i])
- *         check_return(ret, 'eraCal2jd', warns, errs)
- *     return             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":77
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def cal2jd(             # <<<<<<<<<<<<<<
- *     np.ndarray[int, ndim=1] iy,
- *     np.ndarray[int, ndim=1] im,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_9);
-  __Pyx_XDECREF(__pyx_t_10);
-  __Pyx_XDECREF(__pyx_t_11);
-  __Pyx_XDECREF(__pyx_t_13);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_djm.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_djm0.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.cal2jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_djm.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_djm0.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":128
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tai_utc(np.ndarray[int, ndim=1] iy,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] im,
- *               np.ndarray[int, ndim=1] id,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_5d_tai_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_4d_tai_utc[] = "\n    int eraDat(int iy, int im, int id, double fd, double *deltat)\n    For a given UTC date, calculate delta(AT) = TAI-UTC.\n\n    **  Given:\n    **     iy     int      UTC:  year (Notes 1 and 2)\n    **     im     int            month (Note 2)\n    **     id     int            day (Notes 2 and 3)\n    **     fd     double         fraction of day (Note 4)\n    **\n    **  Returned:\n    **     deltat double   TAI minus UT [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_5d_tai_utc = {"d_tai_utc", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_5d_tai_utc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_4d_tai_utc};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_5d_tai_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_iy = 0;
-  PyArrayObject *__pyx_v_im = 0;
-  PyArrayObject *__pyx_v_id = 0;
-  PyArrayObject *__pyx_v_fd = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("d_tai_utc (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_iy,&__pyx_n_s_im,&__pyx_n_s_id,&__pyx_n_s_fd,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_iy)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_im)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tai_utc", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_id)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tai_utc", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fd)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tai_utc", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "d_tai_utc") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_iy = ((PyArrayObject *)values[0]);
-    __pyx_v_im = ((PyArrayObject *)values[1]);
-    __pyx_v_id = ((PyArrayObject *)values[2]);
-    __pyx_v_fd = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("d_tai_utc", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.d_tai_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_iy), __pyx_ptype_5numpy_ndarray, 1, "iy", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_im), __pyx_ptype_5numpy_ndarray, 1, "im", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_id), __pyx_ptype_5numpy_ndarray, 1, "id", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fd), __pyx_ptype_5numpy_ndarray, 1, "fd", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_4d_tai_utc(__pyx_self, __pyx_v_iy, __pyx_v_im, __pyx_v_id, __pyx_v_fd);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_4d_tai_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_fd) {
-  int __pyx_v_i;
-  int __pyx_v_n;
-  PyArrayObject *__pyx_v_out = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_fd;
-  __Pyx_Buffer __pyx_pybuffer_fd;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_id;
-  __Pyx_Buffer __pyx_pybuffer_id;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_im;
-  __Pyx_Buffer __pyx_pybuffer_im;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_iy;
-  __Pyx_Buffer __pyx_pybuffer_iy;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out;
-  __Pyx_Buffer __pyx_pybuffer_out;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  int __pyx_t_8;
-  int __pyx_t_9;
-  int __pyx_t_10;
-  int __pyx_t_11;
-  int __pyx_t_12;
-  int __pyx_t_13;
-  int __pyx_t_14;
-  Py_ssize_t __pyx_t_15;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("d_tai_utc", 0);
-  __pyx_pybuffer_out.pybuffer.buf = NULL;
-  __pyx_pybuffer_out.refcount = 0;
-  __pyx_pybuffernd_out.data = NULL;
-  __pyx_pybuffernd_out.rcbuffer = &__pyx_pybuffer_out;
-  __pyx_pybuffer_iy.pybuffer.buf = NULL;
-  __pyx_pybuffer_iy.refcount = 0;
-  __pyx_pybuffernd_iy.data = NULL;
-  __pyx_pybuffernd_iy.rcbuffer = &__pyx_pybuffer_iy;
-  __pyx_pybuffer_im.pybuffer.buf = NULL;
-  __pyx_pybuffer_im.refcount = 0;
-  __pyx_pybuffernd_im.data = NULL;
-  __pyx_pybuffernd_im.rcbuffer = &__pyx_pybuffer_im;
-  __pyx_pybuffer_id.pybuffer.buf = NULL;
-  __pyx_pybuffer_id.refcount = 0;
-  __pyx_pybuffernd_id.data = NULL;
-  __pyx_pybuffernd_id.rcbuffer = &__pyx_pybuffer_id;
-  __pyx_pybuffer_fd.pybuffer.buf = NULL;
-  __pyx_pybuffer_fd.refcount = 0;
-  __pyx_pybuffernd_fd.data = NULL;
-  __pyx_pybuffernd_fd.rcbuffer = &__pyx_pybuffer_fd;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_iy.rcbuffer->pybuffer, (PyObject*)__pyx_v_iy, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_iy.diminfo[0].strides = __pyx_pybuffernd_iy.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_iy.diminfo[0].shape = __pyx_pybuffernd_iy.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_im.rcbuffer->pybuffer, (PyObject*)__pyx_v_im, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_im.diminfo[0].strides = __pyx_pybuffernd_im.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_im.diminfo[0].shape = __pyx_pybuffernd_im.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_id.rcbuffer->pybuffer, (PyObject*)__pyx_v_id, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_id.diminfo[0].strides = __pyx_pybuffernd_id.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_id.diminfo[0].shape = __pyx_pybuffernd_id.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_fd.rcbuffer->pybuffer, (PyObject*)__pyx_v_fd, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_fd.diminfo[0].strides = __pyx_pybuffernd_fd.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_fd.diminfo[0].shape = __pyx_pybuffernd_fd.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":206
- *     """
- *     cdef int i
- *     cdef int n = iy.shape[0]             # <<<<<<<<<<<<<<
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] == fd.shape[0])
- * 
- */
-  __pyx_v_n = (__pyx_v_iy->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":207
- *     cdef int i
- *     cdef int n = iy.shape[0]
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] == fd.shape[0])             # <<<<<<<<<<<<<<
- * 
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_iy->dimensions[0]) == (__pyx_v_im->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_im->dimensions[0]) == (__pyx_v_id->dimensions[0]));
-      if (__pyx_t_1) {
-        __pyx_t_1 = ((__pyx_v_id->dimensions[0]) == (__pyx_v_fd->dimensions[0]));
-      }
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":209
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] == fd.shape[0])
- * 
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out.diminfo[0].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out.diminfo[0].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":211
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'bad year',
- *              -2: 'bad month (must be 1 to 12)',
- */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_6, __pyx_int_1, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":212
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'bad year',             # <<<<<<<<<<<<<<
- *              -2: 'bad month (must be 1 to 12)',
- *              -3: 'bad day (must be within normal calendar date for a month)',
- */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_6, __pyx_int_neg_1, __pyx_kp_s_bad_year) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, __pyx_int_neg_2, __pyx_kp_s_bad_month_must_be_1_to_12) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, __pyx_int_neg_3, __pyx_kp_s_bad_day_must_be_within_normal_ca) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, __pyx_int_neg_4, __pyx_kp_s_bad_fraction_of_day) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":216
- *              -3: 'bad day (must be within normal calendar date for a month)',
- *              -4: 'bad fraction of day'}
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraDat(iy[i], im[i], id[i], fd[i],
- *                      &out[i])
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":217
- *              -4: 'bad fraction of day'}
- *     for i in range(n):
- *         ret = eraDat(iy[i], im[i], id[i], fd[i],             # <<<<<<<<<<<<<<
- *                      &out[i])
- *         check_return(ret, 'eraDat', warns, errs)
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-
-    /* "astropy/time/erfa_time.pyx":218
- *     for i in range(n):
- *         ret = eraDat(iy[i], im[i], id[i], fd[i],
- *                      &out[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraDat', warns, errs)
- * 
- */
-    __pyx_t_14 = __pyx_v_i;
-
-    /* "astropy/time/erfa_time.pyx":217
- *              -4: 'bad fraction of day'}
- *     for i in range(n):
- *         ret = eraDat(iy[i], im[i], id[i], fd[i],             # <<<<<<<<<<<<<<
- *                      &out[i])
- *         check_return(ret, 'eraDat', warns, errs)
- */
-    __pyx_v_ret = eraDat((*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_iy.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_iy.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_im.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_im.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_id.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_id.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_fd.rcbuffer->pybuffer.buf, __ [...]
-
-    /* "astropy/time/erfa_time.pyx":219
- *         ret = eraDat(iy[i], im[i], id[i], fd[i],
- *                      &out[i])
- *         check_return(ret, 'eraDat', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out
- */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_3 = NULL;
-    __pyx_t_15 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
-      if (likely(__pyx_t_3)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-        __Pyx_INCREF(__pyx_t_3);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_2, function);
-        __pyx_t_15 = 1;
-      }
-    }
-    __pyx_t_5 = PyTuple_New(4+__pyx_t_15); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    if (__pyx_t_3) {
-      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_15, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraDat);
-    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_15, __pyx_n_s_eraDat);
-    __Pyx_GIVEREF(__pyx_n_s_eraDat);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_15, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_5, 3+__pyx_t_15, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_4 = 0;
-    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":221
- *         check_return(ret, 'eraDat', warns, errs)
- * 
- *     return out             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out));
-  __pyx_r = ((PyObject *)__pyx_v_out);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":128
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tai_utc(np.ndarray[int, ndim=1] iy,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] im,
- *               np.ndarray[int, ndim=1] id,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fd.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.d_tai_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fd.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":226
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_dtf(scale, ndp,             # <<<<<<<<<<<<<<
- *               np.ndarray[double, ndim=1] d1,
- *               np.ndarray[double, ndim=1] d2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_7jd_dtf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_6jd_dtf[] = "\n    int eraD2dtf(const char *scale, int ndp, double d1, double d2,\n             int *iy, int *im, int *id, int ihmsf[4])\n\n    **  Given:\n    **     scale     char[]  time scale ID (Note 1)\n    **     ndp       int     resolution (Note 2)\n    **     d1,d2     double  time as a 2-part Julian Date (Notes 3,4)\n    **\n    **  Returned:\n    **     iy,im,id  int     year, month, day in Gregorian calendar (Note 5)\n    **    [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_7jd_dtf = {"jd_dtf", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_7jd_dtf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_6jd_dtf};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_7jd_dtf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_scale = 0;
-  PyObject *__pyx_v_ndp = 0;
-  PyArrayObject *__pyx_v_d1 = 0;
-  PyArrayObject *__pyx_v_d2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("jd_dtf (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scale,&__pyx_n_s_ndp,&__pyx_n_s_d1,&__pyx_n_s_d2,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scale)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ndp)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("jd_dtf", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_d1)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("jd_dtf", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_d2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("jd_dtf", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "jd_dtf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_scale = values[0];
-    __pyx_v_ndp = values[1];
-    __pyx_v_d1 = ((PyArrayObject *)values[2]);
-    __pyx_v_d2 = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("jd_dtf", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_dtf", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_d1), __pyx_ptype_5numpy_ndarray, 1, "d1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_d2), __pyx_ptype_5numpy_ndarray, 1, "d2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_6jd_dtf(__pyx_self, __pyx_v_scale, __pyx_v_ndp, __pyx_v_d1, __pyx_v_d2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_6jd_dtf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_scale, PyObject *__pyx_v_ndp, PyArrayObject *__pyx_v_d1, PyArrayObject *__pyx_v_d2) {
-  int __pyx_v_i;
-  int __pyx_v_n;
-  PyArrayObject *__pyx_v_iy = 0;
-  PyArrayObject *__pyx_v_im = 0;
-  PyArrayObject *__pyx_v_id = 0;
-  PyArrayObject *__pyx_v_ihmsf = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_d1;
-  __Pyx_Buffer __pyx_pybuffer_d1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_d2;
-  __Pyx_Buffer __pyx_pybuffer_d2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_id;
-  __Pyx_Buffer __pyx_pybuffer_id;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ihmsf;
-  __Pyx_Buffer __pyx_pybuffer_ihmsf;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_im;
-  __Pyx_Buffer __pyx_pybuffer_im;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_iy;
-  __Pyx_Buffer __pyx_pybuffer_iy;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  PyArrayObject *__pyx_t_9 = NULL;
-  int __pyx_t_10;
-  int __pyx_t_11;
-  char *__pyx_t_12;
-  int __pyx_t_13;
-  int __pyx_t_14;
-  int __pyx_t_15;
-  int __pyx_t_16;
-  int __pyx_t_17;
-  int __pyx_t_18;
-  int __pyx_t_19;
-  long __pyx_t_20;
-  Py_ssize_t __pyx_t_21;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("jd_dtf", 0);
-  __pyx_pybuffer_iy.pybuffer.buf = NULL;
-  __pyx_pybuffer_iy.refcount = 0;
-  __pyx_pybuffernd_iy.data = NULL;
-  __pyx_pybuffernd_iy.rcbuffer = &__pyx_pybuffer_iy;
-  __pyx_pybuffer_im.pybuffer.buf = NULL;
-  __pyx_pybuffer_im.refcount = 0;
-  __pyx_pybuffernd_im.data = NULL;
-  __pyx_pybuffernd_im.rcbuffer = &__pyx_pybuffer_im;
-  __pyx_pybuffer_id.pybuffer.buf = NULL;
-  __pyx_pybuffer_id.refcount = 0;
-  __pyx_pybuffernd_id.data = NULL;
-  __pyx_pybuffernd_id.rcbuffer = &__pyx_pybuffer_id;
-  __pyx_pybuffer_ihmsf.pybuffer.buf = NULL;
-  __pyx_pybuffer_ihmsf.refcount = 0;
-  __pyx_pybuffernd_ihmsf.data = NULL;
-  __pyx_pybuffernd_ihmsf.rcbuffer = &__pyx_pybuffer_ihmsf;
-  __pyx_pybuffer_d1.pybuffer.buf = NULL;
-  __pyx_pybuffer_d1.refcount = 0;
-  __pyx_pybuffernd_d1.data = NULL;
-  __pyx_pybuffernd_d1.rcbuffer = &__pyx_pybuffer_d1;
-  __pyx_pybuffer_d2.pybuffer.buf = NULL;
-  __pyx_pybuffer_d2.refcount = 0;
-  __pyx_pybuffernd_d2.data = NULL;
-  __pyx_pybuffernd_d2.rcbuffer = &__pyx_pybuffer_d2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_d1.rcbuffer->pybuffer, (PyObject*)__pyx_v_d1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_d1.diminfo[0].strides = __pyx_pybuffernd_d1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_d1.diminfo[0].shape = __pyx_pybuffernd_d1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_d2.rcbuffer->pybuffer, (PyObject*)__pyx_v_d2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_d2.diminfo[0].strides = __pyx_pybuffernd_d2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_d2.diminfo[0].shape = __pyx_pybuffernd_d2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":286
- *     """
- *     cdef int i
- *     cdef int n = d1.shape[0]             # <<<<<<<<<<<<<<
- * 
- *     cdef np.ndarray[int, ndim=1] iy = np.empty(n, dtype=np.intc)
- */
-  __pyx_v_n = (__pyx_v_d1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":288
- *     cdef int n = d1.shape[0]
- * 
- *     cdef np.ndarray[int, ndim=1] iy = np.empty(n, dtype=np.intc)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[int, ndim=1] im = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=1] id = np.empty(n, dtype=np.intc)
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_intc); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_iy.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_iy = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_iy.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_iy.diminfo[0].strides = __pyx_pybuffernd_iy.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_iy.diminfo[0].shape = __pyx_pybuffernd_iy.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_iy = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":289
- * 
- *     cdef np.ndarray[int, ndim=1] iy = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=1] im = np.empty(n, dtype=np.intc)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[int, ndim=1] id = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=2] ihmsf = np.empty((n, 4), dtype=np.intc)
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_intc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_im.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_im = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_im.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_im.diminfo[0].strides = __pyx_pybuffernd_im.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_im.diminfo[0].shape = __pyx_pybuffernd_im.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_im = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":290
- *     cdef np.ndarray[int, ndim=1] iy = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=1] im = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=1] id = np.empty(n, dtype=np.intc)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[int, ndim=2] ihmsf = np.empty((n, 4), dtype=np.intc)
- * 
- */
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_4);
-  __pyx_t_4 = 0;
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_intc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_2);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_id.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_id = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_id.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_id.diminfo[0].strides = __pyx_pybuffernd_id.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_id.diminfo[0].shape = __pyx_pybuffernd_id.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_id = ((PyArrayObject *)__pyx_t_2);
-  __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":291
- *     cdef np.ndarray[int, ndim=1] im = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=1] id = np.empty(n, dtype=np.intc)
- *     cdef np.ndarray[int, ndim=2] ihmsf = np.empty((n, 4), dtype=np.intc)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __Pyx_INCREF(__pyx_int_4);
-  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4);
-  __Pyx_GIVEREF(__pyx_int_4);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_3 = 0;
-  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_intc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ihmsf.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {
-      __pyx_v_ihmsf = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_ihmsf.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_ihmsf.diminfo[0].strides = __pyx_pybuffernd_ihmsf.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ihmsf.diminfo[0].shape = __pyx_pybuffernd_ihmsf.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_ihmsf.diminfo[1].strides = __pyx_pybuffernd_ihmsf.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_ihmsf.diminfo[1].shape = __pyx_pybuffernd_ihmsf.rcbuffer->pybuffer.shape[1];
-    }
-  }
-  __pyx_t_9 = 0;
-  __pyx_v_ihmsf = ((PyArrayObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":293
- *     cdef np.ndarray[int, ndim=2] ihmsf = np.empty((n, 4), dtype=np.intc)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'unacceptable date'}
- * 
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_1, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":294
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'unacceptable date'}             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_1, __pyx_kp_s_unacceptable_date) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":296
- *     errs = {-1: 'unacceptable date'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraD2dtf(scale, ndp, d1[i], d2[i],
- *                      &iy[i], &im[i], &id[i], &ihmsf[i, 0])
- */
-  __pyx_t_10 = __pyx_v_n;
-  for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {
-    __pyx_v_i = __pyx_t_11;
-
-    /* "astropy/time/erfa_time.pyx":297
- * 
- *     for i in range(n):
- *         ret = eraD2dtf(scale, ndp, d1[i], d2[i],             # <<<<<<<<<<<<<<
- *                      &iy[i], &im[i], &id[i], &ihmsf[i, 0])
- *         check_return(ret, 'eraD2dtf', warns, errs)
- */
-    __pyx_t_12 = __Pyx_PyObject_AsString(__pyx_v_scale); if (unlikely((!__pyx_t_12) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_ndp); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-
-    /* "astropy/time/erfa_time.pyx":298
- *     for i in range(n):
- *         ret = eraD2dtf(scale, ndp, d1[i], d2[i],
- *                      &iy[i], &im[i], &id[i], &ihmsf[i, 0])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraD2dtf', warns, errs)
- * 
- */
-    __pyx_t_16 = __pyx_v_i;
-    __pyx_t_17 = __pyx_v_i;
-    __pyx_t_18 = __pyx_v_i;
-    __pyx_t_19 = __pyx_v_i;
-    __pyx_t_20 = 0;
-
-    /* "astropy/time/erfa_time.pyx":297
- * 
- *     for i in range(n):
- *         ret = eraD2dtf(scale, ndp, d1[i], d2[i],             # <<<<<<<<<<<<<<
- *                      &iy[i], &im[i], &id[i], &ihmsf[i, 0])
- *         check_return(ret, 'eraD2dtf', warns, errs)
- */
-    __pyx_v_ret = eraD2dtf(__pyx_t_12, __pyx_t_13, (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_d1.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_d1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_d2.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_d2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_iy.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_iy.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(int *, __pyx_pybuff [...]
-
-    /* "astropy/time/erfa_time.pyx":299
- *         ret = eraD2dtf(scale, ndp, d1[i], d2[i],
- *                      &iy[i], &im[i], &id[i], &ihmsf[i, 0])
- *         check_return(ret, 'eraD2dtf', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return iy, im, id, ihmsf
- */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = NULL;
-    __pyx_t_21 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
-      if (likely(__pyx_t_4)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-        __Pyx_INCREF(__pyx_t_4);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_3, function);
-        __pyx_t_21 = 1;
-      }
-    }
-    __pyx_t_5 = PyTuple_New(4+__pyx_t_21); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    if (__pyx_t_4) {
-      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_21, __pyx_t_2);
-    __Pyx_GIVEREF(__pyx_t_2);
-    __Pyx_INCREF(__pyx_n_s_eraD2dtf);
-    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_21, __pyx_n_s_eraD2dtf);
-    __Pyx_GIVEREF(__pyx_n_s_eraD2dtf);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_21, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_5, 3+__pyx_t_21, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_2 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":301
- *         check_return(ret, 'eraD2dtf', warns, errs)
- * 
- *     return iy, im, id, ihmsf             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(((PyObject *)__pyx_v_iy));
-  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_iy));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_iy));
-  __Pyx_INCREF(((PyObject *)__pyx_v_im));
-  PyTuple_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_v_im));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_im));
-  __Pyx_INCREF(((PyObject *)__pyx_v_id));
-  PyTuple_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_v_id));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_id));
-  __Pyx_INCREF(((PyObject *)__pyx_v_ihmsf));
-  PyTuple_SET_ITEM(__pyx_t_1, 3, ((PyObject *)__pyx_v_ihmsf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_ihmsf));
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":226
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_dtf(scale, ndp,             # <<<<<<<<<<<<<<
- *               np.ndarray[double, ndim=1] d1,
- *               np.ndarray[double, ndim=1] d2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_d1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_d2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ihmsf.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_dtf", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_d1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_d2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ihmsf.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_iy);
-  __Pyx_XDECREF((PyObject *)__pyx_v_im);
-  __Pyx_XDECREF((PyObject *)__pyx_v_id);
-  __Pyx_XDECREF((PyObject *)__pyx_v_ihmsf);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":305
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def dtf_jd(scale,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] iy,
- *               np.ndarray[int, ndim=1] im,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_9dtf_jd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_8dtf_jd[] = "\n    int eraDtf2d(char *scale, int iy, int im, int id, int ihr, int imn, double sec, double *d1, double *d2)\n\n    **  Given:\n    **     scale     char[]  time scale ID (Note 1)\n    **     iy,im,id  int     year, month, day in Gregorian calendar (Note 2)\n    **     ihr,imn   int     hour, minute\n    **     sec       double  seconds\n    **\n    **  Returned:\n    **     d1,d2     double  2-part Julian Date (Notes 3,4)\n   [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_9dtf_jd = {"dtf_jd", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_9dtf_jd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_8dtf_jd};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_9dtf_jd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_scale = 0;
-  PyArrayObject *__pyx_v_iy = 0;
-  PyArrayObject *__pyx_v_im = 0;
-  PyArrayObject *__pyx_v_id = 0;
-  PyArrayObject *__pyx_v_ihr = 0;
-  PyArrayObject *__pyx_v_imn = 0;
-  PyArrayObject *__pyx_v_sec = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("dtf_jd (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scale,&__pyx_n_s_iy,&__pyx_n_s_im,&__pyx_n_s_id,&__pyx_n_s_ihr,&__pyx_n_s_imn,&__pyx_n_s_sec,0};
-    PyObject* values[7] = {0,0,0,0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scale)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_iy)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_im)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_id)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  4:
-        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ihr)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  5:
-        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_imn)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  6:
-        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sec)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dtf_jd") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
-    }
-    __pyx_v_scale = values[0];
-    __pyx_v_iy = ((PyArrayObject *)values[1]);
-    __pyx_v_im = ((PyArrayObject *)values[2]);
-    __pyx_v_id = ((PyArrayObject *)values[3]);
-    __pyx_v_ihr = ((PyArrayObject *)values[4]);
-    __pyx_v_imn = ((PyArrayObject *)values[5]);
-    __pyx_v_sec = ((PyArrayObject *)values[6]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("dtf_jd", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.dtf_jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_iy), __pyx_ptype_5numpy_ndarray, 1, "iy", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_im), __pyx_ptype_5numpy_ndarray, 1, "im", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_id), __pyx_ptype_5numpy_ndarray, 1, "id", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ihr), __pyx_ptype_5numpy_ndarray, 1, "ihr", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_imn), __pyx_ptype_5numpy_ndarray, 1, "imn", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sec), __pyx_ptype_5numpy_ndarray, 1, "sec", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_8dtf_jd(__pyx_self, __pyx_v_scale, __pyx_v_iy, __pyx_v_im, __pyx_v_id, __pyx_v_ihr, __pyx_v_imn, __pyx_v_sec);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_8dtf_jd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_scale, PyArrayObject *__pyx_v_iy, PyArrayObject *__pyx_v_im, PyArrayObject *__pyx_v_id, PyArrayObject *__pyx_v_ihr, PyArrayObject *__pyx_v_imn, PyArrayObject *__pyx_v_sec) {
-  int __pyx_v_i;
-  int __pyx_v_n;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_id;
-  __Pyx_Buffer __pyx_pybuffer_id;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ihr;
-  __Pyx_Buffer __pyx_pybuffer_ihr;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_im;
-  __Pyx_Buffer __pyx_pybuffer_im;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_imn;
-  __Pyx_Buffer __pyx_pybuffer_imn;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_iy;
-  __Pyx_Buffer __pyx_pybuffer_iy;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_sec;
-  __Pyx_Buffer __pyx_pybuffer_sec;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  int __pyx_t_9;
-  int __pyx_t_10;
-  char *__pyx_t_11;
-  int __pyx_t_12;
-  int __pyx_t_13;
-  int __pyx_t_14;
-  int __pyx_t_15;
-  int __pyx_t_16;
-  int __pyx_t_17;
-  int __pyx_t_18;
-  int __pyx_t_19;
-  Py_ssize_t __pyx_t_20;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("dtf_jd", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_iy.pybuffer.buf = NULL;
-  __pyx_pybuffer_iy.refcount = 0;
-  __pyx_pybuffernd_iy.data = NULL;
-  __pyx_pybuffernd_iy.rcbuffer = &__pyx_pybuffer_iy;
-  __pyx_pybuffer_im.pybuffer.buf = NULL;
-  __pyx_pybuffer_im.refcount = 0;
-  __pyx_pybuffernd_im.data = NULL;
-  __pyx_pybuffernd_im.rcbuffer = &__pyx_pybuffer_im;
-  __pyx_pybuffer_id.pybuffer.buf = NULL;
-  __pyx_pybuffer_id.refcount = 0;
-  __pyx_pybuffernd_id.data = NULL;
-  __pyx_pybuffernd_id.rcbuffer = &__pyx_pybuffer_id;
-  __pyx_pybuffer_ihr.pybuffer.buf = NULL;
-  __pyx_pybuffer_ihr.refcount = 0;
-  __pyx_pybuffernd_ihr.data = NULL;
-  __pyx_pybuffernd_ihr.rcbuffer = &__pyx_pybuffer_ihr;
-  __pyx_pybuffer_imn.pybuffer.buf = NULL;
-  __pyx_pybuffer_imn.refcount = 0;
-  __pyx_pybuffernd_imn.data = NULL;
-  __pyx_pybuffernd_imn.rcbuffer = &__pyx_pybuffer_imn;
-  __pyx_pybuffer_sec.pybuffer.buf = NULL;
-  __pyx_pybuffer_sec.refcount = 0;
-  __pyx_pybuffernd_sec.data = NULL;
-  __pyx_pybuffernd_sec.rcbuffer = &__pyx_pybuffer_sec;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_iy.rcbuffer->pybuffer, (PyObject*)__pyx_v_iy, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_iy.diminfo[0].strides = __pyx_pybuffernd_iy.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_iy.diminfo[0].shape = __pyx_pybuffernd_iy.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_im.rcbuffer->pybuffer, (PyObject*)__pyx_v_im, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_im.diminfo[0].strides = __pyx_pybuffernd_im.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_im.diminfo[0].shape = __pyx_pybuffernd_im.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_id.rcbuffer->pybuffer, (PyObject*)__pyx_v_id, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_id.diminfo[0].strides = __pyx_pybuffernd_id.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_id.diminfo[0].shape = __pyx_pybuffernd_id.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ihr.rcbuffer->pybuffer, (PyObject*)__pyx_v_ihr, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ihr.diminfo[0].strides = __pyx_pybuffernd_ihr.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ihr.diminfo[0].shape = __pyx_pybuffernd_ihr.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_imn.rcbuffer->pybuffer, (PyObject*)__pyx_v_imn, &__Pyx_TypeInfo_int, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_imn.diminfo[0].strides = __pyx_pybuffernd_imn.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_imn.diminfo[0].shape = __pyx_pybuffernd_imn.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_sec.rcbuffer->pybuffer, (PyObject*)__pyx_v_sec, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_sec.diminfo[0].strides = __pyx_pybuffernd_sec.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_sec.diminfo[0].shape = __pyx_pybuffernd_sec.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":372
- *     """
- *     cdef int i
- *     cdef int n = iy.shape[0]             # <<<<<<<<<<<<<<
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] ==
- *             ihr.shape[0] == imn.shape[0] == sec.shape[0])
- */
-  __pyx_v_n = (__pyx_v_iy->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":373
- *     cdef int i
- *     cdef int n = iy.shape[0]
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] ==             # <<<<<<<<<<<<<<
- *             ihr.shape[0] == imn.shape[0] == sec.shape[0])
- * 
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_iy->dimensions[0]) == (__pyx_v_im->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_im->dimensions[0]) == (__pyx_v_id->dimensions[0]));
-      if (__pyx_t_1) {
-
-        /* "astropy/time/erfa_time.pyx":374
- *     cdef int n = iy.shape[0]
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] ==
- *             ihr.shape[0] == imn.shape[0] == sec.shape[0])             # <<<<<<<<<<<<<<
- * 
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-        __pyx_t_1 = ((__pyx_v_id->dimensions[0]) == (__pyx_v_ihr->dimensions[0]));
-        if (__pyx_t_1) {
-          __pyx_t_1 = ((__pyx_v_ihr->dimensions[0]) == (__pyx_v_imn->dimensions[0]));
-          if (__pyx_t_1) {
-            __pyx_t_1 = ((__pyx_v_imn->dimensions[0]) == (__pyx_v_sec->dimensions[0]));
-          }
-        }
-      }
-    }
-
-    /* "astropy/time/erfa_time.pyx":373
- *     cdef int i
- *     cdef int n = iy.shape[0]
- *     assert (iy.shape[0] == im.shape[0] == id.shape[0] ==             # <<<<<<<<<<<<<<
- *             ihr.shape[0] == imn.shape[0] == sec.shape[0])
- * 
- */
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":376
- *             ihr.shape[0] == imn.shape[0] == sec.shape[0])
- * 
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":377
- * 
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {3: 'time is after end of day and ' + DUBIOUS,
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":379
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     warns = {3: 'time is after end of day and ' + DUBIOUS,             # <<<<<<<<<<<<<<
- *              2: 'time is after end of day',
- *              1: DUBIOUS}
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyNumber_Add(__pyx_kp_s_time_is_after_end_of_day_and, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_3, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_2, __pyx_kp_s_time_is_after_end_of_day) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":381
- *     warns = {3: 'time is after end of day and ' + DUBIOUS,
- *              2: 'time is after end of day',
- *              1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'bad year',
- *             -2: 'bad month',
- */
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":382
- *              2: 'time is after end of day',
- *              1: DUBIOUS}
- *     errs = {-1: 'bad year',             # <<<<<<<<<<<<<<
- *             -2: 'bad month',
- *             -3: 'bad day',
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_1, __pyx_kp_s_bad_year) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_2, __pyx_kp_s_bad_month) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_3, __pyx_kp_s_bad_day) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_4, __pyx_kp_s_bad_hour) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_5, __pyx_kp_s_bad_minute) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_6, __pyx_kp_s_bad_second_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":389
- *             -6: 'bad second (< 0)'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],
- *                        &out1[i], &out2[i])
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":390
- * 
- *     for i in range(n):
- *         ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],             # <<<<<<<<<<<<<<
- *                        &out1[i], &out2[i])
- *         check_return(ret, 'eraDtf2d', warns, errs)
- */
-    __pyx_t_11 = __Pyx_PyObject_AsString(__pyx_v_scale); if (unlikely((!__pyx_t_11) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_t_16 = __pyx_v_i;
-    __pyx_t_17 = __pyx_v_i;
-
-    /* "astropy/time/erfa_time.pyx":391
- *     for i in range(n):
- *         ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],
- *                        &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraDtf2d', warns, errs)
- * 
- */
-    __pyx_t_18 = __pyx_v_i;
-    __pyx_t_19 = __pyx_v_i;
-
-    /* "astropy/time/erfa_time.pyx":390
- * 
- *     for i in range(n):
- *         ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],             # <<<<<<<<<<<<<<
- *                        &out1[i], &out2[i])
- *         check_return(ret, 'eraDtf2d', warns, errs)
- */
-    __pyx_v_ret = eraDtf2d(__pyx_t_11, (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_iy.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_iy.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_im.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_im.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_id.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_id.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(int *, __pyx_pybuffernd_ihr.rcbuffer->pybu [...]
-
-    /* "astropy/time/erfa_time.pyx":392
- *         ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],
- *                        &out1[i], &out2[i])
- *         check_return(ret, 'eraDtf2d', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_2 = NULL;
-    __pyx_t_20 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
-        __pyx_t_20 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(4+__pyx_t_20); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_20, __pyx_t_6);
-    __Pyx_GIVEREF(__pyx_t_6);
-    __Pyx_INCREF(__pyx_n_s_eraDtf2d);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_20, __pyx_n_s_eraDtf2d);
-    __Pyx_GIVEREF(__pyx_n_s_eraDtf2d);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_20, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_3, 3+__pyx_t_20, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_6 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":394
- *         check_return(ret, 'eraDtf2d', warns, errs)
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":305
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def dtf_jd(scale,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] iy,
- *               np.ndarray[int, ndim=1] im,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ihr.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_imn.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sec.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.dtf_jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_id.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ihr.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_im.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_imn.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_iy.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sec.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":399
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_11tai_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_10tai_tt[] = "\n    int eraTaitt(double tai1, double tai2, double *tt1, double *tt2)\n\n    **  Given:\n    **     tai1,tai2  double    TAI as a 2-part Julian Date\n    **\n    **  Returned:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Note:\n    **\n    **     tai1+tai2 is Julian Date, apportioned in any convenient w [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_11tai_tt = {"tai_tt", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_11tai_tt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_10tai_tt};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_11tai_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tai_tt (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tai_tt", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tai_tt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tai_tt", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_10tai_tt(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_10tai_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tai_tt", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":421
- *     **     tt1,tt2 follow suit.
- *     """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":422
- *     """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":424
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":425
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":427
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTaitt(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaitt')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":428
- * 
- *     for i in range(n):
- *         ret = eraTaitt(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTaitt')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTaitt((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2. [...]
-
-    /* "astropy/time/erfa_time.pyx":429
- *     for i in range(n):
- *         ret = eraTaitt(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaitt')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTaitt);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTaitt);
-    __Pyx_GIVEREF(__pyx_n_s_eraTaitt);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":431
- *         check_return(ret, 'eraTaitt')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":399
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":436
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcb_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_13tcb_tdb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_12tcb_tdb[] = "\n    int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2)\n\n    **  Given:\n    **     tcb1,tcb2  double    TCB as a 2-part Julian Date\n    **\n    **  Returned:\n    **     tdb1,tdb2  double    TDB as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    **\n    **  1) tcb1+tcb2 is Julian Date, apportioned in any conven [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_13tcb_tdb = {"tcb_tdb", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_13tcb_tdb, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_12tcb_tdb};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_13tcb_tdb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tcb_tdb (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tcb_tdb", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tcb_tdb") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tcb_tdb", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tcb_tdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_12tcb_tdb(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_12tcb_tdb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tcb_tdb", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":477
- *     """
- * 
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":478
- * 
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":480
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":481
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":483
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTcbtdb(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTcbtdb')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":484
- * 
- *     for i in range(n):
- *         ret = eraTcbtdb(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTcbtdb')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTcbtdb((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2 [...]
-
-    /* "astropy/time/erfa_time.pyx":485
- *     for i in range(n):
- *         ret = eraTcbtdb(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTcbtdb')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTcbtdb);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTcbtdb);
-    __Pyx_GIVEREF(__pyx_n_s_eraTcbtdb);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":487
- *         check_return(ret, 'eraTcbtdb')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":436
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcb_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tcb_tdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":492
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcg_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_15tcg_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_14tcg_tt[] = "\n   int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2)\n\n   **  Given:\n   **     tcg1,tcg2  double    TCG as a 2-part Julian Date\n   **\n   **  Returned:\n   **     tt1,tt2    double    TT as a 2-part Julian Date\n   **\n   **  Returned (function value):\n   **                int       status:  0 = OK\n    ";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_15tcg_tt = {"tcg_tt", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_15tcg_tt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_14tcg_tt};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_15tcg_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tcg_tt (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tcg_tt", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tcg_tt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tcg_tt", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tcg_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_14tcg_tt(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_14tcg_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tcg_tt", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":508
- *     """
- * 
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":509
- * 
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":511
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":512
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":514
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTcgtt(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTcgtt')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":515
- * 
- *     for i in range(n):
- *         ret = eraTcgtt(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTcgtt')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTcgtt((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2. [...]
-
-    /* "astropy/time/erfa_time.pyx":516
- *     for i in range(n):
- *         ret = eraTcgtt(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTcgtt')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTcgtt);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTcgtt);
-    __Pyx_GIVEREF(__pyx_n_s_eraTcgtt);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":518
- *         check_return(ret, 'eraTcgtt')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":492
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcg_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tcg_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":523
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tcb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_17tdb_tcb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_16tdb_tcb[] = "\n    int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2)\n\n    **  Given:\n    **     tdb1,tdb2  double    TDB as a 2-part Julian Date\n    **\n    **  Returned:\n    **     tcb1,tcb2  double    TCB as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    ";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_17tdb_tcb = {"tdb_tcb", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_17tdb_tcb, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_16tdb_tcb};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_17tdb_tcb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tdb_tcb (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tdb_tcb", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tdb_tcb") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tdb_tcb", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tdb_tcb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_16tdb_tcb(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_16tdb_tcb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tdb_tcb", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":538
- *     **                int       status:  0 = OK
- *     """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":539
- *     """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":541
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":542
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":544
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTdbtcb(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTdbtcb')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":545
- * 
- *     for i in range(n):
- *         ret = eraTdbtcb(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTdbtcb')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTdbtcb((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2 [...]
-
-    /* "astropy/time/erfa_time.pyx":546
- *     for i in range(n):
- *         ret = eraTdbtcb(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTdbtcb')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTdbtcb);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTdbtcb);
-    __Pyx_GIVEREF(__pyx_n_s_eraTdbtcb);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":548
- *         check_return(ret, 'eraTdbtcb')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":523
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tcb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tdb_tcb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":553
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_19tt_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_18tt_tai[] = "\n    int eraTttai(double tt1, double tt2, double *tai1, double *tai2)\n\n    **  Given:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **\n    **  Returned:\n    **     tai1,tai2  double    TAI as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    ";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_19tt_tai = {"tt_tai", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_19tt_tai, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_18tt_tai};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_19tt_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tt_tai (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_tai", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tt_tai") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tt_tai", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_18tt_tai(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_18tt_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tt_tai", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":568
- *     **                int       status:  0 = OK
- *     """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":569
- *     """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":571
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":572
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":574
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTttai(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttai')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":575
- * 
- *     for i in range(n):
- *         ret = eraTttai(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTttai')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTttai((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2. [...]
-
-    /* "astropy/time/erfa_time.pyx":576
- *     for i in range(n):
- *         ret = eraTttai(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttai')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTttai);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTttai);
-    __Pyx_GIVEREF(__pyx_n_s_eraTttai);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":578
- *         check_return(ret, 'eraTttai')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 578; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":553
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":583
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tcg(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_21tt_tcg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_20tt_tcg[] = "\n    int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2)\n    **  Given:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **\n    **  Returned:\n    **     tcg1,tcg2  double    TCG as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    ";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_21tt_tcg = {"tt_tcg", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_21tt_tcg, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_20tt_tcg};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_21tt_tcg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tt_tcg (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_tcg", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tt_tcg") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tt_tcg", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tcg", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_20tt_tcg(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_20tt_tcg(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tt_tcg", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":597
- *     **                int       status:  0 = OK
- *     """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":598
- *     """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":600
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":601
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":603
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTttcg(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttcg')
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":604
- * 
- *     for i in range(n):
- *         ret = eraTttcg(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTttcg')
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTttcg((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2. [...]
-
-    /* "astropy/time/erfa_time.pyx":605
- *     for i in range(n):
- *         ret = eraTttcg(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttcg')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(2+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTttcg);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTttcg);
-    __Pyx_GIVEREF(__pyx_n_s_eraTttcg);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":607
- *         check_return(ret, 'eraTttcg')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 607; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":583
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tcg(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tcg", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":612
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_23utc_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_22utc_tai[] = "\n    int eraUtctai(double utc1, double utc2, double *tai1, double *tai2)\n\n    **  Given:\n    **     utc1,utc2  double   UTC as a 2-part quasi Julian Date (Notes 1-4)\n    **\n    **  Returned:\n    **     tai1,tai2  double   TAI as a 2-part Julian Date (Note 5)\n    **\n    **  Returned (function value):\n    **                int      status: +1 = dubious year (Note 3)\n    **                                  0 = OK\n    [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_23utc_tai = {"utc_tai", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_23utc_tai, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_22utc_tai};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_23utc_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("utc_tai (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("utc_tai", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "utc_tai") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("utc_tai", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.utc_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 613; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_22utc_tai(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_22utc_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("utc_tai", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":652
- *     **
- *     """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":653
- *     """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":655
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":656
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":658
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'unacceptable date'}
- * 
- */
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_1, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":659
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'unacceptable date'}             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_neg_1, __pyx_kp_s_unacceptable_date) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":661
- *     errs = {-1: 'unacceptable date'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraUtctai(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUtctai', warns, errs)
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":662
- * 
- *     for i in range(n):
- *         ret = eraUtctai(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraUtctai', warns, errs)
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraUtctai((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2 [...]
-
-    /* "astropy/time/erfa_time.pyx":663
- *     for i in range(n):
- *         ret = eraUtctai(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUtctai', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 663; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 663; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(4+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 663; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraUtctai);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraUtctai);
-    __Pyx_GIVEREF(__pyx_n_s_eraUtctai);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_2, 2+__pyx_t_14, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_2, 3+__pyx_t_14, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 663; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":665
- *         check_return(ret, 'eraUtctai', warns, errs)
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":612
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.utc_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":670
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_25tai_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_24tai_utc[] = "\n    int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2)\n\n    **  Given:\n    **     tai1,tai2  double   TAI as a 2-part Julian Date (Note 1)\n    **\n    **  Returned:\n    **     utc1,utc2  double   UTC as a 2-part quasi Julian Date (Notes 1-3)\n    **\n    **  Returned (function value):\n    **                int      status: +1 = dubious year (Note 4)\n    **                                  0 = OK\n    [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_25tai_utc = {"tai_utc", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_25tai_utc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_24tai_utc};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_25tai_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tai_utc (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tai_utc", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tai_utc") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tai_utc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_24tai_utc(__pyx_self, __pyx_v_in1, __pyx_v_in2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_24tai_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  Py_ssize_t __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tai_utc", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":709
- *     **     to be trusted.  See eraDat for further details.
- *         """
- *     assert in1.shape[0] == in2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":710
- *         """
- *     assert in1.shape[0] == in2.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":712
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":713
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":715
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'unacceptable date'}
- * 
- */
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_1, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":716
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'unacceptable date'}             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_neg_1, __pyx_kp_s_unacceptable_date) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":718
- *     errs = {-1: 'unacceptable date'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTaiutc(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaiutc', warns, errs)
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":719
- * 
- *     for i in range(n):
- *         ret = eraTaiutc(in1[i], in2[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTaiutc', warns, errs)
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_v_ret = eraTaiutc((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in2.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_out1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out2 [...]
-
-    /* "astropy/time/erfa_time.pyx":720
- *     for i in range(n):
- *         ret = eraTaiutc(in1[i], in2[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaiutc', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = NULL;
-    __pyx_t_14 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_1)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_1);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-        __pyx_t_14 = 1;
-      }
-    }
-    __pyx_t_2 = PyTuple_New(4+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (__pyx_t_1) {
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_3);
-    __Pyx_INCREF(__pyx_n_s_eraTaiutc);
-    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_n_s_eraTaiutc);
-    __Pyx_GIVEREF(__pyx_n_s_eraTaiutc);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_2, 2+__pyx_t_14, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_2, 3+__pyx_t_14, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":722
- *         check_return(ret, 'eraTaiutc', warns, errs)
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":670
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":727
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_27tai_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_26tai_ut1[] = "\n    int eraTaiut1(double tai1, double tai2, double dta, double *ut11, double *ut12)\n\n    **  Given:\n    **     tai1,tai2  double    TAI as a 2-part Julian Date\n    **     dta        double    UT1-TAI in seconds\n    **\n    **  Returned:\n    **     ut11,ut12  double    UT1 as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    ** [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_27tai_ut1 = {"tai_ut1", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_27tai_ut1, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_26tai_ut1};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_27tai_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tai_ut1 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tai_ut1", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tai_ut1", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tai_ut1") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tai_ut1", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_26tai_ut1(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_26tai_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tai_ut1", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":754
- *     **     available from IERS tabulations.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":755
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":757
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":758
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":760
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTaiut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaiut1')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":761
- * 
- *     for i in range(n):
- *         ret = eraTaiut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTaiut1')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraTaiut1((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuff [...]
-
-    /* "astropy/time/erfa_time.pyx":762
- *     for i in range(n):
- *         ret = eraTaiut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTaiut1')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraTaiut1);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraTaiut1);
-    __Pyx_GIVEREF(__pyx_n_s_eraTaiut1);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":764
- *         check_return(ret, 'eraTaiut1')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":727
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tai_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":769
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_29ut1_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_28ut1_tai[] = "\n    int eraUt1tai(double ut11, double ut12, double dta, double *tai1, double *tai2)\n\n    **  Given:\n    **     ut11,ut12  double    UT1 as a 2-part Julian Date\n    **     dta        double    UT1-TAI in seconds\n    **\n    **  Returned:\n    **     tai1,tai2  double    TAI as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    ** [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_29ut1_tai = {"ut1_tai", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_29ut1_tai, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_28ut1_tai};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_29ut1_tai(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("ut1_tai (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_tai", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_tai", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ut1_tai") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("ut1_tai", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_28ut1_tai(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_28ut1_tai(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("ut1_tai", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":796
- *     **     available from IERS tabulations.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":797
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":799
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":800
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":802
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraUt1tai(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1tai')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":803
- * 
- *     for i in range(n):
- *         ret = eraUt1tai(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraUt1tai')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraUt1tai((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuff [...]
-
-    /* "astropy/time/erfa_time.pyx":804
- *     for i in range(n):
- *         ret = eraUt1tai(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1tai')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraUt1tai);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraUt1tai);
-    __Pyx_GIVEREF(__pyx_n_s_eraUt1tai);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":806
- *         check_return(ret, 'eraUt1tai')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":769
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_tai", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":811
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_31tt_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_30tt_ut1[] = "\n    int eraTtut1(double tt1, double tt2, double dt, double *ut11, double *ut12)\n\n    **  Given:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **     dt         double    TT-UT1 in seconds\n    **\n    **  Returned:\n    **     ut11,ut12  double    UT1 as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    **\n    * [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_31tt_ut1 = {"tt_ut1", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_31tt_ut1, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_30tt_ut1};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_31tt_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tt_ut1 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_ut1", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_ut1", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tt_ut1") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tt_ut1", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_30tt_ut1(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_30tt_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tt_ut1", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":837
- *     **  2) The argument dt is classical Delta T.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":838
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":840
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":841
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":843
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTtut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTtut1')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":844
- * 
- *     for i in range(n):
- *         ret = eraTtut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTtut1')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraTtut1((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffe [...]
-
-    /* "astropy/time/erfa_time.pyx":845
- *     for i in range(n):
- *         ret = eraTtut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTtut1')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraTtut1);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraTtut1);
-    __Pyx_GIVEREF(__pyx_n_s_eraTtut1);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":847
- *         check_return(ret, 'eraTtut1')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":811
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":852
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_33ut1_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_32ut1_tt[] = "\n    int eraUt1tt(double ut11, double ut12, double dt, double *tt1, double *tt2)\n\n    **  Given:\n    **     ut11,ut12  double    UT1 as a 2-part Julian Date\n    **     dt         double    TT-UT1 in seconds\n    **\n    **  Returned:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    **\n    * [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_33ut1_tt = {"ut1_tt", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_33ut1_tt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_32ut1_tt};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_33ut1_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("ut1_tt (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_tt", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_tt", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ut1_tt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("ut1_tt", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_32ut1_tt(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_32ut1_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("ut1_tt", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":878
- *     **  2) The argument dt is classical Delta T.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":879
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":881
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":882
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":884
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraUt1tt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1tt')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":885
- * 
- *     for i in range(n):
- *         ret = eraUt1tt(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraUt1tt')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraUt1tt((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffe [...]
-
-    /* "astropy/time/erfa_time.pyx":886
- *     for i in range(n):
- *         ret = eraUt1tt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1tt')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraUt1tt);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraUt1tt);
-    __Pyx_GIVEREF(__pyx_n_s_eraUt1tt);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":888
- *         check_return(ret, 'eraUt1tt')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":852
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":893
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_35tdb_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_34tdb_tt[] = "\n    int eraTdbtt(double tdb1, double tdb2, double dtr, double *tt1, double *tt2)\n\n    **  Given:\n    **     tdb1,tdb2  double    TDB as a 2-part Julian Date\n    **     dtr        double    TDB-TT in seconds\n    **\n    **  Returned:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    **\n     [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_35tdb_tt = {"tdb_tt", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_35tdb_tt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_34tdb_tt};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_35tdb_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tdb_tt (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tdb_tt", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tdb_tt", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tdb_tt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tdb_tt", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tdb_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_34tdb_tt(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_34tdb_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tdb_tt", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":928
- *     **     JPL solar system ephemerides.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":929
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":931
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":932
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":934
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTdbtt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTdbtt')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":935
- * 
- *     for i in range(n):
- *         ret = eraTdbtt(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTdbtt')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraTdbtt((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffe [...]
-
-    /* "astropy/time/erfa_time.pyx":936
- *     for i in range(n):
- *         ret = eraTdbtt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTdbtt')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraTdbtt);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraTdbtt);
-    __Pyx_GIVEREF(__pyx_n_s_eraTdbtt);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":938
- *         check_return(ret, 'eraTdbtt')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":893
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tdb_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":943
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_37tt_tdb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_36tt_tdb[] = "\n    int eraTttdb(double tt1, double tt2, double dtr, double *tdb1, double *tdb2)\n\n    **  Given:\n    **     tt1,tt2    double    TT as a 2-part Julian Date\n    **     dtr        double    TDB-TT in seconds\n    **\n    **  Returned:\n    **     tdb1,tdb2  double    TDB as a 2-part Julian Date\n    **\n    **  Returned (function value):\n    **                int       status:  0 = OK\n    **\n    **  Notes:\n    **\n     [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_37tt_tdb = {"tt_tdb", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_37tt_tdb, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_36tt_tdb};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_37tt_tdb(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("tt_tdb (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_tdb", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("tt_tdb", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "tt_tdb") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("tt_tdb", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_36tt_tdb(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_36tt_tdb(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("tt_tdb", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":978
- *     **     solar system ephemerides.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":979
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":981
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":982
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":984
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraTttdb(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttdb')
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":985
- * 
- *     for i in range(n):
- *         ret = eraTttdb(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraTttdb')
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraTttdb((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuffe [...]
-
-    /* "astropy/time/erfa_time.pyx":986
- *     for i in range(n):
- *         ret = eraTttdb(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraTttdb')             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(2+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraTttdb);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraTttdb);
-    __Pyx_GIVEREF(__pyx_n_s_eraTttdb);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":988
- *         check_return(ret, 'eraTttdb')
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":943
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.tt_tdb", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":993
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_39ut1_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_38ut1_utc[] = "\n    int eraUt1utc(double ut11, double ut12, double dut1, double *utc1, double *utc2)\n\n    **  Given:\n    **     ut11,ut12  double   UT1 as a 2-part Julian Date (Note 1)\n    **     dut1       double   Delta UT1: UT1-UTC in seconds (Note 2)\n    **\n    **  Returned:\n    **     utc1,utc2  double   UTC as a 2-part quasi Julian Date (Notes 3,4)\n    **\n    **  Returned (function value):\n    **                int      sta [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_39ut1_utc = {"ut1_utc", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_39ut1_utc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_38ut1_utc};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_39ut1_utc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("ut1_utc (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_utc", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("ut1_utc", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ut1_utc") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("ut1_utc", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_38ut1_utc(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_38ut1_utc(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("ut1_utc", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1039
- *     **     to be trusted.  See eraDat for further details.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1040
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1042
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1043
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1045
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'unacceptable date'}
- * 
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_1, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1046
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'unacceptable date'}             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_1, __pyx_kp_s_unacceptable_date) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1048
- *     errs = {-1: 'unacceptable date'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraUt1utc(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1utc', warns, errs)
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":1049
- * 
- *     for i in range(n):
- *         ret = eraUt1utc(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraUt1utc', warns, errs)
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraUt1utc((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuff [...]
-
-    /* "astropy/time/erfa_time.pyx":1050
- *     for i in range(n):
- *         ret = eraUt1utc(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUt1utc', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(4+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraUt1utc);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraUt1utc);
-    __Pyx_GIVEREF(__pyx_n_s_eraUt1utc);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_16, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_3, 3+__pyx_t_16, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":1052
- *         check_return(ret, 'eraUt1utc', warns, errs)
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":993
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.ut1_utc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1057
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_41utc_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_40utc_ut1[] = "\n    int eraUtcut1(double utc1, double utc2, double dut1, double *ut11, double *ut12)\n\n    **  Given:\n    **     utc1,utc2  double   UTC as a 2-part quasi Julian Date (Notes 1-4)\n    **     dut1       double   Delta UT1 = UT1-UTC in seconds (Note 5)\n    **\n    **  Returned:\n    **     ut11,ut12  double   UT1 as a 2-part Julian Date (Note 6)\n    **\n    **  Returned (function value):\n    **                int      st [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_41utc_ut1 = {"utc_ut1", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_41utc_ut1, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_40utc_ut1};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_41utc_ut1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_dt = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("utc_ut1 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_dt,0};
-    PyObject* values[3] = {0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("utc_ut1", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dt)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("utc_ut1", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "utc_ut1") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_dt = ((PyArrayObject *)values[2]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("utc_ut1", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.utc_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1058; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_5numpy_ndarray, 1, "dt", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_40utc_ut1(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_dt);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_40utc_ut1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_dt) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_out1 = 0;
-  PyArrayObject *__pyx_v_out2 = 0;
-  PyObject *__pyx_v_warns = NULL;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_dt;
-  __Pyx_Buffer __pyx_pybuffer_dt;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out1;
-  __Pyx_Buffer __pyx_pybuffer_out1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out2;
-  __Pyx_Buffer __pyx_pybuffer_out2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("utc_ut1", 0);
-  __pyx_pybuffer_out1.pybuffer.buf = NULL;
-  __pyx_pybuffer_out1.refcount = 0;
-  __pyx_pybuffernd_out1.data = NULL;
-  __pyx_pybuffernd_out1.rcbuffer = &__pyx_pybuffer_out1;
-  __pyx_pybuffer_out2.pybuffer.buf = NULL;
-  __pyx_pybuffer_out2.refcount = 0;
-  __pyx_pybuffernd_out2.data = NULL;
-  __pyx_pybuffernd_out2.rcbuffer = &__pyx_pybuffer_out2;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_dt.pybuffer.buf = NULL;
-  __pyx_pybuffer_dt.refcount = 0;
-  __pyx_pybuffernd_dt.data = NULL;
-  __pyx_pybuffernd_dt.rcbuffer = &__pyx_pybuffer_dt;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dt.rcbuffer->pybuffer, (PyObject*)__pyx_v_dt, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_dt.diminfo[0].strides = __pyx_pybuffernd_dt.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dt.diminfo[0].shape = __pyx_pybuffernd_dt.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1107
- *     **     to be trusted.  See eraDat for further details.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_dt->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1108
- *     """
- *     assert in1.shape[0] == in2.shape[0] == dt.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1110
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out1.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out1.diminfo[0].strides = __pyx_pybuffernd_out1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out1.diminfo[0].shape = __pyx_pybuffernd_out1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_out1 = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1111
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: DUBIOUS}
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out2.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out2.diminfo[0].strides = __pyx_pybuffernd_out2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out2.diminfo[0].shape = __pyx_pybuffernd_out2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out2 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1113
- *     cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
- * 
- *     warns = {1: DUBIOUS}             # <<<<<<<<<<<<<<
- *     errs = {-1: 'unacceptable date'}
- * 
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_DUBIOUS); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_1, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_v_warns = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1114
- * 
- *     warns = {1: DUBIOUS}
- *     errs = {-1: 'unacceptable date'}             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_int_neg_1, __pyx_kp_s_unacceptable_date) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1116
- *     errs = {-1: 'unacceptable date'}
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         ret = eraUtcut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUtcut1', warns, errs)
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":1117
- * 
- *     for i in range(n):
- *         ret = eraUtcut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraUtcut1', warns, errs)
- * 
- */
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_v_ret = eraUtcut1((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_dt.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_dt.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out1.rcbuff [...]
-
-    /* "astropy/time/erfa_time.pyx":1118
- *     for i in range(n):
- *         ret = eraUtcut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
- *         check_return(ret, 'eraUtcut1', warns, errs)             # <<<<<<<<<<<<<<
- * 
- *     return out1, out2
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = NULL;
-    __pyx_t_16 = 0;
-    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_2)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_2);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-        __pyx_t_16 = 1;
-      }
-    }
-    __pyx_t_3 = PyTuple_New(4+__pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (__pyx_t_2) {
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
-    }
-    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_16, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_n_s_eraUtcut1);
-    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_16, __pyx_n_s_eraUtcut1);
-    __Pyx_GIVEREF(__pyx_n_s_eraUtcut1);
-    __Pyx_INCREF(__pyx_v_warns);
-    PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_16, __pyx_v_warns);
-    __Pyx_GIVEREF(__pyx_v_warns);
-    __Pyx_INCREF(__pyx_v_errs);
-    PyTuple_SET_ITEM(__pyx_t_3, 3+__pyx_t_16, __pyx_v_errs);
-    __Pyx_GIVEREF(__pyx_v_errs);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":1120
- *         check_return(ret, 'eraUtcut1', warns, errs)
- * 
- *     return out1, out2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out1));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_out1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_out2));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_out2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_out2));
-  __pyx_r = __pyx_t_5;
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1057
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.utc_ut1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dt.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out2);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1125
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tdb_tt(np.ndarray[double, ndim=1] in1,             # <<<<<<<<<<<<<<
- *              np.ndarray[double, ndim=1] in2,
- *              np.ndarray[double, ndim=1] ut,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_43d_tdb_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_42d_tdb_tt[] = "\n    compute DTR = TDB-TT\n    double eraDtdb(double date1, double date2, double ut,\n                   double elong, double u, double v)\n\n    **  Given:\n    **     date1,date2   double  date, TDB (Notes 1-3)\n    **     ut            double  universal time (UT1, fraction of one day)\n    **     elong         double  longitude (east positive, radians)\n    **     u             double  distance from Earth spin axis (km)\ [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_43d_tdb_tt = {"d_tdb_tt", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_43d_tdb_tt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_42d_tdb_tt};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_43d_tdb_tt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_in1 = 0;
-  PyArrayObject *__pyx_v_in2 = 0;
-  PyArrayObject *__pyx_v_ut = 0;
-  PyArrayObject *__pyx_v_elong = 0;
-  PyArrayObject *__pyx_v_u = 0;
-  PyArrayObject *__pyx_v_v = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("d_tdb_tt (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_in1,&__pyx_n_s_in2,&__pyx_n_s_ut,&__pyx_n_s_elong,&__pyx_n_s_u,&__pyx_n_s_v,0};
-    PyObject* values[6] = {0,0,0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_in2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_elong)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  4:
-        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_u)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  5:
-        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_v)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "d_tdb_tt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-    }
-    __pyx_v_in1 = ((PyArrayObject *)values[0]);
-    __pyx_v_in2 = ((PyArrayObject *)values[1]);
-    __pyx_v_ut = ((PyArrayObject *)values[2]);
-    __pyx_v_elong = ((PyArrayObject *)values[3]);
-    __pyx_v_u = ((PyArrayObject *)values[4]);
-    __pyx_v_v = ((PyArrayObject *)values[5]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("d_tdb_tt", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.d_tdb_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in1), __pyx_ptype_5numpy_ndarray, 1, "in1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_in2), __pyx_ptype_5numpy_ndarray, 1, "in2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut), __pyx_ptype_5numpy_ndarray, 1, "ut", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_elong), __pyx_ptype_5numpy_ndarray, 1, "elong", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_u), __pyx_ptype_5numpy_ndarray, 1, "u", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_v), __pyx_ptype_5numpy_ndarray, 1, "v", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_42d_tdb_tt(__pyx_self, __pyx_v_in1, __pyx_v_in2, __pyx_v_ut, __pyx_v_elong, __pyx_v_u, __pyx_v_v);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_42d_tdb_tt(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_in1, PyArrayObject *__pyx_v_in2, PyArrayObject *__pyx_v_ut, PyArrayObject *__pyx_v_elong, PyArrayObject *__pyx_v_u, PyArrayObject *__pyx_v_v) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  unsigned int __pyx_v_j;
-  PyArrayObject *__pyx_v_out = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_elong;
-  __Pyx_Buffer __pyx_pybuffer_elong;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in1;
-  __Pyx_Buffer __pyx_pybuffer_in1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_in2;
-  __Pyx_Buffer __pyx_pybuffer_in2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out;
-  __Pyx_Buffer __pyx_pybuffer_out;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_u;
-  __Pyx_Buffer __pyx_pybuffer_u;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut;
-  __Pyx_Buffer __pyx_pybuffer_ut;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_v;
-  __Pyx_Buffer __pyx_pybuffer_v;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  long __pyx_t_11;
-  unsigned int __pyx_t_12;
-  long __pyx_t_13;
-  unsigned int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  unsigned int __pyx_t_16;
-  unsigned int __pyx_t_17;
-  unsigned int __pyx_t_18;
-  unsigned int __pyx_t_19;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("d_tdb_tt", 0);
-  __pyx_pybuffer_out.pybuffer.buf = NULL;
-  __pyx_pybuffer_out.refcount = 0;
-  __pyx_pybuffernd_out.data = NULL;
-  __pyx_pybuffernd_out.rcbuffer = &__pyx_pybuffer_out;
-  __pyx_pybuffer_in1.pybuffer.buf = NULL;
-  __pyx_pybuffer_in1.refcount = 0;
-  __pyx_pybuffernd_in1.data = NULL;
-  __pyx_pybuffernd_in1.rcbuffer = &__pyx_pybuffer_in1;
-  __pyx_pybuffer_in2.pybuffer.buf = NULL;
-  __pyx_pybuffer_in2.refcount = 0;
-  __pyx_pybuffernd_in2.data = NULL;
-  __pyx_pybuffernd_in2.rcbuffer = &__pyx_pybuffer_in2;
-  __pyx_pybuffer_ut.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut.refcount = 0;
-  __pyx_pybuffernd_ut.data = NULL;
-  __pyx_pybuffernd_ut.rcbuffer = &__pyx_pybuffer_ut;
-  __pyx_pybuffer_elong.pybuffer.buf = NULL;
-  __pyx_pybuffer_elong.refcount = 0;
-  __pyx_pybuffernd_elong.data = NULL;
-  __pyx_pybuffernd_elong.rcbuffer = &__pyx_pybuffer_elong;
-  __pyx_pybuffer_u.pybuffer.buf = NULL;
-  __pyx_pybuffer_u.refcount = 0;
-  __pyx_pybuffernd_u.data = NULL;
-  __pyx_pybuffernd_u.rcbuffer = &__pyx_pybuffer_u;
-  __pyx_pybuffer_v.pybuffer.buf = NULL;
-  __pyx_pybuffer_v.refcount = 0;
-  __pyx_pybuffernd_v.data = NULL;
-  __pyx_pybuffernd_v.rcbuffer = &__pyx_pybuffer_v;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in1.rcbuffer->pybuffer, (PyObject*)__pyx_v_in1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in1.diminfo[0].strides = __pyx_pybuffernd_in1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in1.diminfo[0].shape = __pyx_pybuffernd_in1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_in2.rcbuffer->pybuffer, (PyObject*)__pyx_v_in2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_in2.diminfo[0].strides = __pyx_pybuffernd_in2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_in2.diminfo[0].shape = __pyx_pybuffernd_in2.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut.diminfo[0].strides = __pyx_pybuffernd_ut.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut.diminfo[0].shape = __pyx_pybuffernd_ut.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_elong.rcbuffer->pybuffer, (PyObject*)__pyx_v_elong, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_elong.diminfo[0].strides = __pyx_pybuffernd_elong.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_elong.diminfo[0].shape = __pyx_pybuffernd_elong.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_u.rcbuffer->pybuffer, (PyObject*)__pyx_v_u, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_u.diminfo[0].strides = __pyx_pybuffernd_u.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_u.diminfo[0].shape = __pyx_pybuffernd_u.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_v.rcbuffer->pybuffer, (PyObject*)__pyx_v_v, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_v.diminfo[0].strides = __pyx_pybuffernd_v.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_v.diminfo[0].shape = __pyx_pybuffernd_v.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1233
- *     **     TCB and hence between TT and TDB.
- *     """
- *     assert in1.shape[0] == in2.shape[0] == ut.shape[0]             # <<<<<<<<<<<<<<
- *     assert elong.shape[0] == u.shape[0] == v.shape[0]
- *     assert elong.shape[0] == 1 or elong.shape[0] == in1.shape[0]
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_in1->dimensions[0]) == (__pyx_v_in2->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_in2->dimensions[0]) == (__pyx_v_ut->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1234
- *     """
- *     assert in1.shape[0] == in2.shape[0] == ut.shape[0]
- *     assert elong.shape[0] == u.shape[0] == v.shape[0]             # <<<<<<<<<<<<<<
- *     assert elong.shape[0] == 1 or elong.shape[0] == in1.shape[0]
- *     cdef unsigned n = in1.shape[0]
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_elong->dimensions[0]) == (__pyx_v_u->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_u->dimensions[0]) == (__pyx_v_v->dimensions[0]));
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1235
- *     assert in1.shape[0] == in2.shape[0] == ut.shape[0]
- *     assert elong.shape[0] == u.shape[0] == v.shape[0]
- *     assert elong.shape[0] == 1 or elong.shape[0] == in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i, j
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_2 = (((__pyx_v_elong->dimensions[0]) == 1) != 0);
-    if (!__pyx_t_2) {
-    } else {
-      __pyx_t_1 = __pyx_t_2;
-      goto __pyx_L3_bool_binop_done;
-    }
-    __pyx_t_2 = (((__pyx_v_elong->dimensions[0]) == (__pyx_v_in1->dimensions[0])) != 0);
-    __pyx_t_1 = __pyx_t_2;
-    __pyx_L3_bool_binop_done:;
-    if (unlikely(!__pyx_t_1)) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1236
- *     assert elong.shape[0] == u.shape[0] == v.shape[0]
- *     assert elong.shape[0] == 1 or elong.shape[0] == in1.shape[0]
- *     cdef unsigned n = in1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i, j
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_in1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1238
- *     cdef unsigned n = in1.shape[0]
- *     cdef unsigned int i, j
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_3 = 0;
-  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_double); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_7);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_out = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out.diminfo[0].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out.diminfo[0].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_out = ((PyArrayObject *)__pyx_t_7);
-  __pyx_t_7 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1240
- *     cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         j = min(i, elong.shape[0]-1)
- *         out[i] = eraDtdb(in1[i], in2[i], ut[i], elong[j], u[j], v[j])
- */
-  __pyx_t_9 = __pyx_v_n;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":1241
- * 
- *     for i in range(n):
- *         j = min(i, elong.shape[0]-1)             # <<<<<<<<<<<<<<
- *         out[i] = eraDtdb(in1[i], in2[i], ut[i], elong[j], u[j], v[j])
- *     return out
- */
-    __pyx_t_11 = ((__pyx_v_elong->dimensions[0]) - 1);
-    __pyx_t_12 = __pyx_v_i;
-    if (((__pyx_t_11 < __pyx_t_12) != 0)) {
-      __pyx_t_13 = __pyx_t_11;
-    } else {
-      __pyx_t_13 = __pyx_t_12;
-    }
-    __pyx_v_j = __pyx_t_13;
-
-    /* "astropy/time/erfa_time.pyx":1242
- *     for i in range(n):
- *         j = min(i, elong.shape[0]-1)
- *         out[i] = eraDtdb(in1[i], in2[i], ut[i], elong[j], u[j], v[j])             # <<<<<<<<<<<<<<
- *     return out
- * 
- */
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_t_16 = __pyx_v_j;
-    __pyx_t_17 = __pyx_v_j;
-    __pyx_t_18 = __pyx_v_j;
-    __pyx_t_19 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_out.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_out.diminfo[0].strides) = eraDtdb((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in1.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_in1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_in2.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_in2.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut.rcbuffer->pybuffer.buf, _ [...]
-  }
-
-  /* "astropy/time/erfa_time.pyx":1243
- *         j = min(i, elong.shape[0]-1)
- *         out[i] = eraDtdb(in1[i], in2[i], ut[i], elong[j], u[j], v[j])
- *     return out             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out));
-  __pyx_r = ((PyObject *)__pyx_v_out);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1125
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tdb_tt(np.ndarray[double, ndim=1] in1,             # <<<<<<<<<<<<<<
- *              np.ndarray[double, ndim=1] in2,
- *              np.ndarray[double, ndim=1] ut,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elong.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_u.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_v.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.d_tdb_tt", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elong.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_in2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_u.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_v.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_out);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1246
- * 
- * 
- * def era_af2a(sign, ideg, iamin, asec):             # <<<<<<<<<<<<<<
- *     """
- *     int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_45era_af2a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_44era_af2a[] = "\n    int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)\n\n    **  Given:\n    **     s         char    sign:  '-' = negative, otherwise positive\n    **     ideg      int     degrees\n    **     iamin     int     arcminutes\n    **     asec      double  arcseconds\n    **\n    **  Returned:\n    **     rad       double  angle in radians\n    **\n    **  Returned (function value):\n    **               int   [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_45era_af2a = {"era_af2a", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_45era_af2a, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_44era_af2a};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_45era_af2a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_sign = 0;
-  PyObject *__pyx_v_ideg = 0;
-  PyObject *__pyx_v_iamin = 0;
-  PyObject *__pyx_v_asec = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("era_af2a (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sign,&__pyx_n_s_ideg,&__pyx_n_s_iamin,&__pyx_n_s_asec,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sign)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ideg)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_af2a", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_iamin)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_af2a", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_asec)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_af2a", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "era_af2a") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_sign = values[0];
-    __pyx_v_ideg = values[1];
-    __pyx_v_iamin = values[2];
-    __pyx_v_asec = values[3];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("era_af2a", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_af2a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_44era_af2a(__pyx_self, __pyx_v_sign, __pyx_v_ideg, __pyx_v_iamin, __pyx_v_asec);
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_44era_af2a(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sign, PyObject *__pyx_v_ideg, PyObject *__pyx_v_iamin, PyObject *__pyx_v_asec) {
-  double __pyx_v_rad;
-  PyObject *__pyx_v_s = NULL;
-  PyObject *__pyx_v_warns = NULL;
-  int __pyx_v_ret;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  char __pyx_t_3;
-  int __pyx_t_4;
-  int __pyx_t_5;
-  double __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
-  Py_ssize_t __pyx_t_9;
-  PyObject *__pyx_t_10 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("era_af2a", 0);
-
-  /* "astropy/time/erfa_time.pyx":1276
- *     """
- *     cdef double rad
- *     s = ord(sign)             # <<<<<<<<<<<<<<
- * 
- *     warns = {1: 'ideg outside range 0-359',
- */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_v_sign);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_sign);
-  __Pyx_GIVEREF(__pyx_v_sign);
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_v_s = __pyx_t_2;
-  __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1278
- *     s = ord(sign)
- * 
- *     warns = {1: 'ideg outside range 0-359',             # <<<<<<<<<<<<<<
- *              2: 'iamin outside range 0-59',
- *              3: 'asec outside range 0-59.999...'}
- */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_2, __pyx_int_1, __pyx_kp_s_ideg_outside_range_0_359) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_2, __pyx_int_2, __pyx_kp_s_iamin_outside_range_0_59) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_2, __pyx_int_3, __pyx_kp_s_asec_outside_range_0_59_999) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_warns = ((PyObject*)__pyx_t_2);
-  __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1282
- *              3: 'asec outside range 0-59.999...'}
- * 
- *     ret = eraAf2a(s, ideg, iamin, asec, &rad)             # <<<<<<<<<<<<<<
- *     check_return(ret, 'eraAf2a', warns)
- * 
- */
-  __pyx_t_3 = __Pyx_PyInt_As_char(__pyx_v_s); if (unlikely((__pyx_t_3 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_v_ideg); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_v_iamin); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_v_asec); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_ret = eraAf2a(__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, (&__pyx_v_rad));
-
-  /* "astropy/time/erfa_time.pyx":1283
- * 
- *     ret = eraAf2a(s, ideg, iamin, asec, &rad)
- *     check_return(ret, 'eraAf2a', warns)             # <<<<<<<<<<<<<<
- * 
- *     return rad
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = NULL;
-  __pyx_t_9 = 0;
-  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
-    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
-    if (likely(__pyx_t_8)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
-      __Pyx_INCREF(__pyx_t_8);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_1, function);
-      __pyx_t_9 = 1;
-    }
-  }
-  __pyx_t_10 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_10);
-  if (__pyx_t_8) {
-    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
-  }
-  PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_7);
-  __Pyx_INCREF(__pyx_n_s_eraAf2a);
-  PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_n_s_eraAf2a);
-  __Pyx_GIVEREF(__pyx_n_s_eraAf2a);
-  __Pyx_INCREF(__pyx_v_warns);
-  PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_v_warns);
-  __Pyx_GIVEREF(__pyx_v_warns);
-  __pyx_t_7 = 0;
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1285
- *     check_return(ret, 'eraAf2a', warns)
- * 
- *     return rad             # <<<<<<<<<<<<<<
- * 
- * def era_gd2gc(n, elong, phi, height):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_rad); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_r = __pyx_t_2;
-  __pyx_t_2 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1246
- * 
- * 
- * def era_af2a(sign, ideg, iamin, asec):             # <<<<<<<<<<<<<<
- *     """
- *     int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_XDECREF(__pyx_t_10);
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_af2a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_s);
-  __Pyx_XDECREF(__pyx_v_warns);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1287
- *     return rad
- * 
- * def era_gd2gc(n, elong, phi, height):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_47era_gd2gc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_46era_gd2gc[] = "\n    Wrap\n    int eraGd2gc(int n, double elong, double phi, double height, double xyz[3])\n\n    **  Given:\n    **     n       int        ellipsoid identifier (Note 1)\n    **     elong   double     longitude (radians, east +ve)\n    **     phi     double     latitude (geodetic, radians, Note 3)\n    **     height  double     height above ellipsoid (geodetic, Notes 2,3)\n    **\n    **  Returned:\n    **     xyz     doub [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_47era_gd2gc = {"era_gd2gc", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_47era_gd2gc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_46era_gd2gc};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_47era_gd2gc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_n = 0;
-  PyObject *__pyx_v_elong = 0;
-  PyObject *__pyx_v_phi = 0;
-  PyObject *__pyx_v_height = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("era_gd2gc (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_n,&__pyx_n_s_elong,&__pyx_n_s_phi,&__pyx_n_s_height,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_elong)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_gd2gc", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_phi)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_gd2gc", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_height)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_gd2gc", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "era_gd2gc") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_n = values[0];
-    __pyx_v_elong = values[1];
-    __pyx_v_phi = values[2];
-    __pyx_v_height = values[3];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("era_gd2gc", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_gd2gc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_46era_gd2gc(__pyx_self, __pyx_v_n, __pyx_v_elong, __pyx_v_phi, __pyx_v_height);
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_46era_gd2gc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_n, PyObject *__pyx_v_elong, PyObject *__pyx_v_phi, PyObject *__pyx_v_height) {
-  unsigned int __pyx_v_i;
-  unsigned int __pyx_v_nitems;
-  PyArrayObject *__pyx_v_xyz = 0;
-  PyArrayObject *__pyx_v_out = 0;
-  PyObject *__pyx_v_errs = NULL;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_out;
-  __Pyx_Buffer __pyx_pybuffer_out;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_xyz;
-  __Pyx_Buffer __pyx_pybuffer_xyz;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  unsigned int __pyx_t_7;
-  PyArrayObject *__pyx_t_8 = NULL;
-  PyArrayObject *__pyx_t_9 = NULL;
-  unsigned int __pyx_t_10;
-  int __pyx_t_11;
-  double __pyx_t_12;
-  double __pyx_t_13;
-  double __pyx_t_14;
-  long __pyx_t_15;
-  int __pyx_t_16;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("era_gd2gc", 0);
-  __pyx_pybuffer_xyz.pybuffer.buf = NULL;
-  __pyx_pybuffer_xyz.refcount = 0;
-  __pyx_pybuffernd_xyz.data = NULL;
-  __pyx_pybuffernd_xyz.rcbuffer = &__pyx_pybuffer_xyz;
-  __pyx_pybuffer_out.pybuffer.buf = NULL;
-  __pyx_pybuffer_out.refcount = 0;
-  __pyx_pybuffernd_out.data = NULL;
-  __pyx_pybuffernd_out.rcbuffer = &__pyx_pybuffer_out;
-
-  /* "astropy/time/erfa_time.pyx":1331
- *     **  4) The inverse transformation is performed in the function eraGc2gd.
- *     """
- *     assert elong.shape[0] == phi.shape[0] == height.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef unsigned int nitems = elong.shape[0]
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_elong, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_phi, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
-      __Pyx_DECREF(__pyx_t_1);
-      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_height, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-      __Pyx_GOTREF(__pyx_t_5);
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    }
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (unlikely(!__pyx_t_6)) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1333
- *     assert elong.shape[0] == phi.shape[0] == height.shape[0]
- *     cdef unsigned int i
- *     cdef unsigned int nitems = elong.shape[0]             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] xyz = np.empty(3, dtype=np.double)
- *     cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)
- */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_elong, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_7 = __Pyx_PyInt_As_unsigned_int(__pyx_t_3); if (unlikely((__pyx_t_7 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_v_nitems = __pyx_t_7;
-
-  /* "astropy/time/erfa_time.pyx":1334
- *     cdef unsigned int i
- *     cdef unsigned int nitems = elong.shape[0]
- *     cdef np.ndarray[double, ndim=1] xyz = np.empty(3, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)
- * 
- */
-  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_xyz.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_xyz = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_xyz.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_xyz.diminfo[0].strides = __pyx_pybuffernd_xyz.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_xyz.diminfo[0].shape = __pyx_pybuffernd_xyz.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_xyz = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1335
- *     cdef unsigned int nitems = elong.shape[0]
- *     cdef np.ndarray[double, ndim=1] xyz = np.empty(3, dtype=np.double)
- *     cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     errs = {-1: 'illegal identifier',
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_nitems); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __Pyx_INCREF(__pyx_int_3);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_3);
-  __Pyx_GIVEREF(__pyx_int_3);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_9 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {
-      __pyx_v_out = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_out.diminfo[0].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out.diminfo[0].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_out.diminfo[1].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_out.diminfo[1].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[1];
-    }
-  }
-  __pyx_t_9 = 0;
-  __pyx_v_out = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1337
- *     cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)
- * 
- *     errs = {-1: 'illegal identifier',             # <<<<<<<<<<<<<<
- *              -2: 'illegal case'}
- * 
- */
-  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1337; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_neg_1, __pyx_kp_s_illegal_identifier) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1337; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_4, __pyx_int_neg_2, __pyx_kp_s_illegal_case) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1337; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1340
- *              -2: 'illegal case'}
- * 
- *     for i in range(nitems):             # <<<<<<<<<<<<<<
- *         ret = eraGd2gc(n, elong[i], phi[i], height[i], &xyz[0])
- *         check_return(ret, 'eraGd2gc', errors=errs)
- */
-  __pyx_t_7 = __pyx_v_nitems;
-  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_7; __pyx_t_10+=1) {
-    __pyx_v_i = __pyx_t_10;
-
-    /* "astropy/time/erfa_time.pyx":1341
- * 
- *     for i in range(nitems):
- *         ret = eraGd2gc(n, elong[i], phi[i], height[i], &xyz[0])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraGd2gc', errors=errs)
- *         out[i] = xyz
- */
-    __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_n); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_elong, __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_12 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_12 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_phi, __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_13 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_height, __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_14 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_15 = 0;
-    __pyx_t_16 = -1;
-    if (__pyx_t_15 < 0) {
-      __pyx_t_15 += __pyx_pybuffernd_xyz.diminfo[0].shape;
-      if (unlikely(__pyx_t_15 < 0)) __pyx_t_16 = 0;
-    } else if (unlikely(__pyx_t_15 >= __pyx_pybuffernd_xyz.diminfo[0].shape)) __pyx_t_16 = 0;
-    if (unlikely(__pyx_t_16 != -1)) {
-      __Pyx_RaiseBufferIndexError(__pyx_t_16);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-    __pyx_v_ret = eraGd2gc(__pyx_t_11, __pyx_t_12, __pyx_t_13, __pyx_t_14, (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_xyz.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_xyz.diminfo[0].strides))));
-
-    /* "astropy/time/erfa_time.pyx":1342
- *     for i in range(nitems):
- *         ret = eraGd2gc(n, elong[i], phi[i], height[i], &xyz[0])
- *         check_return(ret, 'eraGd2gc', errors=errs)             # <<<<<<<<<<<<<<
- *         out[i] = xyz
- * 
- */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
-    __Pyx_GIVEREF(__pyx_t_1);
-    __Pyx_INCREF(__pyx_n_s_eraGd2gc);
-    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_n_s_eraGd2gc);
-    __Pyx_GIVEREF(__pyx_n_s_eraGd2gc);
-    __pyx_t_1 = 0;
-    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_errors, __pyx_v_errs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-
-    /* "astropy/time/erfa_time.pyx":1343
- *         ret = eraGd2gc(n, elong[i], phi[i], height[i], &xyz[0])
- *         check_return(ret, 'eraGd2gc', errors=errs)
- *         out[i] = xyz             # <<<<<<<<<<<<<<
- * 
- *     return out
- */
-    if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_out), __pyx_v_i, ((PyObject *)__pyx_v_xyz), unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-
-  /* "astropy/time/erfa_time.pyx":1345
- *         out[i] = xyz
- * 
- *     return out             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_out));
-  __pyx_r = ((PyObject *)__pyx_v_out);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1287
- *     return rad
- * 
- * def era_gd2gc(n, elong, phi, height):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_xyz.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_gd2gc", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_xyz.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_xyz);
-  __Pyx_XDECREF((PyObject *)__pyx_v_out);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1349
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def era_gc2gd(n, xyz):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_49era_gc2gd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_48era_gc2gd[] = "\n    Wrap\n    int eraGc2gd(int n, double xyz[3], double *elong, double *phi, double *height )\n\n    **  Given:\n    **     n       int        ellipsoid identifier (Note 1)\n    **     xyz     double[3]  geocentric vector (Note 2)\n    **\n    **  Returned:\n    **     elong   double     longitude (radians, east +ve)\n    **     phi     double     latitude (geodetic, radians, Note 3)\n    **     height  double     height  [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_49era_gc2gd = {"era_gc2gd", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_49era_gc2gd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_48era_gc2gd};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_49era_gc2gd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_n = 0;
-  PyObject *__pyx_v_xyz = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("era_gc2gd (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_n,&__pyx_n_s_xyz,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_xyz)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("era_gc2gd", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "era_gc2gd") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_n = values[0];
-    __pyx_v_xyz = values[1];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("era_gc2gd", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_gc2gd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_48era_gc2gd(__pyx_self, __pyx_v_n, __pyx_v_xyz);
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_48era_gc2gd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_n, PyObject *__pyx_v_xyz) {
-  unsigned int __pyx_v_i;
-  unsigned int __pyx_v_nitems;
-  PyArrayObject *__pyx_v_elong = 0;
-  PyArrayObject *__pyx_v_phi = 0;
-  PyArrayObject *__pyx_v_height = 0;
-  double __pyx_v_xyz_item[3];
-  PyObject *__pyx_v_errs = NULL;
-  long __pyx_v_j;
-  int __pyx_v_ret;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_elong;
-  __Pyx_Buffer __pyx_pybuffer_elong;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_height;
-  __Pyx_Buffer __pyx_pybuffer_height;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_phi;
-  __Pyx_Buffer __pyx_pybuffer_phi;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  int __pyx_t_3;
-  unsigned int __pyx_t_4;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  PyArrayObject *__pyx_t_8 = NULL;
-  PyArrayObject *__pyx_t_9 = NULL;
-  PyArrayObject *__pyx_t_10 = NULL;
-  unsigned int __pyx_t_11;
-  long __pyx_t_12;
-  double __pyx_t_13;
-  int __pyx_t_14;
-  unsigned int __pyx_t_15;
-  unsigned int __pyx_t_16;
-  unsigned int __pyx_t_17;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("era_gc2gd", 0);
-  __pyx_pybuffer_elong.pybuffer.buf = NULL;
-  __pyx_pybuffer_elong.refcount = 0;
-  __pyx_pybuffernd_elong.data = NULL;
-  __pyx_pybuffernd_elong.rcbuffer = &__pyx_pybuffer_elong;
-  __pyx_pybuffer_phi.pybuffer.buf = NULL;
-  __pyx_pybuffer_phi.refcount = 0;
-  __pyx_pybuffernd_phi.data = NULL;
-  __pyx_pybuffernd_phi.rcbuffer = &__pyx_pybuffer_phi;
-  __pyx_pybuffer_height.pybuffer.buf = NULL;
-  __pyx_pybuffer_height.refcount = 0;
-  __pyx_pybuffernd_height.data = NULL;
-  __pyx_pybuffernd_height.rcbuffer = &__pyx_pybuffer_height;
-
-  /* "astropy/time/erfa_time.pyx":1398
- *     **  Derived, with permission, from the SOFA library.  See notes at end of file.
- *     """
- *     assert xyz.shape[1] == 3             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef unsigned int nitems = xyz.shape[0]
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_xyz, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1398; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (unlikely(!__pyx_t_3)) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1400
- *     assert xyz.shape[1] == 3
- *     cdef unsigned int i
- *     cdef unsigned int nitems = xyz.shape[0]             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] elong = np.empty(nitems, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] phi = np.empty(nitems, dtype=np.double)
- */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_xyz, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1400; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_4 = __Pyx_PyInt_As_unsigned_int(__pyx_t_2); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_nitems = __pyx_t_4;
-
-  /* "astropy/time/erfa_time.pyx":1401
- *     cdef unsigned int i
- *     cdef unsigned int nitems = xyz.shape[0]
- *     cdef np.ndarray[double, ndim=1] elong = np.empty(nitems, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] phi = np.empty(nitems, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] height = np.empty(nitems, dtype=np.double)
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_nitems); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_double); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = ((PyArrayObject *)__pyx_t_7);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_elong.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_elong = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_elong.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_elong.diminfo[0].strides = __pyx_pybuffernd_elong.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_elong.diminfo[0].shape = __pyx_pybuffernd_elong.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_8 = 0;
-  __pyx_v_elong = ((PyArrayObject *)__pyx_t_7);
-  __pyx_t_7 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1402
- *     cdef unsigned int nitems = xyz.shape[0]
- *     cdef np.ndarray[double, ndim=1] elong = np.empty(nitems, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] phi = np.empty(nitems, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] height = np.empty(nitems, dtype=np.double)
- *     cdef double xyz_item[3]
- */
-  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = __Pyx_PyInt_From_unsigned_int(__pyx_v_nitems); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_7);
-  __pyx_t_7 = 0;
-  __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_9 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_phi.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_phi = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_phi.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_phi.diminfo[0].strides = __pyx_pybuffernd_phi.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_phi.diminfo[0].shape = __pyx_pybuffernd_phi.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_9 = 0;
-  __pyx_v_phi = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1403
- *     cdef np.ndarray[double, ndim=1] elong = np.empty(nitems, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] phi = np.empty(nitems, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] height = np.empty(nitems, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef double xyz_item[3]
- * 
- */
-  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_nitems); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
-  __Pyx_GIVEREF(__pyx_t_6);
-  __pyx_t_6 = 0;
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_height.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_height = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_height.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_height.diminfo[0].strides = __pyx_pybuffernd_height.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_height.diminfo[0].shape = __pyx_pybuffernd_height.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_10 = 0;
-  __pyx_v_height = ((PyArrayObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1406
- *     cdef double xyz_item[3]
- * 
- *     errs = {-1: 'illegal identifier',             # <<<<<<<<<<<<<<
- *             -2: 'illegal case'}
- *     for i in range(nitems):
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_1, __pyx_kp_s_illegal_identifier) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_1, __pyx_int_neg_2, __pyx_kp_s_illegal_case) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_errs = ((PyObject*)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1408
- *     errs = {-1: 'illegal identifier',
- *             -2: 'illegal case'}
- *     for i in range(nitems):             # <<<<<<<<<<<<<<
- *         # ensure xyz are in a contiguous array
- *         for j in range(3):
- */
-  __pyx_t_4 = __pyx_v_nitems;
-  for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_4; __pyx_t_11+=1) {
-    __pyx_v_i = __pyx_t_11;
-
-    /* "astropy/time/erfa_time.pyx":1410
- *     for i in range(nitems):
- *         # ensure xyz are in a contiguous array
- *         for j in range(3):             # <<<<<<<<<<<<<<
- *             xyz_item[j] = xyz[i, j]
- *         ret = eraGc2gd(n, xyz_item, &elong[i], &phi[i], &height[i])
- */
-    for (__pyx_t_12 = 0; __pyx_t_12 < 3; __pyx_t_12+=1) {
-      __pyx_v_j = __pyx_t_12;
-
-      /* "astropy/time/erfa_time.pyx":1411
- *         # ensure xyz are in a contiguous array
- *         for j in range(3):
- *             xyz_item[j] = xyz[i, j]             # <<<<<<<<<<<<<<
- *         ret = eraGc2gd(n, xyz_item, &elong[i], &phi[i], &height[i])
- *         check_return(ret, 'eraGd2gc', errors=errs)
- */
-      __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_v_j); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
-      __Pyx_GIVEREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6);
-      __Pyx_GIVEREF(__pyx_t_6);
-      __pyx_t_1 = 0;
-      __pyx_t_6 = 0;
-      __pyx_t_6 = PyObject_GetItem(__pyx_v_xyz, __pyx_t_5); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-      __Pyx_GOTREF(__pyx_t_6);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_6); if (unlikely((__pyx_t_13 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      (__pyx_v_xyz_item[__pyx_v_j]) = __pyx_t_13;
-    }
-
-    /* "astropy/time/erfa_time.pyx":1412
- *         for j in range(3):
- *             xyz_item[j] = xyz[i, j]
- *         ret = eraGc2gd(n, xyz_item, &elong[i], &phi[i], &height[i])             # <<<<<<<<<<<<<<
- *         check_return(ret, 'eraGd2gc', errors=errs)
- * 
- */
-    __pyx_t_14 = __Pyx_PyInt_As_int(__pyx_v_n); if (unlikely((__pyx_t_14 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_15 = __pyx_v_i;
-    __pyx_t_16 = __pyx_v_i;
-    __pyx_t_17 = __pyx_v_i;
-    __pyx_v_ret = eraGc2gd(__pyx_t_14, __pyx_v_xyz_item, (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_elong.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_elong.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_phi.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_phi.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_height.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_height.diminfo[0].strides))));
-
-    /* "astropy/time/erfa_time.pyx":1413
- *             xyz_item[j] = xyz[i, j]
- *         ret = eraGc2gd(n, xyz_item, &elong[i], &phi[i], &height[i])
- *         check_return(ret, 'eraGd2gc', errors=errs)             # <<<<<<<<<<<<<<
- * 
- *     return elong, phi, height
- */
-    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_check_return); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_ret); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
-    __Pyx_GIVEREF(__pyx_t_5);
-    __Pyx_INCREF(__pyx_n_s_eraGd2gc);
-    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_eraGd2gc);
-    __Pyx_GIVEREF(__pyx_n_s_eraGd2gc);
-    __pyx_t_5 = 0;
-    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_errors, __pyx_v_errs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  }
-
-  /* "astropy/time/erfa_time.pyx":1415
- *         check_return(ret, 'eraGd2gc', errors=errs)
- * 
- *     return elong, phi, height             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_INCREF(((PyObject *)__pyx_v_elong));
-  PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_v_elong));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_elong));
-  __Pyx_INCREF(((PyObject *)__pyx_v_phi));
-  PyTuple_SET_ITEM(__pyx_t_7, 1, ((PyObject *)__pyx_v_phi));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_phi));
-  __Pyx_INCREF(((PyObject *)__pyx_v_height));
-  PyTuple_SET_ITEM(__pyx_t_7, 2, ((PyObject *)__pyx_v_height));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_height));
-  __pyx_r = __pyx_t_7;
-  __pyx_t_7 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1349
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def era_gc2gd(n, xyz):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elong.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_height.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_phi.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.era_gc2gd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elong.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_height.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_phi.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_elong);
-  __Pyx_XDECREF((PyObject *)__pyx_v_phi);
-  __Pyx_XDECREF((PyObject *)__pyx_v_height);
-  __Pyx_XDECREF(__pyx_v_errs);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1419
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_julian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                     np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpj(double dj1, double dj2)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_51jd_julian_epoch(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_50jd_julian_epoch[] = " Wrap double eraEpj(double dj1, double dj2)\n    **  Julian Date to Julian Epoch.\n\n    **  Given:\n    **     dj1,dj2    double     Julian Date (see note)\n    **\n    **  Returned (function value):\n    **                double     Julian Epoch\n    **\n    **  Note:\n    **\n    **     The Julian Date is supplied in two pieces, in the usual ERFA\n    **     manner, which is designed to preserve time resolution.  T [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_51jd_julian_epoch = {"jd_julian_epoch", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_51jd_julian_epoch, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_50jd_julian_epoch};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_51jd_julian_epoch(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_jd1 = 0;
-  PyArrayObject *__pyx_v_jd2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("jd_julian_epoch (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_jd1,&__pyx_n_s_jd2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_jd1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_jd2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("jd_julian_epoch", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "jd_julian_epoch") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_jd1 = ((PyArrayObject *)values[0]);
-    __pyx_v_jd2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("jd_julian_epoch", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_julian_epoch", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_jd1), __pyx_ptype_5numpy_ndarray, 1, "jd1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_jd2), __pyx_ptype_5numpy_ndarray, 1, "jd2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_50jd_julian_epoch(__pyx_self, __pyx_v_jd1, __pyx_v_jd2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_50jd_julian_epoch(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_jd1, PyArrayObject *__pyx_v_jd2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_epd = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_epd;
-  __Pyx_Buffer __pyx_pybuffer_epd;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd1;
-  __Pyx_Buffer __pyx_pybuffer_jd1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd2;
-  __Pyx_Buffer __pyx_pybuffer_jd2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("jd_julian_epoch", 0);
-  __pyx_pybuffer_epd.pybuffer.buf = NULL;
-  __pyx_pybuffer_epd.refcount = 0;
-  __pyx_pybuffernd_epd.data = NULL;
-  __pyx_pybuffernd_epd.rcbuffer = &__pyx_pybuffer_epd;
-  __pyx_pybuffer_jd1.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd1.refcount = 0;
-  __pyx_pybuffernd_jd1.data = NULL;
-  __pyx_pybuffernd_jd1.rcbuffer = &__pyx_pybuffer_jd1;
-  __pyx_pybuffer_jd2.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd2.refcount = 0;
-  __pyx_pybuffernd_jd2.data = NULL;
-  __pyx_pybuffernd_jd2.rcbuffer = &__pyx_pybuffer_jd2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer, (PyObject*)__pyx_v_jd1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_jd1.diminfo[0].strides = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd1.diminfo[0].shape = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer, (PyObject*)__pyx_v_jd2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_jd2.diminfo[0].strides = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd2.diminfo[0].shape = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1438
- *     **     (J2000.0).
- *     """
- *     assert jd1.shape[0] == jd2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = jd1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_jd1->dimensions[0]) == (__pyx_v_jd2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1439
- *     """
- *     assert jd1.shape[0] == jd2.shape[0]
- *     cdef unsigned n = jd1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_jd1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1441
- *     cdef unsigned n = jd1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_epd.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_epd = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_epd.diminfo[0].strides = __pyx_pybuffernd_epd.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_epd.diminfo[0].shape = __pyx_pybuffernd_epd.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_epd = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1443
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         epd[i] = eraEpj(jd1[i], jd2[i])
- *     return epd
- */
-  __pyx_t_7 = __pyx_v_n;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
-
-    /* "astropy/time/erfa_time.pyx":1444
- * 
- *     for i in range(n):
- *         epd[i] = eraEpj(jd1[i], jd2[i])             # <<<<<<<<<<<<<<
- *     return epd
- * 
- */
-    __pyx_t_9 = __pyx_v_i;
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_epd.diminfo[0].strides) = eraEpj((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_jd1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_jd2.diminfo[0].strides)));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1445
- *     for i in range(n):
- *         epd[i] = eraEpj(jd1[i], jd2[i])
- *     return epd             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_epd));
-  __pyx_r = ((PyObject *)__pyx_v_epd);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1419
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_julian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                     np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpj(double dj1, double dj2)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_julian_epoch", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_epd);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1450
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def julian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpj2jd(double epj, double *djm0, double *djm)
- *     **  Julian Epoch to Julian Date.
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_53julian_epoch_jd(PyObject *__pyx_self, PyObject *__pyx_v_epd); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_52julian_epoch_jd[] = " Wrap void eraEpj2jd(double epj, double *djm0, double *djm)\n    **  Julian Epoch to Julian Date.\n    **  Given:\n    **     epj      double    Julian Epoch (e.g. 1996.8D0)\n    **\n    **  Returned:\n    **     djm0     double    MJD zero-point: always 2400000.5\n    **     djm      double    Modified Julian Date\n    ";
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_53julian_epoch_jd = {"julian_epoch_jd", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_53julian_epoch_jd, METH_O, __pyx_doc_7astropy_4time_9erfa_time_52julian_epoch_jd};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_53julian_epoch_jd(PyObject *__pyx_self, PyObject *__pyx_v_epd) {
-  CYTHON_UNUSED int __pyx_lineno = 0;
-  CYTHON_UNUSED const char *__pyx_filename = NULL;
-  CYTHON_UNUSED int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("julian_epoch_jd (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_epd), __pyx_ptype_5numpy_ndarray, 1, "epd", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_52julian_epoch_jd(__pyx_self, ((PyArrayObject *)__pyx_v_epd));
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_52julian_epoch_jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_epd) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_jd1 = 0;
-  PyArrayObject *__pyx_v_jd2 = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_epd;
-  __Pyx_Buffer __pyx_pybuffer_epd;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd1;
-  __Pyx_Buffer __pyx_pybuffer_jd1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd2;
-  __Pyx_Buffer __pyx_pybuffer_jd2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("julian_epoch_jd", 0);
-  __pyx_pybuffer_jd1.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd1.refcount = 0;
-  __pyx_pybuffernd_jd1.data = NULL;
-  __pyx_pybuffernd_jd1.rcbuffer = &__pyx_pybuffer_jd1;
-  __pyx_pybuffer_jd2.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd2.refcount = 0;
-  __pyx_pybuffernd_jd2.data = NULL;
-  __pyx_pybuffernd_jd2.rcbuffer = &__pyx_pybuffer_jd2;
-  __pyx_pybuffer_epd.pybuffer.buf = NULL;
-  __pyx_pybuffer_epd.refcount = 0;
-  __pyx_pybuffernd_epd.data = NULL;
-  __pyx_pybuffernd_epd.rcbuffer = &__pyx_pybuffer_epd;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_epd.rcbuffer->pybuffer, (PyObject*)__pyx_v_epd, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_epd.diminfo[0].strides = __pyx_pybuffernd_epd.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_epd.diminfo[0].shape = __pyx_pybuffernd_epd.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1460
- *     **     djm      double    Modified Julian Date
- *     """
- *     cdef unsigned n = epd.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_epd->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1462
- *     cdef unsigned n = epd.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_jd1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_jd1.diminfo[0].strides = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd1.diminfo[0].shape = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_jd1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1463
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_jd2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_jd2.diminfo[0].strides = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd2.diminfo[0].shape = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_jd2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1465
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         eraEpj2jd(epd[i], &jd1[i], &jd2[i])
- *     return jd1, jd2
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1466
- * 
- *     for i in range(n):
- *         eraEpj2jd(epd[i], &jd1[i], &jd2[i])             # <<<<<<<<<<<<<<
- *     return jd1, jd2
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    eraEpj2jd((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_epd.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_jd1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_jd2.diminfo[0].strides))));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1467
- *     for i in range(n):
- *         eraEpj2jd(epd[i], &jd1[i], &jd2[i])
- *     return jd1, jd2             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_jd1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_jd1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_jd1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_jd2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_jd2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_jd2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1450
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def julian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpj2jd(double epj, double *djm0, double *djm)
- *     **  Julian Epoch to Julian Date.
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.julian_epoch_jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_jd1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_jd2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1472
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_besselian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                        np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpb(double dj1, double dj2)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_55jd_besselian_epoch(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_54jd_besselian_epoch[] = " Wrap double eraEpb(double dj1, double dj2)\n    **  Julian Date to Besselian Epoch.\n\n    **  Given:\n    **     dj1,dj2    double     Julian Date (see note)\n    **\n    **  Returned (function value):\n    **                double     Besselian Epoch.\n    **\n    **  Note:\n    **\n    **     The Julian Date is supplied in two pieces, in the usual ERFA\n    **     manner, which is designed to preserve time reso [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_55jd_besselian_epoch = {"jd_besselian_epoch", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_55jd_besselian_epoch, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_54jd_besselian_epoch};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_55jd_besselian_epoch(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_jd1 = 0;
-  PyArrayObject *__pyx_v_jd2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("jd_besselian_epoch (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_jd1,&__pyx_n_s_jd2,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_jd1)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_jd2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("jd_besselian_epoch", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "jd_besselian_epoch") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_jd1 = ((PyArrayObject *)values[0]);
-    __pyx_v_jd2 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("jd_besselian_epoch", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_besselian_epoch", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_jd1), __pyx_ptype_5numpy_ndarray, 1, "jd1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_jd2), __pyx_ptype_5numpy_ndarray, 1, "jd2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_54jd_besselian_epoch(__pyx_self, __pyx_v_jd1, __pyx_v_jd2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_54jd_besselian_epoch(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_jd1, PyArrayObject *__pyx_v_jd2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_epd = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_epd;
-  __Pyx_Buffer __pyx_pybuffer_epd;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd1;
-  __Pyx_Buffer __pyx_pybuffer_jd1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd2;
-  __Pyx_Buffer __pyx_pybuffer_jd2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("jd_besselian_epoch", 0);
-  __pyx_pybuffer_epd.pybuffer.buf = NULL;
-  __pyx_pybuffer_epd.refcount = 0;
-  __pyx_pybuffernd_epd.data = NULL;
-  __pyx_pybuffernd_epd.rcbuffer = &__pyx_pybuffer_epd;
-  __pyx_pybuffer_jd1.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd1.refcount = 0;
-  __pyx_pybuffernd_jd1.data = NULL;
-  __pyx_pybuffernd_jd1.rcbuffer = &__pyx_pybuffer_jd1;
-  __pyx_pybuffer_jd2.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd2.refcount = 0;
-  __pyx_pybuffernd_jd2.data = NULL;
-  __pyx_pybuffernd_jd2.rcbuffer = &__pyx_pybuffer_jd2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer, (PyObject*)__pyx_v_jd1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_jd1.diminfo[0].strides = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd1.diminfo[0].shape = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer, (PyObject*)__pyx_v_jd2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_jd2.diminfo[0].strides = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd2.diminfo[0].shape = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1491
- *     **     (J2000.0).
- *     """
- *     assert jd1.shape[0] == jd2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = jd1.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_jd1->dimensions[0]) == (__pyx_v_jd2->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1492
- *     """
- *     assert jd1.shape[0] == jd2.shape[0]
- *     cdef unsigned n = jd1.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_jd1->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1494
- *     cdef unsigned n = jd1.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_epd.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_epd = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_epd.diminfo[0].strides = __pyx_pybuffernd_epd.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_epd.diminfo[0].shape = __pyx_pybuffernd_epd.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_epd = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1496
- *     cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         epd[i] = eraEpb(jd1[i], jd2[i])
- *     return epd
- */
-  __pyx_t_7 = __pyx_v_n;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
-
-    /* "astropy/time/erfa_time.pyx":1497
- * 
- *     for i in range(n):
- *         epd[i] = eraEpb(jd1[i], jd2[i])             # <<<<<<<<<<<<<<
- *     return epd
- * 
- */
-    __pyx_t_9 = __pyx_v_i;
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_epd.diminfo[0].strides) = eraEpb((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_jd1.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_jd2.diminfo[0].strides)));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1498
- *     for i in range(n):
- *         epd[i] = eraEpb(jd1[i], jd2[i])
- *     return epd             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_epd));
-  __pyx_r = ((PyObject *)__pyx_v_epd);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1472
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_besselian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                        np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpb(double dj1, double dj2)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.jd_besselian_epoch", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_epd);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1503
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def besselian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpb2jd(double epj, double *djm0, double *djm)
- *     **  Besselian Epoch to Julian Date.
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_57besselian_epoch_jd(PyObject *__pyx_self, PyObject *__pyx_v_epd); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_56besselian_epoch_jd[] = " Wrap void eraEpb2jd(double epj, double *djm0, double *djm)\n    **  Besselian Epoch to Julian Date.\n\n    **  Given:\n    **     epb      double    Besselian Epoch (e.g. 1957.3D0)\n    **\n    **  Returned:\n    **     djm0     double    MJD zero-point: always 2400000.5\n    **     djm      double    Modified Julian Date\n    **\n    **  Note:\n    **\n    **     The Julian Date is returned in two pieces, in the  [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_57besselian_epoch_jd = {"besselian_epoch_jd", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_57besselian_epoch_jd, METH_O, __pyx_doc_7astropy_4time_9erfa_time_56besselian_epoch_jd};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_57besselian_epoch_jd(PyObject *__pyx_self, PyObject *__pyx_v_epd) {
-  CYTHON_UNUSED int __pyx_lineno = 0;
-  CYTHON_UNUSED const char *__pyx_filename = NULL;
-  CYTHON_UNUSED int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("besselian_epoch_jd (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_epd), __pyx_ptype_5numpy_ndarray, 1, "epd", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_56besselian_epoch_jd(__pyx_self, ((PyArrayObject *)__pyx_v_epd));
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_56besselian_epoch_jd(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_epd) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_jd1 = 0;
-  PyArrayObject *__pyx_v_jd2 = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_epd;
-  __Pyx_Buffer __pyx_pybuffer_epd;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd1;
-  __Pyx_Buffer __pyx_pybuffer_jd1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_jd2;
-  __Pyx_Buffer __pyx_pybuffer_jd2;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("besselian_epoch_jd", 0);
-  __pyx_pybuffer_jd1.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd1.refcount = 0;
-  __pyx_pybuffernd_jd1.data = NULL;
-  __pyx_pybuffernd_jd1.rcbuffer = &__pyx_pybuffer_jd1;
-  __pyx_pybuffer_jd2.pybuffer.buf = NULL;
-  __pyx_pybuffer_jd2.refcount = 0;
-  __pyx_pybuffernd_jd2.data = NULL;
-  __pyx_pybuffernd_jd2.rcbuffer = &__pyx_pybuffer_jd2;
-  __pyx_pybuffer_epd.pybuffer.buf = NULL;
-  __pyx_pybuffer_epd.refcount = 0;
-  __pyx_pybuffernd_epd.data = NULL;
-  __pyx_pybuffernd_epd.rcbuffer = &__pyx_pybuffer_epd;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_epd.rcbuffer->pybuffer, (PyObject*)__pyx_v_epd, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_epd.diminfo[0].strides = __pyx_pybuffernd_epd.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_epd.diminfo[0].shape = __pyx_pybuffernd_epd.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1521
- *     **     djm.
- *     """
- *     cdef unsigned n = epd.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_epd->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1523
- *     cdef unsigned n = epd.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
- * 
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_jd1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_jd1.diminfo[0].strides = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd1.diminfo[0].shape = __pyx_pybuffernd_jd1.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_jd1 = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1524
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_4);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_jd2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_jd2.diminfo[0].strides = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_jd2.diminfo[0].shape = __pyx_pybuffernd_jd2.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_jd2 = ((PyArrayObject *)__pyx_t_4);
-  __pyx_t_4 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1526
- *     cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         eraEpb2jd(epd[i], &jd1[i], &jd2[i])
- *     return jd1, jd2
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1527
- * 
- *     for i in range(n):
- *         eraEpb2jd(epd[i], &jd1[i], &jd2[i])             # <<<<<<<<<<<<<<
- *     return jd1, jd2
- * 
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    eraEpb2jd((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_epd.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_epd.diminfo[0].strides)), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd1.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_jd1.diminfo[0].strides))), (&(*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_jd2.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_jd2.diminfo[0].strides))));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1528
- *     for i in range(n):
- *         eraEpb2jd(epd[i], &jd1[i], &jd2[i])
- *     return jd1, jd2             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_INCREF(((PyObject *)__pyx_v_jd1));
-  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_jd1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_jd1));
-  __Pyx_INCREF(((PyObject *)__pyx_v_jd2));
-  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_v_jd2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_jd2));
-  __pyx_r = __pyx_t_4;
-  __pyx_t_4 = 0;
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1503
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def besselian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpb2jd(double epj, double *djm0, double *djm)
- *     **  Besselian Epoch to Julian Date.
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.besselian_epoch_jd", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_epd.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_jd2.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_jd1);
-  __Pyx_XDECREF((PyObject *)__pyx_v_jd2);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1532
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst00(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_59gmst00(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_58gmst00[] = "Wrap double eraGmst00(double uta, double utb, double tta, double ttb)\n    **  Greenwich mean sidereal time (model consistent with IAU 2000\n    **  resolutions).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **     tta,ttb    double    TT as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich mean sidere [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_59gmst00 = {"gmst00", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_59gmst00, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_58gmst00};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_59gmst00(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  PyArrayObject *__pyx_v_tt1 = 0;
-  PyArrayObject *__pyx_v_tt2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gmst00 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,&__pyx_n_s_tt1,&__pyx_n_s_tt2,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst00", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt1)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst00", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst00", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gmst00") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-    __pyx_v_tt1 = ((PyArrayObject *)values[2]);
-    __pyx_v_tt2 = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gmst00", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst00", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt1), __pyx_ptype_5numpy_ndarray, 1, "tt1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt2), __pyx_ptype_5numpy_ndarray, 1, "tt2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_58gmst00(__pyx_self, __pyx_v_ut11, __pyx_v_ut12, __pyx_v_tt1, __pyx_v_tt2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_58gmst00(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gmst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gmst;
-  __Pyx_Buffer __pyx_pybuffer_gmst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt1;
-  __Pyx_Buffer __pyx_pybuffer_tt1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt2;
-  __Pyx_Buffer __pyx_pybuffer_tt2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gmst00", 0);
-  __pyx_pybuffer_gmst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gmst.refcount = 0;
-  __pyx_pybuffernd_gmst.data = NULL;
-  __pyx_pybuffernd_gmst.rcbuffer = &__pyx_pybuffer_gmst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  __pyx_pybuffer_tt1.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt1.refcount = 0;
-  __pyx_pybuffernd_tt1.data = NULL;
-  __pyx_pybuffernd_tt1.rcbuffer = &__pyx_pybuffer_tt1;
-  __pyx_pybuffer_tt2.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt2.refcount = 0;
-  __pyx_pybuffernd_tt2.data = NULL;
-  __pyx_pybuffernd_tt2.rcbuffer = &__pyx_pybuffer_tt2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt1.diminfo[0].strides = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt1.diminfo[0].shape = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt2.diminfo[0].strides = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt2.diminfo[0].shape = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1602
- *     **  Derived, with permission, from the SOFA library.  See notes at end of file.
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_ut12->dimensions[0]) == (__pyx_v_tt1->dimensions[0]));
-      if (__pyx_t_1) {
-        __pyx_t_1 = ((__pyx_v_tt1->dimensions[0]) == (__pyx_v_tt2->dimensions[0]));
-      }
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1603
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1605
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gmst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gmst.diminfo[0].strides = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gmst.diminfo[0].shape = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_gmst = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1607
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gmst[i] = eraGmst00(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1608
- * 
- *     for i in range(n):
- *         gmst[i] = eraGmst00(ut11[i], ut12[i], tt1[i], tt2[i])             # <<<<<<<<<<<<<<
- * 
- *     return gmst
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_gmst.diminfo[0].strides) = eraGmst00((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_ut12.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_tt1.rcbuffer->pybuff [...]
-  }
-
-  /* "astropy/time/erfa_time.pyx":1610
- *         gmst[i] = eraGmst00(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- *     return gmst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gmst));
-  __pyx_r = ((PyObject *)__pyx_v_gmst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1532
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst00(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst00", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gmst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1614
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst06(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_61gmst06(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_60gmst06[] = "Wrap double eraGmst06(double uta, double utb, double tta, double ttb)\n    **  Greenwich mean sidereal time (consistent with IAU 2006 precession).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **     tta,ttb    double    TT as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich mean sidereal time (radians [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_61gmst06 = {"gmst06", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_61gmst06, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_60gmst06};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_61gmst06(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  PyArrayObject *__pyx_v_tt1 = 0;
-  PyArrayObject *__pyx_v_tt2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gmst06 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,&__pyx_n_s_tt1,&__pyx_n_s_tt2,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst06", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt1)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst06", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst06", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gmst06") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-    __pyx_v_tt1 = ((PyArrayObject *)values[2]);
-    __pyx_v_tt2 = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gmst06", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst06", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt1), __pyx_ptype_5numpy_ndarray, 1, "tt1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt2), __pyx_ptype_5numpy_ndarray, 1, "tt2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1617; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_60gmst06(__pyx_self, __pyx_v_ut11, __pyx_v_ut12, __pyx_v_tt1, __pyx_v_tt2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_60gmst06(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gmst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gmst;
-  __Pyx_Buffer __pyx_pybuffer_gmst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt1;
-  __Pyx_Buffer __pyx_pybuffer_tt1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt2;
-  __Pyx_Buffer __pyx_pybuffer_tt2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gmst06", 0);
-  __pyx_pybuffer_gmst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gmst.refcount = 0;
-  __pyx_pybuffernd_gmst.data = NULL;
-  __pyx_pybuffernd_gmst.rcbuffer = &__pyx_pybuffer_gmst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  __pyx_pybuffer_tt1.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt1.refcount = 0;
-  __pyx_pybuffernd_tt1.data = NULL;
-  __pyx_pybuffernd_tt1.rcbuffer = &__pyx_pybuffer_tt1;
-  __pyx_pybuffer_tt2.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt2.refcount = 0;
-  __pyx_pybuffernd_tt2.data = NULL;
-  __pyx_pybuffernd_tt2.rcbuffer = &__pyx_pybuffer_tt2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt1.diminfo[0].strides = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt1.diminfo[0].shape = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt2.diminfo[0].strides = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt2.diminfo[0].shape = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1671
- *     **     Astron.Astrophys. 432, 355
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_ut12->dimensions[0]) == (__pyx_v_tt1->dimensions[0]));
-      if (__pyx_t_1) {
-        __pyx_t_1 = ((__pyx_v_tt1->dimensions[0]) == (__pyx_v_tt2->dimensions[0]));
-      }
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1672
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1674
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gmst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gmst.diminfo[0].strides = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gmst.diminfo[0].shape = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_gmst = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1676
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gmst[i] = eraGmst06(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1677
- * 
- *     for i in range(n):
- *         gmst[i] = eraGmst06(ut11[i], ut12[i], tt1[i], tt2[i])             # <<<<<<<<<<<<<<
- * 
- *     return gmst
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_gmst.diminfo[0].strides) = eraGmst06((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_ut12.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_tt1.rcbuffer->pybuff [...]
-  }
-
-  /* "astropy/time/erfa_time.pyx":1679
- *         gmst[i] = eraGmst06(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- *     return gmst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gmst));
-  __pyx_r = ((PyObject *)__pyx_v_gmst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1614
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst06(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst06", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gmst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1683
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst82(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12):
- *     """Wrap double double eraGmst82(double dj1, double dj2)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_63gmst82(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_62gmst82[] = "Wrap double double eraGmst82(double dj1, double dj2)\n    **  Universal Time to Greenwich mean sidereal time (IAU 1982 model).\n    **\n    **  Given:\n    **     dj1,dj2    double    UT1 Julian Date (see note)\n    **\n    **  Returned (function value):\n    **                double    Greenwich mean sidereal time (radians)\n    **\n    **  Notes:\n    **\n    **  1) The UT1 date dj1+dj2 is a Julian Date, apportioned in any\n [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_63gmst82 = {"gmst82", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_63gmst82, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_62gmst82};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_63gmst82(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gmst82 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gmst82", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gmst82") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gmst82", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst82", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_62gmst82(__pyx_self, __pyx_v_ut11, __pyx_v_ut12);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_62gmst82(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gmst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gmst;
-  __Pyx_Buffer __pyx_pybuffer_gmst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gmst82", 0);
-  __pyx_pybuffer_gmst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gmst.refcount = 0;
-  __pyx_pybuffernd_gmst.data = NULL;
-  __pyx_pybuffernd_gmst.rcbuffer = &__pyx_pybuffer_gmst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1740
- *     **     Aoki et al., Astron. Astrophys. 105, 359-361 (1982).
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1741
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1743
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gmst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gmst.diminfo[0].strides = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gmst.diminfo[0].shape = __pyx_pybuffernd_gmst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_gmst = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1745
- *     cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gmst[i] = eraGmst82(ut11[i], ut12[i]
- * )
- */
-  __pyx_t_7 = __pyx_v_n;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
-
-    /* "astropy/time/erfa_time.pyx":1746
- * 
- *     for i in range(n):
- *         gmst[i] = eraGmst82(ut11[i], ut12[i]             # <<<<<<<<<<<<<<
- * )
- *     return gmst
- */
-    __pyx_t_9 = __pyx_v_i;
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gmst.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_gmst.diminfo[0].strides) = eraGmst82((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut12.diminfo[0].strides)));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1748
- *         gmst[i] = eraGmst82(ut11[i], ut12[i]
- * )
- *     return gmst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gmst));
-  __pyx_r = ((PyObject *)__pyx_v_gmst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1683
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst82(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12):
- *     """Wrap double double eraGmst82(double dj1, double dj2)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gmst82", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gmst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gmst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1752
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_65gst00a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_64gst00a[] = "Wrap double eraGst00a(double uta, double utb, double tta, double ttb)\n    **  Greenwich apparent sidereal time (consistent with IAU 2000\n    **  resolutions).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **     tta,ttb    double    TT as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich apparent side [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_65gst00a = {"gst00a", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_65gst00a, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_64gst00a};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_65gst00a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  PyArrayObject *__pyx_v_tt1 = 0;
-  PyArrayObject *__pyx_v_tt2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gst00a (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,&__pyx_n_s_tt1,&__pyx_n_s_tt2,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst00a", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt1)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst00a", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst00a", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gst00a") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-    __pyx_v_tt1 = ((PyArrayObject *)values[2]);
-    __pyx_v_tt2 = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gst00a", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst00a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt1), __pyx_ptype_5numpy_ndarray, 1, "tt1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt2), __pyx_ptype_5numpy_ndarray, 1, "tt2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_64gst00a(__pyx_self, __pyx_v_ut11, __pyx_v_ut12, __pyx_v_tt1, __pyx_v_tt2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_64gst00a(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gst;
-  __Pyx_Buffer __pyx_pybuffer_gst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt1;
-  __Pyx_Buffer __pyx_pybuffer_tt1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt2;
-  __Pyx_Buffer __pyx_pybuffer_tt2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gst00a", 0);
-  __pyx_pybuffer_gst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gst.refcount = 0;
-  __pyx_pybuffernd_gst.data = NULL;
-  __pyx_pybuffernd_gst.rcbuffer = &__pyx_pybuffer_gst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  __pyx_pybuffer_tt1.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt1.refcount = 0;
-  __pyx_pybuffernd_tt1.data = NULL;
-  __pyx_pybuffernd_tt1.rcbuffer = &__pyx_pybuffer_tt1;
-  __pyx_pybuffer_tt2.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt2.refcount = 0;
-  __pyx_pybuffernd_tt2.data = NULL;
-  __pyx_pybuffernd_tt2.rcbuffer = &__pyx_pybuffer_tt2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt1.diminfo[0].strides = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt1.diminfo[0].shape = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt2.diminfo[0].strides = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt2.diminfo[0].shape = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1820
- *     **     IERS Technical Note No. 32, BKG (2004)
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_ut12->dimensions[0]) == (__pyx_v_tt1->dimensions[0]));
-      if (__pyx_t_1) {
-        __pyx_t_1 = ((__pyx_v_tt1->dimensions[0]) == (__pyx_v_tt2->dimensions[0]));
-      }
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1820; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1821
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1823
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gst.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gst.diminfo[0].strides = __pyx_pybuffernd_gst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gst.diminfo[0].shape = __pyx_pybuffernd_gst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_gst = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1825
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gst[i] = eraGst00a(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1826
- * 
- *     for i in range(n):
- *         gst[i] = eraGst00a(ut11[i], ut12[i], tt1[i], tt2[i])             # <<<<<<<<<<<<<<
- * 
- *     return gst
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_gst.diminfo[0].strides) = eraGst00a((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_ut12.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_tt1.rcbuffer->pybuffer [...]
-  }
-
-  /* "astropy/time/erfa_time.pyx":1828
- *         gst[i] = eraGst00a(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- *     return gst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gst));
-  __pyx_r = ((PyObject *)__pyx_v_gst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1752
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst00a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1832
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00b(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *             np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst00b(double uta, double utb)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_67gst00b(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_66gst00b[] = "Wrap double eraGst00b(double uta, double utb)\n    **  Greenwich apparent sidereal time (consistent with IAU 2000\n    **  resolutions but using the truncated nutation model IAU 2000B).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich apparent sidereal time (radians)\n    **\n    **  Notes:\n   [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_67gst00b = {"gst00b", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_67gst00b, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_66gst00b};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_67gst00b(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gst00b (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst00b", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gst00b") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gst00b", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst00b", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_66gst00b(__pyx_self, __pyx_v_ut11, __pyx_v_ut12);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_66gst00b(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gst;
-  __Pyx_Buffer __pyx_pybuffer_gst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gst00b", 0);
-  __pyx_pybuffer_gst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gst.refcount = 0;
-  __pyx_pybuffernd_gst.data = NULL;
-  __pyx_pybuffernd_gst.rcbuffer = &__pyx_pybuffer_gst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1906
- *     **     IERS Technical Note No. 32, BKG (2004)
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1907
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1909
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gst.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gst.diminfo[0].strides = __pyx_pybuffernd_gst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gst.diminfo[0].shape = __pyx_pybuffernd_gst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_gst = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1911
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gst[i] = eraGst00b(ut11[i], ut12[i]
- * )
- */
-  __pyx_t_7 = __pyx_v_n;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
-
-    /* "astropy/time/erfa_time.pyx":1912
- * 
- *     for i in range(n):
- *         gst[i] = eraGst00b(ut11[i], ut12[i]             # <<<<<<<<<<<<<<
- * )
- *     return gst
- */
-    __pyx_t_9 = __pyx_v_i;
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_gst.diminfo[0].strides) = eraGst00b((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut12.diminfo[0].strides)));
-  }
-
-  /* "astropy/time/erfa_time.pyx":1914
- *         gst[i] = eraGst00b(ut11[i], ut12[i]
- * )
- *     return gst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gst));
-  __pyx_r = ((PyObject *)__pyx_v_gst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1832
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00b(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *             np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst00b(double uta, double utb)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst00b", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1918
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst06a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_69gst06a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_68gst06a[] = "Wrap double eraGst06a(double uta, double utb, double tta, double ttb)\n    **  Greenwich apparent sidereal time (consistent with IAU 2000 and 2006\n    **  resolutions).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **     tta,ttb    double    TT as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich appa [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_69gst06a = {"gst06a", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_69gst06a, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_68gst06a};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_69gst06a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  PyArrayObject *__pyx_v_tt1 = 0;
-  PyArrayObject *__pyx_v_tt2 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gst06a (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,&__pyx_n_s_tt1,&__pyx_n_s_tt2,0};
-    PyObject* values[4] = {0,0,0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst06a", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt1)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst06a", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_tt2)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst06a", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gst06a") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-    __pyx_v_tt1 = ((PyArrayObject *)values[2]);
-    __pyx_v_tt2 = ((PyArrayObject *)values[3]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gst06a", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst06a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt1), __pyx_ptype_5numpy_ndarray, 1, "tt1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tt2), __pyx_ptype_5numpy_ndarray, 1, "tt2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_68gst06a(__pyx_self, __pyx_v_ut11, __pyx_v_ut12, __pyx_v_tt1, __pyx_v_tt2);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_68gst06a(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12, PyArrayObject *__pyx_v_tt1, PyArrayObject *__pyx_v_tt2) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gst;
-  __Pyx_Buffer __pyx_pybuffer_gst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt1;
-  __Pyx_Buffer __pyx_pybuffer_tt1;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_tt2;
-  __Pyx_Buffer __pyx_pybuffer_tt2;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyArrayObject *__pyx_t_7 = NULL;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gst06a", 0);
-  __pyx_pybuffer_gst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gst.refcount = 0;
-  __pyx_pybuffernd_gst.data = NULL;
-  __pyx_pybuffernd_gst.rcbuffer = &__pyx_pybuffer_gst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  __pyx_pybuffer_tt1.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt1.refcount = 0;
-  __pyx_pybuffernd_tt1.data = NULL;
-  __pyx_pybuffernd_tt1.rcbuffer = &__pyx_pybuffer_tt1;
-  __pyx_pybuffer_tt2.pybuffer.buf = NULL;
-  __pyx_pybuffer_tt2.refcount = 0;
-  __pyx_pybuffernd_tt2.data = NULL;
-  __pyx_pybuffernd_tt2.rcbuffer = &__pyx_pybuffer_tt2;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt1, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt1.diminfo[0].strides = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt1.diminfo[0].shape = __pyx_pybuffernd_tt1.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer, (PyObject*)__pyx_v_tt2, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_tt2.diminfo[0].strides = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tt2.diminfo[0].shape = __pyx_pybuffernd_tt2.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":1977
- *     **     Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    __pyx_t_1 = ((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0]));
-    if (__pyx_t_1) {
-      __pyx_t_1 = ((__pyx_v_ut12->dimensions[0]) == (__pyx_v_tt1->dimensions[0]));
-      if (__pyx_t_1) {
-        __pyx_t_1 = ((__pyx_v_tt1->dimensions[0]) == (__pyx_v_tt2->dimensions[0]));
-      }
-    }
-    if (unlikely(!(__pyx_t_1 != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":1978
- *     """
- *     assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":1980
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gst.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gst.diminfo[0].strides = __pyx_pybuffernd_gst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gst.diminfo[0].shape = __pyx_pybuffernd_gst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_7 = 0;
-  __pyx_v_gst = ((PyArrayObject *)__pyx_t_6);
-  __pyx_t_6 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1982
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gst[i] = eraGst06a(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- */
-  __pyx_t_8 = __pyx_v_n;
-  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
-    __pyx_v_i = __pyx_t_9;
-
-    /* "astropy/time/erfa_time.pyx":1983
- * 
- *     for i in range(n):
- *         gst[i] = eraGst06a(ut11[i], ut12[i], tt1[i], tt2[i])             # <<<<<<<<<<<<<<
- * 
- *     return gst
- */
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    __pyx_t_12 = __pyx_v_i;
-    __pyx_t_13 = __pyx_v_i;
-    __pyx_t_14 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_gst.diminfo[0].strides) = eraGst06a((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_ut12.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_tt1.rcbuffer->pybuffer [...]
-  }
-
-  /* "astropy/time/erfa_time.pyx":1985
- *         gst[i] = eraGst06a(ut11[i], ut12[i], tt1[i], tt2[i])
- * 
- *     return gst             # <<<<<<<<<<<<<<
- * 
- * @cython.wraparound(False)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gst));
-  __pyx_r = ((PyObject *)__pyx_v_gst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1918
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst06a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst06a", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt1.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tt2.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "astropy/time/erfa_time.pyx":1989
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst94(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *           np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst94(double uta, double utb)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_71gst94(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7astropy_4time_9erfa_time_70gst94[] = "Wrap double eraGst94(double uta, double utb)\n    **  Greenwich apparent sidereal time (consistent with IAU 1982/94\n    **  resolutions).\n    **\n    **  Given:\n    **     uta,utb    double    UT1 as a 2-part Julian Date (Notes 1,2)\n    **\n    **  Returned (function value):\n    **                double    Greenwich apparent sidereal time (radians)\n    **\n    **  Notes:\n    **\n    **  1) The UT1 date uta+utb is a Julia [...]
-static PyMethodDef __pyx_mdef_7astropy_4time_9erfa_time_71gst94 = {"gst94", (PyCFunction)__pyx_pw_7astropy_4time_9erfa_time_71gst94, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7astropy_4time_9erfa_time_70gst94};
-static PyObject *__pyx_pw_7astropy_4time_9erfa_time_71gst94(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyArrayObject *__pyx_v_ut11 = 0;
-  PyArrayObject *__pyx_v_ut12 = 0;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("gst94 (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ut11,&__pyx_n_s_ut12,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut11)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ut12)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("gst94", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "gst94") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_ut11 = ((PyArrayObject *)values[0]);
-    __pyx_v_ut12 = ((PyArrayObject *)values[1]);
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("gst94", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst94", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut11), __pyx_ptype_5numpy_ndarray, 1, "ut11", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ut12), __pyx_ptype_5numpy_ndarray, 1, "ut12", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_pf_7astropy_4time_9erfa_time_70gst94(__pyx_self, __pyx_v_ut11, __pyx_v_ut12);
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_7astropy_4time_9erfa_time_70gst94(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_ut11, PyArrayObject *__pyx_v_ut12) {
-  unsigned int __pyx_v_n;
-  unsigned int __pyx_v_i;
-  PyArrayObject *__pyx_v_gst = 0;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_gst;
-  __Pyx_Buffer __pyx_pybuffer_gst;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut11;
-  __Pyx_Buffer __pyx_pybuffer_ut11;
-  __Pyx_LocalBuf_ND __pyx_pybuffernd_ut12;
-  __Pyx_Buffer __pyx_pybuffer_ut12;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyArrayObject *__pyx_t_6 = NULL;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  unsigned int __pyx_t_9;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("gst94", 0);
-  __pyx_pybuffer_gst.pybuffer.buf = NULL;
-  __pyx_pybuffer_gst.refcount = 0;
-  __pyx_pybuffernd_gst.data = NULL;
-  __pyx_pybuffernd_gst.rcbuffer = &__pyx_pybuffer_gst;
-  __pyx_pybuffer_ut11.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut11.refcount = 0;
-  __pyx_pybuffernd_ut11.data = NULL;
-  __pyx_pybuffernd_ut11.rcbuffer = &__pyx_pybuffer_ut11;
-  __pyx_pybuffer_ut12.pybuffer.buf = NULL;
-  __pyx_pybuffer_ut12.refcount = 0;
-  __pyx_pybuffernd_ut12.data = NULL;
-  __pyx_pybuffernd_ut12.rcbuffer = &__pyx_pybuffer_ut12;
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut11, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut11.diminfo[0].strides = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut11.diminfo[0].shape = __pyx_pybuffernd_ut11.rcbuffer->pybuffer.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer, (PyObject*)__pyx_v_ut12, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_pybuffernd_ut12.diminfo[0].strides = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_ut12.diminfo[0].shape = __pyx_pybuffernd_ut12.rcbuffer->pybuffer.shape[0];
-
-  /* "astropy/time/erfa_time.pyx":2048
- *     **     IAU Resolution C7, Recommendation 3 (1994)
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- */
-  #ifndef CYTHON_WITHOUT_ASSERTIONS
-  if (unlikely(!Py_OptimizeFlag)) {
-    if (unlikely(!(((__pyx_v_ut11->dimensions[0]) == (__pyx_v_ut12->dimensions[0])) != 0))) {
-      PyErr_SetNone(PyExc_AssertionError);
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-
-  /* "astropy/time/erfa_time.pyx":2049
- *     """
- *     assert ut11.shape[0] == ut12.shape[0]
- *     cdef unsigned n = ut11.shape[0]             # <<<<<<<<<<<<<<
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- */
-  __pyx_v_n = (__pyx_v_ut11->dimensions[0]);
-
-  /* "astropy/time/erfa_time.pyx":2051
- *     cdef unsigned n = ut11.shape[0]
- *     cdef unsigned int i
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)             # <<<<<<<<<<<<<<
- * 
- *     for i in range(n):
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_gst.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
-      __pyx_v_gst = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf = NULL;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_gst.diminfo[0].strides = __pyx_pybuffernd_gst.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_gst.diminfo[0].shape = __pyx_pybuffernd_gst.rcbuffer->pybuffer.shape[0];
-    }
-  }
-  __pyx_t_6 = 0;
-  __pyx_v_gst = ((PyArrayObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-
-  /* "astropy/time/erfa_time.pyx":2053
- *     cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
- * 
- *     for i in range(n):             # <<<<<<<<<<<<<<
- *         gst[i] = eraGst94(ut11[i], ut12[i])
- * 
- */
-  __pyx_t_7 = __pyx_v_n;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
-
-    /* "astropy/time/erfa_time.pyx":2054
- * 
- *     for i in range(n):
- *         gst[i] = eraGst94(ut11[i], ut12[i])             # <<<<<<<<<<<<<<
- * 
- *     return gst
- */
-    __pyx_t_9 = __pyx_v_i;
-    __pyx_t_10 = __pyx_v_i;
-    __pyx_t_11 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_gst.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_gst.diminfo[0].strides) = eraGst94((*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut11.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_ut11.diminfo[0].strides)), (*__Pyx_BufPtrStrided1d(double *, __pyx_pybuffernd_ut12.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_ut12.diminfo[0].strides)));
-  }
-
-  /* "astropy/time/erfa_time.pyx":2056
- *         gst[i] = eraGst94(ut11[i], ut12[i])
- * 
- *     return gst             # <<<<<<<<<<<<<<
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_gst));
-  __pyx_r = ((PyObject *)__pyx_v_gst);
-  goto __pyx_L0;
-
-  /* "astropy/time/erfa_time.pyx":1989
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst94(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *           np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst94(double uta, double utb)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
-    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
-  __Pyx_AddTraceback("astropy.time.erfa_time.gst94", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  goto __pyx_L2;
-  __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_gst.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut11.rcbuffer->pybuffer);
-  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_ut12.rcbuffer->pybuffer);
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_gst);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
- *         # experimental exception made for __getbuffer__ and __releasebuffer__
- *         # -- the details of this may change.
- *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
- *             # This implementation of getbuffer is geared towards Cython
- *             # requirements, and does not yet fullfill the PEP.
- */
-
-/* Python wrapper */
-static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
-static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
-  int __pyx_v_copy_shape;
-  int __pyx_v_i;
-  int __pyx_v_ndim;
-  int __pyx_v_endian_detector;
-  int __pyx_v_little_endian;
-  int __pyx_v_t;
-  char *__pyx_v_f;
-  PyArray_Descr *__pyx_v_descr = 0;
-  int __pyx_v_offset;
-  int __pyx_v_hasfields;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  int __pyx_t_4;
-  int __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
-  char *__pyx_t_7;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__getbuffer__", 0);
-  if (__pyx_v_info != NULL) {
-    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
-    __Pyx_GIVEREF(__pyx_v_info->obj);
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":200
- *             # of flags
- * 
- *             if info == NULL: return             # <<<<<<<<<<<<<<
- * 
- *             cdef int copy_shape, i, ndim
- */
-  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
-  if (__pyx_t_1) {
-    __pyx_r = 0;
-    goto __pyx_L0;
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203
- * 
- *             cdef int copy_shape, i, ndim
- *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
- * 
- */
-  __pyx_v_endian_detector = 1;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":204
- *             cdef int copy_shape, i, ndim
- *             cdef int endian_detector = 1
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
- * 
- *             ndim = PyArray_NDIM(self)
- */
-  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
- * 
- *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
- * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- */
-  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":208
- *             ndim = PyArray_NDIM(self)
- * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
- *                 copy_shape = 1
- *             else:
- */
-  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209
- * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 copy_shape = 1             # <<<<<<<<<<<<<<
- *             else:
- *                 copy_shape = 0
- */
-    __pyx_v_copy_shape = 1;
-    goto __pyx_L4;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211
- *                 copy_shape = 1
- *             else:
- *                 copy_shape = 0             # <<<<<<<<<<<<<<
- * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- */
-    __pyx_v_copy_shape = 0;
-  }
-  __pyx_L4:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":213
- *                 copy_shape = 0
- * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")
- */
-  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
-  if (__pyx_t_2) {
-  } else {
-    __pyx_t_1 = __pyx_t_2;
-    goto __pyx_L6_bool_binop_done;
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214
- * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
- *                 raise ValueError(u"ndarray is not C contiguous")
- * 
- */
-  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
-  __pyx_t_1 = __pyx_t_2;
-  __pyx_L6_bool_binop_done:;
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- */
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217
- *                 raise ValueError(u"ndarray is not C contiguous")
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
- */
-  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
-  if (__pyx_t_2) {
-  } else {
-    __pyx_t_1 = __pyx_t_2;
-    goto __pyx_L9_bool_binop_done;
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
- * 
- */
-  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
-  __pyx_t_1 = __pyx_t_2;
-  __pyx_L9_bool_binop_done:;
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
- * 
- *             info.buf = PyArray_DATA(self)
- */
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
- * 
- *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
- *             info.ndim = ndim
- *             if copy_shape:
- */
-  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222
- * 
- *             info.buf = PyArray_DATA(self)
- *             info.ndim = ndim             # <<<<<<<<<<<<<<
- *             if copy_shape:
- *                 # Allocate new buffer for strides and shape info.
- */
-  __pyx_v_info->ndim = __pyx_v_ndim;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":223
- *             info.buf = PyArray_DATA(self)
- *             info.ndim = ndim
- *             if copy_shape:             # <<<<<<<<<<<<<<
- *                 # Allocate new buffer for strides and shape info.
- *                 # This is allocated as one block, strides first.
- */
-  __pyx_t_1 = (__pyx_v_copy_shape != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226
- *                 # Allocate new buffer for strides and shape info.
- *                 # This is allocated as one block, strides first.
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):
- */
-    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":227
- *                 # This is allocated as one block, strides first.
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
- *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
- */
-    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":228
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):             # <<<<<<<<<<<<<<
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
- *                     info.shape[i] = PyArray_DIMS(self)[i]
- */
-    __pyx_t_4 = __pyx_v_ndim;
-    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
-      __pyx_v_i = __pyx_t_5;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
- *                     info.shape[i] = PyArray_DIMS(self)[i]
- *             else:
- */
-      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
- *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
- */
-      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
-    }
-    goto __pyx_L11;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232
- *                     info.shape[i] = PyArray_DIMS(self)[i]
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL
- */
-    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)
- */
-    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
-  }
-  __pyx_L11:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":234
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
- *             info.itemsize = PyArray_ITEMSIZE(self)
- *             info.readonly = not PyArray_ISWRITEABLE(self)
- */
-  __pyx_v_info->suboffsets = NULL;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
- *             info.readonly = not PyArray_ISWRITEABLE(self)
- * 
- */
-  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)
- *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
- * 
- *             cdef int t
- */
-  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239
- * 
- *             cdef int t
- *             cdef char* f = NULL             # <<<<<<<<<<<<<<
- *             cdef dtype descr = self.descr
- *             cdef list stack
- */
-  __pyx_v_f = NULL;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":240
- *             cdef int t
- *             cdef char* f = NULL
- *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
- *             cdef list stack
- *             cdef int offset
- */
-  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
-  __Pyx_INCREF(__pyx_t_3);
-  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
-  __pyx_t_3 = 0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":244
- *             cdef int offset
- * 
- *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
- * 
- *             if not hasfields and not copy_shape:
- */
-  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246
- *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
- * 
- *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
- *                 # do not call releasebuffer
- *                 info.obj = None
- */
-  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
-  if (__pyx_t_2) {
-  } else {
-    __pyx_t_1 = __pyx_t_2;
-    goto __pyx_L15_bool_binop_done;
-  }
-  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
-  __pyx_t_1 = __pyx_t_2;
-  __pyx_L15_bool_binop_done:;
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248
- *             if not hasfields and not copy_shape:
- *                 # do not call releasebuffer
- *                 info.obj = None             # <<<<<<<<<<<<<<
- *             else:
- *                 # need to call releasebuffer
- */
-    __Pyx_INCREF(Py_None);
-    __Pyx_GIVEREF(Py_None);
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj);
-    __pyx_v_info->obj = Py_None;
-    goto __pyx_L14;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251
- *             else:
- *                 # need to call releasebuffer
- *                 info.obj = self             # <<<<<<<<<<<<<<
- * 
- *             if not hasfields:
- */
-    __Pyx_INCREF(((PyObject *)__pyx_v_self));
-    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj);
-    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
-  }
-  __pyx_L14:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253
- *                 info.obj = self
- * 
- *             if not hasfields:             # <<<<<<<<<<<<<<
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or
- */
-  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254
- * 
- *             if not hasfields:
- *                 t = descr.type_num             # <<<<<<<<<<<<<<
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
- */
-    __pyx_t_4 = __pyx_v_descr->type_num;
-    __pyx_v_t = __pyx_t_4;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255
- *             if not hasfields:
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")
- */
-    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
-    if (!__pyx_t_2) {
-      goto __pyx_L20_next_or;
-    } else {
-    }
-    __pyx_t_2 = (__pyx_v_little_endian != 0);
-    if (!__pyx_t_2) {
-    } else {
-      __pyx_t_1 = __pyx_t_2;
-      goto __pyx_L19_bool_binop_done;
-    }
-    __pyx_L20_next_or:;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"
- */
-    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
-    if (__pyx_t_2) {
-    } else {
-      __pyx_t_1 = __pyx_t_2;
-      goto __pyx_L19_bool_binop_done;
-    }
-    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
-    __pyx_t_1 = __pyx_t_2;
-    __pyx_L19_bool_binop_done:;
-    if (__pyx_t_1) {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
- */
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- */
-    switch (__pyx_v_t) {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"
- */
-      case NPY_BYTE:
-      __pyx_v_f = __pyx_k_b;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"
- */
-      case NPY_UBYTE:
-      __pyx_v_f = __pyx_k_B;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"
- */
-      case NPY_SHORT:
-      __pyx_v_f = __pyx_k_h;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"
- */
-      case NPY_USHORT:
-      __pyx_v_f = __pyx_k_H;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"
- */
-      case NPY_INT:
-      __pyx_v_f = __pyx_k_i;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"
- */
-      case NPY_UINT:
-      __pyx_v_f = __pyx_k_I;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"
- */
-      case NPY_LONG:
-      __pyx_v_f = __pyx_k_l;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- */
-      case NPY_ULONG:
-      __pyx_v_f = __pyx_k_L;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"
- */
-      case NPY_LONGLONG:
-      __pyx_v_f = __pyx_k_q;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"
- */
-      case NPY_ULONGLONG:
-      __pyx_v_f = __pyx_k_Q;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- */
-      case NPY_FLOAT:
-      __pyx_v_f = __pyx_k_f;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- */
-      case NPY_DOUBLE:
-      __pyx_v_f = __pyx_k_d;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- */
-      case NPY_LONGDOUBLE:
-      __pyx_v_f = __pyx_k_g;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- */
-      case NPY_CFLOAT:
-      __pyx_v_f = __pyx_k_Zf;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- *                 elif t == NPY_OBJECT:      f = "O"
- */
-      case NPY_CDOUBLE:
-      __pyx_v_f = __pyx_k_Zd;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_OBJECT:      f = "O"
- *                 else:
- */
-      case NPY_CLONGDOUBLE:
-      __pyx_v_f = __pyx_k_Zg;
-      break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- */
-      case NPY_OBJECT:
-      __pyx_v_f = __pyx_k_O;
-      break;
-      default:
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276
- *                 elif t == NPY_OBJECT:      f = "O"
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
- *                 info.format = f
- *                 return
- */
-      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_6);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
-      __Pyx_GIVEREF(__pyx_t_6);
-      __pyx_t_6 = 0;
-      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_6);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      break;
-    }
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *                 info.format = f             # <<<<<<<<<<<<<<
- *                 return
- *             else:
- */
-    __pyx_v_info->format = __pyx_v_f;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *                 info.format = f
- *                 return             # <<<<<<<<<<<<<<
- *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
- */
-    __pyx_r = 0;
-    goto __pyx_L0;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280
- *                 return
- *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
- *                 info.format[0] = c'^' # Native data types, manual alignment
- *                 offset = 0
- */
-    __pyx_v_info->format = ((char *)malloc(255));
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281
- *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
- *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
- *                 offset = 0
- *                 f = _util_dtypestring(descr, info.format + 1,
- */
-    (__pyx_v_info->format[0]) = '^';
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
- *                 info.format[0] = c'^' # Native data types, manual alignment
- *                 offset = 0             # <<<<<<<<<<<<<<
- *                 f = _util_dtypestring(descr, info.format + 1,
- *                                       info.format + _buffer_format_string_len,
- */
-    __pyx_v_offset = 0;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283
- *                 info.format[0] = c'^' # Native data types, manual alignment
- *                 offset = 0
- *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
- *                                       info.format + _buffer_format_string_len,
- *                                       &offset)
- */
-    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_v_f = __pyx_t_7;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286
- *                                       info.format + _buffer_format_string_len,
- *                                       &offset)
- *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
- * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
- */
-    (__pyx_v_f[0]) = '\x00';
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":194
- *         # experimental exception made for __getbuffer__ and __releasebuffer__
- *         # -- the details of this may change.
- *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
- *             # This implementation of getbuffer is geared towards Cython
- *             # requirements, and does not yet fullfill the PEP.
- */
-
-  /* function exit code */
-  __pyx_r = 0;
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = -1;
-  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
-  }
-  goto __pyx_L2;
-  __pyx_L0:;
-  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
-    __Pyx_GOTREF(Py_None);
-    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
-  }
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
- *                 f[0] = c'\0' # Terminate format string
- * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)
- */
-
-/* Python wrapper */
-static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
-static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
-  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-}
-
-static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289
- * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
- *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- */
-  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 stdlib.free(info.strides)
- */
-    free(__pyx_v_info->format);
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
- *                 stdlib.free(info.strides)
- *                 # info.shape was stored after info.strides in the same block
- */
-  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
- *                 # info.shape was stored after info.strides in the same block
- * 
- */
-    free(__pyx_v_info->strides);
-    goto __pyx_L4;
-  }
-  __pyx_L4:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288
- *                 f[0] = c'\0' # Terminate format string
- * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)
- */
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
- * ctypedef npy_cdouble     complex_t
- * 
- * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(1, <void*>a)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769
- * 
- * cdef inline object PyArray_MultiIterNew1(a):
- *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew2(a, b):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768
- * ctypedef npy_cdouble     complex_t
- * 
- * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(1, <void*>a)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
- *     return PyArray_MultiIterNew(1, <void*>a)
- * 
- * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772
- * 
- * cdef inline object PyArray_MultiIterNew2(a, b):
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771
- *     return PyArray_MultiIterNew(1, <void*>a)
- * 
- * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
- * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775
- * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
- * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
- * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778
- * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
- * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
- * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781
- * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
- * 
- * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
- * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
- * 
- * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
- *     # Recursive utility function used in __getbuffer__ to get format
- *     # string. The new location in the format string is returned.
- */
-
-static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
-  PyArray_Descr *__pyx_v_child = 0;
-  int __pyx_v_endian_detector;
-  int __pyx_v_little_endian;
-  PyObject *__pyx_v_fields = 0;
-  PyObject *__pyx_v_childname = NULL;
-  PyObject *__pyx_v_new_offset = NULL;
-  PyObject *__pyx_v_t = NULL;
-  char *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  Py_ssize_t __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
-  int __pyx_t_6;
-  int __pyx_t_7;
-  long __pyx_t_8;
-  char *__pyx_t_9;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790
- *     cdef int delta_offset
- *     cdef tuple i
- *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
- *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
- *     cdef tuple fields
- */
-  __pyx_v_endian_detector = 1;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791
- *     cdef tuple i
- *     cdef int endian_detector = 1
- *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
- *     cdef tuple fields
- * 
- */
-  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
- *     cdef tuple fields
- * 
- *     for childname in descr.names:             # <<<<<<<<<<<<<<
- *         fields = descr.fields[childname]
- *         child, new_offset = fields
- */
-  if (unlikely(__pyx_v_descr->names == Py_None)) {
-    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
-    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
-  for (;;) {
-    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-    #if CYTHON_COMPILING_IN_CPYTHON
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    #endif
-    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
-    __pyx_t_3 = 0;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795
- * 
- *     for childname in descr.names:
- *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
- *         child, new_offset = fields
- * 
- */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-    __Pyx_GOTREF(__pyx_t_3);
-    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
-    __pyx_t_3 = 0;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796
- *     for childname in descr.names:
- *         fields = descr.fields[childname]
- *         child, new_offset = fields             # <<<<<<<<<<<<<<
- * 
- *         if (end - f) - <int>(new_offset - offset[0]) < 15:
- */
-    if (likely(__pyx_v_fields != Py_None)) {
-      PyObject* sequence = __pyx_v_fields;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      Py_ssize_t size = Py_SIZE(sequence);
-      #else
-      Py_ssize_t size = PySequence_Size(sequence);
-      #endif
-      if (unlikely(size != 2)) {
-        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
-        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
-      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
-      __Pyx_INCREF(__pyx_t_3);
-      __Pyx_INCREF(__pyx_t_4);
-      #else
-      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      #endif
-    } else {
-      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
-    __pyx_t_3 = 0;
-    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
-    __pyx_t_4 = 0;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798
- *         child, new_offset = fields
- * 
- *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
- * 
- */
-    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
-    if (__pyx_t_6) {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
- * 
- *         if (end - f) - <int>(new_offset - offset[0]) < 15:
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
- * 
- *         if ((child.byteorder == c'>' and little_endian) or
- */
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
- * 
- *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")
- */
-    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
-    if (!__pyx_t_7) {
-      goto __pyx_L8_next_or;
-    } else {
-    }
-    __pyx_t_7 = (__pyx_v_little_endian != 0);
-    if (!__pyx_t_7) {
-    } else {
-      __pyx_t_6 = __pyx_t_7;
-      goto __pyx_L7_bool_binop_done;
-    }
-    __pyx_L8_next_or:;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802
- * 
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
- *             raise ValueError(u"Non-native byte order not supported")
- *             # One could encode it in the format string and have Cython
- */
-    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
-    if (__pyx_t_7) {
-    } else {
-      __pyx_t_6 = __pyx_t_7;
-      goto __pyx_L7_bool_binop_done;
-    }
-    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
-    __pyx_t_6 = __pyx_t_7;
-    __pyx_L7_bool_binop_done:;
-    if (__pyx_t_6) {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *             # One could encode it in the format string and have Cython
- *             # complain instead, BUT: < and > in format strings also imply
- */
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813
- * 
- *         # Output padding bytes
- *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
- *             f[0] = 120 # "x"; pad byte
- *             f += 1
- */
-    while (1) {
-      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (!__pyx_t_6) break;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814
- *         # Output padding bytes
- *         while offset[0] < new_offset:
- *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
- *             f += 1
- *             offset[0] += 1
- */
-      (__pyx_v_f[0]) = 120;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815
- *         while offset[0] < new_offset:
- *             f[0] = 120 # "x"; pad byte
- *             f += 1             # <<<<<<<<<<<<<<
- *             offset[0] += 1
- * 
- */
-      __pyx_v_f = (__pyx_v_f + 1);
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816
- *             f[0] = 120 # "x"; pad byte
- *             f += 1
- *             offset[0] += 1             # <<<<<<<<<<<<<<
- * 
- *         offset[0] += child.itemsize
- */
-      __pyx_t_8 = 0;
-      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
-    }
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818
- *             offset[0] += 1
- * 
- *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
- * 
- *         if not PyDataType_HASFIELDS(child):
- */
-    __pyx_t_8 = 0;
-    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820
- *         offset[0] += child.itemsize
- * 
- *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
- *             t = child.type_num
- *             if end - f < 5:
- */
-    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
-    if (__pyx_t_6) {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821
- * 
- *         if not PyDataType_HASFIELDS(child):
- *             t = child.type_num             # <<<<<<<<<<<<<<
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")
- */
-      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
-      __pyx_t_4 = 0;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822
- *         if not PyDataType_HASFIELDS(child):
- *             t = child.type_num
- *             if end - f < 5:             # <<<<<<<<<<<<<<
- *                 raise RuntimeError(u"Format string allocated too short.")
- * 
- */
-      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
-      if (__pyx_t_6) {
-
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
- *             t = child.type_num
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
- * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- */
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826
- * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 98;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 66;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 104;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 72;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 105;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 73;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 108;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 76;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 113;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 81;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 102;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 100;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 103;
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 102;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 100;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
- *             else:
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 103;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L15;
-      }
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- */
-      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_6) {
-        (__pyx_v_f[0]) = 79;
-        goto __pyx_L15;
-      }
-      /*else*/ {
-
-        /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
- *             f += 1
- *         else:
- */
-        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
-        __Pyx_GIVEREF(__pyx_t_3);
-        __pyx_t_3 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_3);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      __pyx_L15:;
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *             f += 1             # <<<<<<<<<<<<<<
- *         else:
- *             # Cython ignores struct boundary information ("T{...}"),
- */
-      __pyx_v_f = (__pyx_v_f + 1);
-      goto __pyx_L13;
-    }
-    /*else*/ {
-
-      /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849
- *             # Cython ignores struct boundary information ("T{...}"),
- *             # so don't output it
- *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
- *     return f
- * 
- */
-      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_v_f = __pyx_t_9;
-    }
-    __pyx_L13:;
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794
- *     cdef tuple fields
- * 
- *     for childname in descr.names:             # <<<<<<<<<<<<<<
- *         fields = descr.fields[childname]
- *         child, new_offset = fields
- */
-  }
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850
- *             # so don't output it
- *             f = _util_dtypestring(child, f, end, offset)
- *     return f             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __pyx_r = __pyx_v_f;
-  goto __pyx_L0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
- * 
- * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
- *     # Recursive utility function used in __getbuffer__ to get format
- *     # string. The new location in the format string is returned.
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_child);
-  __Pyx_XDECREF(__pyx_v_fields);
-  __Pyx_XDECREF(__pyx_v_childname);
-  __Pyx_XDECREF(__pyx_v_new_offset);
-  __Pyx_XDECREF(__pyx_v_t);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
- * 
- * 
- * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
- *      cdef PyObject* baseptr
- *      if base is None:
- */
-
-static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
-  PyObject *__pyx_v_baseptr;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  __Pyx_RefNannySetupContext("set_array_base", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968
- * cdef inline void set_array_base(ndarray arr, object base):
- *      cdef PyObject* baseptr
- *      if base is None:             # <<<<<<<<<<<<<<
- *          baseptr = NULL
- *      else:
- */
-  __pyx_t_1 = (__pyx_v_base == Py_None);
-  __pyx_t_2 = (__pyx_t_1 != 0);
-  if (__pyx_t_2) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969
- *      cdef PyObject* baseptr
- *      if base is None:
- *          baseptr = NULL             # <<<<<<<<<<<<<<
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!
- */
-    __pyx_v_baseptr = NULL;
-    goto __pyx_L3;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971
- *          baseptr = NULL
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)
- */
-    Py_INCREF(__pyx_v_base);
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!
- *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
- *      Py_XDECREF(arr.base)
- *      arr.base = baseptr
- */
-    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
-  }
-  __pyx_L3:;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973
- *          Py_INCREF(base) # important to do this before decref below!
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
- *      arr.base = baseptr
- * 
- */
-  Py_XDECREF(__pyx_v_arr->base);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)
- *      arr.base = baseptr             # <<<<<<<<<<<<<<
- * 
- * cdef inline object get_array_base(ndarray arr):
- */
-  __pyx_v_arr->base = __pyx_v_baseptr;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966
- * 
- * 
- * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
- *      cdef PyObject* baseptr
- *      if base is None:
- */
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-}
-
-/* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
- *      arr.base = baseptr
- * 
- * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
- *     if arr.base is NULL:
- *         return None
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("get_array_base", 0);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977
- * 
- * cdef inline object get_array_base(ndarray arr):
- *     if arr.base is NULL:             # <<<<<<<<<<<<<<
- *         return None
- *     else:
- */
-  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
-  if (__pyx_t_1) {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978
- * cdef inline object get_array_base(ndarray arr):
- *     if arr.base is NULL:
- *         return None             # <<<<<<<<<<<<<<
- *     else:
- *         return <object>arr.base
- */
-    __Pyx_XDECREF(__pyx_r);
-    __Pyx_INCREF(Py_None);
-    __pyx_r = Py_None;
-    goto __pyx_L0;
-  }
-  /*else*/ {
-
-    /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980
- *         return None
- *     else:
- *         return <object>arr.base             # <<<<<<<<<<<<<<
- */
-    __Pyx_XDECREF(__pyx_r);
-    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
-    __pyx_r = ((PyObject *)__pyx_v_arr->base);
-    goto __pyx_L0;
-  }
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
- *      arr.base = baseptr
- * 
- * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
- *     if arr.base is NULL:
- *         return None
- */
-
-  /* function exit code */
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyMethodDef __pyx_methods[] = {
-  {0, 0, 0, 0}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef __pyx_moduledef = {
-  #if PY_VERSION_HEX < 0x03020000
-    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
-  #else
-    PyModuleDef_HEAD_INIT,
-  #endif
-    "erfa_time",
-    0, /* m_doc */
-    -1, /* m_size */
-    __pyx_methods /* m_methods */,
-    NULL, /* m_reload */
-    NULL, /* m_traverse */
-    NULL, /* m_clear */
-    NULL /* m_free */
-};
-#endif
-
-static __Pyx_StringTabEntry __pyx_string_tab[] = {
-  {&__pyx_kp_s_0_1, __pyx_k_0_1, sizeof(__pyx_k_0_1), 0, 0, 1, 0},
-  {&__pyx_n_s_AstropyUserWarning, __pyx_k_AstropyUserWarning, sizeof(__pyx_k_AstropyUserWarning), 0, 0, 1, 1},
-  {&__pyx_kp_s_Bad_input_day_JD_still_computed, __pyx_k_Bad_input_day_JD_still_computed, sizeof(__pyx_k_Bad_input_day_JD_still_computed), 0, 0, 1, 0},
-  {&__pyx_kp_s_Bad_input_month, __pyx_k_Bad_input_month, sizeof(__pyx_k_Bad_input_month), 0, 0, 1, 0},
-  {&__pyx_kp_s_Bad_input_year, __pyx_k_Bad_input_year, sizeof(__pyx_k_Bad_input_year), 0, 0, 1, 0},
-  {&__pyx_n_s_DUBIOUS, __pyx_k_DUBIOUS, sizeof(__pyx_k_DUBIOUS), 0, 0, 1, 1},
-  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
-  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
-  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
-  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
-  {&__pyx_kp_s_Unexpected_return_code_0_from_1, __pyx_k_Unexpected_return_code_0_from_1, sizeof(__pyx_k_Unexpected_return_code_0_from_1), 0, 0, 1, 0},
-  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
-  {&__pyx_n_s_asec, __pyx_k_asec, sizeof(__pyx_k_asec), 0, 0, 1, 1},
-  {&__pyx_kp_s_asec_outside_range_0_59_999, __pyx_k_asec_outside_range_0_59_999, sizeof(__pyx_k_asec_outside_range_0_59_999), 0, 0, 1, 0},
-  {&__pyx_n_s_astropy_time_erfa_time, __pyx_k_astropy_time_erfa_time, sizeof(__pyx_k_astropy_time_erfa_time), 0, 0, 1, 1},
-  {&__pyx_kp_s_bad_day, __pyx_k_bad_day, sizeof(__pyx_k_bad_day), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_day_must_be_within_normal_ca, __pyx_k_bad_day_must_be_within_normal_ca, sizeof(__pyx_k_bad_day_must_be_within_normal_ca), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_fraction_of_day, __pyx_k_bad_fraction_of_day, sizeof(__pyx_k_bad_fraction_of_day), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_hour, __pyx_k_bad_hour, sizeof(__pyx_k_bad_hour), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_minute, __pyx_k_bad_minute, sizeof(__pyx_k_bad_minute), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_month, __pyx_k_bad_month, sizeof(__pyx_k_bad_month), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_month_must_be_1_to_12, __pyx_k_bad_month_must_be_1_to_12, sizeof(__pyx_k_bad_month_must_be_1_to_12), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_second_0, __pyx_k_bad_second_0, sizeof(__pyx_k_bad_second_0), 0, 0, 1, 0},
-  {&__pyx_kp_s_bad_year, __pyx_k_bad_year, sizeof(__pyx_k_bad_year), 0, 0, 1, 0},
-  {&__pyx_n_s_besselian_epoch_jd, __pyx_k_besselian_epoch_jd, sizeof(__pyx_k_besselian_epoch_jd), 0, 0, 1, 1},
-  {&__pyx_n_s_cal2jd, __pyx_k_cal2jd, sizeof(__pyx_k_cal2jd), 0, 0, 1, 1},
-  {&__pyx_n_s_check_return, __pyx_k_check_return, sizeof(__pyx_k_check_return), 0, 0, 1, 1},
-  {&__pyx_n_s_d1, __pyx_k_d1, sizeof(__pyx_k_d1), 0, 0, 1, 1},
-  {&__pyx_n_s_d2, __pyx_k_d2, sizeof(__pyx_k_d2), 0, 0, 1, 1},
-  {&__pyx_n_s_d_tai_utc, __pyx_k_d_tai_utc, sizeof(__pyx_k_d_tai_utc), 0, 0, 1, 1},
-  {&__pyx_n_s_d_tdb_tt, __pyx_k_d_tdb_tt, sizeof(__pyx_k_d_tdb_tt), 0, 0, 1, 1},
-  {&__pyx_n_s_djm, __pyx_k_djm, sizeof(__pyx_k_djm), 0, 0, 1, 1},
-  {&__pyx_n_s_djm0, __pyx_k_djm0, sizeof(__pyx_k_djm0), 0, 0, 1, 1},
-  {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
-  {&__pyx_n_s_dt, __pyx_k_dt, sizeof(__pyx_k_dt), 0, 0, 1, 1},
-  {&__pyx_n_s_dtf_jd, __pyx_k_dtf_jd, sizeof(__pyx_k_dtf_jd), 0, 0, 1, 1},
-  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
-  {&__pyx_kp_s_dubious_year_for_UTC_before_1960, __pyx_k_dubious_year_for_UTC_before_1960, sizeof(__pyx_k_dubious_year_for_UTC_before_1960), 0, 0, 1, 0},
-  {&__pyx_n_s_elong, __pyx_k_elong, sizeof(__pyx_k_elong), 0, 0, 1, 1},
-  {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
-  {&__pyx_n_s_epd, __pyx_k_epd, sizeof(__pyx_k_epd), 0, 0, 1, 1},
-  {&__pyx_n_s_eraAf2a, __pyx_k_eraAf2a, sizeof(__pyx_k_eraAf2a), 0, 0, 1, 1},
-  {&__pyx_n_s_eraCal2jd, __pyx_k_eraCal2jd, sizeof(__pyx_k_eraCal2jd), 0, 0, 1, 1},
-  {&__pyx_n_s_eraD2dtf, __pyx_k_eraD2dtf, sizeof(__pyx_k_eraD2dtf), 0, 0, 1, 1},
-  {&__pyx_n_s_eraDat, __pyx_k_eraDat, sizeof(__pyx_k_eraDat), 0, 0, 1, 1},
-  {&__pyx_n_s_eraDtf2d, __pyx_k_eraDtf2d, sizeof(__pyx_k_eraDtf2d), 0, 0, 1, 1},
-  {&__pyx_n_s_eraGd2gc, __pyx_k_eraGd2gc, sizeof(__pyx_k_eraGd2gc), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTaitt, __pyx_k_eraTaitt, sizeof(__pyx_k_eraTaitt), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTaiut1, __pyx_k_eraTaiut1, sizeof(__pyx_k_eraTaiut1), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTaiutc, __pyx_k_eraTaiutc, sizeof(__pyx_k_eraTaiutc), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTcbtdb, __pyx_k_eraTcbtdb, sizeof(__pyx_k_eraTcbtdb), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTcgtt, __pyx_k_eraTcgtt, sizeof(__pyx_k_eraTcgtt), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTdbtcb, __pyx_k_eraTdbtcb, sizeof(__pyx_k_eraTdbtcb), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTdbtt, __pyx_k_eraTdbtt, sizeof(__pyx_k_eraTdbtt), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTttai, __pyx_k_eraTttai, sizeof(__pyx_k_eraTttai), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTttcg, __pyx_k_eraTttcg, sizeof(__pyx_k_eraTttcg), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTttdb, __pyx_k_eraTttdb, sizeof(__pyx_k_eraTttdb), 0, 0, 1, 1},
-  {&__pyx_n_s_eraTtut1, __pyx_k_eraTtut1, sizeof(__pyx_k_eraTtut1), 0, 0, 1, 1},
-  {&__pyx_n_s_eraUt1tai, __pyx_k_eraUt1tai, sizeof(__pyx_k_eraUt1tai), 0, 0, 1, 1},
-  {&__pyx_n_s_eraUt1tt, __pyx_k_eraUt1tt, sizeof(__pyx_k_eraUt1tt), 0, 0, 1, 1},
-  {&__pyx_n_s_eraUt1utc, __pyx_k_eraUt1utc, sizeof(__pyx_k_eraUt1utc), 0, 0, 1, 1},
-  {&__pyx_n_s_eraUtctai, __pyx_k_eraUtctai, sizeof(__pyx_k_eraUtctai), 0, 0, 1, 1},
-  {&__pyx_n_s_eraUtcut1, __pyx_k_eraUtcut1, sizeof(__pyx_k_eraUtcut1), 0, 0, 1, 1},
-  {&__pyx_n_s_era_af2a, __pyx_k_era_af2a, sizeof(__pyx_k_era_af2a), 0, 0, 1, 1},
-  {&__pyx_n_s_era_gc2gd, __pyx_k_era_gc2gd, sizeof(__pyx_k_era_gc2gd), 0, 0, 1, 1},
-  {&__pyx_n_s_era_gd2gc, __pyx_k_era_gd2gc, sizeof(__pyx_k_era_gd2gc), 0, 0, 1, 1},
-  {&__pyx_n_s_errors, __pyx_k_errors, sizeof(__pyx_k_errors), 0, 0, 1, 1},
-  {&__pyx_n_s_errs, __pyx_k_errs, sizeof(__pyx_k_errs), 0, 0, 1, 1},
-  {&__pyx_n_s_fd, __pyx_k_fd, sizeof(__pyx_k_fd), 0, 0, 1, 1},
-  {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
-  {&__pyx_n_s_func_name, __pyx_k_func_name, sizeof(__pyx_k_func_name), 0, 0, 1, 1},
-  {&__pyx_n_s_gmst, __pyx_k_gmst, sizeof(__pyx_k_gmst), 0, 0, 1, 1},
-  {&__pyx_n_s_gmst00, __pyx_k_gmst00, sizeof(__pyx_k_gmst00), 0, 0, 1, 1},
-  {&__pyx_n_s_gmst06, __pyx_k_gmst06, sizeof(__pyx_k_gmst06), 0, 0, 1, 1},
-  {&__pyx_n_s_gmst82, __pyx_k_gmst82, sizeof(__pyx_k_gmst82), 0, 0, 1, 1},
-  {&__pyx_n_s_gst, __pyx_k_gst, sizeof(__pyx_k_gst), 0, 0, 1, 1},
-  {&__pyx_n_s_gst00a, __pyx_k_gst00a, sizeof(__pyx_k_gst00a), 0, 0, 1, 1},
-  {&__pyx_n_s_gst00b, __pyx_k_gst00b, sizeof(__pyx_k_gst00b), 0, 0, 1, 1},
-  {&__pyx_n_s_gst06a, __pyx_k_gst06a, sizeof(__pyx_k_gst06a), 0, 0, 1, 1},
-  {&__pyx_n_s_gst94, __pyx_k_gst94, sizeof(__pyx_k_gst94), 0, 0, 1, 1},
-  {&__pyx_n_s_height, __pyx_k_height, sizeof(__pyx_k_height), 0, 0, 1, 1},
-  {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
-  {&__pyx_n_s_iamin, __pyx_k_iamin, sizeof(__pyx_k_iamin), 0, 0, 1, 1},
-  {&__pyx_kp_s_iamin_outside_range_0_59, __pyx_k_iamin_outside_range_0_59, sizeof(__pyx_k_iamin_outside_range_0_59), 0, 0, 1, 0},
-  {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
-  {&__pyx_n_s_ideg, __pyx_k_ideg, sizeof(__pyx_k_ideg), 0, 0, 1, 1},
-  {&__pyx_kp_s_ideg_outside_range_0_359, __pyx_k_ideg_outside_range_0_359, sizeof(__pyx_k_ideg_outside_range_0_359), 0, 0, 1, 0},
-  {&__pyx_n_s_ihmsf, __pyx_k_ihmsf, sizeof(__pyx_k_ihmsf), 0, 0, 1, 1},
-  {&__pyx_n_s_ihr, __pyx_k_ihr, sizeof(__pyx_k_ihr), 0, 0, 1, 1},
-  {&__pyx_kp_s_illegal_case, __pyx_k_illegal_case, sizeof(__pyx_k_illegal_case), 0, 0, 1, 0},
-  {&__pyx_kp_s_illegal_identifier, __pyx_k_illegal_identifier, sizeof(__pyx_k_illegal_identifier), 0, 0, 1, 0},
-  {&__pyx_n_s_im, __pyx_k_im, sizeof(__pyx_k_im), 0, 0, 1, 1},
-  {&__pyx_n_s_imn, __pyx_k_imn, sizeof(__pyx_k_imn), 0, 0, 1, 1},
-  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
-  {&__pyx_n_s_in1, __pyx_k_in1, sizeof(__pyx_k_in1), 0, 0, 1, 1},
-  {&__pyx_n_s_in2, __pyx_k_in2, sizeof(__pyx_k_in2), 0, 0, 1, 1},
-  {&__pyx_n_s_intc, __pyx_k_intc, sizeof(__pyx_k_intc), 0, 0, 1, 1},
-  {&__pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_k_internal_1_root_src_astropy_ast, sizeof(__pyx_k_internal_1_root_src_astropy_ast), 0, 0, 1, 0},
-  {&__pyx_n_s_iy, __pyx_k_iy, sizeof(__pyx_k_iy), 0, 0, 1, 1},
-  {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},
-  {&__pyx_n_s_jd1, __pyx_k_jd1, sizeof(__pyx_k_jd1), 0, 0, 1, 1},
-  {&__pyx_n_s_jd2, __pyx_k_jd2, sizeof(__pyx_k_jd2), 0, 0, 1, 1},
-  {&__pyx_n_s_jd_besselian_epoch, __pyx_k_jd_besselian_epoch, sizeof(__pyx_k_jd_besselian_epoch), 0, 0, 1, 1},
-  {&__pyx_n_s_jd_dtf, __pyx_k_jd_dtf, sizeof(__pyx_k_jd_dtf), 0, 0, 1, 1},
-  {&__pyx_n_s_jd_julian_epoch, __pyx_k_jd_julian_epoch, sizeof(__pyx_k_jd_julian_epoch), 0, 0, 1, 1},
-  {&__pyx_n_s_julian_epoch_jd, __pyx_k_julian_epoch_jd, sizeof(__pyx_k_julian_epoch_jd), 0, 0, 1, 1},
-  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
-  {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1},
-  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
-  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
-  {&__pyx_n_s_ndp, __pyx_k_ndp, sizeof(__pyx_k_ndp), 0, 0, 1, 1},
-  {&__pyx_n_s_nitems, __pyx_k_nitems, sizeof(__pyx_k_nitems), 0, 0, 1, 1},
-  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
-  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
-  {&__pyx_n_s_ord, __pyx_k_ord, sizeof(__pyx_k_ord), 0, 0, 1, 1},
-  {&__pyx_n_s_out, __pyx_k_out, sizeof(__pyx_k_out), 0, 0, 1, 1},
-  {&__pyx_n_s_out1, __pyx_k_out1, sizeof(__pyx_k_out1), 0, 0, 1, 1},
-  {&__pyx_n_s_out2, __pyx_k_out2, sizeof(__pyx_k_out2), 0, 0, 1, 1},
-  {&__pyx_n_s_phi, __pyx_k_phi, sizeof(__pyx_k_phi), 0, 0, 1, 1},
-  {&__pyx_n_s_rad, __pyx_k_rad, sizeof(__pyx_k_rad), 0, 0, 1, 1},
-  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
-  {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1},
-  {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1},
-  {&__pyx_n_s_scale, __pyx_k_scale, sizeof(__pyx_k_scale), 0, 0, 1, 1},
-  {&__pyx_n_s_sec, __pyx_k_sec, sizeof(__pyx_k_sec), 0, 0, 1, 1},
-  {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
-  {&__pyx_n_s_sign, __pyx_k_sign, sizeof(__pyx_k_sign), 0, 0, 1, 1},
-  {&__pyx_n_s_tai_tt, __pyx_k_tai_tt, sizeof(__pyx_k_tai_tt), 0, 0, 1, 1},
-  {&__pyx_n_s_tai_ut1, __pyx_k_tai_ut1, sizeof(__pyx_k_tai_ut1), 0, 0, 1, 1},
-  {&__pyx_n_s_tai_utc, __pyx_k_tai_utc, sizeof(__pyx_k_tai_utc), 0, 0, 1, 1},
-  {&__pyx_n_s_tcb_tdb, __pyx_k_tcb_tdb, sizeof(__pyx_k_tcb_tdb), 0, 0, 1, 1},
-  {&__pyx_n_s_tcg_tt, __pyx_k_tcg_tt, sizeof(__pyx_k_tcg_tt), 0, 0, 1, 1},
-  {&__pyx_n_s_tdb_tcb, __pyx_k_tdb_tcb, sizeof(__pyx_k_tdb_tcb), 0, 0, 1, 1},
-  {&__pyx_n_s_tdb_tt, __pyx_k_tdb_tt, sizeof(__pyx_k_tdb_tt), 0, 0, 1, 1},
-  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
-  {&__pyx_kp_s_time_is_after_end_of_day, __pyx_k_time_is_after_end_of_day, sizeof(__pyx_k_time_is_after_end_of_day), 0, 0, 1, 0},
-  {&__pyx_kp_s_time_is_after_end_of_day_and, __pyx_k_time_is_after_end_of_day_and, sizeof(__pyx_k_time_is_after_end_of_day_and), 0, 0, 1, 0},
-  {&__pyx_n_s_tt1, __pyx_k_tt1, sizeof(__pyx_k_tt1), 0, 0, 1, 1},
-  {&__pyx_n_s_tt2, __pyx_k_tt2, sizeof(__pyx_k_tt2), 0, 0, 1, 1},
-  {&__pyx_n_s_tt_tai, __pyx_k_tt_tai, sizeof(__pyx_k_tt_tai), 0, 0, 1, 1},
-  {&__pyx_n_s_tt_tcg, __pyx_k_tt_tcg, sizeof(__pyx_k_tt_tcg), 0, 0, 1, 1},
-  {&__pyx_n_s_tt_tdb, __pyx_k_tt_tdb, sizeof(__pyx_k_tt_tdb), 0, 0, 1, 1},
-  {&__pyx_n_s_tt_ut1, __pyx_k_tt_ut1, sizeof(__pyx_k_tt_ut1), 0, 0, 1, 1},
-  {&__pyx_n_s_u, __pyx_k_u, sizeof(__pyx_k_u), 0, 0, 1, 1},
-  {&__pyx_kp_s_unacceptable_date, __pyx_k_unacceptable_date, sizeof(__pyx_k_unacceptable_date), 0, 0, 1, 0},
-  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
-  {&__pyx_n_s_ut, __pyx_k_ut, sizeof(__pyx_k_ut), 0, 0, 1, 1},
-  {&__pyx_n_s_ut11, __pyx_k_ut11, sizeof(__pyx_k_ut11), 0, 0, 1, 1},
-  {&__pyx_n_s_ut12, __pyx_k_ut12, sizeof(__pyx_k_ut12), 0, 0, 1, 1},
-  {&__pyx_n_s_ut1_tai, __pyx_k_ut1_tai, sizeof(__pyx_k_ut1_tai), 0, 0, 1, 1},
-  {&__pyx_n_s_ut1_tt, __pyx_k_ut1_tt, sizeof(__pyx_k_ut1_tt), 0, 0, 1, 1},
-  {&__pyx_n_s_ut1_utc, __pyx_k_ut1_utc, sizeof(__pyx_k_ut1_utc), 0, 0, 1, 1},
-  {&__pyx_n_s_utc_tai, __pyx_k_utc_tai, sizeof(__pyx_k_utc_tai), 0, 0, 1, 1},
-  {&__pyx_n_s_utc_ut1, __pyx_k_utc_ut1, sizeof(__pyx_k_utc_ut1), 0, 0, 1, 1},
-  {&__pyx_n_s_utils_exceptions, __pyx_k_utils_exceptions, sizeof(__pyx_k_utils_exceptions), 0, 0, 1, 1},
-  {&__pyx_n_s_v, __pyx_k_v, sizeof(__pyx_k_v), 0, 0, 1, 1},
-  {&__pyx_n_s_warn, __pyx_k_warn, sizeof(__pyx_k_warn), 0, 0, 1, 1},
-  {&__pyx_n_s_warnings, __pyx_k_warnings, sizeof(__pyx_k_warnings), 0, 0, 1, 1},
-  {&__pyx_n_s_warns, __pyx_k_warns, sizeof(__pyx_k_warns), 0, 0, 1, 1},
-  {&__pyx_n_s_xyz, __pyx_k_xyz, sizeof(__pyx_k_xyz), 0, 0, 1, 1},
-  {&__pyx_n_s_xyz_item, __pyx_k_xyz_item, sizeof(__pyx_k_xyz_item), 0, 0, 1, 1},
-  {0, 0, 0, 0, 0, 0, 0}
-};
-static int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_ord = __Pyx_GetBuiltinName(__pyx_n_s_ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  return 0;
-  __pyx_L1_error:;
-  return -1;
-}
-
-static int __Pyx_InitCachedConstants(void) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
-
-  /* "astropy/time/erfa_time.pyx":1334
- *     cdef unsigned int i
- *     cdef unsigned int nitems = elong.shape[0]
- *     cdef np.ndarray[double, ndim=1] xyz = np.empty(3, dtype=np.double)             # <<<<<<<<<<<<<<
- *     cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)
- * 
- */
-  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_int_3); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__3);
-  __Pyx_GIVEREF(__pyx_tuple__3);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":215
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- */
-  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__4);
-  __Pyx_GIVEREF(__pyx_tuple__4);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":219
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
- * 
- *             info.buf = PyArray_DATA(self)
- */
-  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__5);
-  __Pyx_GIVEREF(__pyx_tuple__5);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
- */
-  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__6);
-  __Pyx_GIVEREF(__pyx_tuple__6);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799
- * 
- *         if (end - f) - <int>(new_offset - offset[0]) < 15:
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
- * 
- *         if ((child.byteorder == c'>' and little_endian) or
- */
-  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__7);
-  __Pyx_GIVEREF(__pyx_tuple__7);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *             # One could encode it in the format string and have Cython
- *             # complain instead, BUT: < and > in format strings also imply
- */
-  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__8);
-  __Pyx_GIVEREF(__pyx_tuple__8);
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823
- *             t = child.type_num
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
- * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- */
-  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__9);
-  __Pyx_GIVEREF(__pyx_tuple__9);
-
-  /* "astropy/time/erfa_time.pyx":64
- *           'beyond last known leap second)'
- * 
- * def check_return(ret, func_name, warns={}, errors={}):             # <<<<<<<<<<<<<<
- *     """Check the return value from an era routine"""
- *     if ret in warns:
- */
-  __pyx_tuple__10 = PyTuple_Pack(4, __pyx_n_s_ret, __pyx_n_s_func_name, __pyx_n_s_warns, __pyx_n_s_errors); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__10);
-  __Pyx_GIVEREF(__pyx_tuple__10);
-  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_check_return, 64, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":77
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def cal2jd(             # <<<<<<<<<<<<<<
- *     np.ndarray[int, ndim=1] iy,
- *     np.ndarray[int, ndim=1] im,
- */
-  __pyx_tuple__12 = PyTuple_Pack(10, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_djm0, __pyx_n_s_djm, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__12);
-  __Pyx_GIVEREF(__pyx_tuple__12);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(5, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_cal2jd, 77, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":128
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tai_utc(np.ndarray[int, ndim=1] iy,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] im,
- *               np.ndarray[int, ndim=1] id,
- */
-  __pyx_tuple__14 = PyTuple_Pack(10, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_fd, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_out, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__14);
-  __Pyx_GIVEREF(__pyx_tuple__14);
-  __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(4, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_d_tai_utc, 128, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":226
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_dtf(scale, ndp,             # <<<<<<<<<<<<<<
- *               np.ndarray[double, ndim=1] d1,
- *               np.ndarray[double, ndim=1] d2):
- */
-  __pyx_tuple__16 = PyTuple_Pack(13, __pyx_n_s_scale, __pyx_n_s_ndp, __pyx_n_s_d1, __pyx_n_s_d2, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_ihmsf, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__16);
-  __Pyx_GIVEREF(__pyx_tuple__16);
-  __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(4, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_jd_dtf, 226, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":305
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def dtf_jd(scale,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] iy,
- *               np.ndarray[int, ndim=1] im,
- */
-  __pyx_tuple__18 = PyTuple_Pack(14, __pyx_n_s_scale, __pyx_n_s_iy, __pyx_n_s_im, __pyx_n_s_id, __pyx_n_s_ihr, __pyx_n_s_imn, __pyx_n_s_sec, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__18);
-  __Pyx_GIVEREF(__pyx_tuple__18);
-  __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(7, 0, 14, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_dtf_jd, 305, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":399
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__20 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__20);
-  __Pyx_GIVEREF(__pyx_tuple__20);
-  __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tai_tt, 399, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":436
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcb_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__22 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__22);
-  __Pyx_GIVEREF(__pyx_tuple__22);
-  __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tcb_tdb, 436, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":492
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcg_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__24 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__24);
-  __Pyx_GIVEREF(__pyx_tuple__24);
-  __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tcg_tt, 492, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":523
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tcb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__26 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
-  __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tdb_tcb, 523, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":553
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__28 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
-  __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tt_tai, 553, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":583
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tcg(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__30 = PyTuple_Pack(7, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__30);
-  __Pyx_GIVEREF(__pyx_tuple__30);
-  __pyx_codeobj__31 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__30, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tt_tcg, 583, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":612
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__32 = PyTuple_Pack(9, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__32);
-  __Pyx_GIVEREF(__pyx_tuple__32);
-  __pyx_codeobj__33 = (PyObject*)__Pyx_PyCode_New(2, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__32, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_utc_tai, 612, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":670
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_tuple__34 = PyTuple_Pack(9, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__34);
-  __Pyx_GIVEREF(__pyx_tuple__34);
-  __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(2, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tai_utc, 670, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":727
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__36 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__36);
-  __Pyx_GIVEREF(__pyx_tuple__36);
-  __pyx_codeobj__37 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__36, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tai_ut1, 727, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":769
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__38 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__38);
-  __Pyx_GIVEREF(__pyx_tuple__38);
-  __pyx_codeobj__39 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__38, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_ut1_tai, 769, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":811
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__40 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__40);
-  __Pyx_GIVEREF(__pyx_tuple__40);
-  __pyx_codeobj__41 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__40, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tt_ut1, 811, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":852
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__42 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__42);
-  __Pyx_GIVEREF(__pyx_tuple__42);
-  __pyx_codeobj__43 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__42, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_ut1_tt, 852, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":893
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__44 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__44);
-  __Pyx_GIVEREF(__pyx_tuple__44);
-  __pyx_codeobj__45 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__44, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tdb_tt, 893, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":943
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__46 = PyTuple_Pack(8, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__46);
-  __Pyx_GIVEREF(__pyx_tuple__46);
-  __pyx_codeobj__47 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__46, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_tt_tdb, 943, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":993
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__48 = PyTuple_Pack(10, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__48);
-  __Pyx_GIVEREF(__pyx_tuple__48);
-  __pyx_codeobj__49 = (PyObject*)__Pyx_PyCode_New(3, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__48, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_ut1_utc, 993, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1057
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_tuple__50 = PyTuple_Pack(10, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_dt, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_out1, __pyx_n_s_out2, __pyx_n_s_warns, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__50);
-  __Pyx_GIVEREF(__pyx_tuple__50);
-  __pyx_codeobj__51 = (PyObject*)__Pyx_PyCode_New(3, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__50, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_utc_ut1, 1057, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1125
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tdb_tt(np.ndarray[double, ndim=1] in1,             # <<<<<<<<<<<<<<
- *              np.ndarray[double, ndim=1] in2,
- *              np.ndarray[double, ndim=1] ut,
- */
-  __pyx_tuple__52 = PyTuple_Pack(10, __pyx_n_s_in1, __pyx_n_s_in2, __pyx_n_s_ut, __pyx_n_s_elong, __pyx_n_s_u, __pyx_n_s_v, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_out); if (unlikely(!__pyx_tuple__52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__52);
-  __Pyx_GIVEREF(__pyx_tuple__52);
-  __pyx_codeobj__53 = (PyObject*)__Pyx_PyCode_New(6, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__52, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_d_tdb_tt, 1125, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1246
- * 
- * 
- * def era_af2a(sign, ideg, iamin, asec):             # <<<<<<<<<<<<<<
- *     """
- *     int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
- */
-  __pyx_tuple__54 = PyTuple_Pack(8, __pyx_n_s_sign, __pyx_n_s_ideg, __pyx_n_s_iamin, __pyx_n_s_asec, __pyx_n_s_rad, __pyx_n_s_s, __pyx_n_s_warns, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__54)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__54);
-  __Pyx_GIVEREF(__pyx_tuple__54);
-  __pyx_codeobj__55 = (PyObject*)__Pyx_PyCode_New(4, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__54, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_era_af2a, 1246, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__55)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1287
- *     return rad
- * 
- * def era_gd2gc(n, elong, phi, height):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-  __pyx_tuple__56 = PyTuple_Pack(10, __pyx_n_s_n, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_i, __pyx_n_s_nitems, __pyx_n_s_xyz, __pyx_n_s_out, __pyx_n_s_errs, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__56)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__56);
-  __Pyx_GIVEREF(__pyx_tuple__56);
-  __pyx_codeobj__57 = (PyObject*)__Pyx_PyCode_New(4, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__56, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_era_gd2gc, 1287, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1349
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def era_gc2gd(n, xyz):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-  __pyx_tuple__58 = PyTuple_Pack(11, __pyx_n_s_n, __pyx_n_s_xyz, __pyx_n_s_i, __pyx_n_s_nitems, __pyx_n_s_elong, __pyx_n_s_phi, __pyx_n_s_height, __pyx_n_s_xyz_item, __pyx_n_s_errs, __pyx_n_s_j, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__58)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__58);
-  __Pyx_GIVEREF(__pyx_tuple__58);
-  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(2, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_era_gc2gd, 1349, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1419
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_julian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                     np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpj(double dj1, double dj2)
- */
-  __pyx_tuple__60 = PyTuple_Pack(5, __pyx_n_s_jd1, __pyx_n_s_jd2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_epd); if (unlikely(!__pyx_tuple__60)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__60);
-  __Pyx_GIVEREF(__pyx_tuple__60);
-  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_jd_julian_epoch, 1419, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1450
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def julian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpj2jd(double epj, double *djm0, double *djm)
- *     **  Julian Epoch to Julian Date.
- */
-  __pyx_tuple__62 = PyTuple_Pack(5, __pyx_n_s_epd, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_jd1, __pyx_n_s_jd2); if (unlikely(!__pyx_tuple__62)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__62);
-  __Pyx_GIVEREF(__pyx_tuple__62);
-  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_julian_epoch_jd, 1450, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1472
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_besselian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                        np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpb(double dj1, double dj2)
- */
-  __pyx_tuple__64 = PyTuple_Pack(5, __pyx_n_s_jd1, __pyx_n_s_jd2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_epd); if (unlikely(!__pyx_tuple__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__64);
-  __Pyx_GIVEREF(__pyx_tuple__64);
-  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_jd_besselian_epoch, 1472, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1503
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def besselian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpb2jd(double epj, double *djm0, double *djm)
- *     **  Besselian Epoch to Julian Date.
- */
-  __pyx_tuple__66 = PyTuple_Pack(5, __pyx_n_s_epd, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_jd1, __pyx_n_s_jd2); if (unlikely(!__pyx_tuple__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__66);
-  __Pyx_GIVEREF(__pyx_tuple__66);
-  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_besselian_epoch_jd, 1503, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1532
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst00(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_tuple__68 = PyTuple_Pack(7, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gmst); if (unlikely(!__pyx_tuple__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__68);
-  __Pyx_GIVEREF(__pyx_tuple__68);
-  __pyx_codeobj__69 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__68, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gmst00, 1532, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1614
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst06(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_tuple__70 = PyTuple_Pack(7, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gmst); if (unlikely(!__pyx_tuple__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__70);
-  __Pyx_GIVEREF(__pyx_tuple__70);
-  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gmst06, 1614, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1683
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst82(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12):
- *     """Wrap double double eraGmst82(double dj1, double dj2)
- */
-  __pyx_tuple__72 = PyTuple_Pack(5, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gmst); if (unlikely(!__pyx_tuple__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__72);
-  __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gmst82, 1683, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1752
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_tuple__74 = PyTuple_Pack(7, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gst); if (unlikely(!__pyx_tuple__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__74);
-  __Pyx_GIVEREF(__pyx_tuple__74);
-  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gst00a, 1752, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1832
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00b(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *             np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst00b(double uta, double utb)
- */
-  __pyx_tuple__76 = PyTuple_Pack(5, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gst); if (unlikely(!__pyx_tuple__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__76);
-  __Pyx_GIVEREF(__pyx_tuple__76);
-  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gst00b, 1832, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1918
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst06a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_tuple__78 = PyTuple_Pack(7, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_tt1, __pyx_n_s_tt2, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gst); if (unlikely(!__pyx_tuple__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__78);
-  __Pyx_GIVEREF(__pyx_tuple__78);
-  __pyx_codeobj__79 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__78, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gst06a, 1918, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":1989
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst94(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *           np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst94(double uta, double utb)
- */
-  __pyx_tuple__80 = PyTuple_Pack(5, __pyx_n_s_ut11, __pyx_n_s_ut12, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_gst); if (unlikely(!__pyx_tuple__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_tuple__80);
-  __Pyx_GIVEREF(__pyx_tuple__80);
-  __pyx_codeobj__81 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__80, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_internal_1_root_src_astropy_ast, __pyx_n_s_gst94, 1989, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_RefNannyFinishContext();
-  return 0;
-  __pyx_L1_error:;
-  __Pyx_RefNannyFinishContext();
-  return -1;
-}
-
-static int __Pyx_InitGlobals(void) {
-  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_2 = PyInt_FromLong(-2); if (unlikely(!__pyx_int_neg_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_3 = PyInt_FromLong(-3); if (unlikely(!__pyx_int_neg_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_4 = PyInt_FromLong(-4); if (unlikely(!__pyx_int_neg_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_5 = PyInt_FromLong(-5); if (unlikely(!__pyx_int_neg_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_int_neg_6 = PyInt_FromLong(-6); if (unlikely(!__pyx_int_neg_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  return 0;
-  __pyx_L1_error:;
-  return -1;
-}
-
-#if PY_MAJOR_VERSION < 3
-PyMODINIT_FUNC initerfa_time(void); /*proto*/
-PyMODINIT_FUNC initerfa_time(void)
-#else
-PyMODINIT_FUNC PyInit_erfa_time(void); /*proto*/
-PyMODINIT_FUNC PyInit_erfa_time(void)
-#endif
-{
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannyDeclarations
-  #if CYTHON_REFNANNY
-  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
-  if (!__Pyx_RefNanny) {
-      PyErr_Clear();
-      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
-      if (!__Pyx_RefNanny)
-          Py_FatalError("failed to import 'refnanny' module");
-  }
-  #endif
-  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_erfa_time(void)", 0);
-  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #ifdef __Pyx_CyFunction_USED
-  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  #ifdef __Pyx_FusedFunction_USED
-  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  #ifdef __Pyx_Generator_USED
-  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  /*--- Library function declarations ---*/
-  /*--- Threads initialization code ---*/
-  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
-  #ifdef WITH_THREAD /* Python build with threading support? */
-  PyEval_InitThreads();
-  #endif
-  #endif
-  /*--- Module creation code ---*/
-  #if PY_MAJOR_VERSION < 3
-  __pyx_m = Py_InitModule4("erfa_time", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
-  #else
-  __pyx_m = PyModule_Create(&__pyx_moduledef);
-  #endif
-  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_INCREF(__pyx_d);
-  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #if CYTHON_COMPILING_IN_PYPY
-  Py_INCREF(__pyx_b);
-  #endif
-  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  /*--- Initialize various global constants etc. ---*/
-  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
-  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  if (__pyx_module_is_main_astropy__time__erfa_time) {
-    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  }
-  #if PY_MAJOR_VERSION >= 3
-  {
-    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (!PyDict_GetItemString(modules, "astropy.time.erfa_time")) {
-      if (unlikely(PyDict_SetItemString(modules, "astropy.time.erfa_time", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-  /*--- Builtin init code ---*/
-  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Constants init code ---*/
-  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Global init code ---*/
-  /*--- Variable export code ---*/
-  /*--- Function export code ---*/
-  /*--- Type init code ---*/
-  /*--- Type import code ---*/
-  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
-  #if CYTHON_COMPILING_IN_PYPY
-  sizeof(PyTypeObject),
-  #else
-  sizeof(PyHeapTypeObject),
-  #endif
-  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Variable import code ---*/
-  /*--- Function import code ---*/
-  /*--- Execution code ---*/
-
-  /* "astropy/time/erfa_time.pyx":1
- * import warnings             # <<<<<<<<<<<<<<
- * 
- * from ..utils.exceptions import AstropyUserWarning
- */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_warnings, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
-  /* "astropy/time/erfa_time.pyx":3
- * import warnings
- * 
- * from ..utils.exceptions import AstropyUserWarning             # <<<<<<<<<<<<<<
- * 
- * import numpy as np
- */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_n_s_AstropyUserWarning);
-  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_AstropyUserWarning);
-  __Pyx_GIVEREF(__pyx_n_s_AstropyUserWarning);
-  __pyx_t_2 = __Pyx_Import(__pyx_n_s_utils_exceptions, __pyx_t_1, 2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_AstropyUserWarning); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_AstropyUserWarning, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":5
- * from ..utils.exceptions import AstropyUserWarning
- * 
- * import numpy as np             # <<<<<<<<<<<<<<
- * cimport numpy as np
- * import cython
- */
-  __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":61
- *     double eraGst94(double uta, double utb)
- * 
- * DUBIOUS = 'dubious year for UTC (before 1960.0 or 5 years ' \             # <<<<<<<<<<<<<<
- *           'beyond last known leap second)'
- * 
- */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DUBIOUS, __pyx_kp_s_dubious_year_for_UTC_before_1960) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "astropy/time/erfa_time.pyx":64
- *           'beyond last known leap second)'
- * 
- * def check_return(ret, func_name, warns={}, errors={}):             # <<<<<<<<<<<<<<
- *     """Check the return value from an era routine"""
- *     if ret in warns:
- */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_k_ = __pyx_t_2;
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_k__2 = __pyx_t_2;
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_1check_return, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_check_return, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":77
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def cal2jd(             # <<<<<<<<<<<<<<
- *     np.ndarray[int, ndim=1] iy,
- *     np.ndarray[int, ndim=1] im,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_3cal2jd, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_cal2jd, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":128
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tai_utc(np.ndarray[int, ndim=1] iy,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] im,
- *               np.ndarray[int, ndim=1] id,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_5d_tai_utc, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_d_tai_utc, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":226
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_dtf(scale, ndp,             # <<<<<<<<<<<<<<
- *               np.ndarray[double, ndim=1] d1,
- *               np.ndarray[double, ndim=1] d2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_7jd_dtf, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_jd_dtf, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":305
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def dtf_jd(scale,             # <<<<<<<<<<<<<<
- *               np.ndarray[int, ndim=1] iy,
- *               np.ndarray[int, ndim=1] im,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_9dtf_jd, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_dtf_jd, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":399
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_11tai_tt, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tai_tt, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":436
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcb_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_13tcb_tdb, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tcb_tdb, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":492
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tcg_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_15tcg_tt, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tcg_tt, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":523
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tcb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_17tdb_tcb, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tdb_tcb, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":553
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_19tt_tai, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tt_tai, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":583
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tcg(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_21tt_tcg, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tt_tcg, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":612
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_23utc_tai, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_utc_tai, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":670
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2):
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_25tai_utc, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tai_utc, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":727
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tai_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_27tai_ut1, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tai_ut1, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":769
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tai(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_29ut1_tai, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1_tai, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":811
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_31tt_ut1, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tt_ut1, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":852
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_33ut1_tt, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1_tt, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":893
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tdb_tt(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_35tdb_tt, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tdb_tt, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":943
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def tt_tdb(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_37tt_tdb, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_tt_tdb, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":993
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def ut1_utc(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_39ut1_utc, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ut1_utc, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1057
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def utc_ut1(             # <<<<<<<<<<<<<<
- *     np.ndarray[double, ndim=1] in1,
- *     np.ndarray[double, ndim=1] in2,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_41utc_ut1, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_utc_ut1, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1125
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def d_tdb_tt(np.ndarray[double, ndim=1] in1,             # <<<<<<<<<<<<<<
- *              np.ndarray[double, ndim=1] in2,
- *              np.ndarray[double, ndim=1] ut,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_43d_tdb_tt, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_d_tdb_tt, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1246
- * 
- * 
- * def era_af2a(sign, ideg, iamin, asec):             # <<<<<<<<<<<<<<
- *     """
- *     int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_45era_af2a, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_era_af2a, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1287
- *     return rad
- * 
- * def era_gd2gc(n, elong, phi, height):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_47era_gd2gc, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_era_gd2gc, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1349
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def era_gc2gd(n, xyz):             # <<<<<<<<<<<<<<
- *     """
- *     Wrap
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_49era_gc2gd, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_era_gc2gd, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1419
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_julian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                     np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpj(double dj1, double dj2)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_51jd_julian_epoch, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_jd_julian_epoch, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1450
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def julian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpj2jd(double epj, double *djm0, double *djm)
- *     **  Julian Epoch to Julian Date.
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_53julian_epoch_jd, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_julian_epoch_jd, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1472
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def jd_besselian_epoch(np.ndarray[double, ndim=1] jd1,             # <<<<<<<<<<<<<<
- *                        np.ndarray[double, ndim=1] jd2):
- *     """ Wrap double eraEpb(double dj1, double dj2)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_55jd_besselian_epoch, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_jd_besselian_epoch, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1503
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def besselian_epoch_jd(np.ndarray[double, ndim=1] epd):             # <<<<<<<<<<<<<<
- *     """ Wrap void eraEpb2jd(double epj, double *djm0, double *djm)
- *     **  Besselian Epoch to Julian Date.
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_57besselian_epoch_jd, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_besselian_epoch_jd, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1532
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst00(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_59gmst00, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst00, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1532; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1614
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst06(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_61gmst06, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst06, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1683
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gmst82(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12):
- *     """Wrap double double eraGmst82(double dj1, double dj2)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_63gmst82, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gmst82, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1683; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1752
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_65gst00a, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst00a, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1832
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst00b(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *             np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst00b(double uta, double utb)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_67gst00b, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst00b, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1918
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst06a(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *            np.ndarray[double, ndim=1] ut12,
- *            np.ndarray[double, ndim=1] tt1,
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_69gst06a, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst06a, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1989
- * @cython.wraparound(False)
- * @cython.boundscheck(False)
- * def gst94(np.ndarray[double, ndim=1] ut11,             # <<<<<<<<<<<<<<
- *           np.ndarray[double, ndim=1] ut12):
- *     """Wrap double eraGst94(double uta, double utb)
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7astropy_4time_9erfa_time_71gst94, NULL, __pyx_n_s_astropy_time_erfa_time); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gst94, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "astropy/time/erfa_time.pyx":1
- * import warnings             # <<<<<<<<<<<<<<
- * 
- * from ..utils.exceptions import AstropyUserWarning
- */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "../../../usr/local/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976
- *      arr.base = baseptr
- * 
- * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
- *     if arr.base is NULL:
- *         return None
- */
-
-  /*--- Wrapped vars code ---*/
-
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  if (__pyx_m) {
-    if (__pyx_d) {
-      __Pyx_AddTraceback("init astropy.time.erfa_time", __pyx_clineno, __pyx_lineno, __pyx_filename);
-    }
-    Py_DECREF(__pyx_m); __pyx_m = 0;
-  } else if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_ImportError, "init astropy.time.erfa_time");
-  }
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  #if PY_MAJOR_VERSION < 3
-  return;
-  #else
-  return __pyx_m;
-  #endif
-}
-
-/* Runtime support code */
-#if CYTHON_REFNANNY
-static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
-    PyObject *m = NULL, *p = NULL;
-    void *r = NULL;
-    m = PyImport_ImportModule((char *)modname);
-    if (!m) goto end;
-    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
-    if (!p) goto end;
-    r = PyLong_AsVoidPtr(p);
-end:
-    Py_XDECREF(p);
-    Py_XDECREF(m);
-    return (__Pyx_RefNannyAPIStruct *)r;
-}
-#endif
-
-static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
-    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
-    if (unlikely(!result)) {
-        PyErr_Format(PyExc_NameError,
-#if PY_MAJOR_VERSION >= 3
-            "name '%U' is not defined", name);
-#else
-            "name '%.200s' is not defined", PyString_AS_STRING(name));
-#endif
-    }
-    return result;
-}
-
-static void __Pyx_RaiseArgtupleInvalid(
-    const char* func_name,
-    int exact,
-    Py_ssize_t num_min,
-    Py_ssize_t num_max,
-    Py_ssize_t num_found)
-{
-    Py_ssize_t num_expected;
-    const char *more_or_less;
-    if (num_found < num_min) {
-        num_expected = num_min;
-        more_or_less = "at least";
-    } else {
-        num_expected = num_max;
-        more_or_less = "at most";
-    }
-    if (exact) {
-        more_or_less = "exactly";
-    }
-    PyErr_Format(PyExc_TypeError,
-                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
-                 func_name, more_or_less, num_expected,
-                 (num_expected == 1) ? "" : "s", num_found);
-}
-
-static void __Pyx_RaiseDoubleKeywordsError(
-    const char* func_name,
-    PyObject* kw_name)
-{
-    PyErr_Format(PyExc_TypeError,
-        #if PY_MAJOR_VERSION >= 3
-        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
-        #else
-        "%s() got multiple values for keyword argument '%s'", func_name,
-        PyString_AsString(kw_name));
-        #endif
-}
-
-static int __Pyx_ParseOptionalKeywords(
-    PyObject *kwds,
-    PyObject **argnames[],
-    PyObject *kwds2,
-    PyObject *values[],
-    Py_ssize_t num_pos_args,
-    const char* function_name)
-{
-    PyObject *key = 0, *value = 0;
-    Py_ssize_t pos = 0;
-    PyObject*** name;
-    PyObject*** first_kw_arg = argnames + num_pos_args;
-    while (PyDict_Next(kwds, &pos, &key, &value)) {
-        name = first_kw_arg;
-        while (*name && (**name != key)) name++;
-        if (*name) {
-            values[name-argnames] = value;
-            continue;
-        }
-        name = first_kw_arg;
-        #if PY_MAJOR_VERSION < 3
-        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
-            while (*name) {
-                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
-                        && _PyString_Eq(**name, key)) {
-                    values[name-argnames] = value;
-                    break;
-                }
-                name++;
-            }
-            if (*name) continue;
-            else {
-                PyObject*** argname = argnames;
-                while (argname != first_kw_arg) {
-                    if ((**argname == key) || (
-                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
-                             && _PyString_Eq(**argname, key))) {
-                        goto arg_passed_twice;
-                    }
-                    argname++;
-                }
-            }
-        } else
-        #endif
-        if (likely(PyUnicode_Check(key))) {
-            while (*name) {
-                int cmp = (**name == key) ? 0 :
-                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
-                #endif
-                    PyUnicode_Compare(**name, key);
-                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
-                if (cmp == 0) {
-                    values[name-argnames] = value;
-                    break;
-                }
-                name++;
-            }
-            if (*name) continue;
-            else {
-                PyObject*** argname = argnames;
-                while (argname != first_kw_arg) {
-                    int cmp = (**argname == key) ? 0 :
-                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
-                    #endif
-                        PyUnicode_Compare(**argname, key);
-                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
-                    if (cmp == 0) goto arg_passed_twice;
-                    argname++;
-                }
-            }
-        } else
-            goto invalid_keyword_type;
-        if (kwds2) {
-            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
-        } else {
-            goto invalid_keyword;
-        }
-    }
-    return 0;
-arg_passed_twice:
-    __Pyx_RaiseDoubleKeywordsError(function_name, key);
-    goto bad;
-invalid_keyword_type:
-    PyErr_Format(PyExc_TypeError,
-        "%.200s() keywords must be strings", function_name);
-    goto bad;
-invalid_keyword:
-    PyErr_Format(PyExc_TypeError,
-    #if PY_MAJOR_VERSION < 3
-        "%.200s() got an unexpected keyword argument '%.200s'",
-        function_name, PyString_AsString(key));
-    #else
-        "%s() got an unexpected keyword argument '%U'",
-        function_name, key);
-    #endif
-bad:
-    return -1;
-}
-
-static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
-    PyObject *result;
-#if CYTHON_COMPILING_IN_CPYTHON
-    result = PyDict_GetItem(__pyx_d, name);
-    if (likely(result)) {
-        Py_INCREF(result);
-    } else {
-#else
-    result = PyObject_GetItem(__pyx_d, name);
-    if (!result) {
-        PyErr_Clear();
-#endif
-        result = __Pyx_GetBuiltinName(name);
-    }
-    return result;
-}
-
-#if CYTHON_COMPILING_IN_CPYTHON
-static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
-    PyObject *result;
-    ternaryfunc call = func->ob_type->tp_call;
-    if (unlikely(!call))
-        return PyObject_Call(func, arg, kw);
-    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
-        return NULL;
-    result = (*call)(func, arg, kw);
-    Py_LeaveRecursiveCall();
-    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
-        PyErr_SetString(
-            PyExc_SystemError,
-            "NULL result without error in PyObject_Call");
-    }
-    return result;
-}
-#endif
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    PyObject *tmp_type, *tmp_value, *tmp_tb;
-    PyThreadState *tstate = PyThreadState_GET();
-    tmp_type = tstate->curexc_type;
-    tmp_value = tstate->curexc_value;
-    tmp_tb = tstate->curexc_traceback;
-    tstate->curexc_type = type;
-    tstate->curexc_value = value;
-    tstate->curexc_traceback = tb;
-    Py_XDECREF(tmp_type);
-    Py_XDECREF(tmp_value);
-    Py_XDECREF(tmp_tb);
-#else
-    PyErr_Restore(type, value, tb);
-#endif
-}
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    PyThreadState *tstate = PyThreadState_GET();
-    *type = tstate->curexc_type;
-    *value = tstate->curexc_value;
-    *tb = tstate->curexc_traceback;
-    tstate->curexc_type = 0;
-    tstate->curexc_value = 0;
-    tstate->curexc_traceback = 0;
-#else
-    PyErr_Fetch(type, value, tb);
-#endif
-}
-
-#if PY_MAJOR_VERSION < 3
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
-                        CYTHON_UNUSED PyObject *cause) {
-    Py_XINCREF(type);
-    if (!value || value == Py_None)
-        value = NULL;
-    else
-        Py_INCREF(value);
-    if (!tb || tb == Py_None)
-        tb = NULL;
-    else {
-        Py_INCREF(tb);
-        if (!PyTraceBack_Check(tb)) {
-            PyErr_SetString(PyExc_TypeError,
-                "raise: arg 3 must be a traceback or None");
-            goto raise_error;
-        }
-    }
-    if (PyType_Check(type)) {
-#if CYTHON_COMPILING_IN_PYPY
-        if (!value) {
-            Py_INCREF(Py_None);
-            value = Py_None;
-        }
-#endif
-        PyErr_NormalizeException(&type, &value, &tb);
-    } else {
-        if (value) {
-            PyErr_SetString(PyExc_TypeError,
-                "instance exception may not have a separate value");
-            goto raise_error;
-        }
-        value = type;
-        type = (PyObject*) Py_TYPE(type);
-        Py_INCREF(type);
-        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
-            PyErr_SetString(PyExc_TypeError,
-                "raise: exception class must be a subclass of BaseException");
-            goto raise_error;
-        }
-    }
-    __Pyx_ErrRestore(type, value, tb);
-    return;
-raise_error:
-    Py_XDECREF(value);
-    Py_XDECREF(type);
-    Py_XDECREF(tb);
-    return;
-}
-#else
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
-    PyObject* owned_instance = NULL;
-    if (tb == Py_None) {
-        tb = 0;
-    } else if (tb && !PyTraceBack_Check(tb)) {
-        PyErr_SetString(PyExc_TypeError,
-            "raise: arg 3 must be a traceback or None");
-        goto bad;
-    }
-    if (value == Py_None)
-        value = 0;
-    if (PyExceptionInstance_Check(type)) {
-        if (value) {
-            PyErr_SetString(PyExc_TypeError,
-                "instance exception may not have a separate value");
-            goto bad;
-        }
-        value = type;
-        type = (PyObject*) Py_TYPE(value);
-    } else if (PyExceptionClass_Check(type)) {
-        PyObject *instance_class = NULL;
-        if (value && PyExceptionInstance_Check(value)) {
-            instance_class = (PyObject*) Py_TYPE(value);
-            if (instance_class != type) {
-                if (PyObject_IsSubclass(instance_class, type)) {
-                    type = instance_class;
-                } else {
-                    instance_class = NULL;
-                }
-            }
-        }
-        if (!instance_class) {
-            PyObject *args;
-            if (!value)
-                args = PyTuple_New(0);
-            else if (PyTuple_Check(value)) {
-                Py_INCREF(value);
-                args = value;
-            } else
-                args = PyTuple_Pack(1, value);
-            if (!args)
-                goto bad;
-            owned_instance = PyObject_Call(type, args, NULL);
-            Py_DECREF(args);
-            if (!owned_instance)
-                goto bad;
-            value = owned_instance;
-            if (!PyExceptionInstance_Check(value)) {
-                PyErr_Format(PyExc_TypeError,
-                             "calling %R should have returned an instance of "
-                             "BaseException, not %R",
-                             type, Py_TYPE(value));
-                goto bad;
-            }
-        }
-    } else {
-        PyErr_SetString(PyExc_TypeError,
-            "raise: exception class must be a subclass of BaseException");
-        goto bad;
-    }
-#if PY_VERSION_HEX >= 0x03030000
-    if (cause) {
-#else
-    if (cause && cause != Py_None) {
-#endif
-        PyObject *fixed_cause;
-        if (cause == Py_None) {
-            fixed_cause = NULL;
-        } else if (PyExceptionClass_Check(cause)) {
-            fixed_cause = PyObject_CallObject(cause, NULL);
-            if (fixed_cause == NULL)
-                goto bad;
-        } else if (PyExceptionInstance_Check(cause)) {
-            fixed_cause = cause;
-            Py_INCREF(fixed_cause);
-        } else {
-            PyErr_SetString(PyExc_TypeError,
-                            "exception causes must derive from "
-                            "BaseException");
-            goto bad;
-        }
-        PyException_SetCause(value, fixed_cause);
-    }
-    PyErr_SetObject(type, value);
-    if (tb) {
-#if CYTHON_COMPILING_IN_PYPY
-        PyObject *tmp_type, *tmp_value, *tmp_tb;
-        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
-        Py_INCREF(tb);
-        PyErr_Restore(tmp_type, tmp_value, tb);
-        Py_XDECREF(tmp_tb);
-#else
-        PyThreadState *tstate = PyThreadState_GET();
-        PyObject* tmp_tb = tstate->curexc_traceback;
-        if (tb != tmp_tb) {
-            Py_INCREF(tb);
-            tstate->curexc_traceback = tb;
-            Py_XDECREF(tmp_tb);
-        }
-#endif
-    }
-bad:
-    Py_XDECREF(owned_instance);
-    return;
-}
-#endif
-
-static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
-    PyErr_Format(PyExc_TypeError,
-        "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
-        name, type->tp_name, Py_TYPE(obj)->tp_name);
-}
-static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
-    const char *name, int exact)
-{
-    if (unlikely(!type)) {
-        PyErr_SetString(PyExc_SystemError, "Missing type object");
-        return 0;
-    }
-    if (none_allowed && obj == Py_None) return 1;
-    else if (exact) {
-        if (likely(Py_TYPE(obj) == type)) return 1;
-        #if PY_MAJOR_VERSION == 2
-        else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
-        #endif
-    }
-    else {
-        if (likely(PyObject_TypeCheck(obj, type))) return 1;
-    }
-    __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
-    return 0;
-}
-
-static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
-  unsigned int n = 1;
-  return *(unsigned char*)(&n) != 0;
-}
-static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
-                              __Pyx_BufFmt_StackElem* stack,
-                              __Pyx_TypeInfo* type) {
-  stack[0].field = &ctx->root;
-  stack[0].parent_offset = 0;
-  ctx->root.type = type;
-  ctx->root.name = "buffer dtype";
-  ctx->root.offset = 0;
-  ctx->head = stack;
-  ctx->head->field = &ctx->root;
-  ctx->fmt_offset = 0;
-  ctx->head->parent_offset = 0;
-  ctx->new_packmode = '@';
-  ctx->enc_packmode = '@';
-  ctx->new_count = 1;
-  ctx->enc_count = 0;
-  ctx->enc_type = 0;
-  ctx->is_complex = 0;
-  ctx->is_valid_array = 0;
-  ctx->struct_alignment = 0;
-  while (type->typegroup == 'S') {
-    ++ctx->head;
-    ctx->head->field = type->fields;
-    ctx->head->parent_offset = 0;
-    type = type->fields->type;
-  }
-}
-static int __Pyx_BufFmt_ParseNumber(const char** ts) {
-    int count;
-    const char* t = *ts;
-    if (*t < '0' || *t > '9') {
-      return -1;
-    } else {
-        count = *t++ - '0';
-        while (*t >= '0' && *t < '9') {
-            count *= 10;
-            count += *t++ - '0';
-        }
-    }
-    *ts = t;
-    return count;
-}
-static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
-    int number = __Pyx_BufFmt_ParseNumber(ts);
-    if (number == -1)
-        PyErr_Format(PyExc_ValueError,\
-                     "Does not understand character buffer dtype format string ('%c')", **ts);
-    return number;
-}
-static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
-  PyErr_Format(PyExc_ValueError,
-               "Unexpected format string character: '%c'", ch);
-}
-static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
-  switch (ch) {
-    case 'c': return "'char'";
-    case 'b': return "'signed char'";
-    case 'B': return "'unsigned char'";
-    case 'h': return "'short'";
-    case 'H': return "'unsigned short'";
-    case 'i': return "'int'";
-    case 'I': return "'unsigned int'";
-    case 'l': return "'long'";
-    case 'L': return "'unsigned long'";
-    case 'q': return "'long long'";
-    case 'Q': return "'unsigned long long'";
-    case 'f': return (is_complex ? "'complex float'" : "'float'");
-    case 'd': return (is_complex ? "'complex double'" : "'double'");
-    case 'g': return (is_complex ? "'complex long double'" : "'long double'");
-    case 'T': return "a struct";
-    case 'O': return "Python object";
-    case 'P': return "a pointer";
-    case 's': case 'p': return "a string";
-    case 0: return "end";
-    default: return "unparseable format string";
-  }
-}
-static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
-  switch (ch) {
-    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
-    case 'h': case 'H': return 2;
-    case 'i': case 'I': case 'l': case 'L': return 4;
-    case 'q': case 'Q': return 8;
-    case 'f': return (is_complex ? 8 : 4);
-    case 'd': return (is_complex ? 16 : 8);
-    case 'g': {
-      PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
-      return 0;
-    }
-    case 'O': case 'P': return sizeof(void*);
-    default:
-      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
-      return 0;
-    }
-}
-static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
-  switch (ch) {
-    case 'c': case 'b': case 'B': case 's': case 'p': return 1;
-    case 'h': case 'H': return sizeof(short);
-    case 'i': case 'I': return sizeof(int);
-    case 'l': case 'L': return sizeof(long);
-    #ifdef HAVE_LONG_LONG
-    case 'q': case 'Q': return sizeof(PY_LONG_LONG);
-    #endif
-    case 'f': return sizeof(float) * (is_complex ? 2 : 1);
-    case 'd': return sizeof(double) * (is_complex ? 2 : 1);
-    case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
-    case 'O': case 'P': return sizeof(void*);
-    default: {
-      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
-      return 0;
-    }
-  }
-}
-typedef struct { char c; short x; } __Pyx_st_short;
-typedef struct { char c; int x; } __Pyx_st_int;
-typedef struct { char c; long x; } __Pyx_st_long;
-typedef struct { char c; float x; } __Pyx_st_float;
-typedef struct { char c; double x; } __Pyx_st_double;
-typedef struct { char c; long double x; } __Pyx_st_longdouble;
-typedef struct { char c; void *x; } __Pyx_st_void_p;
-#ifdef HAVE_LONG_LONG
-typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
-#endif
-static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
-  switch (ch) {
-    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
-    case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
-    case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
-    case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
-#ifdef HAVE_LONG_LONG
-    case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
-#endif
-    case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
-    case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
-    case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
-    case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
-    default:
-      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
-      return 0;
-    }
-}
-/* These are for computing the padding at the end of the struct to align
-   on the first member of the struct. This will probably the same as above,
-   but we don't have any guarantees.
- */
-typedef struct { short x; char c; } __Pyx_pad_short;
-typedef struct { int x; char c; } __Pyx_pad_int;
-typedef struct { long x; char c; } __Pyx_pad_long;
-typedef struct { float x; char c; } __Pyx_pad_float;
-typedef struct { double x; char c; } __Pyx_pad_double;
-typedef struct { long double x; char c; } __Pyx_pad_longdouble;
-typedef struct { void *x; char c; } __Pyx_pad_void_p;
-#ifdef HAVE_LONG_LONG
-typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
-#endif
-static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
-  switch (ch) {
-    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
-    case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
-    case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
-    case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
-#ifdef HAVE_LONG_LONG
-    case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
-#endif
-    case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
-    case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
-    case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
-    case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
-    default:
-      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
-      return 0;
-    }
-}
-static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
-  switch (ch) {
-    case 'c':
-        return 'H';
-    case 'b': case 'h': case 'i':
-    case 'l': case 'q': case 's': case 'p':
-        return 'I';
-    case 'B': case 'H': case 'I': case 'L': case 'Q':
-        return 'U';
-    case 'f': case 'd': case 'g':
-        return (is_complex ? 'C' : 'R');
-    case 'O':
-        return 'O';
-    case 'P':
-        return 'P';
-    default: {
-      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
-      return 0;
-    }
-  }
-}
-static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
-  if (ctx->head == NULL || ctx->head->field == &ctx->root) {
-    const char* expected;
-    const char* quote;
-    if (ctx->head == NULL) {
-      expected = "end";
-      quote = "";
-    } else {
-      expected = ctx->head->field->type->name;
-      quote = "'";
-    }
-    PyErr_Format(PyExc_ValueError,
-                 "Buffer dtype mismatch, expected %s%s%s but got %s",
-                 quote, expected, quote,
-                 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
-  } else {
-    __Pyx_StructField* field = ctx->head->field;
-    __Pyx_StructField* parent = (ctx->head - 1)->field;
-    PyErr_Format(PyExc_ValueError,
-                 "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
-                 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
-                 parent->type->name, field->name);
-  }
-}
-static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
-  char group;
-  size_t size, offset, arraysize = 1;
-  if (ctx->enc_type == 0) return 0;
-  if (ctx->head->field->type->arraysize[0]) {
-    int i, ndim = 0;
-    if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
-        ctx->is_valid_array = ctx->head->field->type->ndim == 1;
-        ndim = 1;
-        if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
-            PyErr_Format(PyExc_ValueError,
-                         "Expected a dimension of size %zu, got %zu",
-                         ctx->head->field->type->arraysize[0], ctx->enc_count);
-            return -1;
-        }
-    }
-    if (!ctx->is_valid_array) {
-      PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
-                   ctx->head->field->type->ndim, ndim);
-      return -1;
-    }
-    for (i = 0; i < ctx->head->field->type->ndim; i++) {
-      arraysize *= ctx->head->field->type->arraysize[i];
-    }
-    ctx->is_valid_array = 0;
-    ctx->enc_count = 1;
-  }
-  group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
-  do {
-    __Pyx_StructField* field = ctx->head->field;
-    __Pyx_TypeInfo* type = field->type;
-    if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
-      size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
-    } else {
-      size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
-    }
-    if (ctx->enc_packmode == '@') {
-      size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
-      size_t align_mod_offset;
-      if (align_at == 0) return -1;
-      align_mod_offset = ctx->fmt_offset % align_at;
-      if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
-      if (ctx->struct_alignment == 0)
-          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
-                                                                 ctx->is_complex);
-    }
-    if (type->size != size || type->typegroup != group) {
-      if (type->typegroup == 'C' && type->fields != NULL) {
-        size_t parent_offset = ctx->head->parent_offset + field->offset;
-        ++ctx->head;
-        ctx->head->field = type->fields;
-        ctx->head->parent_offset = parent_offset;
-        continue;
-      }
-      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
-      } else {
-          __Pyx_BufFmt_RaiseExpected(ctx);
-          return -1;
-      }
-    }
-    offset = ctx->head->parent_offset + field->offset;
-    if (ctx->fmt_offset != offset) {
-      PyErr_Format(PyExc_ValueError,
-                   "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
-                   (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
-      return -1;
-    }
-    ctx->fmt_offset += size;
-    if (arraysize)
-      ctx->fmt_offset += (arraysize - 1) * size;
-    --ctx->enc_count;
-    while (1) {
-      if (field == &ctx->root) {
-        ctx->head = NULL;
-        if (ctx->enc_count != 0) {
-          __Pyx_BufFmt_RaiseExpected(ctx);
-          return -1;
-        }
-        break;
-      }
-      ctx->head->field = ++field;
-      if (field->type == NULL) {
-        --ctx->head;
-        field = ctx->head->field;
-        continue;
-      } else if (field->type->typegroup == 'S') {
-        size_t parent_offset = ctx->head->parent_offset + field->offset;
-        if (field->type->fields->type == NULL) continue;
-        field = field->type->fields;
-        ++ctx->head;
-        ctx->head->field = field;
-        ctx->head->parent_offset = parent_offset;
-        break;
-      } else {
-        break;
-      }
-    }
-  } while (ctx->enc_count);
-  ctx->enc_type = 0;
-  ctx->is_complex = 0;
-  return 0;
-}
-static CYTHON_INLINE PyObject *
-__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
-{
-    const char *ts = *tsp;
-    int i = 0, number;
-    int ndim = ctx->head->field->type->ndim;
-;
-    ++ts;
-    if (ctx->new_count != 1) {
-        PyErr_SetString(PyExc_ValueError,
-                        "Cannot handle repeated arrays in format string");
-        return NULL;
-    }
-    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-    while (*ts && *ts != ')') {
-        switch (*ts) {
-            case ' ': case '\f': case '\r': case '\n': case '\t': case '\v':  continue;
-            default:  break;
-        }
-        number = __Pyx_BufFmt_ExpectNumber(&ts);
-        if (number == -1) return NULL;
-        if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
-            return PyErr_Format(PyExc_ValueError,
-                        "Expected a dimension of size %zu, got %d",
-                        ctx->head->field->type->arraysize[i], number);
-        if (*ts != ',' && *ts != ')')
-            return PyErr_Format(PyExc_ValueError,
-                                "Expected a comma in format string, got '%c'", *ts);
-        if (*ts == ',') ts++;
-        i++;
-    }
-    if (i != ndim)
-        return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
-                            ctx->head->field->type->ndim, i);
-    if (!*ts) {
-        PyErr_SetString(PyExc_ValueError,
-                        "Unexpected end of format string, expected ')'");
-        return NULL;
-    }
-    ctx->is_valid_array = 1;
-    ctx->new_count = 1;
-    *tsp = ++ts;
-    return Py_None;
-}
-static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
-  int got_Z = 0;
-  while (1) {
-    switch(*ts) {
-      case 0:
-        if (ctx->enc_type != 0 && ctx->head == NULL) {
-          __Pyx_BufFmt_RaiseExpected(ctx);
-          return NULL;
-        }
-        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-        if (ctx->head != NULL) {
-          __Pyx_BufFmt_RaiseExpected(ctx);
-          return NULL;
-        }
-        return ts;
-      case ' ':
-      case '\r':
-      case '\n':
-        ++ts;
-        break;
-      case '<':
-        if (!__Pyx_IsLittleEndian()) {
-          PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
-          return NULL;
-        }
-        ctx->new_packmode = '=';
-        ++ts;
-        break;
-      case '>':
-      case '!':
-        if (__Pyx_IsLittleEndian()) {
-          PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
-          return NULL;
-        }
-        ctx->new_packmode = '=';
-        ++ts;
-        break;
-      case '=':
-      case '@':
-      case '^':
-        ctx->new_packmode = *ts++;
-        break;
-      case 'T':
-        {
-          const char* ts_after_sub;
-          size_t i, struct_count = ctx->new_count;
-          size_t struct_alignment = ctx->struct_alignment;
-          ctx->new_count = 1;
-          ++ts;
-          if (*ts != '{') {
-            PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
-            return NULL;
-          }
-          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-          ctx->enc_type = 0;
-          ctx->enc_count = 0;
-          ctx->struct_alignment = 0;
-          ++ts;
-          ts_after_sub = ts;
-          for (i = 0; i != struct_count; ++i) {
-            ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
-            if (!ts_after_sub) return NULL;
-          }
-          ts = ts_after_sub;
-          if (struct_alignment) ctx->struct_alignment = struct_alignment;
-        }
-        break;
-      case '}':
-        {
-          size_t alignment = ctx->struct_alignment;
-          ++ts;
-          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-          ctx->enc_type = 0;
-          if (alignment && ctx->fmt_offset % alignment) {
-            ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
-          }
-        }
-        return ts;
-      case 'x':
-        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-        ctx->fmt_offset += ctx->new_count;
-        ctx->new_count = 1;
-        ctx->enc_count = 0;
-        ctx->enc_type = 0;
-        ctx->enc_packmode = ctx->new_packmode;
-        ++ts;
-        break;
-      case 'Z':
-        got_Z = 1;
-        ++ts;
-        if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
-          __Pyx_BufFmt_RaiseUnexpectedChar('Z');
-          return NULL;
-        }
-      case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
-      case 'l': case 'L': case 'q': case 'Q':
-      case 'f': case 'd': case 'g':
-      case 'O': case 'p':
-        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
-            ctx->enc_packmode == ctx->new_packmode) {
-          ctx->enc_count += ctx->new_count;
-          ctx->new_count = 1;
-          got_Z = 0;
-          ++ts;
-          break;
-        }
-      case 's':
-        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
-        ctx->enc_count = ctx->new_count;
-        ctx->enc_packmode = ctx->new_packmode;
-        ctx->enc_type = *ts;
-        ctx->is_complex = got_Z;
-        ++ts;
-        ctx->new_count = 1;
-        got_Z = 0;
-        break;
-      case ':':
-        ++ts;
-        while(*ts != ':') ++ts;
-        ++ts;
-        break;
-      case '(':
-        if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
-        break;
-      default:
-        {
-          int number = __Pyx_BufFmt_ExpectNumber(&ts);
-          if (number == -1) return NULL;
-          ctx->new_count = (size_t)number;
-        }
-    }
-  }
-}
-static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
-  buf->buf = NULL;
-  buf->obj = NULL;
-  buf->strides = __Pyx_zeros;
-  buf->shape = __Pyx_zeros;
-  buf->suboffsets = __Pyx_minusones;
-}
-static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
-        Py_buffer* buf, PyObject* obj,  __Pyx_TypeInfo* dtype, int flags,
-        int nd, int cast, __Pyx_BufFmt_StackElem* stack)
-{
-  if (obj == Py_None || obj == NULL) {
-    __Pyx_ZeroBuffer(buf);
-    return 0;
-  }
-  buf->buf = NULL;
-  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
-  if (buf->ndim != nd) {
-    PyErr_Format(PyExc_ValueError,
-                 "Buffer has wrong number of dimensions (expected %d, got %d)",
-                 nd, buf->ndim);
-    goto fail;
-  }
-  if (!cast) {
-    __Pyx_BufFmt_Context ctx;
-    __Pyx_BufFmt_Init(&ctx, stack, dtype);
-    if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
-  }
-  if ((unsigned)buf->itemsize != dtype->size) {
-    PyErr_Format(PyExc_ValueError,
-      "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
-      buf->itemsize, (buf->itemsize > 1) ? "s" : "",
-      dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
-    goto fail;
-  }
-  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
-  return 0;
-fail:;
-  __Pyx_ZeroBuffer(buf);
-  return -1;
-}
-static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
-  if (info->buf == NULL) return;
-  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
-  __Pyx_ReleaseBuffer(info);
-}
-
-static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
-    if (unlikely(!type)) {
-        PyErr_SetString(PyExc_SystemError, "Missing type object");
-        return 0;
-    }
-    if (likely(PyObject_TypeCheck(obj, type)))
-        return 1;
-    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
-                 Py_TYPE(obj)->tp_name, type->tp_name);
-    return 0;
-}
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
-    PyObject *r;
-    if (!j) return NULL;
-    r = PyObject_GetItem(o, j);
-    Py_DECREF(j);
-    return r;
-}
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
-                                                              int wraparound, int boundscheck) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
-    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
-        PyObject *r = PyList_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-#else
-    return PySequence_GetItem(o, i);
-#endif
-}
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
-                                                              int wraparound, int boundscheck) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
-    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
-        PyObject *r = PyTuple_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-#else
-    return PySequence_GetItem(o, i);
-#endif
-}
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
-                                                     int is_list, int wraparound, int boundscheck) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (is_list || PyList_CheckExact(o)) {
-        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
-        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
-            PyObject *r = PyList_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    }
-    else if (PyTuple_CheckExact(o)) {
-        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
-        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
-            PyObject *r = PyTuple_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    } else {
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_item)) {
-            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
-                if (likely(l >= 0)) {
-                    i += l;
-                } else {
-                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
-                        PyErr_Clear();
-                    else
-                        return NULL;
-                }
-            }
-            return m->sq_item(o, i);
-        }
-    }
-#else
-    if (is_list || PySequence_Check(o)) {
-        return PySequence_GetItem(o, i);
-    }
-#endif
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-}
-
-static void __Pyx_RaiseBufferIndexError(int axis) {
-  PyErr_Format(PyExc_IndexError,
-     "Out of bounds on buffer access (axis %d)", axis);
-}
-
-static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
-    int r;
-    if (!j) return -1;
-    r = PyObject_SetItem(o, j, v);
-    Py_DECREF(j);
-    return r;
-}
-static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
-                                               int is_list, int wraparound, int boundscheck) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (is_list || PyList_CheckExact(o)) {
-        Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
-        if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
-            PyObject* old = PyList_GET_ITEM(o, n);
-            Py_INCREF(v);
-            PyList_SET_ITEM(o, n, v);
-            Py_DECREF(old);
-            return 1;
-        }
-    } else {
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_ass_item)) {
-            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
-                if (likely(l >= 0)) {
-                    i += l;
-                } else {
-                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
-                        PyErr_Clear();
-                    else
-                        return -1;
-                }
-            }
-            return m->sq_ass_item(o, i, v);
-        }
-    }
-#else
-#if CYTHON_COMPILING_IN_PYPY
-    if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
-#else
-    if (is_list || PySequence_Check(o)) {
-#endif
-        return PySequence_SetItem(o, i, v);
-    }
-#endif
-    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
-}
-
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
-    PyErr_Format(PyExc_ValueError,
-                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
-}
-
-static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
-    PyErr_Format(PyExc_ValueError,
-                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
-                 index, (index == 1) ? "" : "s");
-}
-
-static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
-    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
-}
-
-static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
-    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
-    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
-        PyErr_Format(PyExc_ImportError,
-        #if PY_MAJOR_VERSION < 3
-            "cannot import name %.230s", PyString_AS_STRING(name));
-        #else
-            "cannot import name %S", name);
-        #endif
-    }
-    return value;
-}
-
-static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
-    int start = 0, mid = 0, end = count - 1;
-    if (end >= 0 && code_line > entries[end].code_line) {
-        return count;
-    }
-    while (start < end) {
-        mid = (start + end) / 2;
-        if (code_line < entries[mid].code_line) {
-            end = mid;
-        } else if (code_line > entries[mid].code_line) {
-             start = mid + 1;
-        } else {
-            return mid;
-        }
-    }
-    if (code_line <= entries[mid].code_line) {
-        return mid;
-    } else {
-        return mid + 1;
-    }
-}
-static PyCodeObject *__pyx_find_code_object(int code_line) {
-    PyCodeObject* code_object;
-    int pos;
-    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
-        return NULL;
-    }
-    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
-    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
-        return NULL;
-    }
-    code_object = __pyx_code_cache.entries[pos].code_object;
-    Py_INCREF(code_object);
-    return code_object;
-}
-static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
-    int pos, i;
-    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
-    if (unlikely(!code_line)) {
-        return;
-    }
-    if (unlikely(!entries)) {
-        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
-        if (likely(entries)) {
-            __pyx_code_cache.entries = entries;
-            __pyx_code_cache.max_count = 64;
-            __pyx_code_cache.count = 1;
-            entries[0].code_line = code_line;
-            entries[0].code_object = code_object;
-            Py_INCREF(code_object);
-        }
-        return;
-    }
-    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
-    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
-        PyCodeObject* tmp = entries[pos].code_object;
-        entries[pos].code_object = code_object;
-        Py_DECREF(tmp);
-        return;
-    }
-    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
-        int new_max = __pyx_code_cache.max_count + 64;
-        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
-            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
-        if (unlikely(!entries)) {
-            return;
-        }
-        __pyx_code_cache.entries = entries;
-        __pyx_code_cache.max_count = new_max;
-    }
-    for (i=__pyx_code_cache.count; i>pos; i--) {
-        entries[i] = entries[i-1];
-    }
-    entries[pos].code_line = code_line;
-    entries[pos].code_object = code_object;
-    __pyx_code_cache.count++;
-    Py_INCREF(code_object);
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
-            const char *funcname, int c_line,
-            int py_line, const char *filename) {
-    PyCodeObject *py_code = 0;
-    PyObject *py_srcfile = 0;
-    PyObject *py_funcname = 0;
-    #if PY_MAJOR_VERSION < 3
-    py_srcfile = PyString_FromString(filename);
-    #else
-    py_srcfile = PyUnicode_FromString(filename);
-    #endif
-    if (!py_srcfile) goto bad;
-    if (c_line) {
-        #if PY_MAJOR_VERSION < 3
-        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
-        #else
-        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
-        #endif
-    }
-    else {
-        #if PY_MAJOR_VERSION < 3
-        py_funcname = PyString_FromString(funcname);
-        #else
-        py_funcname = PyUnicode_FromString(funcname);
-        #endif
-    }
-    if (!py_funcname) goto bad;
-    py_code = __Pyx_PyCode_New(
-        0,
-        0,
-        0,
-        0,
-        0,
-        __pyx_empty_bytes, /*PyObject *code,*/
-        __pyx_empty_tuple, /*PyObject *consts,*/
-        __pyx_empty_tuple, /*PyObject *names,*/
-        __pyx_empty_tuple, /*PyObject *varnames,*/
-        __pyx_empty_tuple, /*PyObject *freevars,*/
-        __pyx_empty_tuple, /*PyObject *cellvars,*/
-        py_srcfile,   /*PyObject *filename,*/
-        py_funcname,  /*PyObject *name,*/
-        py_line,
-        __pyx_empty_bytes  /*PyObject *lnotab*/
-    );
-    Py_DECREF(py_srcfile);
-    Py_DECREF(py_funcname);
-    return py_code;
-bad:
-    Py_XDECREF(py_srcfile);
-    Py_XDECREF(py_funcname);
-    return NULL;
-}
-static void __Pyx_AddTraceback(const char *funcname, int c_line,
-                               int py_line, const char *filename) {
-    PyCodeObject *py_code = 0;
-    PyFrameObject *py_frame = 0;
-    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
-    if (!py_code) {
-        py_code = __Pyx_CreateCodeObjectForTraceback(
-            funcname, c_line, py_line, filename);
-        if (!py_code) goto bad;
-        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
-    }
-    py_frame = PyFrame_New(
-        PyThreadState_GET(), /*PyThreadState *tstate,*/
-        py_code,             /*PyCodeObject *code,*/
-        __pyx_d,      /*PyObject *globals,*/
-        0                    /*PyObject *locals*/
-    );
-    if (!py_frame) goto bad;
-    py_frame->f_lineno = py_line;
-    PyTraceBack_Here(py_frame);
-bad:
-    Py_XDECREF(py_code);
-    Py_XDECREF(py_frame);
-}
-
-#if PY_MAJOR_VERSION < 3
-static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
-    if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
-        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
-    PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
-    return -1;
-}
-static void __Pyx_ReleaseBuffer(Py_buffer *view) {
-    PyObject *obj = view->obj;
-    if (!obj) return;
-    if (PyObject_CheckBuffer(obj)) {
-        PyBuffer_Release(view);
-        return;
-    }
-        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
-    Py_DECREF(obj);
-    view->obj = NULL;
-}
-#endif
-
-
-        static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
-    PyObject *empty_list = 0;
-    PyObject *module = 0;
-    PyObject *global_dict = 0;
-    PyObject *empty_dict = 0;
-    PyObject *list;
-    #if PY_VERSION_HEX < 0x03030000
-    PyObject *py_import;
-    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
-    if (!py_import)
-        goto bad;
-    #endif
-    if (from_list)
-        list = from_list;
-    else {
-        empty_list = PyList_New(0);
-        if (!empty_list)
-            goto bad;
-        list = empty_list;
-    }
-    global_dict = PyModule_GetDict(__pyx_m);
-    if (!global_dict)
-        goto bad;
-    empty_dict = PyDict_New();
-    if (!empty_dict)
-        goto bad;
-    {
-        #if PY_MAJOR_VERSION >= 3
-        if (level == -1) {
-            if (strchr(__Pyx_MODULE_NAME, '.')) {
-                #if PY_VERSION_HEX < 0x03030000
-                PyObject *py_level = PyInt_FromLong(1);
-                if (!py_level)
-                    goto bad;
-                module = PyObject_CallFunctionObjArgs(py_import,
-                    name, global_dict, empty_dict, list, py_level, NULL);
-                Py_DECREF(py_level);
-                #else
-                module = PyImport_ImportModuleLevelObject(
-                    name, global_dict, empty_dict, list, 1);
-                #endif
-                if (!module) {
-                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
-                        goto bad;
-                    PyErr_Clear();
-                }
-            }
-            level = 0;
-        }
-        #endif
-        if (!module) {
-            #if PY_VERSION_HEX < 0x03030000
-            PyObject *py_level = PyInt_FromLong(level);
-            if (!py_level)
-                goto bad;
-            module = PyObject_CallFunctionObjArgs(py_import,
-                name, global_dict, empty_dict, list, py_level, NULL);
-            Py_DECREF(py_level);
-            #else
-            module = PyImport_ImportModuleLevelObject(
-                name, global_dict, empty_dict, list, level);
-            #endif
-        }
-    }
-bad:
-    #if PY_VERSION_HEX < 0x03030000
-    Py_XDECREF(py_import);
-    #endif
-    Py_XDECREF(empty_list);
-    Py_XDECREF(empty_dict);
-    return module;
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
-    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (is_unsigned) {
-        if (sizeof(unsigned int) < sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
-            return PyLong_FromUnsignedLong((unsigned long) value);
-        } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
-            return PyLong_FromUnsignedLongLong((unsigned long long) value);
-        }
-    } else {
-        if (sizeof(unsigned int) <= sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(unsigned int) <= sizeof(long long)) {
-            return PyLong_FromLongLong((long long) value);
-        }
-    }
-    {
-        int one = 1; int little = (int)*(unsigned char *)&one;
-        unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
-                                     little, !is_unsigned);
-    }
-}
-
-#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
-    {                                                                     \
-        func_type value = func_value;                                     \
-        if (sizeof(target_type) < sizeof(func_type)) {                    \
-            if (unlikely(value != (func_type) (target_type) value)) {     \
-                func_type zero = 0;                                       \
-                if (is_unsigned && unlikely(value < zero))                \
-                    goto raise_neg_overflow;                              \
-                else                                                      \
-                    goto raise_overflow;                                  \
-            }                                                             \
-        }                                                                 \
-        return (target_type) value;                                       \
-    }
-
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-  #include "longintrepr.h"
- #endif
-#endif
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
-    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_MAJOR_VERSION < 3
-    if (likely(PyInt_Check(x))) {
-        if (sizeof(unsigned int) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
-        } else {
-            long val = PyInt_AS_LONG(x);
-            if (is_unsigned && unlikely(val < 0)) {
-                goto raise_neg_overflow;
-            }
-            return (unsigned int) val;
-        }
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (unlikely(Py_SIZE(x) < 0)) {
-                goto raise_neg_overflow;
-            }
-            if (sizeof(unsigned int) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
-            } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
-                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
-            }
-        } else {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(unsigned int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
-                case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (sizeof(unsigned int) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
-            } else if (sizeof(unsigned int) <= sizeof(long long)) {
-                __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
-            }
-        }
-        {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-            PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-#else
-            unsigned int val;
-            PyObject *v = __Pyx_PyNumber_Int(x);
- #if PY_MAJOR_VERSION < 3
-            if (likely(v) && !PyLong_Check(v)) {
-                PyObject *tmp = v;
-                v = PyNumber_Long(tmp);
-                Py_DECREF(tmp);
-            }
- #endif
-            if (likely(v)) {
-                int one = 1; int is_little = (int)*(unsigned char *)&one;
-                unsigned char *bytes = (unsigned char *)&val;
-                int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                              bytes, sizeof(val),
-                                              is_little, !is_unsigned);
-                Py_DECREF(v);
-                if (likely(!ret))
-                    return val;
-            }
-#endif
-            return (unsigned int) -1;
-        }
-    } else {
-        unsigned int val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (unsigned int) -1;
-        val = __Pyx_PyInt_As_unsigned_int(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-raise_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to unsigned int");
-    return (unsigned int) -1;
-raise_neg_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to unsigned int");
-    return (unsigned int) -1;
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
-    const int neg_one = (int) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (is_unsigned) {
-        if (sizeof(int) < sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(int) <= sizeof(unsigned long)) {
-            return PyLong_FromUnsignedLong((unsigned long) value);
-        } else if (sizeof(int) <= sizeof(unsigned long long)) {
-            return PyLong_FromUnsignedLongLong((unsigned long long) value);
-        }
-    } else {
-        if (sizeof(int) <= sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(int) <= sizeof(long long)) {
-            return PyLong_FromLongLong((long long) value);
-        }
-    }
-    {
-        int one = 1; int little = (int)*(unsigned char *)&one;
-        unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(int),
-                                     little, !is_unsigned);
-    }
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
-    const int neg_one = (int) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_MAJOR_VERSION < 3
-    if (likely(PyInt_Check(x))) {
-        if (sizeof(int) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
-        } else {
-            long val = PyInt_AS_LONG(x);
-            if (is_unsigned && unlikely(val < 0)) {
-                goto raise_neg_overflow;
-            }
-            return (int) val;
-        }
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (unlikely(Py_SIZE(x) < 0)) {
-                goto raise_neg_overflow;
-            }
-            if (sizeof(int) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
-            } else if (sizeof(int) <= sizeof(unsigned long long)) {
-                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
-            }
-        } else {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
-                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (sizeof(int) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
-            } else if (sizeof(int) <= sizeof(long long)) {
-                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
-            }
-        }
-        {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-            PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-#else
-            int val;
-            PyObject *v = __Pyx_PyNumber_Int(x);
- #if PY_MAJOR_VERSION < 3
-            if (likely(v) && !PyLong_Check(v)) {
-                PyObject *tmp = v;
-                v = PyNumber_Long(tmp);
-                Py_DECREF(tmp);
-            }
- #endif
-            if (likely(v)) {
-                int one = 1; int is_little = (int)*(unsigned char *)&one;
-                unsigned char *bytes = (unsigned char *)&val;
-                int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                              bytes, sizeof(val),
-                                              is_little, !is_unsigned);
-                Py_DECREF(v);
-                if (likely(!ret))
-                    return val;
-            }
-#endif
-            return (int) -1;
-        }
-    } else {
-        int val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (int) -1;
-        val = __Pyx_PyInt_As_int(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-raise_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to int");
-    return (int) -1;
-raise_neg_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to int");
-    return (int) -1;
-}
-
-static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
-    const char neg_one = (char) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_MAJOR_VERSION < 3
-    if (likely(PyInt_Check(x))) {
-        if (sizeof(char) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
-        } else {
-            long val = PyInt_AS_LONG(x);
-            if (is_unsigned && unlikely(val < 0)) {
-                goto raise_neg_overflow;
-            }
-            return (char) val;
-        }
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (unlikely(Py_SIZE(x) < 0)) {
-                goto raise_neg_overflow;
-            }
-            if (sizeof(char) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
-            } else if (sizeof(char) <= sizeof(unsigned long long)) {
-                __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
-            }
-        } else {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(char,  digit, +(((PyLongObject*)x)->ob_digit[0]));
-                case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (sizeof(char) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
-            } else if (sizeof(char) <= sizeof(long long)) {
-                __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
-            }
-        }
-        {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-            PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-#else
-            char val;
-            PyObject *v = __Pyx_PyNumber_Int(x);
- #if PY_MAJOR_VERSION < 3
-            if (likely(v) && !PyLong_Check(v)) {
-                PyObject *tmp = v;
-                v = PyNumber_Long(tmp);
-                Py_DECREF(tmp);
-            }
- #endif
-            if (likely(v)) {
-                int one = 1; int is_little = (int)*(unsigned char *)&one;
-                unsigned char *bytes = (unsigned char *)&val;
-                int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                              bytes, sizeof(val),
-                                              is_little, !is_unsigned);
-                Py_DECREF(v);
-                if (likely(!ret))
-                    return val;
-            }
-#endif
-            return (char) -1;
-        }
-    } else {
-        char val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (char) -1;
-        val = __Pyx_PyInt_As_char(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-raise_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to char");
-    return (char) -1;
-raise_neg_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to char");
-    return (char) -1;
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
-    const long neg_one = (long) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (is_unsigned) {
-        if (sizeof(long) < sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(long) <= sizeof(unsigned long)) {
-            return PyLong_FromUnsignedLong((unsigned long) value);
-        } else if (sizeof(long) <= sizeof(unsigned long long)) {
-            return PyLong_FromUnsignedLongLong((unsigned long long) value);
-        }
-    } else {
-        if (sizeof(long) <= sizeof(long)) {
-            return PyInt_FromLong((long) value);
-        } else if (sizeof(long) <= sizeof(long long)) {
-            return PyLong_FromLongLong((long long) value);
-        }
-    }
-    {
-        int one = 1; int little = (int)*(unsigned char *)&one;
-        unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(long),
-                                     little, !is_unsigned);
-    }
-}
-
-static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
-    const long neg_one = (long) -1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_MAJOR_VERSION < 3
-    if (likely(PyInt_Check(x))) {
-        if (sizeof(long) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
-        } else {
-            long val = PyInt_AS_LONG(x);
-            if (is_unsigned && unlikely(val < 0)) {
-                goto raise_neg_overflow;
-            }
-            return (long) val;
-        }
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (unlikely(Py_SIZE(x) < 0)) {
-                goto raise_neg_overflow;
-            }
-            if (sizeof(long) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
-            } else if (sizeof(long) <= sizeof(unsigned long long)) {
-                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
-            }
-        } else {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
- #if CYTHON_USE_PYLONG_INTERNALS
-            switch (Py_SIZE(x)) {
-                case  0: return 0;
-                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
-                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
-            }
- #endif
-#endif
-            if (sizeof(long) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
-            } else if (sizeof(long) <= sizeof(long long)) {
-                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
-            }
-        }
-        {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-            PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-#else
-            long val;
-            PyObject *v = __Pyx_PyNumber_Int(x);
- #if PY_MAJOR_VERSION < 3
-            if (likely(v) && !PyLong_Check(v)) {
-                PyObject *tmp = v;
-                v = PyNumber_Long(tmp);
-                Py_DECREF(tmp);
-            }
- #endif
-            if (likely(v)) {
-                int one = 1; int is_little = (int)*(unsigned char *)&one;
-                unsigned char *bytes = (unsigned char *)&val;
-                int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                              bytes, sizeof(val),
-                                              is_little, !is_unsigned);
-                Py_DECREF(v);
-                if (likely(!ret))
-                    return val;
-            }
-#endif
-            return (long) -1;
-        }
-    } else {
-        long val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (long) -1;
-        val = __Pyx_PyInt_As_long(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-raise_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to long");
-    return (long) -1;
-raise_neg_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to long");
-    return (long) -1;
-}
-
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
-      return ::std::complex< float >(x, y);
-    }
-  #else
-    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
-      return x + y*(__pyx_t_float_complex)_Complex_I;
-    }
-  #endif
-#else
-    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
-      __pyx_t_float_complex z;
-      z.real = x;
-      z.imag = y;
-      return z;
-    }
-#endif
-
-#if CYTHON_CCOMPLEX
-#else
-    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-       return (a.real == b.real) && (a.imag == b.imag);
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-        __pyx_t_float_complex z;
-        z.real = a.real + b.real;
-        z.imag = a.imag + b.imag;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-        __pyx_t_float_complex z;
-        z.real = a.real - b.real;
-        z.imag = a.imag - b.imag;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-        __pyx_t_float_complex z;
-        z.real = a.real * b.real - a.imag * b.imag;
-        z.imag = a.real * b.imag + a.imag * b.real;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-        __pyx_t_float_complex z;
-        float denom = b.real * b.real + b.imag * b.imag;
-        z.real = (a.real * b.real + a.imag * b.imag) / denom;
-        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
-        __pyx_t_float_complex z;
-        z.real = -a.real;
-        z.imag = -a.imag;
-        return z;
-    }
-    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
-       return (a.real == 0) && (a.imag == 0);
-    }
-    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
-        __pyx_t_float_complex z;
-        z.real =  a.real;
-        z.imag = -a.imag;
-        return z;
-    }
-    #if 1
-        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
-          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
-            return sqrtf(z.real*z.real + z.imag*z.imag);
-          #else
-            return hypotf(z.real, z.imag);
-          #endif
-        }
-        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
-            __pyx_t_float_complex z;
-            float r, lnr, theta, z_r, z_theta;
-            if (b.imag == 0 && b.real == (int)b.real) {
-                if (b.real < 0) {
-                    float denom = a.real * a.real + a.imag * a.imag;
-                    a.real = a.real / denom;
-                    a.imag = -a.imag / denom;
-                    b.real = -b.real;
-                }
-                switch ((int)b.real) {
-                    case 0:
-                        z.real = 1;
-                        z.imag = 0;
-                        return z;
-                    case 1:
-                        return a;
-                    case 2:
-                        z = __Pyx_c_prodf(a, a);
-                        return __Pyx_c_prodf(a, a);
-                    case 3:
-                        z = __Pyx_c_prodf(a, a);
-                        return __Pyx_c_prodf(z, a);
-                    case 4:
-                        z = __Pyx_c_prodf(a, a);
-                        return __Pyx_c_prodf(z, z);
-                }
-            }
-            if (a.imag == 0) {
-                if (a.real == 0) {
-                    return a;
-                }
-                r = a.real;
-                theta = 0;
-            } else {
-                r = __Pyx_c_absf(a);
-                theta = atan2f(a.imag, a.real);
-            }
-            lnr = logf(r);
-            z_r = expf(lnr * b.real - theta * b.imag);
-            z_theta = theta * b.real + lnr * b.imag;
-            z.real = z_r * cosf(z_theta);
-            z.imag = z_r * sinf(z_theta);
-            return z;
-        }
-    #endif
-#endif
-
-#if CYTHON_CCOMPLEX
-  #ifdef __cplusplus
-    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
-      return ::std::complex< double >(x, y);
-    }
-  #else
-    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
-      return x + y*(__pyx_t_double_complex)_Complex_I;
-    }
-  #endif
-#else
-    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
-      __pyx_t_double_complex z;
-      z.real = x;
-      z.imag = y;
-      return z;
-    }
-#endif
-
-#if CYTHON_CCOMPLEX
-#else
-    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-       return (a.real == b.real) && (a.imag == b.imag);
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-        __pyx_t_double_complex z;
-        z.real = a.real + b.real;
-        z.imag = a.imag + b.imag;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-        __pyx_t_double_complex z;
-        z.real = a.real - b.real;
-        z.imag = a.imag - b.imag;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-        __pyx_t_double_complex z;
-        z.real = a.real * b.real - a.imag * b.imag;
-        z.imag = a.real * b.imag + a.imag * b.real;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-        __pyx_t_double_complex z;
-        double denom = b.real * b.real + b.imag * b.imag;
-        z.real = (a.real * b.real + a.imag * b.imag) / denom;
-        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
-        return z;
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
-        __pyx_t_double_complex z;
-        z.real = -a.real;
-        z.imag = -a.imag;
-        return z;
-    }
-    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
-       return (a.real == 0) && (a.imag == 0);
-    }
-    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
-        __pyx_t_double_complex z;
-        z.real =  a.real;
-        z.imag = -a.imag;
-        return z;
-    }
-    #if 1
-        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
-          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
-            return sqrt(z.real*z.real + z.imag*z.imag);
-          #else
-            return hypot(z.real, z.imag);
-          #endif
-        }
-        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
-            __pyx_t_double_complex z;
-            double r, lnr, theta, z_r, z_theta;
-            if (b.imag == 0 && b.real == (int)b.real) {
-                if (b.real < 0) {
-                    double denom = a.real * a.real + a.imag * a.imag;
-                    a.real = a.real / denom;
-                    a.imag = -a.imag / denom;
-                    b.real = -b.real;
-                }
-                switch ((int)b.real) {
-                    case 0:
-                        z.real = 1;
-                        z.imag = 0;
-                        return z;
-                    case 1:
-                        return a;
-                    case 2:
-                        z = __Pyx_c_prod(a, a);
-                        return __Pyx_c_prod(a, a);
-                    case 3:
-                        z = __Pyx_c_prod(a, a);
-                        return __Pyx_c_prod(z, a);
-                    case 4:
-                        z = __Pyx_c_prod(a, a);
-                        return __Pyx_c_prod(z, z);
-                }
-            }
-            if (a.imag == 0) {
-                if (a.real == 0) {
-                    return a;
-                }
-                r = a.real;
-                theta = 0;
-            } else {
-                r = __Pyx_c_abs(a);
-                theta = atan2(a.imag, a.real);
-            }
-            lnr = log(r);
-            z_r = exp(lnr * b.real - theta * b.imag);
-            z_theta = theta * b.real + lnr * b.imag;
-            z.real = z_r * cos(z_theta);
-            z.imag = z_r * sin(z_theta);
-            return z;
-        }
-    #endif
-#endif
-
-static int __Pyx_check_binary_version(void) {
-    char ctversion[4], rtversion[4];
-    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
-    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
-    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
-        char message[200];
-        PyOS_snprintf(message, sizeof(message),
-                      "compiletime version %s of module '%.100s' "
-                      "does not match runtime version %s",
-                      ctversion, __Pyx_MODULE_NAME, rtversion);
-        return PyErr_WarnEx(NULL, message, 1);
-    }
-    return 0;
-}
-
-#ifndef __PYX_HAVE_RT_ImportModule
-#define __PYX_HAVE_RT_ImportModule
-static PyObject *__Pyx_ImportModule(const char *name) {
-    PyObject *py_name = 0;
-    PyObject *py_module = 0;
-    py_name = __Pyx_PyIdentifier_FromString(name);
-    if (!py_name)
-        goto bad;
-    py_module = PyImport_Import(py_name);
-    Py_DECREF(py_name);
-    return py_module;
-bad:
-    Py_XDECREF(py_name);
-    return 0;
-}
-#endif
-
-#ifndef __PYX_HAVE_RT_ImportType
-#define __PYX_HAVE_RT_ImportType
-static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
-    size_t size, int strict)
-{
-    PyObject *py_module = 0;
-    PyObject *result = 0;
-    PyObject *py_name = 0;
-    char warning[200];
-    Py_ssize_t basicsize;
-#ifdef Py_LIMITED_API
-    PyObject *py_basicsize;
-#endif
-    py_module = __Pyx_ImportModule(module_name);
-    if (!py_module)
-        goto bad;
-    py_name = __Pyx_PyIdentifier_FromString(class_name);
-    if (!py_name)
-        goto bad;
-    result = PyObject_GetAttr(py_module, py_name);
-    Py_DECREF(py_name);
-    py_name = 0;
-    Py_DECREF(py_module);
-    py_module = 0;
-    if (!result)
-        goto bad;
-    if (!PyType_Check(result)) {
-        PyErr_Format(PyExc_TypeError,
-            "%.200s.%.200s is not a type object",
-            module_name, class_name);
-        goto bad;
-    }
-#ifndef Py_LIMITED_API
-    basicsize = ((PyTypeObject *)result)->tp_basicsize;
-#else
-    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
-    if (!py_basicsize)
-        goto bad;
-    basicsize = PyLong_AsSsize_t(py_basicsize);
-    Py_DECREF(py_basicsize);
-    py_basicsize = 0;
-    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
-        goto bad;
-#endif
-    if (!strict && (size_t)basicsize > size) {
-        PyOS_snprintf(warning, sizeof(warning),
-            "%s.%s size changed, may indicate binary incompatibility",
-            module_name, class_name);
-        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
-    }
-    else if ((size_t)basicsize != size) {
-        PyErr_Format(PyExc_ValueError,
-            "%.200s.%.200s has the wrong size, try recompiling",
-            module_name, class_name);
-        goto bad;
-    }
-    return (PyTypeObject *)result;
-bad:
-    Py_XDECREF(py_module);
-    Py_XDECREF(result);
-    return NULL;
-}
-#endif
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
-    while (t->p) {
-        #if PY_MAJOR_VERSION < 3
-        if (t->is_unicode) {
-            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
-        } else if (t->intern) {
-            *t->p = PyString_InternFromString(t->s);
-        } else {
-            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
-        }
-        #else
-        if (t->is_unicode | t->is_str) {
-            if (t->intern) {
-                *t->p = PyUnicode_InternFromString(t->s);
-            } else if (t->encoding) {
-                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
-            } else {
-                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
-            }
-        } else {
-            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
-        }
-        #endif
-        if (!*t->p)
-            return -1;
-        ++t;
-    }
-    return 0;
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
-    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
-}
-static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
-    Py_ssize_t ignore;
-    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
-}
-static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
-#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
-    if (
-#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
-            __Pyx_sys_getdefaultencoding_not_ascii &&
-#endif
-            PyUnicode_Check(o)) {
-#if PY_VERSION_HEX < 0x03030000
-        char* defenc_c;
-        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
-        if (!defenc) return NULL;
-        defenc_c = PyBytes_AS_STRING(defenc);
-#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
-        {
-            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
-            char* c;
-            for (c = defenc_c; c < end; c++) {
-                if ((unsigned char) (*c) >= 128) {
-                    PyUnicode_AsASCIIString(o);
-                    return NULL;
-                }
-            }
-        }
-#endif
-        *length = PyBytes_GET_SIZE(defenc);
-        return defenc_c;
-#else
-        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
-#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
-        if (PyUnicode_IS_ASCII(o)) {
-            *length = PyUnicode_GET_LENGTH(o);
-            return PyUnicode_AsUTF8(o);
-        } else {
-            PyUnicode_AsASCIIString(o);
-            return NULL;
-        }
-#else
-        return PyUnicode_AsUTF8AndSize(o, length);
-#endif
-#endif
-    } else
-#endif
-#if !CYTHON_COMPILING_IN_PYPY
-    if (PyByteArray_Check(o)) {
-        *length = PyByteArray_GET_SIZE(o);
-        return PyByteArray_AS_STRING(o);
-    } else
-#endif
-    {
-        char* result;
-        int r = PyBytes_AsStringAndSize(o, &result, length);
-        if (unlikely(r < 0)) {
-            return NULL;
-        } else {
-            return result;
-        }
-    }
-}
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
-   int is_true = x == Py_True;
-   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
-   else return PyObject_IsTrue(x);
-}
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
-  PyNumberMethods *m;
-  const char *name = NULL;
-  PyObject *res = NULL;
-#if PY_MAJOR_VERSION < 3
-  if (PyInt_Check(x) || PyLong_Check(x))
-#else
-  if (PyLong_Check(x))
-#endif
-    return Py_INCREF(x), x;
-  m = Py_TYPE(x)->tp_as_number;
-#if PY_MAJOR_VERSION < 3
-  if (m && m->nb_int) {
-    name = "int";
-    res = PyNumber_Int(x);
-  }
-  else if (m && m->nb_long) {
-    name = "long";
-    res = PyNumber_Long(x);
-  }
-#else
-  if (m && m->nb_int) {
-    name = "int";
-    res = PyNumber_Long(x);
-  }
-#endif
-  if (res) {
-#if PY_MAJOR_VERSION < 3
-    if (!PyInt_Check(res) && !PyLong_Check(res)) {
-#else
-    if (!PyLong_Check(res)) {
-#endif
-      PyErr_Format(PyExc_TypeError,
-                   "__%.4s__ returned non-%.4s (type %.200s)",
-                   name, name, Py_TYPE(res)->tp_name);
-      Py_DECREF(res);
-      return NULL;
-    }
-  }
-  else if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError,
-                    "an integer is required");
-  }
-  return res;
-}
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
-  Py_ssize_t ival;
-  PyObject *x;
-#if PY_MAJOR_VERSION < 3
-  if (likely(PyInt_CheckExact(b)))
-      return PyInt_AS_LONG(b);
-#endif
-  if (likely(PyLong_CheckExact(b))) {
-    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
-     #if CYTHON_USE_PYLONG_INTERNALS
-       switch (Py_SIZE(b)) {
-       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
-       case  0: return 0;
-       case  1: return ((PyLongObject*)b)->ob_digit[0];
-       }
-     #endif
-    #endif
-    return PyLong_AsSsize_t(b);
-  }
-  x = PyNumber_Index(b);
-  if (!x) return -1;
-  ival = PyInt_AsSsize_t(x);
-  Py_DECREF(x);
-  return ival;
-}
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
-    return PyInt_FromSize_t(ival);
-}
-
-
-#endif /* Py_PYTHON_H */
diff --git a/astropy/time/erfa_time.py b/astropy/time/erfa_time.py
new file mode 100644
index 0000000..5789e24
--- /dev/null
+++ b/astropy/time/erfa_time.py
@@ -0,0 +1,40 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This module is a compatibility layer, mapping the `astropy._erfa` function names
+to the names used in the ``astropy/time/erfa_time.pyx`` wrapper that was used
+before `astropy._erfa` was implemented.
+
+This module will probably remove in a future version - either `time` will be
+changed to use names fully compatible with `astropy._erfa`, or `astropy._erfa`
+will gain the ability to have "official" aliases to match these names.
+"""
+
+from .._erfa import *
+
+d_tai_utc = dat
+jd_dtf = d2dtf
+
+dtf_jd = dtf2d
+tai_tt = taitt
+tcb_tdb = tcbtdb
+tcg_tt = tcgtt
+tdb_tcb = tdbtcb
+tt_tai = tttai
+tt_tcg = tttcg
+utc_tai = utctai
+tai_utc = taiutc
+tai_ut1 = taiut1
+ut1_tai = ut1tai
+tt_ut1 = ttut1
+ut1_tt = ut1tt
+tdb_tt = tdbtt
+tt_tdb = tttdb
+ut1_utc = ut1utc
+utc_ut1 = utcut1
+d_tdb_tt = dtdb
+era_gd2gc = gd2gc
+era_gc2gd = gc2gd
+jd_julian_epoch = epj
+julian_epoch_jd = epj2jd
+jd_besselian_epoch = epb
+besselian_epoch_jd = epb2jd
diff --git a/astropy/time/erfa_time.pyx b/astropy/time/erfa_time.pyx
deleted file mode 100644
index 0889082..0000000
--- a/astropy/time/erfa_time.pyx
+++ /dev/null
@@ -1,2056 +0,0 @@
-import warnings
-
-from ..utils.exceptions import AstropyUserWarning
-
-import numpy as np
-cimport numpy as np
-import cython
-
-ctypedef np.double_t DOUBLE_T
-
-cdef extern from "erfa.h":
-    double eraEpb(double dj1, double dj2)
-    double eraEpj(double dj1, double dj2)
-    void eraEpj2jd(double epj, double *djm0, double *djm)
-    void eraEpb2jd(double epb, double *djm0, double *djm)
-    int eraCal2jd(int iy, int im, int id, double *djm0, double *djm)
-    int eraJd2cal(double dj1, double dj2,int *iy, int *im, int *id, double *fd)
-    int eraJdcalf(int ndp, double dj1, double dj2, int iymdf[4])
-
-    # Internal JD to/from datetime format converters
-    int eraD2dtf(char *scale, int ndp, double d1, double d2, int *iy, int *im, int *id, int ihmsf[4])
-    int eraDtf2d(char *scale, int iy, int im, int id, int ihr, int imn, double sec, double *d1, double *d2)
-
-    # Time scale helper routines
-    double eraDtdb(double date1, double date2, double ut, double elong, double u, double v)
-    int eraDat(int iy, int im, int id, double fd, double *deltat)
-
-    # Time scale conversion routines
-    int eraTaitt(double tai1, double tai2, double *tt1, double *tt2)
-    int eraTttai(double tt1, double tt2, double *tai1, double *tai2)
-    int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2)
-    int eraUtctai(double utc1, double utc2, double *tai1, double *tai2)
-    int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2)
-    int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2)
-    int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2)
-    int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2)
-
-    int eraTaiut1(double tai1, double tai2, double dta, double *ut11, double *ut12)
-    int eraUt1tai(double ut11, double ut12, double dta, double *tai1, double *tai2)
-    int eraTtut1(double tt1, double tt2, double dt, double *ut11, double *ut12)
-    int eraUt1tt(double ut11, double ut12, double dt, double *tt1, double *tt2)
-    int eraTdbtt(double tdb1, double tdb2, double dtr, double *tt1, double *tt2)
-    int eraTttdb(double tt1, double tt2, double dtr, double *tdb1, double *tdb2)
-    int eraUt1utc(double ut11, double ut12, double dut1, double *utc1, double *utc2)
-    int eraUtcut1(double utc1, double utc2, double dut1, double *ut11, double *ut12)
-
-    # Geodetic
-    int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
-    int eraGd2gc(int n, double elong, double phi, double height, double xyz[3])
-    int eraGc2gd(int n, double xyz[3], double *elong, double *phi, double *height )
-
-    # Sidereal time
-    double eraGmst06(double uta, double utb, double tta, double ttb)
-    double eraGmst00(double uta, double utb, double tta, double ttb)
-    double eraGmst82(double dj1, double dj2)
-    double eraGst00a(double uta, double utb, double tta, double ttb)
-    double eraGst00b(double uta, double utb)
-    double eraGst06a(double uta, double utb, double tta, double ttb)
-    double eraGst94(double uta, double utb)
-
-DUBIOUS = 'dubious year for UTC (before 1960.0 or 5 years ' \
-          'beyond last known leap second)'
-
-def check_return(ret, func_name, warns={}, errors={}):
-    """Check the return value from an era routine"""
-    if ret in warns:
-        warnings.warn('{0}: {1}'.format(func_name, warns[ret]), AstropyUserWarning)
-    elif ret in errors:
-        raise ValueError('{0}: {1}'.format(func_name, errors[ret]))
-    elif ret != 0:
-        raise ValueError('Unexpected return code {0} from {1}'
-                         .format(repr(ret), func_name))
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def cal2jd( 
-    np.ndarray[int, ndim=1] iy,
-    np.ndarray[int, ndim=1] im,
-    np.ndarray[int, ndim=1] id,
-    np.ndarray[double, ndim=1] djm0,
-    np.ndarray[double, ndim=1] djm):
-    """
-    int eraCal2jd(int iy, int im, int id, double *djm0, double *djm)
-    Calendar date to high-precision JD.
-
-    **  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.
-    """
-    cdef unsigned int i
-    cdef unsigned n = iy.shape[0]
-    warns = {-3: 'Bad input day (JD still computed)'}
-    errs = {-1: 'Bad input year',
-             -2: 'Bad input month'}
-    for i in range(n):
-        ret = eraCal2jd( iy[i], im[i], id[i], &djm0[i], &djm[i])
-        check_return(ret, 'eraCal2jd', warns, errs)
-    return
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def d_tai_utc(np.ndarray[int, ndim=1] iy,
-              np.ndarray[int, ndim=1] im,
-              np.ndarray[int, ndim=1] id,
-              np.ndarray[double, ndim=1] fd):
-    """
-    int eraDat(int iy, int im, int id, double fd, double *deltat)
-    For a given UTC date, calculate delta(AT) = TAI-UTC.
-
-    **  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)
-    **
-    **  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 parameter
-    **     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
-    **     j=+1.  This is distinct from the error status j=-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 UTC-TAI 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 UTC-TAI 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 (zero to less than 1 is
-    **     the valid range) even if not used;  if invalid, zero is used and
-    **     status j=-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, j=-2 (bad month)
-    **     will be returned.
-    **
-    **  6) In cases where a valid result is not available, zero is returned.
-
-    **                       1 = dubious year (Note 1)
-    **                       0 = OK
-    **                      -1 = bad year
-    **                      -2 = bad month
-    **                      -3 = bad day (Note 3)
-    **                      -4 = bad fraction (Note 4)
-
-    """
-    cdef int i
-    cdef int n = iy.shape[0]
-    assert (iy.shape[0] == im.shape[0] == id.shape[0] == fd.shape[0])
-
-    cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'bad year',
-             -2: 'bad month (must be 1 to 12)',
-             -3: 'bad day (must be within normal calendar date for a month)',
-             -4: 'bad fraction of day'}
-    for i in range(n):
-        ret = eraDat(iy[i], im[i], id[i], fd[i],
-                     &out[i])
-        check_return(ret, 'eraDat', warns, errs)
-
-    return out
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def jd_dtf(scale, ndp,
-              np.ndarray[double, ndim=1] d1,
-              np.ndarray[double, ndim=1] d2):
-    """
-    int eraD2dtf(const char *scale, int ndp, double d1, double d2,
-             int *iy, int *im, int *id, int ihmsf[4])
-
-    **  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.
-    **
-    **  5) The warning status "dubious year" flags UTCs that predate the
-    **     introduction of the time scale and that are too far in the future
-    **     to be trusted.  See eraDat for further details.
-    **
-    **  6) For calendar conventions and limitations, see eraCal2jd.
-    """
-    cdef int i
-    cdef int n = d1.shape[0]
-
-    cdef np.ndarray[int, ndim=1] iy = np.empty(n, dtype=np.intc)
-    cdef np.ndarray[int, ndim=1] im = np.empty(n, dtype=np.intc)
-    cdef np.ndarray[int, ndim=1] id = np.empty(n, dtype=np.intc)
-    cdef np.ndarray[int, ndim=2] ihmsf = np.empty((n, 4), dtype=np.intc)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'unacceptable date'}
-
-    for i in range(n):
-        ret = eraD2dtf(scale, ndp, d1[i], d2[i],
-                     &iy[i], &im[i], &id[i], &ihmsf[i, 0])
-        check_return(ret, 'eraD2dtf', warns, errs)
-
-    return iy, im, id, ihmsf
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def dtf_jd(scale,
-              np.ndarray[int, ndim=1] iy,
-              np.ndarray[int, ndim=1] im,
-              np.ndarray[int, ndim=1] id,
-              np.ndarray[int, ndim=1] ihr,
-              np.ndarray[int, ndim=1] imn,
-              np.ndarray[double, ndim=1] sec):
-    """
-    int eraDtf2d(char *scale, int iy, int im, int id, int ihr, int imn, double sec, double *d1, double *d2)
-
-    **  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.
-    **
-    **  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 and 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.
-
-    """
-    cdef int i
-    cdef int n = iy.shape[0]
-    assert (iy.shape[0] == im.shape[0] == id.shape[0] ==
-            ihr.shape[0] == imn.shape[0] == sec.shape[0])
-
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    warns = {3: 'time is after end of day and ' + DUBIOUS,
-             2: 'time is after end of day',
-             1: DUBIOUS}
-    errs = {-1: 'bad year',
-            -2: 'bad month',
-            -3: 'bad day',
-            -4: 'bad hour',
-            -5: 'bad minute',
-            -6: 'bad second (< 0)'}
-
-    for i in range(n):
-        ret = eraDtf2d(scale, iy[i], im[i], id[i], ihr[i], imn[i], sec[i],
-                       &out1[i], &out2[i])
-        check_return(ret, 'eraDtf2d', warns, errs)
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tai_tt( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTaitt(double tai1, double tai2, double *tt1, double *tt2)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTaitt(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTaitt')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tcb_tdb( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2)
-
-    **  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.
-    """
-
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTcbtdb(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTcbtdb')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tcg_tt( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-   int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2)
-
-   **  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
-    """
-
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTcgtt(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTcgtt')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tdb_tcb( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2)
-
-    **  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
-    """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTdbtcb(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTdbtcb')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tt_tai( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTttai(double tt1, double tt2, double *tai1, double *tai2)
-
-    **  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
-    """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTttai(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTttai')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tt_tcg( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2)
-    **  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
-    """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTttcg(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTttcg')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def utc_tai( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraUtctai(double utc1, double utc2, double *tai1, double *tai2)
-
-    **  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.
-    **
-    **  3) The warning status "dubious year" flags UTCs that predate the
-    **     introduction of the time scale and 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.
-    **
-    """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'unacceptable date'}
-
-    for i in range(n):
-        ret = eraUtctai(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraUtctai', warns, errs)
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tai_utc( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2):
-    """
-    int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2)
-
-    **  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.
-    **
-    **  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 and that are too far in the future
-    **     to be trusted.  See eraDat for further details.
-        """
-    assert in1.shape[0] == in2.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'unacceptable date'}
-
-    for i in range(n):
-        ret = eraTaiutc(in1[i], in2[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTaiutc', warns, errs)
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tai_ut1( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraTaiut1(double tai1, double tai2, double dta, double *ut11, double *ut12)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTaiut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTaiut1')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def ut1_tai( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraUt1tai(double ut11, double ut12, double dta, double *tai1, double *tai2)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraUt1tai(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraUt1tai')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tt_ut1( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraTtut1(double tt1, double tt2, double dt, double *ut11, double *ut12)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTtut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTtut1')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def ut1_tt( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraUt1tt(double ut11, double ut12, double dt, double *tt1, double *tt2)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraUt1tt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraUt1tt')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tdb_tt( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraTdbtt(double tdb1, double tdb2, double dtr, double *tt1, double *tt2)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTdbtt(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTdbtt')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def tt_tdb( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraTttdb(double tt1, double tt2, double dtr, double *tdb1, double *tdb2)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        ret = eraTttdb(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraTttdb')
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def ut1_utc( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraUt1utc(double ut11, double ut12, double dut1, double *utc1, double *utc2)
-
-    **  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 and that are too far in the future
-    **     to be trusted.  See eraDat for further details.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'unacceptable date'}
-
-    for i in range(n):
-        ret = eraUt1utc(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraUt1utc', warns, errs)
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def utc_ut1( 
-    np.ndarray[double, ndim=1] in1,
-    np.ndarray[double, ndim=1] in2,
-    np.ndarray[double, ndim=1] dt):
-    """
-    int eraUtcut1(double utc1, double utc2, double dut1, double *ut11, double *ut12)
-
-    **  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 7)
-    **                                  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 and 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
-    **     It is the caller's responsibility to supply a DUT 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.
-    **
-    **  7) The warning status "dubious year" flags UTCs that predate the
-    **     introduction of the time scale and that are too far in the future
-    **     to be trusted.  See eraDat for further details.
-    """
-    assert in1.shape[0] == in2.shape[0] == dt.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] out1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] out2 = np.empty(n, dtype=np.double)
-
-    warns = {1: DUBIOUS}
-    errs = {-1: 'unacceptable date'}
-
-    for i in range(n):
-        ret = eraUtcut1(in1[i], in2[i], dt[i], &out1[i], &out2[i])
-        check_return(ret, 'eraUtcut1', warns, errs)
-
-    return out1, out2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def d_tdb_tt(np.ndarray[double, ndim=1] in1,
-             np.ndarray[double, ndim=1] in2,
-             np.ndarray[double, ndim=1] ut,
-             np.ndarray[double, ndim=1] elong,
-	     np.ndarray[double, ndim=1] u,
-	     np.ndarray[double, ndim=1] v):
-    """
-    compute DTR = TDB-TT
-    double eraDtdb(double date1, double date2, double ut,
-                   double elong, double u, double v)
-
-    **  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.
-    """
-    assert in1.shape[0] == in2.shape[0] == ut.shape[0]
-    assert elong.shape[0] == u.shape[0] == v.shape[0]
-    assert elong.shape[0] == 1 or elong.shape[0] == in1.shape[0]
-    cdef unsigned n = in1.shape[0]
-    cdef unsigned int i, j
-    cdef np.ndarray[double, ndim=1] out = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        j = min(i, elong.shape[0]-1)
-        out[i] = eraDtdb(in1[i], in2[i], ut[i], elong[j], u[j], v[j])
-    return out
-
-
-def era_af2a(sign, ideg, iamin, asec):
-    """
-    int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
-
-    **  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.
-    """
-    cdef double rad
-    s = ord(sign)
-
-    warns = {1: 'ideg outside range 0-359',
-             2: 'iamin outside range 0-59',
-             3: 'asec outside range 0-59.999...'}
-
-    ret = eraAf2a(s, ideg, iamin, asec, &rad)
-    check_return(ret, 'eraAf2a', warns)
-
-    return rad
-
-def era_gd2gc(n, elong, phi, height):
-    """
-    Wrap
-    int eraGd2gc(int n, double elong, double phi, double height, double xyz[3])
-
-    **  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     WGS84
-    **        2     GRS80
-    **        3     WGS72
-    **
-    **     The n value has no significance outside the ERFA software.  For
-    **     convenience, symbols 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.
-    """
-    assert elong.shape[0] == phi.shape[0] == height.shape[0]
-    cdef unsigned int i
-    cdef unsigned int nitems = elong.shape[0]
-    cdef np.ndarray[double, ndim=1] xyz = np.empty(3, dtype=np.double)
-    cdef np.ndarray[double, ndim=2] out = np.empty((nitems, 3), dtype=np.double)
-
-    errs = {-1: 'illegal identifier',
-             -2: 'illegal case'}
-
-    for i in range(nitems):
-        ret = eraGd2gc(n, elong[i], phi[i], height[i], &xyz[0])
-        check_return(ret, 'eraGd2gc', errors=errs)
-        out[i] = xyz
-
-    return out
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def era_gc2gd(n, xyz):
-    """
-    Wrap
-    int eraGc2gd(int n, double xyz[3], double *elong, double *phi, double *height )
-
-    **  Given:
-    **     n       int        ellipsoid identifier (Note 1)
-    **     xyz     double[3]  geocentric vector (Note 2)
-    **
-    **  Returned:
-    **     elong   double     longitude (radians, east +ve)
-    **     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,
-    **     phi and height are both 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, NumFOCUS Foundation.
-    **  Derived, with permission, from the SOFA library.  See notes at end of file.
-    """
-    assert xyz.shape[1] == 3
-    cdef unsigned int i
-    cdef unsigned int nitems = xyz.shape[0]
-    cdef np.ndarray[double, ndim=1] elong = np.empty(nitems, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] phi = np.empty(nitems, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] height = np.empty(nitems, dtype=np.double)
-    cdef double xyz_item[3]
-
-    errs = {-1: 'illegal identifier',
-            -2: 'illegal case'}
-    for i in range(nitems):
-        # ensure xyz are in a contiguous array
-        for j in range(3):
-            xyz_item[j] = xyz[i, j]
-        ret = eraGc2gd(n, xyz_item, &elong[i], &phi[i], &height[i])
-        check_return(ret, 'eraGd2gc', errors=errs)
-
-    return elong, phi, height
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def jd_julian_epoch(np.ndarray[double, ndim=1] jd1,
-                    np.ndarray[double, ndim=1] jd2):
-    """ Wrap double eraEpj(double dj1, double dj2)
-    **  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 2451545D0
-    **     (J2000.0).
-    """
-    assert jd1.shape[0] == jd2.shape[0]
-    cdef unsigned n = jd1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        epd[i] = eraEpj(jd1[i], jd2[i])
-    return epd
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def julian_epoch_jd(np.ndarray[double, ndim=1] epd):
-    """ Wrap void eraEpj2jd(double epj, double *djm0, double *djm)
-    **  Julian Epoch to Julian Date.
-    **  Given:
-    **     epj      double    Julian Epoch (e.g. 1996.8D0)
-    **
-    **  Returned:
-    **     djm0     double    MJD zero-point: always 2400000.5
-    **     djm      double    Modified Julian Date
-    """
-    cdef unsigned n = epd.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        eraEpj2jd(epd[i], &jd1[i], &jd2[i])
-    return jd1, jd2
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def jd_besselian_epoch(np.ndarray[double, ndim=1] jd1,
-                       np.ndarray[double, ndim=1] jd2):
-    """ Wrap double eraEpb(double dj1, double dj2)
-    **  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 2451545D0
-    **     (J2000.0).
-    """
-    assert jd1.shape[0] == jd2.shape[0]
-    cdef unsigned n = jd1.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] epd = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        epd[i] = eraEpb(jd1[i], jd2[i])
-    return epd
-
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def besselian_epoch_jd(np.ndarray[double, ndim=1] epd):
-    """ Wrap void eraEpb2jd(double epj, double *djm0, double *djm)
-    **  Besselian Epoch to Julian Date.
-
-    **  Given:
-    **     epb      double    Besselian Epoch (e.g. 1957.3D0)
-    **
-    **  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.
-    """
-    cdef unsigned n = epd.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] jd1 = np.empty(n, dtype=np.double)
-    cdef np.ndarray[double, ndim=1] jd2 = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        eraEpb2jd(epd[i], &jd1[i], &jd2[i])
-    return jd1, jd2
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gmst00(np.ndarray[double, ndim=1] ut11,
-           np.ndarray[double, ndim=1] ut12,
-           np.ndarray[double, ndim=1] tt1,
-           np.ndarray[double, ndim=1] tt2):
-    """Wrap double eraGmst00(double uta, double utb, double tta, double ttb)
-    **  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, NumFOCUS Foundation.
-    **  Derived, with permission, from the SOFA library.  See notes at end of file.
-    """
-    assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gmst[i] = eraGmst00(ut11[i], ut12[i], tt1[i], tt2[i])
-
-    return gmst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gmst06(np.ndarray[double, ndim=1] ut11,
-           np.ndarray[double, ndim=1] ut12,
-           np.ndarray[double, ndim=1] tt1,
-           np.ndarray[double, ndim=1] tt2):
-    """Wrap double eraGmst06(double uta, double utb, double tta, double ttb)
-    **  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
-    """
-    assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gmst[i] = eraGmst06(ut11[i], ut12[i], tt1[i], tt2[i])
-
-    return gmst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gmst82(np.ndarray[double, ndim=1] ut11,
-           np.ndarray[double, ndim=1] ut12):
-    """Wrap double double eraGmst82(double dj1, double dj2)
-    **  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.7D0        0D0        (JD method)
-    **          2451545D0      -1421.3D0     (J2000 method)
-    **         2400000.5D0     50123.2D0     (MJD method)
-    **         2450123.5D0       0.2D0       (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).
-    """
-    assert ut11.shape[0] == ut12.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gmst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gmst[i] = eraGmst82(ut11[i], ut12[i]
-)
-    return gmst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gst00a(np.ndarray[double, ndim=1] ut11,
-           np.ndarray[double, ndim=1] ut12,
-           np.ndarray[double, ndim=1] tt1,
-           np.ndarray[double, ndim=1] tt2):
-    """Wrap double eraGst00a(double uta, double utb, double tta, double ttb)
-    **  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)
-    """
-    assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gst[i] = eraGst00a(ut11[i], ut12[i], tt1[i], tt2[i])
-
-    return gst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gst00b(np.ndarray[double, ndim=1] ut11,
-            np.ndarray[double, ndim=1] ut12):
-    """Wrap double eraGst00b(double uta, double utb)
-    **  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)
-    """
-    assert ut11.shape[0] == ut12.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gst[i] = eraGst00b(ut11[i], ut12[i]
-)
-    return gst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gst06a(np.ndarray[double, ndim=1] ut11,
-           np.ndarray[double, ndim=1] ut12,
-           np.ndarray[double, ndim=1] tt1,
-           np.ndarray[double, ndim=1] tt2):
-    """Wrap double eraGst06a(double uta, double utb, double tta, double ttb)
-    **  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
-    """
-    assert ut11.shape[0] == ut12.shape[0] == tt1.shape[0] == tt2.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gst[i] = eraGst06a(ut11[i], ut12[i], tt1[i], tt2[i])
-
-    return gst
-
- at cython.wraparound(False)
- at cython.boundscheck(False)
-def gst94(np.ndarray[double, ndim=1] ut11,
-          np.ndarray[double, ndim=1] ut12):
-    """Wrap double eraGst94(double uta, double utb)
-    **  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)
-    """
-    assert ut11.shape[0] == ut12.shape[0]
-    cdef unsigned n = ut11.shape[0]
-    cdef unsigned int i
-    cdef np.ndarray[double, ndim=1] gst = np.empty(n, dtype=np.double)
-
-    for i in range(n):
-        gst[i] = eraGst94(ut11[i], ut12[i])
-
-    return gst
diff --git a/astropy/time/setup_package.py b/astropy/time/setup_package.py
index 08bfae6..3cd9f7c 100644
--- a/astropy/time/setup_package.py
+++ b/astropy/time/setup_package.py
@@ -1,36 +1,5 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
-import os
-from distutils.extension import Extension
-
-from astropy_helpers import setup_helpers
-
-TIMEROOT = os.path.relpath(os.path.dirname(__file__))
-
-
-def get_extensions():
-    sources = [os.path.join(TIMEROOT, "erfa_time.pyx")]
-    include_dirs = ['numpy']
-    libraries = []
-
-    if setup_helpers.use_system_library('erfa'):
-        libraries.append('erfa')
-    else:
-        sources.append("cextern/erfa/erfa.c")
-        include_dirs.append('cextern/erfa')
-
-    time_ext = Extension(
-        name="astropy.time.erfa_time",
-        sources=sources,
-        include_dirs=include_dirs,
-        libraries=libraries,
-        language="c",)
-
-    return [time_ext]
-
-
-def get_external_libraries():
-    return ['erfa']
 
 def requires_2to3():
     return False
diff --git a/astropy/time/tests/test_basic.py b/astropy/time/tests/test_basic.py
index 19c9f17..748acd3 100644
--- a/astropy/time/tests/test_basic.py
+++ b/astropy/time/tests/test_basic.py
@@ -6,11 +6,12 @@ import copy
 import functools
 import sys
 
-from datetime import datetime
+from datetime import datetime, tzinfo, timedelta
 
 import numpy as np
 
-from ...tests.helper import pytest
+from ...tests.helper import pytest, catch_warnings
+from ...extern import six
 from .. import Time, ScaleValueError, erfa_time, TIME_SCALES
 from ...coordinates import EarthLocation
 
@@ -55,6 +56,26 @@ class TestBasic():
 
         assert allclose_sec(t.cxcsec, np.array([31536064.307456788, 378691266.18400002]))
 
+    def test_different_dimensions(self):
+        """Test scalars, vector, and higher-dimensions"""
+        # scalar
+        val, val1 = 2450000.0, 0.125
+        t1 = Time(val, val1, format='jd')
+        assert t1.isscalar is True and t1.shape == ()
+        # vector
+        val = np.arange(2450000., 2450010.)
+        t2 = Time(val, format='jd')
+        assert t2.isscalar is False and t2.shape == val.shape
+        # explicitly check broadcasting for mixed vector, scalar.
+        val2 = 0.
+        t3 = Time(val, val2, format='jd')
+        assert t3.isscalar is False and t3.shape == val.shape
+        val2 = (np.arange(5.)/10.).reshape(5, 1)
+        # now see if broadcasting to two-dimensional works
+        t4 = Time(val, val2, format='jd')
+        assert t4.isscalar is False
+        assert t4.shape == np.broadcast(val, val2).shape
+
     def test_copy_time(self):
         """Test copying the values of a Time object by passing it into the
         Time initializer.
@@ -87,7 +108,7 @@ class TestBasic():
         t = Time(mjd, format='mjd', scale='utc', location=('45d', '50d'))
         t1 = t[3]
         assert t1.isscalar is True
-        assert np.all(t1._time.jd1 == np.array([t._time.jd1[3]]))
+        assert t1._time.jd1 == t._time.jd1[3]
         assert t1.location is t.location
         t1a = Time(mjd[3], format='mjd', scale='utc')
         assert t1a.isscalar is True
@@ -124,6 +145,19 @@ class TestBasic():
         assert t4.location.view(np.ndarray)[5] != allzeros
         t6.location.view(np.ndarray)[-1] = allzeros
         assert t4.location.view(np.ndarray)[5] == allzeros
+        # Test subscription also works for two-dimensional arrays.
+        frac = np.arange(0., 0.999, 0.2)
+        t7 = Time(mjd[:, np.newaxis] + frac, format='mjd', scale='utc',
+                  location=('45d', '50d'))
+        assert t7[0, 0]._time.jd1 == t7._time.jd1[0, 0]
+        assert t7[0, 0].isscalar is True
+        assert np.all(t7[5]._time.jd1 == t7._time.jd1[5])
+        assert np.all(t7[5]._time.jd2 == t7._time.jd2[5])
+        assert np.all(t7[:, 2]._time.jd1 == t7._time.jd1[:, 2])
+        assert np.all(t7[:, 2]._time.jd2 == t7._time.jd2[:, 2])
+        assert np.all(t7[:, 0]._time.jd1 == t._time.jd1)
+        assert np.all(t7[:, 0]._time.jd2 == t._time.jd2)
+
 
     def test_properties(self):
         """Use properties to convert scales and formats.  Note that the UT1 to
@@ -211,7 +245,7 @@ class TestBasic():
     def test_location_array(self):
         """Check that location arrays are checked for size and used
         for the corresponding times.  Also checks that erfa_time.d_tdb_tt
-        can handle array-valued locations.
+        can handle array-valued locations, and can broadcast these if needed.
         """
 
         lat = 19.48125
@@ -234,6 +268,23 @@ class TestBasic():
             Time(['2006-01-15 21:24:37.5']*3, format='iso', scale='utc',
                  precision=6, location=(np.array([lon, 0]),
                                         np.array([lat, 0])))
+        # multidimensional
+        mjd = np.arange(50000., 50008.).reshape(4, 2)
+        t3 = Time(mjd, format='mjd', scale='utc', location=(lon, lat))
+        assert t3.shape == (4, 2)
+        assert t3.location.shape == ()
+        assert t3.tdb.shape == (4, 2)
+        t4 = Time(mjd, format='mjd', scale='utc',
+                  location=(np.array([lon, 0]), np.array([lat, 0])))
+        assert t4.shape == (4, 2)
+        assert t4.location.shape == (2,)
+        assert t4.tdb.shape == (4, 2)
+        t5 = Time(mjd, format='mjd', scale='utc',
+                  location=(np.array([[lon], [0], [0], [0]]),
+                            np.array([[lat], [0], [0], [0]])))
+        assert t5.shape == (4, 2)
+        assert t5.location.shape == (4, 1)
+        assert t5.tdb.shape == (4, 2)
 
     def test_all_transforms(self):
         """Test that all transforms work.  Does not test correctness,
@@ -242,7 +293,7 @@ class TestBasic():
         lon = -155.933222
         for scale1 in TIME_SCALES:
             t1 = Time('2006-01-15 21:24:37.5', format='iso', scale=scale1,
-                      lat=lat, lon=lon)
+                      location=(lon, lat))
             for scale2 in TIME_SCALES:
                 t2 = getattr(t1, scale2)
                 t21 = getattr(t2, scale1)
@@ -250,6 +301,7 @@ class TestBasic():
 
     def test_creating_all_formats(self):
         """Create a time object using each defined format"""
+        Time(2000.5, format='decimalyear')
         Time(100.0, format='cxcsec')
         Time(100.0, format='unix')
         Time(100.0, format='gps')
@@ -289,6 +341,17 @@ class TestBasic():
         t = Time('2000-01-01 01:01:01.123456789', scale='tai')
         assert t.datetime == datetime(2000, 1, 1, 1, 1, 1, 123457)
 
+        # broadcasting
+        dt3 = (dt + (dt2-dt)*np.arange(12)).reshape(4, 3)
+        t3 = Time(dt3, scale='utc')
+        assert t3.shape == (4, 3)
+        assert t3[2, 1].value == dt3[2, 1]
+        assert t3[2, 1] == Time(dt3[2, 1])
+        assert np.all(t3.value == dt3)
+        assert np.all(t3[1].value == dt3[1])
+        assert np.all(t3[:, 2] == Time(dt3[:, 2]))
+        assert Time(t3[2, 0]) == t3[2, 0]
+
     def test_epoch_transform(self):
         """Besselian and julian epoch transforms"""
         jd = 2457073.05631
@@ -377,6 +440,13 @@ class TestBasic():
         assert t3.format == t1.format  # yday
         assert np.all(t3.value == np.concatenate([[t1.tt.yday], t2.tt.yday]))
 
+        # OK, how likely is this... but might as well test.
+        mjd = np.arange(50000., 50006.)
+        frac = np.arange(0., 0.999, 0.2)
+        t4 = Time(mjd[:, np.newaxis] + frac, format='mjd', scale='utc')
+        t5 = Time([t4[:2], t4[4:5]])
+        assert t5.shape == (3, 5)
+
 
 class TestVal2():
     """Tests related to val2"""
@@ -392,11 +462,13 @@ class TestVal2():
         assert t.mjd[0] == t.mjd[1]
         assert t.jd[0] == t.jd[1]
 
-    def test_val_matches_val2(self):
+    def test_val_broadcasts_against_val2(self):
+        mjd = np.arange(50000., 50007.)
+        frac = np.arange(0., 0.999, 0.2)
+        t = Time(mjd[:, np.newaxis], frac, format='mjd', scale='utc')
+        assert t.shape == (7, 5)
         with pytest.raises(ValueError):
-            Time([0.0, 50000.0], [0.0], format='mjd', scale='tai')
-        with pytest.raises(ValueError):
-            Time([0.0], 0.0, format='mjd', scale='tai')
+            Time([0.0, 50000.0], [0.0, 1.0, 2.0], format='mjd', scale='tai')
 
 
 class TestSubFormat():
@@ -533,26 +605,29 @@ class TestSubFormat():
 
 
 class TestSofaErrors():
-    """Test that erfa_time.pyx handles erfa status return values correctly"""
+    """Test that erfa status return values are handled correctly"""
 
     def test_bad_time(self):
         iy = np.array([2000], dtype=np.intc)
         im = np.array([2000], dtype=np.intc)  # bad month
         id = np.array([2000], dtype=np.intc)  # bad day
-        djm0 = np.array([0], dtype=np.double)
-        djm = np.array([0], dtype=np.double)
         with pytest.raises(ValueError):  # bad month, fatal error
-            erfa_time.cal2jd(iy, im, id, djm0, djm)
+            djm0, djm = erfa_time.cal2jd(iy, im, id)
 
-        # Set month to a good value so now the bad day just gives a warning
+        iy[0] = -5000
         im[0] = 2
-        erfa_time.cal2jd(iy, im, id, djm0, djm)
+        with pytest.raises(ValueError):  # bad year, fatal error
+            djm0, djm = erfa_time.cal2jd(iy, im, id)
+
+        iy[0] = 2000
+        with catch_warnings() as w:
+            djm0, djm = erfa_time.cal2jd(iy, im, id)
+        assert len(w) == 1
+        assert 'bad day    (JD computed)' in six.text_type(w[0].message)
+
         assert allclose_jd(djm0, [2400000.5])
         assert allclose_jd(djm, [53574.])
 
-        # How do you test for warnings in pytest?  Test that dubious year for
-        # UTC works.
-
 
 class TestCopyReplicate():
     """Test issues related to copying and replicating data"""
@@ -640,11 +715,8 @@ def test_now():
     # times are more like microseconds.  But it seems safer in case some
     # platforms have slow clock calls or something.
 
-    version_info = sys.version_info
-    # py < 2.7 and py3 < 3.2 doesn't have `total_seconds`
-    if ((version_info[0] == 2 and version_info[1] < 7) or
-        (version_info[0] == 3 and version_info[1] < 2) or
-            version_info[0] < 2):
+    # py < 2.7 doesn't have `total_seconds`
+    if sys.version_info[:2] < (2, 7):
         total_secs = lambda td: (td.microseconds + (
             td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 6.
     else:
@@ -652,6 +724,20 @@ def test_now():
     assert total_secs(dt) < 0.1
 
 
+def test_decimalyear():
+    t = Time('2001:001', format='yday')
+    assert t.decimalyear == 2001.0
+
+    t = Time(2000.0, [0.5, 0.75], format='decimalyear')
+    assert np.all(t.value == [2000.5, 2000.75])
+
+    jd0 = Time('2000:001').jd
+    jd1 = Time('2001:001').jd
+    d_jd = jd1 - jd0
+    assert np.all(t.jd == [jd0 + 0.5 * d_jd,
+                           jd0 + 0.75 * d_jd])
+
+
 def test_dir():
     t = Time('2000:001', format='yday', scale='tai')
     assert 'utc' in dir(t)
@@ -680,3 +766,16 @@ def test_byteorder():
     time_little = Time(little_endian, format='mjd')
     assert np.all(time_big == time_mjd)
     assert np.all(time_little == time_mjd)
+
+
+def test_datetime_tzinfo():
+    """
+    Test #3160 that time zone info in datetime objects is respected.
+    """
+    class TZm6(tzinfo):
+        def utcoffset(self, dt):
+            return timedelta(hours=-6)
+
+    d = datetime(2002, 1, 2, 10, 3, 4, tzinfo=TZm6())
+    t = Time(d)
+    assert t.value == datetime(2002, 1, 2, 16, 3, 4)
diff --git a/astropy/time/tests/test_delta.py b/astropy/time/tests/test_delta.py
index db5b4be..e4fcd8f 100644
--- a/astropy/time/tests/test_delta.py
+++ b/astropy/time/tests/test_delta.py
@@ -160,7 +160,7 @@ class TestTimeDelta():
 
         # Include initializers
         dt2 = TimeDelta(dt, format='sec')
-        assert allclose_sec(dt2.val, 86400.0)
+        assert allclose_sec(dt2.value, 86400.0)
 
     def test_neg_abs(self):
         for dt in (self.dt, self.dt_array):
diff --git a/astropy/time/tests/test_precision.py b/astropy/time/tests/test_precision.py
index dfca9b9..96f50c1 100644
--- a/astropy/time/tests/test_precision.py
+++ b/astropy/time/tests/test_precision.py
@@ -110,3 +110,13 @@ def test_precision_epoch():
     t_tai = Time(range(1980, 2001), format='jyear', scale='tai')
     dt = t_utc - t_tai
     assert allclose_sec(dt.sec, np.round(dt.sec))
+
+
+def test_leap_seconds_rounded_correctly():
+    """Regression tests against #2083, where a leap second was rounded
+    incorrectly by the underlying ERFA routine."""
+    t = Time(['2012-06-30 23:59:59.413',
+              '2012-07-01 00:00:00.413'], scale='ut1', precision=3).utc
+    assert np.all(t.iso == np.array(['2012-06-30 23:59:60.000',
+                                     '2012-07-01 00:00:00.000']))
+    # with the bug, both yielded '2012-06-30 23:59:60.000'
diff --git a/astropy/time/tests/test_quantity_interaction.py b/astropy/time/tests/test_quantity_interaction.py
index 96a2e73..6f73eca 100644
--- a/astropy/time/tests/test_quantity_interaction.py
+++ b/astropy/time/tests/test_quantity_interaction.py
@@ -71,6 +71,11 @@ class TestTimeQuantity():
         q2 = 1.*u.day
         t2 = t0 - q2
         assert allclose_sec(t2.value, t0.value-q2.to(u.second).value)
+        # check broadcasting
+        q3 = np.arange(15.).reshape(3, 5) * u.hour
+        t3 = t0 - q3
+        assert t3.shape == q3.shape
+        assert allclose_sec(t3.value, t0.value-q3.to(u.second).value)
 
     def test_invalid_quantity_operations(self):
         """Check that comparisons of Time with quantities does not work
@@ -125,6 +130,11 @@ class TestTimeDeltaQuantity():
         # now comparisons
         assert t0 > q1
         assert t0 < 1.*u.yr
+        # and broadcasting
+        q3 = np.arange(12.).reshape(4, 3) * u.hour
+        t3 = t0 + q3
+        assert t3.shape == q3.shape
+        assert allclose_sec(t3.value, t0.value + q3.to(u.second).value)
 
     def test_valid_quantity_operations2(self):
         """Check that TimeDelta is treated as a quantity where possible."""
@@ -143,8 +153,21 @@ class TestTimeDeltaQuantity():
         v = s/t0
         assert isinstance(v, u.Quantity)
         assert v.decompose().unit == u.m / u.second
+        # broadcasting
+        t1 = TimeDelta(np.arange(100000., 100012.).reshape(6, 2), format='sec')
+        f = np.array([1., 2.]) * u.cycle * u.Hz
+        phase = f * t1
+        assert isinstance(phase, u.Quantity)
+        assert phase.shape == t1.shape
+        assert phase.unit.is_equivalent(u.cycle)
 
     def test_invalid_quantity_operations(self):
         """Check comparisons of TimeDelta with non-time quantities fails."""
         with pytest.raises(OperandTypeError):
             TimeDelta(100000., format='sec') > 10.*u.m
+
+    def test_invalid_quantity_broadcast(self):
+        """Check broadcasting rules in interactions with Quantity."""
+        t0 = TimeDelta(np.arange(12.).reshape(4, 3), format='sec')
+        with pytest.raises(ValueError):
+            t0 + np.arange(4.) * u.s
diff --git a/astropy/units/__init__.py b/astropy/units/__init__.py
index 5a17987..d5f38a5 100644
--- a/astropy/units/__init__.py
+++ b/astropy/units/__init__.py
@@ -13,6 +13,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 
 from .core import *
 from .quantity import *
+from .decorators import *
 
 from . import si
 from . import cgs
diff --git a/astropy/units/astrophys.py b/astropy/units/astrophys.py
index 57de06d..9e3af7d 100644
--- a/astropy/units/astrophys.py
+++ b/astropy/units/astrophys.py
@@ -17,7 +17,7 @@ from __future__ import (absolute_import, division, print_function,
 
 from . import si
 from ..constants import si as _si
-from .core import UnitBase, def_unit
+from .core import UnitBase, def_unit, si_prefixes, binary_prefixes
 
 import numpy as _numpy
 
@@ -26,7 +26,7 @@ _ns = globals()
 ###########################################################################
 # LENGTH
 
-def_unit((['AU', 'au'], []), _si.au.value * si.m, namespace=_ns, prefixes=True,
+def_unit((['AU', 'au'], ['astronomical_unit']), _si.au.value * si.m, namespace=_ns, prefixes=True,
          doc="astronomical unit: approximately the mean Earth--Sun "
          "distance.")
 
@@ -34,10 +34,10 @@ def_unit(['pc', 'parsec'], _si.pc.value * si.m, namespace=_ns, prefixes=True,
          doc="parsec: approximately 3.26 light-years.")
 
 def_unit(['solRad', 'R_sun', 'Rsun'], _si.R_sun.value * si.m, namespace=_ns,
-         doc="Solar radius",
+         doc="Solar radius", prefixes=True,
          format={'latex': r'R_{\odot}', 'unicode': 'R⊙'})
 def_unit(['lyr', 'lightyear'], _si.c.value * si.yr.to(si.s) * si.m,
-         namespace=_ns, doc="Light year")
+         namespace=_ns, prefixes=True, doc="Light year")
 
 
 ###########################################################################
@@ -68,6 +68,7 @@ def_unit(['M_e'], _si.m_e.value * si.kg, namespace=_ns,
          format={'latex': r'M_{e}', 'unicode': 'Mₑ'})
 # Unified atomic mass unit
 def_unit(['u', 'Da', 'Dalton'], 1.6605387e-27 * si.kg, namespace=_ns,
+         prefixes=True, exclude_prefixes=['a', 'da'],
          doc="Unified atomic mass unit")
 
 
@@ -75,6 +76,7 @@ def_unit(['u', 'Da', 'Dalton'], 1.6605387e-27 * si.kg, namespace=_ns,
 # ENERGY
 
 def_unit(['Ry', 'rydberg'], 13.605692 * si.eV, namespace=_ns,
+         prefixes=True,
          doc="Rydberg: Energy of a photon whose wavenumber is the Rydberg "
          "constant",
          format={'latex': r'R_{\infty}', 'unicode': 'R∞'})
@@ -91,9 +93,9 @@ def_unit(['solLum', 'L_sun', 'Lsun'], _si.L_sun.value * si.W, namespace=_ns,
 ###########################################################################
 # SPECTRAL DENSITY
 
-def_unit(['ph', 'photon'],
-         format={'ogip': 'photon'},
-         namespace=_ns)
+def_unit((['ph', 'photon'], ['photon']),
+         format={'ogip': 'photon', 'vounit': 'photon'},
+         namespace=_ns, prefixes=True)
 def_unit(['Jy', 'Jansky', 'jansky'], 1e-26 * si.W / si.m ** 2 / si.Hz,
          namespace=_ns, prefixes=True,
          doc="Jansky: spectral flux density")
@@ -117,27 +119,30 @@ def_unit(['Sun'], namespace=_ns)
 ###########################################################################
 # EVENTS
 
-def_unit(['ct', 'count'],
-         format={'fits': 'count', 'ogip': 'count'},
-         namespace=_ns)
-def_unit(['pix', 'pixel'],
-         format={'ogip': 'pixel'},
-         namespace=_ns)
+def_unit((['ct', 'count'], ['count']),
+         format={'fits': 'count', 'ogip': 'count', 'vounit': 'count'},
+         namespace=_ns, prefixes=True, exclude_prefixes=['p'])
+def_unit((['pix', 'pixel'], ['pixel']),
+         format={'ogip': 'pixel', 'vounit': 'pixel'},
+         namespace=_ns, prefixes=True)
 
 
 ###########################################################################
 # MISCELLANEOUS
 
-def_unit(['chan'], namespace=_ns)
-def_unit(['bin'], namespace=_ns)
-def_unit(['vox', 'voxel'],
+def_unit(['chan'], namespace=_ns, prefixes=True)
+def_unit(['bin'], namespace=_ns, prefixes=True)
+def_unit((['vox', 'voxel'], ['voxel']),
          format={'fits': 'voxel', 'ogip': 'voxel', 'vounit': 'voxel'},
-         namespace=_ns)
-def_unit((['bit', 'b'], ['bit']), namespace=_ns, prefixes=True)
-def_unit((['byte', 'B'], ['byte']), namespace=_ns, prefixes=True,
+         namespace=_ns, prefixes=True)
+def_unit((['bit', 'b'], ['bit']), namespace=_ns,
+         prefixes=si_prefixes + binary_prefixes)
+def_unit((['byte', 'B'], ['byte']), 8 * bit, namespace=_ns,
+         format={'vounit': 'byte'},
+         prefixes=si_prefixes + binary_prefixes,
          exclude_prefixes=['d'])
-def_unit(['adu'], namespace=_ns)
-def_unit(['beam'], namespace=_ns)
+def_unit(['adu'], namespace=_ns, prefixes=True)
+def_unit(['beam'], namespace=_ns, prefixes=True)
 def_unit(['electron'], doc="Number of electrons", namespace=_ns,
          format={'latex': r'e^{-}', 'unicode': 'e⁻'})
 
diff --git a/astropy/units/cds.py b/astropy/units/cds.py
index 87ec0af..b5861f0 100644
--- a/astropy/units/cds.py
+++ b/astropy/units/cds.py
@@ -35,14 +35,7 @@ def _initialize_module():
 
     # The CDS format also supports power-of-2 prefixes as defined here:
     # http://physics.nist.gov/cuu/Units/binary.html
-    prefixes = core.si_prefixes + [
-        (['Ki'], ['kibi'], 2. ** 10),
-        (['Mi'], ['mebi'], 2. ** 20),
-        (['Gi'], ['gibi'], 2. ** 30),
-        (['Ti'], ['tebi'], 2. ** 40),
-        (['Pi'], ['pebi'], 2. ** 50),
-        (['Ei'], ['exbi'], 2. ** 60)
-        ]
+    prefixes = core.si_prefixes + core.binary_prefixes
 
     # CDS only uses the short prefixes
     prefixes = [(short, short, factor) for (short, long, factor) in prefixes]
diff --git a/astropy/units/cgs.py b/astropy/units/cgs.py
index 681b931..f176cfb 100644
--- a/astropy/units/cgs.py
+++ b/astropy/units/cgs.py
@@ -86,7 +86,7 @@ def_unit(['k', 'Kayser', 'kayser'], cm ** -1, namespace=_ns,
 # ELECTRICAL
 
 def_unit(['D', 'Debye', 'debye'], Fraction(1, 3) * 1e-29 * C * si.m,
-         namespace=_ns,
+         namespace=_ns, prefixes=True,
          doc="Debye: CGS unit of electric dipole moment")
 
 def_unit(['Fr', 'Franklin', 'statcoulomb', 'statC', 'esu'],
diff --git a/astropy/units/core.py b/astropy/units/core.py
index 3b4ecac..e536240 100644
--- a/astropy/units/core.py
+++ b/astropy/units/core.py
@@ -17,8 +17,9 @@ import textwrap
 import warnings
 import numpy as np
 
+from ..utils.decorators import lazyproperty
 from ..utils.exceptions import AstropyWarning
-from ..utils.misc import isiterable, InheritDocstrings, lazyproperty
+from ..utils.misc import isiterable, InheritDocstrings
 from .utils import (is_effectively_unity, sanitize_scale, validate_power,
                     add_powers)
 from . import format as unit_format
@@ -307,14 +308,14 @@ def set_enabled_units(units):
     >>> u.m.find_equivalent_units()
       Primary name | Unit definition | Aliases
     [
-      AU           | 1.49598e+11 m   | au           ,
-      Angstrom     | 1e-10 m         | AA, angstrom ,
-      cm           | 0.01 m          | centimeter   ,
-      lyr          | 9.46073e+15 m   | lightyear    ,
-      m            | irreducible     | meter        ,
-      micron       | 1e-06 m         |              ,
-      pc           | 3.08568e+16 m   | parsec       ,
-      solRad       | 6.95508e+08 m   | R_sun, Rsun  ,
+      AU           | 1.49598e+11 m   | au, astronomical_unit ,
+      Angstrom     | 1e-10 m         | AA, angstrom          ,
+      cm           | 0.01 m          | centimeter            ,
+      lyr          | 9.46073e+15 m   | lightyear             ,
+      m            | irreducible     | meter                 ,
+      micron       | 1e-06 m         |                       ,
+      pc           | 3.08568e+16 m   | parsec                ,
+      solRad       | 6.95508e+08 m   | R_sun, Rsun           ,
     ]
     """
     # get a context with a new registry, using equivalencies of the current one
@@ -354,19 +355,19 @@ def add_enabled_units(units):
     ...
       Primary name | Unit definition | Aliases
     [
-      AU           | 1.49598e+11 m   | au               ,
-      Angstrom     | 1e-10 m         | AA, angstrom     ,
-      cm           | 0.01 m          | centimeter       ,
-      ft           | 0.3048 m        | foot             ,
-      inch         | 0.0254 m        |                  ,
-      lyr          | 9.46073e+15 m   | lightyear        ,
-      m            | irreducible     | meter            ,
-      mi           | 1609.34 m       | mile             ,
-      micron       | 1e-06 m         |                  ,
-      nmi          | 1852 m          | nauticalmile, NM ,
-      pc           | 3.08568e+16 m   | parsec           ,
-      solRad       | 6.95508e+08 m   | R_sun, Rsun      ,
-      yd           | 0.9144 m        | yard             ,
+      AU           | 1.49598e+11 m   | au, astronomical_unit ,
+      Angstrom     | 1e-10 m         | AA, angstrom          ,
+      cm           | 0.01 m          | centimeter            ,
+      ft           | 0.3048 m        | foot                  ,
+      inch         | 0.0254 m        |                       ,
+      lyr          | 9.46073e+15 m   | lightyear             ,
+      m            | irreducible     | meter                 ,
+      mi           | 1609.34 m       | mile                  ,
+      micron       | 1e-06 m         |                       ,
+      nmi          | 1852 m          | nauticalmile, NM      ,
+      pc           | 3.08568e+16 m   | parsec                ,
+      solRad       | 6.95508e+08 m   | R_sun, Rsun           ,
+      yd           | 0.9144 m        | yard                  ,
     ]
     """
     # get a context with a new registry, which is a copy of the current one
@@ -440,6 +441,19 @@ class UnitsError(Exception):
     """
 
 
+class UnitScaleError(UnitsError, ValueError):
+    """
+    Used to catch the errors involving scaled units,
+    which are not recognized by FITS format.
+    """
+    pass
+
+
+# Maintain error in old location for backward compatibility
+from .format import fits as _fits
+_fits.UnitScaleError = UnitScaleError
+
+
 class UnitsWarning(AstropyWarning):
     """
     The base class for unit-specific exceptions.
@@ -559,7 +573,7 @@ class UnitBase(object):
         """
         return [1]
 
-    def to_string(self, format='generic'):
+    def to_string(self, format=unit_format.Generic):
         """
         Output the unit in the given format as a string.
 
@@ -626,9 +640,16 @@ class UnitBase(object):
         if isinstance(m, (bytes, six.text_type)):
             return Unit(m) / self
 
-        # Cannot handle this as Unit, re-try as Quantity
+        # Cannot handle this as Unit.  Here, m cannot be a Quantity,
+        # so we make it into one, fasttracking when it does not have a unit,
+        # for the common case of <array> / <unit>.
         from .quantity import Quantity
-        return m / Quantity(1, self)
+        if hasattr(m, 'unit'):
+            result = Quantity(m)
+            result /= self
+            return result
+        else:
+            return Quantity(m, self**(-1))
 
     __truediv__ = __div__
 
@@ -645,7 +666,7 @@ class UnitBase(object):
                 return m
             return CompositeUnit(1, [self, m], [1, 1], _error_check=False)
 
-        # Cannot handle this as Unit, re-try as Quantity
+        # Cannot handle this as Unit, re-try as Quantity.
         from .quantity import Quantity
         return Quantity(1, self) * m
 
@@ -653,9 +674,16 @@ class UnitBase(object):
         if isinstance(m, (bytes, six.text_type)):
             return Unit(m) * self
 
-        # Cannot handle this as Unit, re-try as Quantity
+        # Cannot handle this as Unit.  Here, m cannot be a Quantity,
+        # so we make it into one, fasttracking when it does not have a unit
+        # for the common case of <array> * <unit>.
         from .quantity import Quantity
-        return m * Quantity(1, self)
+        if hasattr(m, 'unit'):
+            result = Quantity(m)
+            result *= self
+            return result
+        else:
+            return Quantity(m, self)
 
     def __hash__(self):
         # This must match the hash used in CompositeUnit for a unit
@@ -1638,7 +1666,7 @@ class UnrecognizedUnit(IrreducibleUnit):
     if six.PY3:
         __str__ = __unicode__
 
-    def to_string(self, format='generic'):
+    def to_string(self, format=unit_format.Generic):
         return self.name
 
     def _unrecognized_operator(self, *args, **kwargs):
@@ -1727,7 +1755,7 @@ class _UnitMetaClass(InheritDocstrings):
                 return dimensionless_unscaled
 
             if format is None:
-                format = 'generic'
+                format = unit_format.Generic
 
             f = unit_format.get_format(format)
             if six.PY3 and isinstance(s, bytes):
@@ -1739,8 +1767,10 @@ class _UnitMetaClass(InheritDocstrings):
                 if parse_strict == 'silent':
                     pass
                 else:
-                    if format != 'generic':
-                        format_clause = format + ' '
+                    # Deliberately not isinstance here. Subclasses
+                    # should use their name.
+                    if type(f) is not unit_format.Generic:
+                        format_clause = f.name + ' '
                     else:
                         format_clause = ''
                     msg = ("'{0}' did not parse as {1}unit: {2}"
@@ -2076,6 +2106,16 @@ si_prefixes = [
 ]
 
 
+binary_prefixes = [
+    (['Ki'], ['kibi'], 2. ** 10),
+    (['Mi'], ['mebi'], 2. ** 20),
+    (['Gi'], ['gibi'], 2. ** 30),
+    (['Ti'], ['tebi'], 2. ** 40),
+    (['Pi'], ['pebi'], 2. ** 50),
+    (['Ei'], ['exbi'], 2. ** 60)
+]
+
+
 def _add_prefixes(u, excludes=[], namespace=None, prefixes=False):
     """
     Set up all of the standard metric prefixes for a unit.  This
@@ -2194,7 +2234,7 @@ def def_unit(s, represents=None, register=None, doc=None,
     """
     if register is not None:
         warnings.warn(
-            "The registry kwarg was removed in astropy 0.3. "
+            "The register kwarg was removed in astropy 0.3. "
             "Use the namespace kwarg to inject the unit into "
             "a namespace and add_enabled_units() to enable it "
             "in the global unit registry.",
diff --git a/astropy/units/decorators.py b/astropy/units/decorators.py
new file mode 100644
index 0000000..d0a72fb
--- /dev/null
+++ b/astropy/units/decorators.py
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+__all__ = ['quantity_input']
+
+from ..utils.decorators import wraps
+from ..utils.compat import funcsigs
+
+from .core import UnitsError, add_enabled_equivalencies
+
+class QuantityInput(object):
+
+    @classmethod
+    def as_decorator(cls, func=None, **kwargs):
+        """
+        A decorator for validating the units of arguments to functions.
+
+        Unit specifications can be provided as keyword arguments to the decorator,
+        or by using Python 3's function annotation syntax. Arguments to the decorator
+        take precedence over any function annotations present.
+
+        A `~astropy.units.UnitsError` will be raised if the unit attribute of
+        the argument is not equivalent to the unit specified to the decorator
+        or in the annotation.
+        If the argument has no unit attribute, i.e. it is not a Quantity object, a
+        `~exceptions.ValueError` will be raised.
+
+        Where an equivalency is specified in the decorator, the function will be
+        executed with that equivalency in force.
+
+        Notes
+        -----
+
+        The checking of arguments inside variable arguments to a function is not
+        supported (i.e. \*arg or \**kwargs).
+
+        Examples
+        --------
+
+        Python 2 and 3::
+
+            import astropy.units as u
+            @u.quantity_input(myangle=u.arcsec)
+            def myfunction(myangle):
+                return myangle**2
+
+        Python 3 only::
+
+            import astropy.units as u
+            @u.quantity_input
+            def myfunction(myangle: u.arcsec):
+                return myangle**2
+
+        Using equivalencies::
+
+            import astropy.units as u
+            @u.quantity_input(myenergy=u.eV, equivalencies=u.mass_energy())
+            def myfunction(myenergy):
+                return myenergy**2
+
+        """
+        self = cls(**kwargs)
+        if func is not None and not kwargs:
+            return self(func)
+        else:
+            return self
+
+    def __init__(self, func=None, **kwargs):
+        self.equivalencies = kwargs.pop('equivalencies', [])
+        self.decorator_kwargs = kwargs
+
+    def __call__(self, wrapped_function):
+
+        # Extract the function signature for the function we are wrapping.
+        wrapped_signature = funcsigs.signature(wrapped_function)
+
+        # Define a new function to return in place of the wrapped one
+        @wraps(wrapped_function)
+        def wrapper(*func_args, **func_kwargs):
+            # Bind the arguments to our new function to the signature of the original.
+            bound_args = wrapped_signature.bind(*func_args, **func_kwargs)
+
+            # Iterate through the parameters of the original signature
+            for param in wrapped_signature.parameters.values():
+                # We do not support variable arguments (*args, **kwargs)
+                if param.kind in (funcsigs.Parameter.VAR_KEYWORD,
+                                  funcsigs.Parameter.VAR_POSITIONAL):
+                    continue
+                # Catch the (never triggered) case where bind relied on a default value.
+                if param.name not in bound_args.arguments and param.default is not param.empty:
+                    bound_args.arguments[param.name] = param.default
+
+                # Get the value of this parameter (argument to new function)
+                arg = bound_args.arguments[param.name]
+
+                # Get target unit, either from decorator kwargs or annotations
+                if param.name in self.decorator_kwargs:
+                    target_unit = self.decorator_kwargs[param.name]
+                else:
+                    target_unit = param.annotation
+
+                # If the target unit is empty, then no unit was specified so we
+                # move past it
+                if target_unit is not funcsigs.Parameter.empty:
+                    try:
+                        equivalent = arg.unit.is_equivalent(target_unit,
+                                                  equivalencies=self.equivalencies)
+
+                        if not equivalent:
+                            raise UnitsError("Argument '{0}' to function '{1}'"
+                                             " must be in units convertable to"
+                                             " '{2}'.".format(param.name,
+                                                     wrapped_function.__name__,
+                                                     target_unit.to_string()))
+
+                    # Either there is no .unit or no .is_equivalent
+                    except AttributeError:
+                        if hasattr(arg, "unit"):
+                            error_msg = "a 'unit' attribute without an 'is_equivalent' method"
+                        else:
+                            error_msg = "no 'unit' attribute"
+                        raise TypeError("Argument '{0}' to function has '{1}' {2}. "
+                              "You may want to pass in an astropy Quantity instead."
+                                 .format(param.name, wrapped_function.__name__, error_msg))
+
+            # Call the original function with any equivalencies in force.
+            with add_enabled_equivalencies(self.equivalencies):
+                return wrapped_function(*func_args, **func_kwargs)
+
+        return wrapper
+
+quantity_input = QuantityInput.as_decorator
diff --git a/astropy/units/format/__init__.py b/astropy/units/format/__init__.py
index 61179b7..7f7b77f 100644
--- a/astropy/units/format/__init__.py
+++ b/astropy/units/format/__init__.py
@@ -7,26 +7,21 @@ A collection of different unit formats.
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-from inspect import isclass
-
 from .base import Base
 from .generic import Generic, Unscaled
 from .cds import CDS
 from .console import Console
 from .fits import Fits
-from .latex import Latex
+from .latex import Latex, LatexInline
 from .ogip import OGIP
 from .unicode_format import Unicode
 from .vounit import VOUnit
 
-__all__ = [
-    'Base', 'Generic', 'CDS', 'Console', 'Fits', 'Latex', 'OGIP', 'Unicode',
-    'Unscaled', 'VOUnit', 'get_format']
-
-FORMATS = [
-    'Generic', 'CDS', 'Console', 'Fits', 'Latex', 'OGIP', 'Unicode',
-    'Unscaled', 'VOUnit']
+from ...extern.six import string_types
 
+__all__ = [
+    'Base', 'Generic', 'CDS', 'Console', 'Fits', 'Latex', 'LatexInline',
+    'OGIP', 'Unicode', 'Unscaled', 'VOUnit', 'get_format']
 
 def get_format(format=None):
     """
@@ -47,12 +42,19 @@ def get_format(format=None):
         return format()
     elif isinstance(format, Base):
         return format
+    elif not (isinstance(format, string_types) or format is None):
+        raise TypeError(
+            "Formatter must a subclass or instance of a subclass of {0!r} "
+            "or a string giving the name of the formatter.  Valid formatter "
+            "names are: [{1}]".format(Base, ', '.join(Base.registry)))
 
     if format is None:
         format = 'generic'
-    format = format.lower()
-    for key in FORMATS:
-        val = globals()[key]
-        if isclass(val) and (issubclass(val, Base) and key.lower() == format.lower()):
-            return val()
-    raise ValueError("Unknown format {0!r}".format(format))
+
+    format_lower = format.lower()
+
+    if format_lower in Base.registry:
+        return Base.registry[format_lower]()
+
+    raise ValueError("Unknown format {0!r}.  Valid formatter names are: "
+                     "[{1}]".format(format, ', '.join(Base.registry)))
diff --git a/astropy/units/format/base.py b/astropy/units/format/base.py
index 16045af..adf7c86 100644
--- a/astropy/units/format/base.py
+++ b/astropy/units/format/base.py
@@ -8,7 +8,23 @@ from ...utils.misc import InheritDocstrings
 from ...extern import six
 
 
- at six.add_metaclass(InheritDocstrings)
+class _FormatterMeta(InheritDocstrings):
+    registry = {}
+
+    def __new__(mcls, name, bases, members):
+        if 'name' in members:
+            formatter_name = members['name'].lower()
+        else:
+            formatter_name = members['name'] = name.lower()
+
+        cls = super(mcls, _FormatterMeta).__new__(mcls, name, bases, members)
+
+        mcls.registry[formatter_name] = cls
+
+        return cls
+
+
+ at six.add_metaclass(_FormatterMeta)
 class Base(object):
     """
     The abstract base class of all unit formats.
diff --git a/astropy/units/format/cds.py b/astropy/units/format/cds.py
index 2f49c9d..6ce8e26 100644
--- a/astropy/units/format/cds.py
+++ b/astropy/units/format/cds.py
@@ -264,7 +264,7 @@ class CDS(Base):
         if unit not in cls._units:
             if detailed_exception:
                 raise ValueError(
-                    "Unit {0!r} not supported by the CDS SAC "
+                    "Unit '{0}' not supported by the CDS SAC "
                     "standard. {1}".format(
                         unit, did_you_mean(
                             unit, cls._units)))
diff --git a/astropy/units/format/console.py b/astropy/units/format/console.py
index 25b74a4..ee9698d 100644
--- a/astropy/units/format/console.py
+++ b/astropy/units/format/console.py
@@ -31,25 +31,29 @@ class Console(base.Base):
     _times = "*"
     _line = "-"
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         return unit.get_format_name('console')
 
-    def _format_superscript(self, number):
+    @classmethod
+    def _format_superscript(cls, number):
         return '^{0}'.format(number)
 
-    def _format_unit_list(self, units):
+    @classmethod
+    def _format_unit_list(cls, units):
         out = []
         for base, power in units:
             if power == 1:
-                out.append(self._get_unit_name(base))
+                out.append(cls._get_unit_name(base))
             else:
                 out.append('{0}{1}'.format(
-                    self._get_unit_name(base),
-                    self._format_superscript(
+                    cls._get_unit_name(base),
+                    cls._format_superscript(
                             utils.format_power(power))))
         return ' '.join(out)
 
-    def _format_exponential_notation(self, val):
+    @classmethod
+    def format_exponential_notation(cls, val):
         m, ex = utils.split_mantissa_exponent(val)
 
         parts = []
@@ -58,9 +62,9 @@ class Console(base.Base):
 
         if ex:
             parts.append("10{0}".format(
-                self._format_superscript(ex)))
+                cls._format_superscript(ex)))
 
-        return self._times.join(parts)
+        return cls._times.join(parts)
 
     def to_string(self, unit):
         from .. import core
@@ -69,7 +73,7 @@ class Console(base.Base):
             if unit.scale == 1:
                 s = ''
             else:
-                s = self._format_exponential_notation(unit.scale)
+                s = self.format_exponential_notation(unit.scale)
 
             if len(unit.bases):
                 positives, negatives = utils.get_grouped_by_powers(
diff --git a/astropy/units/format/fits.py b/astropy/units/format/fits.py
index 2310507..5b29025 100644
--- a/astropy/units/format/fits.py
+++ b/astropy/units/format/fits.py
@@ -8,20 +8,12 @@ from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 from ...extern.six.moves import zip
 
+import copy
 import keyword
-import warnings
-
-from ...utils.exceptions import AstropyDeprecationWarning
 
 from . import generic
 from . import utils
-from ...utils.misc import did_you_mean
 
-class UnitScaleError(ValueError):
-    """
-    Used to catch the errors involving scaled units,
-    which are not recognized by FITS format.
-    """
 
 class Fits(generic.Generic):
     """
@@ -88,56 +80,65 @@ class Fits(generic.Generic):
         return names, deprecated_names
 
     @classmethod
-    def _parse_unit(cls, unit, detailed_exception=True):
+    def _validate_unit(cls, unit, detailed_exception=True):
         if unit not in cls._units:
             if detailed_exception:
                 raise ValueError(
-                    "Unit {0!r} not supported by the FITS standard. {1}".format(
-                        unit, did_you_mean(
-                            unit, cls._units)))
+                    "Unit '{0}' not supported by the FITS standard. {1}".format(
+                        unit, utils.did_you_mean_units(
+                            unit, cls._units, cls._deprecated_units,
+                            cls._to_decomposed_alternative)))
             else:
                 raise ValueError()
 
         if unit in cls._deprecated_units:
-            warnings.warn(
-                "The unit {0!r} has been deprecated in the FITS "
-                "standard.".format(unit),
-                AstropyDeprecationWarning)
+            utils.unit_deprecation_warning(
+                unit, cls._units[unit], 'FITS',
+                cls._to_decomposed_alternative)
 
+    @classmethod
+    def _parse_unit(cls, unit, detailed_exception=True):
+        cls._validate_unit(unit)
         return cls._units[unit]
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         name = unit.get_format_name('fits')
-
-        if name not in self._units:
-            raise ValueError(
-                "Unit {0!r} is not part of the FITS standard".format(name))
-
-        if name in self._deprecated_units:
-            warnings.warn(
-                "The unit {0!r} has been deprecated in the FITS "
-                "standard.".format(name),
-                AstropyDeprecationWarning)
-
+        cls._validate_unit(name)
         return name
 
-    def to_string(self, unit):
+    @classmethod
+    def to_string(cls, unit):
         from .. import core
 
         # Remove units that aren't known to the format
-        unit = utils.decompose_to_known_units(unit, self._get_unit_name)
+        unit = utils.decompose_to_known_units(unit, cls._get_unit_name)
 
         if isinstance(unit, core.CompositeUnit):
             if unit.scale != 1:
-                raise UnitScaleError(
+                raise core.UnitScaleError(
                     "The FITS unit format is not able to represent scale. "
                     "Multiply your data by {0:e}.".format(unit.scale))
 
             pairs = list(zip(unit.bases, unit.powers))
             pairs.sort(key=lambda x: x[1], reverse=True)
 
-            s = self._format_unit_list(pairs)
+            s = cls._format_unit_list(pairs)
         elif isinstance(unit, core.NamedUnit):
-            s = self._get_unit_name(unit)
+            s = cls._get_unit_name(unit)
+
+        return s
+
+    @classmethod
+    def _to_decomposed_alternative(cls, unit):
+        from .. import core
 
+        try:
+            s = cls.to_string(unit)
+        except core.UnitScaleError:
+            scale = unit.scale
+            unit = copy.copy(unit)
+            unit._scale = 1.0
+            return '{0} (with data multiplied by {1})'.format(
+                cls.to_string(unit), scale)
         return s
diff --git a/astropy/units/format/generic.py b/astropy/units/format/generic.py
index 1634554..82b4791 100644
--- a/astropy/units/format/generic.py
+++ b/astropy/units/format/generic.py
@@ -18,6 +18,36 @@ from .base import Base
 from ...utils.misc import did_you_mean
 
 
+def _to_string(cls, unit):
+    from .. import core
+
+    if isinstance(unit, core.CompositeUnit):
+        parts = []
+
+        if cls._show_scale and unit.scale != 1:
+            parts.append('{0:g}'.format(unit.scale))
+
+        if len(unit.bases):
+            positives, negatives = utils.get_grouped_by_powers(
+                unit.bases, unit.powers)
+            if len(positives):
+                parts.append(cls._format_unit_list(positives))
+            elif len(parts) == 0:
+                parts.append('1')
+
+            if len(negatives):
+                parts.append('/')
+                unit_list = cls._format_unit_list(negatives)
+                if len(negatives) == 1:
+                    parts.append('{0}'.format(unit_list))
+                else:
+                    parts.append('({0})'.format(unit_list))
+
+        return ' '.join(parts)
+    elif isinstance(unit, core.NamedUnit):
+        return cls._get_unit_name(unit)
+
+
 class Generic(Base):
     """
     A "generic" format.
@@ -58,7 +88,7 @@ class Generic(Base):
             'CARET',
             'OPEN_PAREN',
             'CLOSE_PAREN',
-            'SQRT',
+            'FUNCNAME',
             'UNIT',
             'SIGN',
             'UINT',
@@ -99,12 +129,12 @@ class Generic(Base):
 
         # This needs to be a function so we can force it to happen
         # before t_UNIT
-        def t_SQRT(t):
-            r'sqrt'
+        def t_FUNCNAME(t):
+            r'(sqrt)|(ln)|(exp)|(log)'
             return t
 
         def t_UNIT(t):
-            r'%|((?!\d)\w)+'
+            r"%|([YZEPTGMkhdcmunpfazy]?'((?!\d)\w)+')|((?!\d)\w)+"
             t.value = cls._get_unit(t)
             return t
 
@@ -306,7 +336,7 @@ class Generic(Base):
 
         def p_function_name(p):
             '''
-            function_name : SQRT
+            function_name : FUNCNAME
             '''
             p[0] = p[1]
 
@@ -318,7 +348,7 @@ class Generic(Base):
                 p[0] = p[3] ** 0.5
             else:
                 raise ValueError(
-                   '{0!r} is not a recognized function'.format(p[1]))
+                   "'{0}' is not a recognized function".format(p[1]))
 
         def p_error(p):
             raise ValueError()
@@ -372,67 +402,45 @@ class Generic(Base):
         return result
 
     def _do_parse(self, s, debug=False):
-        # This is a short circuit for the case where the string
-        # is just a single unit name
         try:
+            # This is a short circuit for the case where the string
+            # is just a single unit name
             return self._parse_unit(s, detailed_exception=False)
         except ValueError as e:
             try:
                 return self._parser.parse(s, lexer=self._lexer, debug=debug)
             except ValueError as e:
                 if six.text_type(e):
-                    raise ValueError(six.text_type(e))
+                    raise
                 else:
-                    raise ValueError("Syntax error")
+                    raise ValueError(
+                        "Syntax error parsing unit '{0}'".format(s))
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         return unit.get_format_name('generic')
 
-    def _format_unit_list(self, units):
+    @classmethod
+    def _format_unit_list(cls, units):
         out = []
-        units.sort(key=lambda x: self._get_unit_name(x[0]).lower())
+        units.sort(key=lambda x: cls._get_unit_name(x[0]).lower())
 
         for base, power in units:
             if power == 1:
-                out.append(self._get_unit_name(base))
+                out.append(cls._get_unit_name(base))
             else:
                 power = utils.format_power(power)
                 if '/' in power:
                     out.append('{0}({1})'.format(
-                        self._get_unit_name(base), power))
+                        cls._get_unit_name(base), power))
                 else:
                     out.append('{0}{1}'.format(
-                        self._get_unit_name(base), power))
+                        cls._get_unit_name(base), power))
         return ' '.join(out)
 
-    def to_string(self, unit):
-        from .. import core
-
-        if isinstance(unit, core.CompositeUnit):
-            parts = []
-
-            if self._show_scale and unit.scale != 1:
-                parts.append('{0:g}'.format(unit.scale))
-
-            if len(unit.bases):
-                positives, negatives = utils.get_grouped_by_powers(
-                    unit.bases, unit.powers)
-                if len(positives):
-                    parts.append(self._format_unit_list(positives))
-                elif len(parts) == 0:
-                    parts.append('1')
-
-                if len(negatives):
-                    parts.append('/')
-                    unit_list = self._format_unit_list(negatives)
-                    if len(negatives) == 1:
-                        parts.append('{0}'.format(unit_list))
-                    else:
-                        parts.append('({0})'.format(unit_list))
-
-            return ' '.join(parts)
-        elif isinstance(unit, core.NamedUnit):
-            return self._get_unit_name(unit)
+    @classmethod
+    def to_string(cls, unit):
+        return _to_string(cls, unit)
 
 
 class Unscaled(Generic):
diff --git a/astropy/units/format/generic_lextab.py b/astropy/units/format/generic_lextab.py
index dceb5e1..ad08301 100644
--- a/astropy/units/format/generic_lextab.py
+++ b/astropy/units/format/generic_lextab.py
@@ -1,9 +1,9 @@
 # generic_lextab.py. This file automatically created by PLY (version 3.4). Don't edit!
 _tabversion   = '3.4'
-_lextokens    = {'CARET': 1, 'SOLIDUS': 1, 'STAR': 1, 'DOUBLE_STAR': 1, 'PERIOD': 1, 'SQRT': 1, 'SIGN': 1, 'OPEN_PAREN': 1, 'UINT': 1, 'UNIT': 1, 'CLOSE_PAREN': 1, 'UFLOAT': 1}
+_lextokens    = {'CARET': 1, 'SOLIDUS': 1, 'STAR': 1, 'DOUBLE_STAR': 1, 'PERIOD': 1, 'FUNCNAME': 1, 'OPEN_PAREN': 1, 'UINT': 1, 'UNIT': 1, 'SIGN': 1, 'CLOSE_PAREN': 1, 'UFLOAT': 1}
 _lexreflags   = 32
 _lexliterals  = ''
 _lexstateinfo = {'INITIAL': 'inclusive'}
-_lexstatere   = {'INITIAL': [('(?P<t_UFLOAT>((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+)?)|(?P<t_UINT>\\d+)|(?P<t_SIGN>[+-](?=\\d))|(?P<t_SQRT>sqrt)|(?P<t_UNIT>%|((?!\\d)\\w)+)|(?P<t_DOUBLE_STAR>\\*\\*)|(?P<t_CARET>\\^)|(?P<t_CLOSE_PAREN>\\))|(?P<t_OPEN_PAREN>\\()|(?P<t_PERIOD>\\.)|(?P<t_STAR>\\*)|(?P<t_SOLIDUS>/)', [None, ('t_UFLOAT', 'UFLOAT'), None, None, None, None, ('t_UINT', 'UINT'), ('t_SIGN', 'SIGN'), ('t_SQRT', 'SQRT'), ('t_UNIT', 'UNIT'), None, (None, 'DOUBLE_STAR'), (None, 'CARET [...]
+_lexstatere   = {'INITIAL': [("(?P<t_UFLOAT>((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+)?)|(?P<t_UINT>\\d+)|(?P<t_SIGN>[+-](?=\\d))|(?P<t_FUNCNAME>(sqrt)|(ln)|(exp)|(log))|(?P<t_UNIT>%|([YZEPTGMkhdcmunpfazy]?'((?!\\d)\\w)+')|((?!\\d)\\w)+)|(?P<t_DOUBLE_STAR>\\*\\*)|(?P<t_CARET>\\^)|(?P<t_OPEN_PAREN>\\()|(?P<t_CLOSE_PAREN>\\))|(?P<t_PERIOD>\\.)|(?P<t_STAR>\\*)|(?P<t_SOLIDUS>/)", [None, ('t_UFLOAT', 'UFLOAT'), None, None, None, None, ('t_UINT', 'UINT'), ('t_SIGN', 'SIGN'), ('t_FUNCNAME', 'FUN [...]
 _lexstateignore = {'INITIAL': ' '}
 _lexstateerrorf = {'INITIAL': 't_error'}
diff --git a/astropy/units/format/generic_parsetab.py b/astropy/units/format/generic_parsetab.py
index 36e02c6..f4e8263 100644
--- a/astropy/units/format/generic_parsetab.py
+++ b/astropy/units/format/generic_parsetab.py
@@ -6,9 +6,9 @@ _tabversion = '3.2'
 
 _lr_method = 'LALR'
 
-_lr_signature = b'\x06\x88\x92t\x1d[(\x7f\xb5\t\xa0\xbd\xaamgF'
+_lr_signature = b'\x91n3d*\xfd\x8d\x87$W\xd5^\xb8\xc6\x16['
 
-_lr_action_items = {'CARET':([17,18,34,40,],[35,35,35,35,]),'SOLIDUS':([0,3,4,5,7,8,12,14,15,17,18,19,21,22,25,26,31,39,44,45,46,47,50,51,52,54,55,56,61,62,63,64,65,],[1,-25,-9,1,1,-23,-24,-13,-11,-16,-29,-12,-45,-44,-9,1,-22,-17,-28,-8,-26,-21,-14,-18,-43,-19,-27,-30,-47,-15,-20,1,-31,]),'STAR':([3,8,12,18,44,46,55,56,61,65,],[-25,29,-24,-29,-28,-26,-27,-30,-47,-31,]),'DOUBLE_STAR':([17,18,34,40,],[37,37,37,37,]),'PERIOD':([3,8,12,18,44,46,55,56,61,65,],[-25,30,-24,-29,-28,-26,-27,-30,- [...]
+_lr_action_items = {'CARET':([17,18,34,40,],[35,35,35,35,]),'SOLIDUS':([0,3,4,5,7,8,12,14,15,17,18,19,21,22,25,26,31,39,44,45,46,47,50,51,52,54,55,56,61,62,63,64,65,],[1,-25,-9,1,1,-23,-24,-13,-11,-16,-29,-12,-45,-44,-9,1,-22,-17,-28,-8,-26,-21,-14,-18,-43,-19,-27,-30,-47,-15,-20,1,-31,]),'STAR':([3,8,12,18,44,46,55,56,61,65,],[-25,29,-24,-29,-28,-26,-27,-30,-47,-31,]),'DOUBLE_STAR':([17,18,34,40,],[37,37,37,37,]),'PERIOD':([3,8,12,18,44,46,55,56,61,65,],[-25,30,-24,-29,-28,-26,-27,-30,- [...]
 
 _lr_action = { }
 for _k, _v in _lr_action_items.items():
@@ -27,51 +27,51 @@ for _k, _v in _lr_goto_items.items():
 del _lr_goto_items
 _lr_productions = [
   ("S' -> main","S'",1,None,None,None),
-  ('main -> product_of_units','main',1,'p_main','astropy/units/format/generic.py',124),
-  ('main -> factor product_of_units','main',2,'p_main','astropy/units/format/generic.py',125),
-  ('main -> division_product_of_units','main',1,'p_main','astropy/units/format/generic.py',126),
-  ('main -> factor division_product_of_units','main',2,'p_main','astropy/units/format/generic.py',127),
-  ('main -> inverse_unit','main',1,'p_main','astropy/units/format/generic.py',128),
-  ('main -> factor inverse_unit','main',2,'p_main','astropy/units/format/generic.py',129),
-  ('main -> factor','main',1,'p_main','astropy/units/format/generic.py',130),
-  ('division_product_of_units -> division_product_of_units division product_of_units','division_product_of_units',3,'p_division_product_of_units','astropy/units/format/generic.py',140),
-  ('division_product_of_units -> product_of_units','division_product_of_units',1,'p_division_product_of_units','astropy/units/format/generic.py',141),
-  ('inverse_unit -> division unit_expression','inverse_unit',2,'p_inverse_unit','astropy/units/format/generic.py',151),
-  ('factor -> factor_float','factor',1,'p_factor','astropy/units/format/generic.py',157),
-  ('factor -> factor_int','factor',1,'p_factor','astropy/units/format/generic.py',158),
-  ('factor_float -> signed_float','factor_float',1,'p_factor_float','astropy/units/format/generic.py',164),
-  ('factor_float -> signed_float UINT signed_int','factor_float',3,'p_factor_float','astropy/units/format/generic.py',165),
-  ('factor_float -> signed_float UINT power numeric_power','factor_float',4,'p_factor_float','astropy/units/format/generic.py',166),
-  ('factor_int -> UINT','factor_int',1,'p_factor_int','astropy/units/format/generic.py',177),
-  ('factor_int -> UINT signed_int','factor_int',2,'p_factor_int','astropy/units/format/generic.py',178),
-  ('factor_int -> UINT power numeric_power','factor_int',3,'p_factor_int','astropy/units/format/generic.py',179),
-  ('factor_int -> UINT UINT signed_int','factor_int',3,'p_factor_int','astropy/units/format/generic.py',180),
-  ('factor_int -> UINT UINT power numeric_power','factor_int',4,'p_factor_int','astropy/units/format/generic.py',181),
-  ('product_of_units -> unit_expression product product_of_units','product_of_units',3,'p_product_of_units','astropy/units/format/generic.py',197),
-  ('product_of_units -> unit_expression product_of_units','product_of_units',2,'p_product_of_units','astropy/units/format/generic.py',198),
-  ('product_of_units -> unit_expression','product_of_units',1,'p_product_of_units','astropy/units/format/generic.py',199),
-  ('unit_expression -> function','unit_expression',1,'p_unit_expression','astropy/units/format/generic.py',210),
-  ('unit_expression -> unit_with_power','unit_expression',1,'p_unit_expression','astropy/units/format/generic.py',211),
-  ('unit_expression -> OPEN_PAREN product_of_units CLOSE_PAREN','unit_expression',3,'p_unit_expression','astropy/units/format/generic.py',212),
-  ('unit_with_power -> UNIT power numeric_power','unit_with_power',3,'p_unit_with_power','astropy/units/format/generic.py',221),
-  ('unit_with_power -> UNIT numeric_power','unit_with_power',2,'p_unit_with_power','astropy/units/format/generic.py',222),
-  ('unit_with_power -> UNIT','unit_with_power',1,'p_unit_with_power','astropy/units/format/generic.py',223),
-  ('numeric_power -> sign UINT','numeric_power',2,'p_numeric_power','astropy/units/format/generic.py',234),
-  ('numeric_power -> OPEN_PAREN paren_expr CLOSE_PAREN','numeric_power',3,'p_numeric_power','astropy/units/format/generic.py',235),
-  ('paren_expr -> sign UINT','paren_expr',2,'p_paren_expr','astropy/units/format/generic.py',244),
-  ('paren_expr -> signed_float','paren_expr',1,'p_paren_expr','astropy/units/format/generic.py',245),
-  ('paren_expr -> frac','paren_expr',1,'p_paren_expr','astropy/units/format/generic.py',246),
-  ('frac -> sign UINT division sign UINT','frac',5,'p_frac','astropy/units/format/generic.py',255),
-  ('sign -> SIGN','sign',1,'p_sign','astropy/units/format/generic.py',261),
-  ('sign -> <empty>','sign',0,'p_sign','astropy/units/format/generic.py',262),
-  ('product -> STAR','product',1,'p_product','astropy/units/format/generic.py',271),
-  ('product -> PERIOD','product',1,'p_product','astropy/units/format/generic.py',272),
-  ('division -> SOLIDUS','division',1,'p_division','astropy/units/format/generic.py',278),
-  ('power -> DOUBLE_STAR','power',1,'p_power','astropy/units/format/generic.py',284),
-  ('power -> CARET','power',1,'p_power','astropy/units/format/generic.py',285),
-  ('signed_int -> SIGN UINT','signed_int',2,'p_signed_int','astropy/units/format/generic.py',291),
-  ('signed_float -> sign UINT','signed_float',2,'p_signed_float','astropy/units/format/generic.py',297),
-  ('signed_float -> sign UFLOAT','signed_float',2,'p_signed_float','astropy/units/format/generic.py',298),
-  ('function_name -> SQRT','function_name',1,'p_function_name','astropy/units/format/generic.py',304),
-  ('function -> function_name OPEN_PAREN unit_expression CLOSE_PAREN','function',4,'p_function','astropy/units/format/generic.py',310),
+  ('main -> product_of_units','main',1,'p_main','astropy/units/format/generic.py',130),
+  ('main -> factor product_of_units','main',2,'p_main','astropy/units/format/generic.py',131),
+  ('main -> division_product_of_units','main',1,'p_main','astropy/units/format/generic.py',132),
+  ('main -> factor division_product_of_units','main',2,'p_main','astropy/units/format/generic.py',133),
+  ('main -> inverse_unit','main',1,'p_main','astropy/units/format/generic.py',134),
+  ('main -> factor inverse_unit','main',2,'p_main','astropy/units/format/generic.py',135),
+  ('main -> factor','main',1,'p_main','astropy/units/format/generic.py',136),
+  ('division_product_of_units -> division_product_of_units division product_of_units','division_product_of_units',3,'p_division_product_of_units','astropy/units/format/generic.py',146),
+  ('division_product_of_units -> product_of_units','division_product_of_units',1,'p_division_product_of_units','astropy/units/format/generic.py',147),
+  ('inverse_unit -> division unit_expression','inverse_unit',2,'p_inverse_unit','astropy/units/format/generic.py',157),
+  ('factor -> factor_float','factor',1,'p_factor','astropy/units/format/generic.py',163),
+  ('factor -> factor_int','factor',1,'p_factor','astropy/units/format/generic.py',164),
+  ('factor_float -> signed_float','factor_float',1,'p_factor_float','astropy/units/format/generic.py',170),
+  ('factor_float -> signed_float UINT signed_int','factor_float',3,'p_factor_float','astropy/units/format/generic.py',171),
+  ('factor_float -> signed_float UINT power numeric_power','factor_float',4,'p_factor_float','astropy/units/format/generic.py',172),
+  ('factor_int -> UINT','factor_int',1,'p_factor_int','astropy/units/format/generic.py',183),
+  ('factor_int -> UINT signed_int','factor_int',2,'p_factor_int','astropy/units/format/generic.py',184),
+  ('factor_int -> UINT power numeric_power','factor_int',3,'p_factor_int','astropy/units/format/generic.py',185),
+  ('factor_int -> UINT UINT signed_int','factor_int',3,'p_factor_int','astropy/units/format/generic.py',186),
+  ('factor_int -> UINT UINT power numeric_power','factor_int',4,'p_factor_int','astropy/units/format/generic.py',187),
+  ('product_of_units -> unit_expression product product_of_units','product_of_units',3,'p_product_of_units','astropy/units/format/generic.py',203),
+  ('product_of_units -> unit_expression product_of_units','product_of_units',2,'p_product_of_units','astropy/units/format/generic.py',204),
+  ('product_of_units -> unit_expression','product_of_units',1,'p_product_of_units','astropy/units/format/generic.py',205),
+  ('unit_expression -> function','unit_expression',1,'p_unit_expression','astropy/units/format/generic.py',216),
+  ('unit_expression -> unit_with_power','unit_expression',1,'p_unit_expression','astropy/units/format/generic.py',217),
+  ('unit_expression -> OPEN_PAREN product_of_units CLOSE_PAREN','unit_expression',3,'p_unit_expression','astropy/units/format/generic.py',218),
+  ('unit_with_power -> UNIT power numeric_power','unit_with_power',3,'p_unit_with_power','astropy/units/format/generic.py',227),
+  ('unit_with_power -> UNIT numeric_power','unit_with_power',2,'p_unit_with_power','astropy/units/format/generic.py',228),
+  ('unit_with_power -> UNIT','unit_with_power',1,'p_unit_with_power','astropy/units/format/generic.py',229),
+  ('numeric_power -> sign UINT','numeric_power',2,'p_numeric_power','astropy/units/format/generic.py',240),
+  ('numeric_power -> OPEN_PAREN paren_expr CLOSE_PAREN','numeric_power',3,'p_numeric_power','astropy/units/format/generic.py',241),
+  ('paren_expr -> sign UINT','paren_expr',2,'p_paren_expr','astropy/units/format/generic.py',250),
+  ('paren_expr -> signed_float','paren_expr',1,'p_paren_expr','astropy/units/format/generic.py',251),
+  ('paren_expr -> frac','paren_expr',1,'p_paren_expr','astropy/units/format/generic.py',252),
+  ('frac -> sign UINT division sign UINT','frac',5,'p_frac','astropy/units/format/generic.py',261),
+  ('sign -> SIGN','sign',1,'p_sign','astropy/units/format/generic.py',267),
+  ('sign -> <empty>','sign',0,'p_sign','astropy/units/format/generic.py',268),
+  ('product -> STAR','product',1,'p_product','astropy/units/format/generic.py',277),
+  ('product -> PERIOD','product',1,'p_product','astropy/units/format/generic.py',278),
+  ('division -> SOLIDUS','division',1,'p_division','astropy/units/format/generic.py',284),
+  ('power -> DOUBLE_STAR','power',1,'p_power','astropy/units/format/generic.py',290),
+  ('power -> CARET','power',1,'p_power','astropy/units/format/generic.py',291),
+  ('signed_int -> SIGN UINT','signed_int',2,'p_signed_int','astropy/units/format/generic.py',297),
+  ('signed_float -> sign UINT','signed_float',2,'p_signed_float','astropy/units/format/generic.py',303),
+  ('signed_float -> sign UFLOAT','signed_float',2,'p_signed_float','astropy/units/format/generic.py',304),
+  ('function_name -> FUNCNAME','function_name',1,'p_function_name','astropy/units/format/generic.py',310),
+  ('function -> function_name OPEN_PAREN unit_expression CLOSE_PAREN','function',4,'p_function','astropy/units/format/generic.py',316),
 ]
diff --git a/astropy/units/format/latex.py b/astropy/units/format/latex.py
index 163ae9f..4f1b375 100644
--- a/astropy/units/format/latex.py
+++ b/astropy/units/format/latex.py
@@ -7,8 +7,11 @@ Handles the "LaTeX" unit format.
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
+import numpy as np
+
 from . import base
 from . import utils
+from ...extern.six.moves import zip
 
 
 class Latex(base.Base):
@@ -21,39 +24,49 @@ class Latex(base.Base):
     def __init__(self):
         pass
 
-    def _latex_escape(self, name):
+    @classmethod
+    def _latex_escape(cls, name):
         # This doesn't escape arbitrary LaTeX strings, but it should
         # be good enough for unit names which are required to be alpha
         # + "_" anyway.
         return name.replace('_', r'\_')
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         name = unit.get_format_name('latex')
         if name == unit.name:
-            return self._latex_escape(name)
+            return cls._latex_escape(name)
         return name
 
-    def _format_unit_list(self, units):
+    @classmethod
+    def _format_unit_list(cls, units):
         out = []
         for base, power in units:
             if power == 1:
-                out.append(self._get_unit_name(base))
+                out.append(cls._get_unit_name(base))
             else:
                 out.append('{0}^{{{1}}}'.format(
-                    self._get_unit_name(base),
+                    cls._get_unit_name(base),
                     utils.format_power(power)))
         return r'\,'.join(out)
 
-    def _format_exponential_notation(self, val):
-        m, ex = utils.split_mantissa_exponent(val)
+    @classmethod
+    def _format_bases(cls, unit):
+        positives, negatives = utils.get_grouped_by_powers(
+                unit.bases, unit.powers)
 
-        parts = []
-        if m:
-            parts.append(m)
-        if ex:
-            parts.append("10^{{{0}}}".format(ex))
+        if len(negatives):
+            if len(positives):
+                positives = cls._format_unit_list(positives)
+            else:
+                positives = '1'
+            negatives = cls._format_unit_list(negatives)
+            s = r'\frac{{{0}}}{{{1}}}'.format(positives, negatives)
+        else:
+            positives = cls._format_unit_list(positives)
+            s = positives
 
-        return r" \times ".join(parts)
+        return s
 
     def to_string(self, unit):
         from .. import core
@@ -68,22 +81,63 @@ class Latex(base.Base):
             if unit.scale == 1:
                 s = ''
             else:
-                s = self._format_exponential_notation(unit.scale) + r'\,'
+                s = self.format_exponential_notation(unit.scale) + r'\,'
 
             if len(unit.bases):
-                positives, negatives = utils.get_grouped_by_powers(
-                    unit.bases, unit.powers)
-                if len(negatives):
-                    if len(positives):
-                        positives = self._format_unit_list(positives)
-                    else:
-                        positives = '1'
-                    negatives = self._format_unit_list(negatives)
-                    s += r'\frac{{{0}}}{{{1}}}'.format(positives, negatives)
-                else:
-                    positives = self._format_unit_list(positives)
-                    s += positives
+                s += self._format_bases(unit)
+
         elif isinstance(unit, core.NamedUnit):
             s = self._latex_escape(unit.name)
 
         return r'$\mathrm{{{0}}}$'.format(s)
+
+    @classmethod
+    def format_exponential_notation(cls, val):
+        """
+        Formats a value in exponential notation for LaTeX.
+
+        Parameters
+        ----------
+        val : number
+            The value to be formatted
+
+        Returns
+        -------
+        latex_string : str
+            The value in exponential notation in a format suitable for LaTeX.
+        """
+        if np.isfinite(val):
+            m, ex = utils.split_mantissa_exponent(val)
+
+            parts = []
+            if m:
+                parts.append(m)
+            if ex:
+                parts.append("10^{{{0}}}".format(ex))
+
+            return r" \times ".join(parts)
+        else:
+            if np.isnan(val):
+                return r'{\rm NaN}'
+            elif val > 0:
+                #positive infinity
+                return r'\infty'
+            else:
+                #negative infinity
+                return r'-\infty'
+
+class LatexInline(Latex):
+    """
+    Output LaTeX to display the unit based on IAU style guidelines with negative
+    powers.
+
+    Attempts to follow the `IAU Style Manual
+    <http://www.iau.org/static/publications/stylemanual1989.pdf>`_ and the
+    `ApJ and AJ style guide
+    <http://aas.org/authors/manuscript-preparation-aj-apj-author-instructions>`_.
+    """
+    name = 'latex_inline'
+
+    @classmethod
+    def _format_bases(cls, unit):
+        return cls._format_unit_list(zip(unit.bases, unit.powers))
diff --git a/astropy/units/format/ogip.py b/astropy/units/format/ogip.py
index 416c0af..529b8fb 100644
--- a/astropy/units/format/ogip.py
+++ b/astropy/units/format/ogip.py
@@ -17,12 +17,12 @@ import math
 import os
 import warnings
 
-from .generic import Generic
+from . import generic
 from . import utils
 from ...utils.compat.fractions import Fraction
 
 
-class OGIP(Generic):
+class OGIP(generic.Generic):
     """
     Support the units in `Office of Guest Investigator Programs (OGIP)
     FITS files
@@ -76,7 +76,7 @@ class OGIP(Generic):
         # Create a separate, disconnected unit for the special case of
         # Crab and mCrab, since OGIP doesn't define their quantities.
         Crab = u.def_unit(['Crab'], prefixes=False, doc='Crab (X-ray flux)')
-        mCrab = 10 ** -3 * Crab
+        mCrab = u.Unit(10 ** -3 * Crab)
         names['Crab'] = Crab
         names['mCrab'] = mCrab
 
@@ -356,26 +356,32 @@ class OGIP(Generic):
     def _get_unit(cls, t):
         try:
             return cls._parse_unit(t.value)
-        except ValueError:
+        except ValueError as e:
             raise ValueError(
-                "At col {0}, {1!r} is not a valid unit according to the "
-                "OGIP standard".format(
-                    t.lexpos, t.value))
+                "At col {0}, '{1}': {2}".format(
+                    t.lexpos, t.value, six.text_type(e)))
 
     @classmethod
-    def _parse_unit(cls, unit):
+    def _validate_unit(cls, unit, detailed_exception=True):
         if unit not in cls._units:
-            raise ValueError(
-                "Unit {0!r} not supported by the OGIP "
-                "standard".format(unit))
+            if detailed_exception:
+                raise ValueError(
+                    "Unit '{0}' not supported by the OGIP "
+                    "standard. {1}".format(
+                        unit, utils.did_you_mean_units(
+                            unit, cls._units, cls._deprecated_units,
+                            cls._to_decomposed_alternative)))
+            else:
+                raise ValueError()
 
         if unit in cls._deprecated_units:
-            from ..core import UnitsWarning
-            warnings.warn(
-                "The unit {0!r} is discouraged in the OGIP "
-                "standard".format(unit),
-                UnitsWarning)
+            utils.unit_deprecation_warning(
+                unit, cls._units[unit], 'OGIP',
+                cls._to_decomposed_alternative)
 
+    @classmethod
+    def _parse_unit(cls, unit, detailed_exception=True):
+        cls._validate_unit(unit, detailed_exception=detailed_exception)
         return cls._units[unit]
 
     def parse(self, s, debug=False):
@@ -383,7 +389,7 @@ class OGIP(Generic):
         try:
             # This is a short circuit for the case where the string is
             # just a single unit name
-            return self._parse_unit(s)
+            return self._parse_unit(s, detailed_exception=False)
         except ValueError:
             from ..core import Unit
             try:
@@ -391,50 +397,41 @@ class OGIP(Generic):
                     self._parser.parse(s, lexer=self._lexer, debug=debug))
             except ValueError as e:
                 if six.text_type(e):
-                    raise ValueError("{0} in unit {1!r}".format(
-                        six.text_type(e), s))
+                    raise
                 else:
                     raise ValueError(
-                        "Syntax error parsing unit {0!r}".format(s))
+                        "Syntax error parsing unit '{0}'".format(s))
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         name = unit.get_format_name('ogip')
-
-        if name not in self._units:
-            raise ValueError(
-                "Unit {0!r} is not part of the OGIP standard".format(name))
-
-        if unit in self._deprecated_units:
-            from ..core import UnitsWarning
-            warnings.warn(
-                "The unit {0!r} is discouraged in the OGIP "
-                "standard".format(unit),
-                UnitsWarning)
-
+        cls._validate_unit(name)
         return name
 
-    def _format_unit_list(self, units):
+    @classmethod
+    def _format_unit_list(cls, units):
         out = []
-        units.sort(key=lambda x: self._get_unit_name(x[0]).lower())
+        units.sort(key=lambda x: cls._get_unit_name(x[0]).lower())
 
         for base, power in units:
             if power == 1:
-                out.append(self._get_unit_name(base))
+                out.append(cls._get_unit_name(base))
             else:
                 power = utils.format_power(power)
                 if '/' in power:
                     out.append('{0}**({1})'.format(
-                        self._get_unit_name(base), power))
+                        cls._get_unit_name(base), power))
                 else:
                     out.append('{0}**{1}'.format(
-                        self._get_unit_name(base), power))
+                        cls._get_unit_name(base), power))
         return ' '.join(out)
 
-    def to_string(self, unit):
+    @classmethod
+    def to_string(cls, unit):
         from .. import core
 
         # Remove units that aren't known to the format
-        unit = utils.decompose_to_known_units(unit, self._get_unit_name)
+        unit = utils.decompose_to_known_units(unit, cls._get_unit_name)
 
         if isinstance(unit, core.CompositeUnit):
             # Can't use np.log10 here, because p[0] may be a Python long.
@@ -445,4 +442,22 @@ class OGIP(Generic):
                         unit.scale),
                     core.UnitsWarning)
 
-        return Generic.to_string(self, unit)
+        return generic._to_string(cls, unit)
+
+    @classmethod
+    def _to_decomposed_alternative(cls, unit):
+        from .. import core
+
+        # Remove units that aren't known to the format
+        unit = utils.decompose_to_known_units(unit, cls._get_unit_name)
+
+        if isinstance(unit, core.CompositeUnit):
+            # Can't use np.log10 here, because p[0] may be a Python long.
+            if math.log10(unit.scale) % 1.0 != 0.0:
+                scale = unit.scale
+                unit = copy.copy(unit)
+                unit._scale = 1.0
+                return '{0} (with data multiplied by {1})'.format(
+                    generic._to_string(cls, unit), scale)
+
+        return generic._to_string(unit)
diff --git a/astropy/units/format/unicode_format.py b/astropy/units/format/unicode_format.py
index d0cee6e..1be5f9b 100644
--- a/astropy/units/format/unicode_format.py
+++ b/astropy/units/format/unicode_format.py
@@ -32,10 +32,12 @@ class Unicode(console.Console):
     _times = "×"
     _line = "─"
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
         return unit.get_format_name('unicode')
 
-    def _format_exponential_notation(self, val):
+    @classmethod
+    def format_exponential_notation(cls, val):
         m, ex = utils.split_mantissa_exponent(val)
 
         parts = []
@@ -44,12 +46,12 @@ class Unicode(console.Console):
 
         if ex:
             parts.append("10{0}".format(
-                self._format_superscript(ex)))
+                cls._format_superscript(ex)))
 
-        return self._times.join(parts)
+        return cls._times.join(parts)
 
-    @staticmethod
-    def _format_superscript(number):
+    @classmethod
+    def _format_superscript(cls, number):
         mapping = {
             '0': '⁰',
             '1': '¹',
diff --git a/astropy/units/format/utils.py b/astropy/units/format/utils.py
index 6dd264e..5176748 100644
--- a/astropy/units/format/utils.py
+++ b/astropy/units/format/utils.py
@@ -7,9 +7,11 @@ Utilities shared by the different formats.
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
+import warnings
 
 from ...extern import six
 from ...utils.compat.fractions import Fraction
+from ...utils.misc import did_you_mean
 
 
 def get_grouped_by_powers(bases, powers):
@@ -126,3 +128,94 @@ def format_power(power):
         else:
             power = int(power)
     return six.text_type(power)
+
+
+def _try_decomposed(unit, format_decomposed):
+    represents = getattr(unit, '_represents', None)
+    if represents is not None:
+        try:
+            represents_string = format_decomposed(represents)
+        except ValueError:
+            pass
+        else:
+            return represents_string
+
+    decomposed = unit.decompose()
+    if decomposed is not unit:
+        try:
+            decompose_string = format_decomposed(decomposed)
+        except ValueError:
+            pass
+        else:
+            return decompose_string
+
+    return None
+
+
+def did_you_mean_units(s, all_units, deprecated_units, format_decomposed):
+    """
+    A wrapper around `astropy.utils.misc.did_you_mean` that deals with
+    the display of deprecated units.
+
+    Parameters
+    ----------
+    s : str
+        The invalid unit string
+
+    all_units : dict
+        A mapping from valid unit names to unit objects.
+
+    deprecated_units : sequence
+        The deprecated unit names
+
+    format_decomposed : callable
+        A function to turn a decomposed version of the unit into a
+        string.  Should return `None` if not possible
+
+    Returns
+    -------
+    msg : str
+        A string message with a list of alternatives, or the empty
+        string.
+    """
+    def fix_deprecated(x):
+        if x in deprecated_units:
+            results = [x + ' (deprecated)']
+            decomposed = _try_decomposed(
+                all_units[x], format_decomposed)
+            if decomposed is not None:
+                results.append(decomposed)
+            return results
+        return (x,)
+
+    return did_you_mean(s, all_units, fix=fix_deprecated)
+
+
+def unit_deprecation_warning(s, unit, standard_name, format_decomposed):
+    """
+    Raises a UnitsWarning about a deprecated unit in a given format.
+    Suggests a decomposed alternative if one is available.
+
+    Parameters
+    ----------
+    s : str
+        The deprecated unit name.
+
+    unit : astropy.units.core.UnitBase
+        The unit object.
+
+    standard_name : str
+        The name of the format for which the unit is deprecated.
+
+    format_decomposed : callable
+        A function to turn a decomposed version of the unit into a
+        string.  Should return `None` if not possible
+    """
+    from ..core import UnitsWarning
+
+    message = "The unit '{0}' has been deprecated in the {1} standard.".format(
+        s, standard_name)
+    decomposed = _try_decomposed(unit, format_decomposed)
+    if decomposed is not None:
+        message += " Suggested: {0}.".format(decomposed)
+    warnings.warn(message, UnitsWarning)
diff --git a/astropy/units/format/vounit.py b/astropy/units/format/vounit.py
index 8a70661..541ecea 100644
--- a/astropy/units/format/vounit.py
+++ b/astropy/units/format/vounit.py
@@ -4,25 +4,31 @@ Handles the "VOUnit" unit format.
 """
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
+
 from ...extern import six
 from ...extern.six.moves import zip
 
+import copy
 import keyword
+import re
 import warnings
-from ...utils.exceptions import AstropyDeprecationWarning
 
 from . import generic
 from . import utils
-from ...utils.misc import did_you_mean
 
 
 class VOUnit(generic.Generic):
     """
-    The proposed IVOA standard for units used by the VO.
+    The IVOA standard for units used by the VO.
 
-    This is an implementation of `proposed IVOA standard for units
+    This is an implementation of `Units in the VO 1.0
     <http://www.ivoa.net/Documents/VOUnits/>`_.
     """
+    _explicit_custom_unit_regex = re.compile(
+        "^[YZEPTGMkhdcmunpfazy]?'((?!\d)\w)+'$")
+    _custom_unit_regex = re.compile("^((?!\d)\w)+$")
+    _custom_units = {}
+
     def __init__(self):
         if '_parser' not in VOUnit.__dict__:
             VOUnit._parser, VOUnit._lexer = self._make_parser()
@@ -39,92 +45,173 @@ class VOUnit(generic.Generic):
         deprecated_names = set()
 
         bases = [
-            'm', 's', 'A', 'K', 'mol', 'cd', 'g', 'rad', 'sr', 'Hz', 'N', 'Pa',
-            'J', 'W', 'C', 'V', 'S', 'F', 'Wb', 'T', 'H', 'lm', 'lx', 'Ohm']
-        prefixes = [
-            'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd',
-            '', 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
-
-        for base in bases:
-            for prefix in prefixes:
-                key = prefix + base
-                if keyword.iskeyword(key):
-                    continue
-                names[key] = getattr(u, key)
-
+            'A', 'C', 'D', 'F', 'G', 'H', 'Hz', 'J', 'Jy', 'K', 'N',
+            'Ohm', 'Pa', 'R', 'Ry', 'S', 'T', 'V', 'W', 'Wb', 'a',
+            'adu', 'arcmin', 'arcsec', 'barn', 'beam', 'bin', 'cd',
+            'chan', 'count', 'ct', 'd', 'deg', 'eV', 'erg', 'g', 'h',
+            'lm', 'lx', 'lyr', 'm', 'mag', 'min', 'mol', 'pc', 'ph',
+            'photon', 'pix', 'pixel', 'rad', 'rad', 's', 'solLum',
+            'solMass', 'solRad', 'sr', 'u', 'voxel', 'yr'
+        ]
+        binary_bases = [
+            'bit', 'byte', 'B'
+        ]
         simple_units = [
-            'min', 'h', 'd', 'a', 'yr', 'arcsec', 'arcmin', 'deg',
-            'mas', 'AU', 'pc', 'u', 'eV', 'Jy']
-
-        deprecated_units = [
-            'angstrom', 'Angstrom', 'barn', 'erg', 'G', 'mag', 'dB', 'solMass',
-            'solLum', 'solRad', 'lyr', 'ct', 'count', 'photon', 'ph', 'R',
-            'pix', 'pixel', 'D', 'Sun', 'chan', 'bin', 'voxel', 'bit', 'byte',
-            'adu', 'beam']
-
-        for unit in simple_units + deprecated_units:
-            names[unit] = getattr(u, unit)
-        for unit in deprecated_units:
-            deprecated_names.add(unit)
+            'Angstrom', 'angstrom', 'AU', 'au', 'Ba', 'dB', 'mas'
+        ]
+        si_prefixes = [
+            'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd',
+            '', 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
+        ]
+        binary_prefixes = [
+            'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei'
+        ]
+        deprecated_units = set([
+            'a', 'angstrom', 'Angstrom', 'au', 'Ba', 'barn', 'ct',
+            'erg', 'G', 'ph', 'pix'
+        ])
+
+        def do_defines(bases, prefixes, skips=[]):
+            for base in bases:
+                for prefix in prefixes:
+                    key = prefix + base
+                    if key in skips:
+                        continue
+                    if keyword.iskeyword(key):
+                        continue
+                    names[key] = getattr(u, key)
+                    if base in deprecated_units:
+                        deprecated_names.add(key)
+
+        do_defines(bases, si_prefixes, ['pct', 'pcount', 'yd'])
+        do_defines(binary_bases, si_prefixes + binary_prefixes, ['dB', 'dbyte'])
+        do_defines(simple_units, [''])
 
         return names, deprecated_names
 
     def parse(self, s, debug=False):
-        result = self._do_parse(s, debug=debug)
+        from ... import units as u
+
+        if s in ('unknown', 'UNKNOWN'):
+            return None
+        if s == '':
+            return u.dimensionless_unscaled
         if s.count('/') > 1:
             from ..core import UnitsError
             raise UnitsError(
                 "'{0}' contains multiple slashes, which is "
                 "disallowed by the VOUnit standard".format(s))
+        result = self._do_parse(s, debug=debug)
         return result
 
     @classmethod
     def _parse_unit(cls, unit, detailed_exception=True):
+        from ... import units as u
+
         if unit not in cls._units:
-            if detailed_exception:
-                raise ValueError(
-                    "Unit {0!r} not supported by the VOUnit "
-                    "standard. {1}".format(
-                        unit, did_you_mean(
-                            unit, cls._units)))
-            else:
+            if cls._explicit_custom_unit_regex.match(unit):
+                return cls._def_custom_unit(unit)
+
+            if not cls._custom_unit_regex.match(unit):
                 raise ValueError()
 
-        if unit in cls._deprecated_units:
             warnings.warn(
-                "The use of unit {0!r} is discouraged by the "
-                "VOUnit standard.".format(unit),
-                AstropyDeprecationWarning)
+                "Unit {0!r} not supported by the VOUnit "
+                "standard. {1}".format(
+                    unit, utils.did_you_mean_units(
+                        unit, cls._units, cls._deprecated_units,
+                        cls._to_decomposed_alternative)),
+                u.UnitsWarning)
+
+            return cls._def_custom_unit(unit)
+
+        if unit in cls._deprecated_units:
+            utils.unit_deprecation_warning(
+                unit, cls._units[unit], 'VOUnit',
+                cls._to_decomposed_alternative)
 
         return cls._units[unit]
 
-    def _get_unit_name(self, unit):
+    @classmethod
+    def _get_unit_name(cls, unit):
+        from ... import units as u
+
+        # The da- and d- prefixes are discouraged.  This has the
+        # effect of adding a scale to value in the result.
+        if isinstance(unit, u.PrefixUnit):
+            if unit._represents.scale == 10.0:
+                raise ValueError(
+                    "In '{0}': VOUnit can not represent units with the 'da' "
+                    "(deka) prefix".format(unit))
+            elif unit._represents.scale == 0.1:
+                raise ValueError(
+                    "In '{0}': VOUnit can not represent units with the 'd' "
+                    "(deci) prefix".format(unit))
+
         name = unit.get_format_name('vounit')
 
-        if name not in self._units:
+        if unit in six.itervalues(cls._custom_units):
+            return name
+
+        if name not in cls._units:
             raise ValueError(
                 "Unit {0!r} is not part of the VOUnit standard".format(name))
 
-        if name in self._deprecated_units:
-            warnings.warn(
-                "The use of unit {0!r} is discouraged by the "
-                "VOUnit standard.".format(name),
-                AstropyDeprecationWarning)
+        if name in cls._deprecated_units:
+            utils.unit_deprecation_warning(
+                name, unit, 'VOUnit',
+                cls._to_decomposed_alternative)
 
         return name
 
-    def to_string(self, unit):
+    @classmethod
+    def _def_custom_unit(cls, unit):
+        from ... import units as u
+
+        def def_base(name):
+            if name in cls._custom_units:
+                return cls._custom_units[name]
+
+            if name.startswith("'"):
+                return u.def_unit(
+                    [name[1:-1], name],
+                    format={'vounit': name},
+                    namespace=cls._custom_units)
+            else:
+                return u.def_unit(
+                    name, namespace=cls._custom_units)
+
+        if unit in cls._custom_units:
+            return cls._custom_units[unit]
+
+        for short, full, factor in u.si_prefixes:
+            for prefix in short:
+                if unit.startswith(prefix):
+                    base_name = unit[len(prefix):]
+                    base_unit = def_base(base_name)
+                    return u.PrefixUnit(
+                        [prefix + x for x in base_unit.names],
+                        u.CompositeUnit(factor, [base_unit], [1],
+                                        _error_check=False),
+                        format={'vounit': prefix + base_unit.names[-1]},
+                        namespace=cls._custom_units)
+
+        return def_base(unit)
+
+    @classmethod
+    def to_string(cls, unit):
         from .. import core
 
         # Remove units that aren't known to the format
-        unit = utils.decompose_to_known_units(unit, self._get_unit_name)
+        unit = utils.decompose_to_known_units(unit, cls._get_unit_name)
 
         if isinstance(unit, core.CompositeUnit):
             if unit.physical_type == 'dimensionless' and unit.scale != 1:
-                raise ValueError("The VOUnit format is not able to "
-                                 "represent scale for dimensionless units. "
-                                 "Multiply your data by {0:e}."
-                                 .format(unit.scale))
+                raise core.UnitScaleError(
+                    "The VOUnit format is not able to "
+                    "represent scale for dimensionless units. "
+                    "Multiply your data by {0:e}."
+                    .format(unit.scale))
             s = ''
             if unit.scale != 1:
                 m, ex = utils.split_mantissa_exponent(unit.scale)
@@ -142,8 +229,22 @@ class VOUnit(generic.Generic):
             pairs = list(zip(unit.bases, unit.powers))
             pairs.sort(key=lambda x: x[1], reverse=True)
 
-            s += self._format_unit_list(pairs)
+            s += cls._format_unit_list(pairs)
         elif isinstance(unit, core.NamedUnit):
-            s = self._get_unit_name(unit)
+            s = cls._get_unit_name(unit)
+
+        return s
+
+    @classmethod
+    def _to_decomposed_alternative(cls, unit):
+        from .. import core
 
+        try:
+            s = cls.to_string(unit)
+        except core.UnitScaleError:
+            scale = unit.scale
+            unit = copy.copy(unit)
+            unit._scale = 1.0
+            return '{0} (with data multiplied by {1})'.format(
+                cls.to_string(unit), scale)
         return s
diff --git a/astropy/units/quantity.py b/astropy/units/quantity.py
index 4fabe7e..f5541f1 100644
--- a/astropy/units/quantity.py
+++ b/astropy/units/quantity.py
@@ -10,6 +10,7 @@ from __future__ import (absolute_import, unicode_literals, division,
                         print_function)
 
 # Standard library
+import re
 import numbers
 
 import numpy as np
@@ -21,10 +22,12 @@ NUMPY_LT_1P9 = [int(x) for x in np.__version__.split('.')[:2]] < [1, 9]
 from ..extern import six
 from .core import (Unit, dimensionless_unscaled, UnitBase, UnitsError,
                    get_current_unit_registry)
+from .format.latex import Latex
 from ..utils import lazyproperty
 from ..utils.compat.misc import override__dir__
 from ..utils.misc import isiterable, InheritDocstrings
 from .utils import validate_power
+from .. import config as _config
 
 
 __all__ = ["Quantity"]
@@ -34,15 +37,20 @@ __all__ = ["Quantity"]
 __doctest_skip__ = ['Quantity.*']
 
 
-def _can_cast(arg, dtype):
-    """
-    This is needed for compatibility with Numpy < 1.6, in which ``can_cast``
-    can only take a dtype or type as its first argument.
-    """
-    return np.can_cast(getattr(arg, 'dtype', type(arg)), dtype)
+_UNIT_NOT_INITIALISED = "(Unit not initialised)"
 
 
-_UNIT_NOT_INITIALISED = "(Unit not initialised)"
+class Conf(_config.ConfigNamespace):
+    """
+    Configuration parameters for Quantity
+    """
+    latex_array_threshold = _config.ConfigItem(100,
+        'The maximum size an array Quantity can be before its LaTeX '
+        'representation for IPython gets "summarized" (meaning only the first '
+        'and last few elements are shown with "..." between). Setting this to a '
+        'negative number means that the value will instead be whatever numpy '
+        'gets from get_printoptions.')
+conf = Conf()
 
 
 def _can_have_arbitrary_unit(value):
@@ -110,7 +118,7 @@ class QuantityIterator(object):
 
 @six.add_metaclass(InheritDocstrings)
 class Quantity(np.ndarray):
-    """ A `Quantity` represents a number with some associated unit.
+    """ A `~astropy.units.Quantity` represents a number with some associated unit.
 
     Parameters
     ----------
@@ -333,8 +341,10 @@ class Quantity(np.ndarray):
 
         # We now prepare the output object
 
-        if self is obj:  # happens if the output object is self, which happens
-                         # for in-place operations such as q1 += q2
+        if self is obj:
+
+            # this happens if the output object is self, which happens
+            # for in-place operations such as q1 += q2
 
             # In some cases, the result of a ufunc should be a plain Numpy
             # array, which we can't do if we are doing an in-place operation.
@@ -355,7 +365,7 @@ class Quantity(np.ndarray):
             # decomposed, which involves being scaled by a float, but since
             # the array is an integer the output then gets converted to an int
             # and truncated.
-            if(any(not _can_cast(arg, obj.dtype) for arg in args) or
+            if(any(not np.can_cast(arg, obj.dtype) for arg in args) or
                np.any(np.array(scales, dtype=obj.dtype) != np.array(scales))):
                 raise TypeError("Arguments cannot be cast safely to inplace "
                                 "output with dtype={0}".format(self.dtype))
@@ -459,7 +469,7 @@ class Quantity(np.ndarray):
                 # array is not integral. Here, we set the obj_array to `None`
                 # when it can not be used to store the scaled result.
                 if(result_unit is not None and
-                   any(not _can_cast(scaled_arg, obj_array.dtype)
+                   any(not np.can_cast(scaled_arg, obj_array.dtype)
                        for scaled_arg in inputs)):
                     obj_array = None
 
@@ -931,25 +941,45 @@ class Quantity(np.ndarray):
 
     def _repr_latex_(self):
         """
-        Generate latex representation of the quantity and its unit.
-        This is used by the IPython notebook to show it all latexified.
-        It only works for scalar quantities; for arrays, the standard
-        reprensation is returned.
+        Generate a latex representation of the quantity and its unit.
+
+        The behavior of this function can be altered via the
+        `numpy.set_printoptions` function and its various keywords.  The
+        exception to this is the ``threshold`` keyword, which is controlled via
+        the ``[units.quantity]`` configuration item ``latex_array_threshold``.
+        This is treated separately because the numpy default of 1000 is too big
+        for most browsers to handle.
 
         Returns
         -------
         lstr
-            LaTeX string
+            A LaTeX string with the contents of this Quantity
         """
-
-        if not self.isscalar:
-            raise NotImplementedError('Cannot represent Quantity arrays '
-                                      'in LaTex format')
-
-        # Format value
-        latex_value = "{0:g}".format(self.value)
-        if "e" in latex_value:
-            latex_value = latex_value.replace('e', '\\times 10^{') + '}'
+        if NUMPY_LT_1P7:
+            if self.isscalar:
+                latex_value = Latex.format_exponential_notation(self.value)
+            else:
+                raise NotImplementedError('Cannot represent Quantity arrays '
+                                          'in LaTex format for numpy < v1.7.')
+        else:
+            # need to do try/finally because "threshold" cannot be overridden
+            # with array2string
+            pops = np.get_printoptions()
+            try:
+                formatter = {'all' : Latex.format_exponential_notation,
+                             'str_kind': lambda x: x}
+                if conf.latex_array_threshold > -1:
+                    np.set_printoptions(threshold=conf.latex_array_threshold,
+                                        formatter=formatter)
+
+                # the view is needed for the scalar case - value might be float
+                latex_value = np.array2string(self.view(np.ndarray),
+                                              style=Latex.format_exponential_notation,
+                                              max_line_width=np.inf,
+                                              separator=',~')
+                latex_value = latex_value.replace('...', r'\dots')
+            finally:
+                np.set_printoptions(**pops)
 
         # Format unit
         # [1:-1] strips the '$' on either side needed for math mode
@@ -1307,3 +1337,51 @@ class Quantity(np.ndarray):
         def nansum(self, axis=None, out=None, keepdims=False):
             return self._wrap_function(np.nansum, axis,
                                        out=out, keepdims=keepdims)
+
+    def insert(self, obj, values, axis=None):
+        """
+        Insert values along the given axis before the given indices and return
+        a new `~astropy.units.Quantity` object.
+
+        This is a thin wrapper around the `numpy.insert` function.
+
+        Parameters
+        ----------
+        obj : int, slice or sequence of ints
+            Object that defines the index or indices before which ``values`` is
+            inserted.
+        values : array-like
+            Values to insert.  If the type of ``values`` is different
+            from that of quantity, ``values`` is converted to the matching type.
+            ``values`` should be shaped so that it can be broadcast appropriately
+            The unit of ``values`` must be consistent with this quantity.
+        axis : int, optional
+            Axis along which to insert ``values``.  If ``axis`` is None then
+            the quantity array is flattened before insertion.
+
+        Returns
+        -------
+        out : `~astropy.units.Quantity`
+            A copy of quantity with ``values`` inserted.  Note that the
+            insertion does not occur in-place: a new quantity array is returned.
+
+        Examples
+        --------
+        >>> import astropy.units as u
+        >>> q = [1, 2] * u.m
+        >>> q.insert(0, 50 * u.cm)
+        <Quantity [ 0.5,  1.,  2.] m>
+
+        >>> q = [[1, 2], [3, 4]] * u.m
+        >>> q.insert(1, [10, 20] * u.m, axis=0)
+        <Quantity [[  1.,  2.],
+                   [ 10., 20.],
+                   [  3.,  4.]] m>
+
+        >>> q.insert(1, 10 * u.m, axis=1)
+        <Quantity [[  1., 10.,  2.],
+                   [  3., 10.,  4.]] m>
+
+        """
+        out_array = np.insert(self.value, obj, self._to_own_unit(values), axis)
+        return self._new_view(out_array)
diff --git a/astropy/units/si.py b/astropy/units/si.py
index 5c2166c..039e0e0 100644
--- a/astropy/units/si.py
+++ b/astropy/units/si.py
@@ -37,7 +37,7 @@ def_unit(['micron'], um, namespace=_ns,
 def_unit(['Angstrom', 'AA', 'angstrom'], 0.1 * nm, namespace=_ns,
          doc="ångström: 10 ** -10 m",
          format={'latex': r'\overset{\circ}{A}', 'unicode': 'Å',
-                 'vounit': 'angstrom'})
+                 'vounit': 'Angstrom'})
 
 
 ###########################################################################
@@ -55,6 +55,7 @@ def_unit(['rad', 'radian'], namespace=_ns, prefixes=True,
          doc="radian: angular measurement of the ratio between the length "
          "on an arc and its radius")
 def_unit(['deg', 'degree'], _numpy.pi / 180.0 * rad, namespace=_ns,
+         prefixes=True,
          doc="degree: angular measurement 1/360 of full rotation",
          format={'latex': r'{}^{\circ}', 'unicode': '°'})
 def_unit(['hourangle'], 15.0 * deg, namespace=_ns, prefixes=False,
@@ -86,9 +87,11 @@ def_unit(['s', 'second'], namespace=_ns, prefixes=True,
          exclude_prefixes=['a'],
          doc="second: base unit of time in SI.")
 
-def_unit(['min', 'minute'], 60 * s, namespace=_ns)
-def_unit(['h', 'hour', 'hr'], 3600 * s, namespace=_ns)
-def_unit(['d', 'day'], 24 * h, namespace=_ns)
+def_unit(['min', 'minute'], 60 * s, prefixes=True, namespace=_ns)
+def_unit(['h', 'hour', 'hr'], 3600 * s, namespace=_ns, prefixes=True,
+         exclude_prefixes=['p'])
+def_unit(['d', 'day'], 24 * h, namespace=_ns, prefixes=True,
+         exclude_prefixes=['c', 'y'])
 def_unit(['sday'], 86164.09053 * s, namespace=_ns,
          doc="Sidereal day (sday) is the time of one rotation of the Earth.")
 def_unit(['wk', 'week'], 7 * day, namespace=_ns)
diff --git a/astropy/units/tests/py3_test_quantity_annotations.py b/astropy/units/tests/py3_test_quantity_annotations.py
new file mode 100644
index 0000000..0d873ad
--- /dev/null
+++ b/astropy/units/tests/py3_test_quantity_annotations.py
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from functools import wraps
+from textwrap import dedent
+
+from ... import units as u
+from ...extern import six
+from ...tests.helper import pytest
+
+
+def py3only(func):
+    if not six.PY3:
+        return pytest.mark.skipif('not six.PY3')(func)
+    else:
+        @wraps(func)
+        def wrapper(*args, **kwargs):
+            code = compile(dedent(func.__doc__), __file__, 'exec')
+            # This uses an unqualified exec statement illegally in Python 2,
+            # but perfectly allowed in Python 3 so in fact we eval the exec
+            # call :)
+            eval('exec(code)')
+
+        return wrapper
+
+
+ at py3only
+def test_args3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.arcsec):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec, 1*u.arcsec)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.arcsec
+    """
+
+
+ at py3only
+def test_args_noconvert3():
+    """
+    @u.quantity_input()
+    def myfunc_args(solarx: u.arcsec, solary: u.arcsec):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.deg, 1*u.arcmin)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.deg
+    assert solary.unit == u.arcmin
+    """
+
+
+ at py3only
+def test_args_nonquantity3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec, 100)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+
+    assert solarx.unit == u.arcsec
+    """
+
+
+ at py3only
+def test_arg_equivalencies3():
+    """
+    @u.quantity_input(equivalencies=u.mass_energy())
+    def myfunc_args(solarx: u.arcsec, solary: u.eV):
+        return solarx, solary+(10*u.J)  # Add an energy to check equiv is working
+
+    solarx, solary = myfunc_args(1*u.arcsec, 100*u.gram)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.gram
+    """
+
+
+ at py3only
+def test_wrong_unit3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.deg):
+        return solarx, solary
+
+    with pytest.raises(u.UnitsError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, 100*u.km)
+    assert str(e.value) == "Argument 'solary' to function 'myfunc_args' must be in units convertable to 'deg'."
+    """
+
+
+ at py3only
+def test_not_quantity3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.deg):
+        return solarx, solary
+
+    with pytest.raises(TypeError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, 100)
+    assert str(e.value) == "Argument 'solary' to function has 'myfunc_args' no 'unit' attribute. You may want to pass in an astropy Quantity instead."
+    """
+
+
+ at py3only
+def test_decorator_override():
+    """
+    @u.quantity_input(solarx=u.arcsec)
+    def myfunc_args(solarx: u.km, solary: u.arcsec):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec, 1*u.arcsec)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.arcsec
+    """
+
+
+ at py3only
+def test_kwargs3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary, myk: u.arcsec=1*u.arcsec):
+        return solarx, solary, myk
+
+    solarx, solary, myk = myfunc_args(1*u.arcsec, 100, myk=100*u.deg)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+    assert isinstance(myk, u.Quantity)
+
+    assert myk.unit == u.deg
+    """
+
+
+ at py3only
+def test_unused_kwargs3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary, myk: u.arcsec=1*u.arcsec, myk2=1000):
+        return solarx, solary, myk, myk2
+
+    solarx, solary, myk, myk2 = myfunc_args(1*u.arcsec, 100, myk=100*u.deg, myk2=10)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+    assert isinstance(myk, u.Quantity)
+    assert isinstance(myk2, int)
+
+    assert myk.unit == u.deg
+    assert myk2 == 10
+    """
+
+
+ at py3only
+def test_kwarg_equivalencies3():
+    """
+    @u.quantity_input(equivalencies=u.mass_energy())
+    def myfunc_args(solarx: u.arcsec, energy: u.eV=10*u.eV):
+        return solarx, energy+(10*u.J)  # Add an energy to check equiv is working
+
+    solarx, energy = myfunc_args(1*u.arcsec, 100*u.gram)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(energy, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert energy.unit == u.gram
+    """
+
+
+ at py3only
+def test_kwarg_wrong_unit3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.deg=10*u.deg):
+        return solarx, solary
+
+    with pytest.raises(u.UnitsError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, solary=100*u.km)
+    assert str(e.value) == "Argument 'solary' to function 'myfunc_args' must be in units convertable to 'deg'."
+    """
+
+
+ at py3only
+def test_kwarg_not_quantity3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.deg=10*u.deg):
+        return solarx, solary
+
+    with pytest.raises(TypeError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, solary=100)
+    assert str(e.value) == "Argument 'solary' to function has 'myfunc_args' no 'unit' attribute. You may want to pass in an astropy Quantity instead."
+    """
+
+
+ at py3only
+def test_kwarg_default3():
+    """
+    @u.quantity_input
+    def myfunc_args(solarx: u.arcsec, solary: u.deg=10*u.deg):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec)
+    """
diff --git a/astropy/units/tests/test_format.py b/astropy/units/tests/test_format.py
index f96996d..736b343 100644
--- a/astropy/units/tests/test_format.py
+++ b/astropy/units/tests/test_format.py
@@ -13,14 +13,13 @@ from __future__ import (absolute_import, unicode_literals, division,
 from ...extern import six
 
 from numpy.testing.utils import assert_allclose
-from ...tests.helper import raises, pytest
+from ...tests.helper import raises, pytest, catch_warnings
 
 from ... import units as u
 from ...constants import si
 from .. import core
 from .. import format as u_format
 from ..utils import is_effectively_unity
-from ... import wcs
 
 
 def test_unit_grammar():
@@ -264,6 +263,16 @@ def test_new_style_latex():
     assert "{0:latex}".format(fluxunit) == r'$\mathrm{\frac{erg}{s\,cm^{2}}}$'
 
 
+def test_latex_scale():
+    latex = '$\\mathrm{2.1798721 \\times 10^{-18}\\,\\frac{m^{2}\\,kg}{s^{2}}}$'
+    assert u.Ry.decompose().to_string('latex') == latex
+
+
+def test_latex_inline_scale():
+    latex_inline = '$\\mathrm{2.1798721 \\times 10^{-18}\\,m^{2}\\,kg\\,s^{-2}}$'
+    assert u.Ry.decompose().to_string('latex_inline') == latex_inline
+
+
 def test_format_styles():
     fluxunit = u.erg / (u.cm ** 2 * u.s)
     def _test_format_styles(format_spec, s):
@@ -274,6 +283,7 @@ def test_format_styles():
         ('s', 'erg / (cm2 s)'),
         ('console', '  erg  \n ------\n s cm^2'),
         ('latex', '$\\mathrm{\\frac{erg}{s\\,cm^{2}}}$'),
+        ('latex_inline', '$\\mathrm{erg\\,s^{-1}\\,cm^{-2}}$'),
         ('>20s','       erg / (cm2 s)'),
     ]
 
@@ -354,3 +364,79 @@ def test_scaled_dimensionless():
 
     with pytest.raises(ValueError):
         u.Unit(0.1).to_string('vounit')
+
+
+def test_deprecated_did_you_mean_units():
+    try:
+        u.Unit('ANGSTROM', format='fits')
+    except ValueError as e:
+        assert 'angstrom (deprecated)' in six.text_type(e)
+        assert 'Angstrom (deprecated)' in six.text_type(e)
+        assert 'nm (with data multiplied by 0.1)' in six.text_type(e)
+
+    with catch_warnings() as w:
+        u.Unit('Angstrom', format='fits')
+    assert len(w) == 1
+    assert 'nm (with data multiplied by 0.1)' in six.text_type(w[0].message)
+
+    try:
+        u.Unit('crab', format='ogip')
+    except ValueError as e:
+        assert 'Crab (deprecated)' in six.text_type(e)
+        assert 'mCrab (deprecated)' in six.text_type(e)
+
+    try:
+        u.Unit('ANGSTROM', format='vounit')
+    except ValueError as e:
+        assert 'angstrom (deprecated)' in six.text_type(e)
+        assert '0.1nm' in six.text_type(e)
+        assert six.text_type(e).count('0.1nm') == 1
+
+    with catch_warnings() as w:
+        u.Unit('angstrom', format='vounit')
+    assert len(w) == 1
+    assert '0.1nm' in six.text_type(w[0].message)
+
+
+def test_vounit_binary_prefix():
+    u.Unit('KiB', format='vounit') == u.Unit('1024 B')
+    u.Unit('Kibyte', format='vounit') == u.Unit('1024 B')
+    u.Unit('Kibit', format='vounit') == u.Unit('1024 B')
+    with catch_warnings() as w:
+        u.Unit('kibibyte', format='vounit')
+    assert len(w) == 1
+
+
+def test_vounit_unknown():
+    assert u.Unit('unknown', format='vounit') is None
+    assert u.Unit('UNKNOWN', format='vounit') is None
+    assert u.Unit('', format='vounit') is u.dimensionless_unscaled
+
+
+def test_vounit_details():
+    assert u.Unit('Pa', format='vounit') is u.Pascal
+
+    # The da- prefix is not allowed, and the d- prefix is discouraged
+    assert u.dam.to_string('vounit') == '10m'
+    assert u.Unit('dam dag').to_string('vounit') == '100g m'
+
+
+def test_vounit_custom():
+    x = u.Unit("'foo' m", format='vounit')
+    x_vounit = x.to_string('vounit')
+    assert x_vounit == "'foo' m"
+    x_string = x.to_string()
+    assert x_string == "foo m"
+
+    x = u.Unit("m'foo' m", format='vounit')
+    assert x.bases[1]._represents.scale == 0.001
+    x_vounit = x.to_string('vounit')
+    assert x_vounit == "m m'foo'"
+    x_string = x.to_string()
+    assert x_string == 'm mfoo'
+
+
+def test_vounit_implicit_custom():
+    x = u.Unit("furlong/week", format="vounit")
+    assert x.bases[0]._represents.scale == 1e-15
+    assert x.bases[0]._represents.bases[0].name == 'urlong'
diff --git a/astropy/units/tests/test_physical.py b/astropy/units/tests/test_physical.py
index 95e4772..55c1464 100644
--- a/astropy/units/tests/test_physical.py
+++ b/astropy/units/tests/test_physical.py
@@ -58,3 +58,8 @@ def test_photnu():
 @raises(ValueError)
 def test_redundant_physical_type():
     physical.def_physical_type(u.m, 'utter craziness')
+
+
+def test_data_quantity():
+    assert u.byte.physical_type == 'data quantity'
+    assert u.bit.physical_type == 'data quantity'
diff --git a/astropy/units/tests/test_quantity.py b/astropy/units/tests/test_quantity.py
index ba72622..602352e 100644
--- a/astropy/units/tests/test_quantity.py
+++ b/astropy/units/tests/test_quantity.py
@@ -9,11 +9,11 @@ from __future__ import (absolute_import, unicode_literals, division,
 
 import copy
 import decimal
+from distutils import version
 
 import numpy as np
 from numpy.testing import (assert_allclose, assert_array_equal,
                            assert_array_almost_equal)
-from distutils import version
 NUMPY_VERSION = version.LooseVersion(np.__version__)
 
 from ...tests.helper import raises, pytest
@@ -701,13 +701,62 @@ class TestQuantityDisplay(object):
         assert repr(bad_quantity).endswith(_UNIT_NOT_INITIALISED + '>')
 
     def test_repr_latex(self):
-        q2 = u.Quantity(1.5e14, 'm/s')
+        from ...units.quantity import conf
+
+        q2scalar = u.Quantity(1.5e14, 'm/s')
         assert self.scalarintq._repr_latex_() == '$1 \\; \\mathrm{m}$'
         assert self.scalarfloatq._repr_latex_() == '$1.3 \\; \\mathrm{m}$'
-        assert (q2._repr_latex_() ==
-                '$1.5\\times 10^{+14} \\; \\mathrm{\\frac{m}{s}}$')
-        with pytest.raises(NotImplementedError):
-            self.arrq._repr_latex_()
+        assert (q2scalar._repr_latex_() ==
+                '$1.5 \\times 10^{14} \\; \\mathrm{\\frac{m}{s}}$')
+
+        if NUMPY_VERSION < version.LooseVersion('1.7.0'):
+            with pytest.raises(NotImplementedError):
+                self.arrq._repr_latex_()
+            return  # all arrays should fail
+
+        assert self.arrq._repr_latex_() == '$[1,~2.3,~8.9] \; \mathrm{m}$'
+
+        qmed = np.arange(100)*u.m
+        qbig = np.arange(1000)*u.m
+        qvbig = np.arange(10000)*1e9*u.m
+
+        pops = np.get_printoptions()
+        oldlat = conf.latex_array_threshold
+        try:
+            #check thresholding behavior
+            conf.latex_array_threshold = 100  # should be default
+            lsmed = qmed._repr_latex_()
+            assert r'\dots' not in lsmed
+            lsbig = qbig._repr_latex_()
+            assert r'\dots' in lsbig
+            lsvbig = qvbig._repr_latex_()
+            assert r'\dots' in lsvbig
+
+            conf.latex_array_threshold = 1001
+            lsmed = qmed._repr_latex_()
+            assert r'\dots' not in lsmed
+            lsbig = qbig._repr_latex_()
+            assert r'\dots' not in lsbig
+            lsvbig = qvbig._repr_latex_()
+            assert r'\dots' in lsvbig
+
+
+            conf.latex_array_threshold = -1  # means use the numpy threshold
+            np.set_printoptions(threshold=99)
+            lsmed = qmed._repr_latex_()
+            assert r'\dots' in lsmed
+            lsbig = qbig._repr_latex_()
+            assert r'\dots' in lsbig
+            lsvbig = qvbig._repr_latex_()
+            assert r'\dots' in lsvbig
+        finally:
+            # prevent side-effects from influencing other tests
+            np.set_printoptions(**pops)
+            conf.latex_array_threshold = oldlat
+
+        qinfnan = [np.inf, -np.inf, np.nan] * u.m
+        assert qinfnan._repr_latex_() == r'$[\infty,~-\infty,~{\rm NaN}] \; \mathrm{m}$'
+
 
 
 def test_decompose():
@@ -946,9 +995,6 @@ def test_copy():
     assert q1.dtype == q2.dtype
     assert q1.value is not q2.value
 
-    if NUMPY_VERSION < version.LooseVersion('1.6.0'):
-        return  # numpy 1.5 doesn't allow arguments to `copy`
-
     q3 = q1.copy(order='F')
     assert q3.flags['F_CONTIGUOUS']
     assert np.all(q1.value == q3.value)
@@ -1071,3 +1117,41 @@ def test_quantity_from_table():
     qbp = u.Quantity(t['b'], u.pc)
     assert qbp.unit == u.pc
     assert_array_equal(qbp.value, t['b'])
+
+def test_insert():
+    """
+    Test Quantity.insert method.  This does not test the full capabilities
+    of the underlying np.insert, but hits the key functionality for
+    Quantity.
+    """
+    q = [1, 2] * u.m
+
+    # Insert a compatible float with different units
+    q2 = q.insert(0, 1 * u.km)
+    assert np.all(q2.value == [ 1000,  1,  2])
+    assert q2.unit is u.m
+    assert q2.dtype.kind == 'f'
+
+    if NUMPY_VERSION >= version.LooseVersion('1.8.0'):
+        q2 = q.insert(1, [1, 2] * u.km)
+        assert np.all(q2.value == [1, 1000, 2000, 2])
+        assert q2.unit is u.m
+
+    # Cannot convert 1.5 * u.s to m
+    with pytest.raises(u.UnitsError):
+        q.insert(1, 1.5 * u.s)
+
+    # Tests with multi-dim quantity
+    q = [[1, 2], [3, 4]] * u.m
+    q2 = q.insert(1, [10, 20] * u.m, axis=0)
+    assert np.all(q2.value == [[  1,  2],
+                               [ 10, 20],
+                               [  3,  4]])
+
+    q2 = q.insert(1, [10, 20] * u.m, axis=1)
+    assert np.all(q2.value == [[  1, 10,  2],
+                               [  3, 20,  4]])
+
+    q2 = q.insert(1, 10 * u.m, axis=1)
+    assert np.all(q2.value == [[  1,  10, 2],
+                               [  3,  10, 4]])
diff --git a/astropy/units/tests/test_quantity_array_methods.py b/astropy/units/tests/test_quantity_array_methods.py
index 37e3b8b..e11f7af 100644
--- a/astropy/units/tests/test_quantity_array_methods.py
+++ b/astropy/units/tests/test_quantity_array_methods.py
@@ -8,6 +8,7 @@ from ...tests.helper import pytest
 
 NUMPY_LT_1P7 = [int(x) for x in np.__version__.split('.')[:2]] < [1, 7]
 NUMPY_LT_1P8 = [int(x) for x in np.__version__.split('.')[:2]] < [1, 8]
+NUMPY_LT_1P9P1 = [int(x) for x in np.__version__.split('.')[:3]] < [1, 9, 1]
 
 
 class TestQuantityArrayCopy(object):
@@ -144,14 +145,15 @@ class TestQuantityStatsFuncs(object):
         q1 = np.array([1., 2.]) * u.m
         assert np.std(q1) == 0.5 * u.m
 
+    # For 1.7 <= Numpy < 1.9.1, inplace causes the variance to be stored instead
+    # of the standard deviation; https://github.com/numpy/numpy/issues/5240
+    @pytest.mark.xfail("NUMPY_LT_1P9P1")
     def test_std_inplace(self):
 
-        # For Numpy >= 1.7, inplace causes the variance to be stored instead
-        # of the standard deviation.
-        # see https://github.com/numpy/numpy/issues/5240
-        # For Numpy < 1.7, the test segfaults.  Hence, we cannot use the xfail
-        # decorator since py.test will run the test anyway to see if it works.
-        pytest.xfail()
+        # For Numpy < 1.7, the test segfaults.  Hence, the xfail decorator does
+        # not suffice: py.test will run the test anyway to see if it works.
+        if NUMPY_LT_1P7:
+            pytest.xfail()
 
         q1 = np.array([1., 2.]) * u.m
         qi = 1.5 * u.s
diff --git a/astropy/units/tests/test_quantity_decorator.py b/astropy/units/tests/test_quantity_decorator.py
new file mode 100644
index 0000000..7e100d8
--- /dev/null
+++ b/astropy/units/tests/test_quantity_decorator.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from astropy.extern import six
+
+from ... import units as u
+from ...extern import six
+from ...tests.helper import pytest
+
+
+from .py3_test_quantity_annotations import *
+
+
+def test_args():
+    @u.quantity_input(solarx=u.arcsec, solary=u.arcsec)
+    def myfunc_args(solarx, solary):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec, 1*u.arcsec)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.arcsec
+
+def test_args_noconvert():
+    @u.quantity_input(solarx=u.arcsec, solary=u.arcsec)
+    def myfunc_args(solarx, solary):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.deg, 1*u.arcmin)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.deg
+    assert solary.unit == u.arcmin
+
+
+def test_args_nonquantity():
+    @u.quantity_input(solarx=u.arcsec)
+    def myfunc_args(solarx, solary):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec, 100)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+
+    assert solarx.unit == u.arcsec
+
+def test_arg_equivalencies():
+    @u.quantity_input(solarx=u.arcsec, solary=u.eV, equivalencies=u.mass_energy())
+    def myfunc_args(solarx, solary):
+        return solarx, solary+(10*u.J)  # Add an energy to check equiv is working
+
+    solarx, solary = myfunc_args(1*u.arcsec, 100*u.gram)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.gram
+
+def test_wrong_unit():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx, solary):
+        return solarx, solary
+
+    with pytest.raises(u.UnitsError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, 100*u.km)
+    assert str(e.value) == "Argument 'solary' to function 'myfunc_args' must be in units convertable to 'deg'."
+
+def test_not_quantity():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx, solary):
+        return solarx, solary
+
+    with pytest.raises(TypeError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, 100)
+    assert str(e.value) == "Argument 'solary' to function has 'myfunc_args' no 'unit' attribute. You may want to pass in an astropy Quantity instead."
+
+def test_kwargs():
+    @u.quantity_input(solarx=u.arcsec, myk=u.deg)
+    def myfunc_args(solarx, solary, myk=1*u.arcsec):
+        return solarx, solary, myk
+
+    solarx, solary, myk = myfunc_args(1*u.arcsec, 100, myk=100*u.deg)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+    assert isinstance(myk, u.Quantity)
+
+    assert myk.unit == u.deg
+
+def test_unused_kwargs():
+    @u.quantity_input(solarx=u.arcsec, myk=u.deg)
+    def myfunc_args(solarx, solary, myk=1*u.arcsec, myk2=1000):
+        return solarx, solary, myk, myk2
+
+    solarx, solary, myk, myk2 = myfunc_args(1*u.arcsec, 100, myk=100*u.deg, myk2=10)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, int)
+    assert isinstance(myk, u.Quantity)
+    assert isinstance(myk2, int)
+
+    assert myk.unit == u.deg
+    assert myk2 == 10
+
+def test_kwarg_equivalencies():
+    @u.quantity_input(solarx=u.arcsec, energy=u.eV, equivalencies=u.mass_energy())
+    def myfunc_args(solarx, energy=10*u.eV):
+        return solarx, energy+(10*u.J)  # Add an energy to check equiv is working
+
+    solarx, energy = myfunc_args(1*u.arcsec, 100*u.gram)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(energy, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert energy.unit == u.gram
+
+def test_kwarg_wrong_unit():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx, solary=10*u.deg):
+        return solarx, solary
+
+    with pytest.raises(u.UnitsError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, solary=100*u.km)
+    assert str(e.value) == "Argument 'solary' to function 'myfunc_args' must be in units convertable to 'deg'."
+
+def test_kwarg_not_quantity():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx, solary=10*u.deg):
+        return solarx, solary
+
+    with pytest.raises(TypeError) as e:
+        solarx, solary = myfunc_args(1*u.arcsec, solary=100)
+    assert str(e.value) == "Argument 'solary' to function has 'myfunc_args' no 'unit' attribute. You may want to pass in an astropy Quantity instead."
+
+def test_kwarg_default():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx, solary=10*u.deg):
+        return solarx, solary
+
+    solarx, solary = myfunc_args(1*u.arcsec)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.deg
+
+def test_no_equivalent():
+    class test_unit(object):
+        pass
+    class test_quantity(object):
+        unit = test_unit()
+
+    @u.quantity_input(solarx=u.arcsec)
+    def myfunc_args(solarx):
+        return solarx
+
+    with pytest.raises(TypeError) as e:
+        solarx, solary = myfunc_args(test_quantity())
+
+        assert str(e.value) == "Argument 'solarx' to function has 'myfunc_args' a 'unit' attribute without an 'is_equivalent' method. You may want to pass in an astropy Quantity instead."
+
+def test_kwargs_input():
+    @u.quantity_input(solarx=u.arcsec, solary=u.deg)
+    def myfunc_args(solarx=1*u.arcsec, solary=1*u.deg):
+        return solarx, solary
+
+    kwargs = {'solarx':10*u.arcsec, 'solary':10*u.deg}
+    solarx, solary = myfunc_args(**kwargs)
+
+    assert isinstance(solarx, u.Quantity)
+    assert isinstance(solary, u.Quantity)
+
+    assert solarx.unit == u.arcsec
+    assert solary.unit == u.deg
+
+def test_kwargs_extra():
+    @u.quantity_input(solary=u.deg)
+    def myfunc_args(solarx, **kwargs):
+        return solarx
+
+    solarx = myfunc_args(1*u.deg)
+
+    assert isinstance(solarx, u.Quantity)
+
+    assert solarx.unit == u.deg
+
diff --git a/astropy/units/tests/test_quantity_ufuncs.py b/astropy/units/tests/test_quantity_ufuncs.py
index 4de4dee..cb89e84 100644
--- a/astropy/units/tests/test_quantity_ufuncs.py
+++ b/astropy/units/tests/test_quantity_ufuncs.py
@@ -7,8 +7,6 @@ from numpy.testing.utils import assert_allclose
 from ... import units as u
 from ...tests.helper import pytest, raises
 
-NUMPY_LT_1P6 = [int(x) for x in np.__version__.split('.')[:2]] < [1, 6]
-
 
 class TestUfuncCoverage(object):
     """Test that we cover all ufunc's"""
@@ -522,7 +520,6 @@ class TestComparisonUfuncs(object):
 
 class TestInplaceUfuncs(object):
 
-    @pytest.mark.skipif("NUMPY_LT_1P6")
     @pytest.mark.parametrize(('value'), [1., np.arange(10.)])
     def test_one_argument_ufunc_inplace(self, value):
         # without scaling
@@ -539,7 +536,6 @@ class TestInplaceUfuncs(object):
         assert check2.unit == u.dimensionless_unscaled
         assert_allclose(s.value, s2.value)
 
-    @pytest.mark.skipif("NUMPY_LT_1P6")
     @pytest.mark.parametrize(('value'), [1., np.arange(10.)])
     def test_one_argument_ufunc_inplace_2(self, value):
         """Check inplace works with non-quantity input and quantity output"""
@@ -600,7 +596,6 @@ class TestInplaceUfuncs(object):
         assert check is s
         assert np.all(check == value * u.cycle)
 
-    @pytest.mark.skipif("NUMPY_LT_1P6")
     @pytest.mark.parametrize(('value'), [1., np.arange(10.)])
     def test_two_argument_ufunc_inplace_2(self, value):
         s = value * u.cycle
@@ -622,7 +617,6 @@ class TestInplaceUfuncs(object):
         assert check is s
         assert check.unit == u.deg / u.s
 
-    @pytest.mark.skipif("NUMPY_LT_1P6")
     def test_two_argument_ufunc_inplace_3(self):
         s = np.array([1., 2., 3.]) * u.dimensionless_unscaled
         np.add(np.array([1., 2., 3.]), np.array([1., 2., 3.]) * 2., out=s)
diff --git a/astropy/units/tests/test_units.py b/astropy/units/tests/test_units.py
index b7db63b..2abfe65 100644
--- a/astropy/units/tests/test_units.py
+++ b/astropy/units/tests/test_units.py
@@ -636,6 +636,10 @@ def test_composite_compose():
     u.s.compose(units=[composite_unit])
 
 
+def test_data_quantities():
+    assert u.byte.is_equivalent(u.bit)
+
+
 def test_compare_with_none():
     # Ensure that equality comparisons with `None` work, and don't
     # raise exceptions.  We are deliberately not using `is None` here
diff --git a/astropy/units/utils.py b/astropy/units/utils.py
index a25f6d3..d7c7f4c 100644
--- a/astropy/units/utils.py
+++ b/astropy/units/utils.py
@@ -22,7 +22,6 @@ from ..extern import six
 from ..utils.compat.fractions import Fraction
 from ..utils.exceptions import AstropyDeprecationWarning
 
-
 _float_finfo = finfo(float)
 # take float here to ensure comparison with another float is fast
 # give a little margin since often multiple calculations happened
diff --git a/astropy/utils/__init__.py b/astropy/utils/__init__.py
index 8247d31..7942e15 100644
--- a/astropy/utils/__init__.py
+++ b/astropy/utils/__init__.py
@@ -12,5 +12,8 @@ from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
 
+from .codegen import *
 from .compat.odict import OrderedDict
+from .decorators import *
+from .introspection import *
 from .misc import *
diff --git a/astropy/utils/codegen.py b/astropy/utils/codegen.py
new file mode 100644
index 0000000..d421f1e
--- /dev/null
+++ b/astropy/utils/codegen.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Utilities for generating new Python code at runtime."""
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import inspect
+import itertools
+import keyword
+import os
+import re
+import textwrap
+
+from .introspection import find_current_module
+from ..extern import six
+
+
+__all__ = ['make_function_with_signature']
+
+
+_ARGNAME_RE = re.compile(r'^[A-Za-z][A-Za-z_]*')
+"""
+Regular expression used my make_func which limits the allowed argument
+names for the created function.  Only valid Python variable names in
+the ASCII range and not beginning with '_' are allowed, currently.
+"""
+
+
+def make_function_with_signature(func, args=(), kwargs={}, varargs=None,
+                                 varkwargs=None, name=None):
+    """
+    Make a new function from an existing function but with the desired
+    signature.
+
+    The desired signature must of course be compatible with the arguments
+    actually accepted by the input function.
+
+    The ``args`` are strings that should be the names of the positional
+    arguments.  ``kwargs`` can map names of keyword arguments to their
+    default values.  It may be either a ``dict`` or a list of ``(keyword,
+    default)`` tuples.
+
+    If ``varargs`` is a string it is added to the positional arguments as
+    ``*<varargs>``.  Likewise ``varkwargs`` can be the name for a variable
+    keyword argument placeholder like ``**<varkwargs>``.
+
+    If not specified the name of the new function is taken from the original
+    function.  Otherwise, the ``name`` argument can be used to specify a new
+    name.
+
+    Note, the names may only be valid Python variable names.
+    """
+
+    pos_args = []
+    key_args = []
+
+    if six.PY2 and varargs and kwargs:
+        raise SyntaxError('keyword arguments not allowed after '
+                          '*{0}'.format(varargs))
+
+    if isinstance(kwargs, dict):
+        iter_kwargs = six.iteritems(kwargs)
+    else:
+        iter_kwargs = iter(kwargs)
+
+    # Check that all the argument names are valid
+    for item in itertools.chain(args, iter_kwargs):
+        if isinstance(item, tuple):
+            argname = item[0]
+            key_args.append(item)
+        else:
+            argname = item
+            pos_args.append(item)
+
+        if keyword.iskeyword(argname) or not _ARGNAME_RE.match(argname):
+            raise SyntaxError('invalid argument name: {0}'.format(argname))
+
+    for item in (varargs, varkwargs):
+        if item is not None:
+            if keyword.iskeyword(item) or not _ARGNAME_RE.match(item):
+                raise SyntaxError('invalid argument name: {0}'.format(item))
+
+    def_signature = [', '.join(pos_args)]
+
+    if varargs:
+        def_signature.append(', *{0}'.format(varargs))
+
+    call_signature = def_signature[:]
+
+    if name is None:
+        name = func.__name__
+
+    global_vars = {'__{0}__func'.format(name): func}
+    local_vars = {}
+    # Make local variables to handle setting the default args
+    for idx, item in enumerate(key_args):
+        key, value = item
+        default_var = '_kwargs{0}'.format(idx)
+        local_vars[default_var] = value
+        def_signature.append(', {0}={1}'.format(key, default_var))
+        call_signature.append(', {0}={0}'.format(key))
+
+    if varkwargs:
+        def_signature.append(', **{0}'.format(varkwargs))
+        call_signature.append(', **{0}'.format(varkwargs))
+
+    def_signature = ''.join(def_signature).lstrip(', ')
+    call_signature = ''.join(call_signature).lstrip(', ')
+
+    mod = find_current_module(2)
+    frm = inspect.currentframe().f_back
+
+    if mod:
+        filename = mod.__file__
+        modname = mod.__name__
+        if filename.endswith('.pyc'):
+            filename = os.path.splitext(filename)[0] + '.py'
+    else:
+        filename = '<string>'
+        modname = '__main__'
+
+    # Subtract 2 from the line number since the length of the template itself
+    # is two lines.  Therefore we have to subtract those off in order for the
+    # pointer in tracebacks from __{name}__func to point to the right spot.
+    lineno = frm.f_lineno - 2
+
+    # The lstrip is in case there were *no* positional arguments (a rare case)
+    # in any context this will actually be used...
+    template = textwrap.dedent("""{0}\
+    def {name}({sig1}):
+        return __{name}__func({sig2})
+    """.format('\n' * lineno, name=name, sig1=def_signature,
+               sig2=call_signature))
+
+    code = compile(template, filename, 'single')
+
+    eval(code, global_vars, local_vars)
+
+    new_func = local_vars[name]
+    new_func.__module__ = modname
+    new_func.__doc__ = func.__doc__
+
+    return new_func
diff --git a/astropy/utils/compat/_funcsigs.py b/astropy/utils/compat/_funcsigs.py
new file mode 100644
index 0000000..47eb1cd
--- /dev/null
+++ b/astropy/utils/compat/_funcsigs.py
@@ -0,0 +1,813 @@
+# Copyright 2001-2013 Python Software Foundation; All Rights Reserved
+"""Function signature objects for callables
+
+Back port of Python 3.3's function signature tools from the inspect module,
+modified to be compatible with Python 2.6, 2.7 and 3.2+.
+"""
+from __future__ import absolute_import, division, print_function
+import itertools
+import functools
+import re
+import types
+
+from .odict import OrderedDict
+
+__all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
+
+
+_WrapperDescriptor = type(type.__call__)
+_MethodWrapper = type(all.__call__)
+
+_NonUserDefinedCallables = (_WrapperDescriptor,
+                            _MethodWrapper,
+                            types.BuiltinFunctionType)
+
+
+def formatannotation(annotation, base_module=None):
+    if isinstance(annotation, type):
+        if annotation.__module__ in ('builtins', '__builtin__', base_module):
+            return annotation.__name__
+        return annotation.__module__+'.'+annotation.__name__
+    return repr(annotation)
+
+
+def _get_user_defined_method(cls, method_name, *nested):
+    try:
+        if cls is type:
+            return
+        meth = getattr(cls, method_name)
+        for name in nested:
+            meth = getattr(meth, name, meth)
+    except AttributeError:
+        return
+    else:
+        if not isinstance(meth, _NonUserDefinedCallables):
+            # Once '__signature__' will be added to 'C'-level
+            # callables, this check won't be necessary
+            return meth
+
+
+def signature(obj):
+    '''Get a signature object for the passed callable.'''
+
+    if not callable(obj):
+        raise TypeError('{0!r} is not a callable object'.format(obj))
+
+    if isinstance(obj, types.MethodType):
+        sig = signature(obj.__func__)
+        if obj.__self__ is None:
+            # Unbound method: the first parameter becomes positional-only
+            if sig.parameters:
+                first = sig.parameters.values()[0].replace(
+                    kind=_POSITIONAL_ONLY)
+                return sig.replace(
+                    parameters=(first,) + tuple(sig.parameters.values())[1:])
+            else:
+                return sig
+        else:
+            # In this case we skip the first parameter of the underlying
+            # function (usually `self` or `cls`).
+            return sig.replace(parameters=tuple(sig.parameters.values())[1:])
+
+    try:
+        sig = obj.__signature__
+    except AttributeError:
+        pass
+    else:
+        if sig is not None:
+            return sig
+
+    try:
+        # Was this function wrapped by a decorator?
+        wrapped = obj.__wrapped__
+    except AttributeError:
+        pass
+    else:
+        return signature(wrapped)
+
+    if isinstance(obj, types.FunctionType):
+        return Signature.from_function(obj)
+
+    if isinstance(obj, functools.partial):
+        sig = signature(obj.func)
+
+        new_params = OrderedDict(sig.parameters.items())
+
+        partial_args = obj.args or ()
+        partial_keywords = obj.keywords or {}
+        try:
+            ba = sig.bind_partial(*partial_args, **partial_keywords)
+        except TypeError as ex:
+            msg = 'partial object {0!r} has incorrect arguments'.format(obj)
+            raise ValueError(msg)
+
+        for arg_name, arg_value in ba.arguments.items():
+            param = new_params[arg_name]
+            if arg_name in partial_keywords:
+                # We set a new default value, because the following code
+                # is correct:
+                #
+                #   >>> def foo(a): print(a)
+                #   >>> print(partial(partial(foo, a=10), a=20)())
+                #   20
+                #   >>> print(partial(partial(foo, a=10), a=20)(a=30))
+                #   30
+                #
+                # So, with 'partial' objects, passing a keyword argument is
+                # like setting a new default value for the corresponding
+                # parameter
+                #
+                # We also mark this parameter with '_partial_kwarg'
+                # flag.  Later, in '_bind', the 'default' value of this
+                # parameter will be added to 'kwargs', to simulate
+                # the 'functools.partial' real call.
+                new_params[arg_name] = param.replace(default=arg_value,
+                                                     _partial_kwarg=True)
+
+            elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
+                            not param._partial_kwarg):
+                new_params.pop(arg_name)
+
+        return sig.replace(parameters=new_params.values())
+
+    sig = None
+    if isinstance(obj, type):
+        # obj is a class or a metaclass
+
+        # First, let's see if it has an overloaded __call__ defined
+        # in its metaclass
+        call = _get_user_defined_method(type(obj), '__call__')
+        if call is not None:
+            sig = signature(call)
+        else:
+            # Now we check if the 'obj' class has a '__new__' method
+            new = _get_user_defined_method(obj, '__new__')
+            if new is not None:
+                sig = signature(new)
+            else:
+                # Finally, we should have at least __init__ implemented
+                init = _get_user_defined_method(obj, '__init__')
+                if init is not None:
+                    sig = signature(init)
+    elif not isinstance(obj, _NonUserDefinedCallables):
+        # An object with __call__
+        # We also check that the 'obj' is not an instance of
+        # _WrapperDescriptor or _MethodWrapper to avoid
+        # infinite recursion (and even potential segfault)
+        call = _get_user_defined_method(type(obj), '__call__', 'im_func')
+        if call is not None:
+            sig = signature(call)
+
+    if sig is not None:
+        # For classes and objects we skip the first parameter of their
+        # __call__, __new__, or __init__ methods
+        return sig.replace(parameters=tuple(sig.parameters.values())[1:])
+
+    if isinstance(obj, types.BuiltinFunctionType):
+        # Raise a nicer error message for builtins
+        msg = 'no signature found for builtin function {0!r}'.format(obj)
+        raise ValueError(msg)
+
+    raise ValueError('callable {0!r} is not supported by signature'.format(obj))
+
+
+class _void(object):
+    '''A private marker - used in Parameter & Signature'''
+
+
+class _empty(object):
+    pass
+
+
+class _ParameterKind(int):
+    def __new__(self, *args, **kwargs):
+        obj = int.__new__(self, *args)
+        obj._name = kwargs['name']
+        return obj
+
+    def __str__(self):
+        return self._name
+
+    def __repr__(self):
+        return '<_ParameterKind: {0!r}>'.format(self._name)
+
+
+_POSITIONAL_ONLY        = _ParameterKind(0, name='POSITIONAL_ONLY')
+_POSITIONAL_OR_KEYWORD  = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
+_VAR_POSITIONAL         = _ParameterKind(2, name='VAR_POSITIONAL')
+_KEYWORD_ONLY           = _ParameterKind(3, name='KEYWORD_ONLY')
+_VAR_KEYWORD            = _ParameterKind(4, name='VAR_KEYWORD')
+
+
+class Parameter(object):
+    '''Represents a parameter in a function signature.
+
+    Has the following public attributes:
+
+    * name : str
+        The name of the parameter as a string.
+    * default : object
+        The default value for the parameter if specified.  If the
+        parameter has no default value, this attribute is not set.
+    * annotation
+        The annotation for the parameter if specified.  If the
+        parameter has no annotation, this attribute is not set.
+    * kind : str
+        Describes how argument values are bound to the parameter.
+        Possible values: `Parameter.POSITIONAL_ONLY`,
+        `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
+        `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
+    '''
+
+    __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
+
+    POSITIONAL_ONLY         = _POSITIONAL_ONLY
+    POSITIONAL_OR_KEYWORD   = _POSITIONAL_OR_KEYWORD
+    VAR_POSITIONAL          = _VAR_POSITIONAL
+    KEYWORD_ONLY            = _KEYWORD_ONLY
+    VAR_KEYWORD             = _VAR_KEYWORD
+
+    empty = _empty
+
+    def __init__(self, name, kind, default=_empty, annotation=_empty,
+                 _partial_kwarg=False):
+
+        if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
+                        _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
+            raise ValueError("invalid value for 'Parameter.kind' attribute")
+        self._kind = kind
+
+        if default is not _empty:
+            if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
+                msg = '{0} parameters cannot have default values'.format(kind)
+                raise ValueError(msg)
+        self._default = default
+        self._annotation = annotation
+
+        if name is None:
+            if kind != _POSITIONAL_ONLY:
+                raise ValueError("None is not a valid name for a "
+                                 "non-positional-only parameter")
+            self._name = name
+        else:
+            name = str(name)
+            if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
+                msg = '{0!r} is not a valid parameter name'.format(name)
+                raise ValueError(msg)
+            self._name = name
+
+        self._partial_kwarg = _partial_kwarg
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def default(self):
+        return self._default
+
+    @property
+    def annotation(self):
+        return self._annotation
+
+    @property
+    def kind(self):
+        return self._kind
+
+    def replace(self, name=_void, kind=_void, annotation=_void,
+                default=_void, _partial_kwarg=_void):
+        '''Creates a customized copy of the Parameter.'''
+
+        if name is _void:
+            name = self._name
+
+        if kind is _void:
+            kind = self._kind
+
+        if annotation is _void:
+            annotation = self._annotation
+
+        if default is _void:
+            default = self._default
+
+        if _partial_kwarg is _void:
+            _partial_kwarg = self._partial_kwarg
+
+        return type(self)(name, kind, default=default, annotation=annotation,
+                          _partial_kwarg=_partial_kwarg)
+
+    def __str__(self):
+        kind = self.kind
+
+        formatted = self._name
+        if kind == _POSITIONAL_ONLY:
+            if formatted is None:
+                formatted = ''
+            formatted = '<{0}>'.format(formatted)
+
+        # Add annotation and default value
+        if self._annotation is not _empty:
+            formatted = '{0}:{1}'.format(formatted,
+                                       formatannotation(self._annotation))
+
+        if self._default is not _empty:
+            formatted = '{0}={1}'.format(formatted, repr(self._default))
+
+        if kind == _VAR_POSITIONAL:
+            formatted = '*' + formatted
+        elif kind == _VAR_KEYWORD:
+            formatted = '**' + formatted
+
+        return formatted
+
+    def __repr__(self):
+        return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
+                                           id(self), self.name)
+
+    def __hash__(self):
+        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
+        raise TypeError(msg)
+
+    def __eq__(self, other):
+        return (issubclass(other.__class__, Parameter) and
+                self._name == other._name and
+                self._kind == other._kind and
+                self._default == other._default and
+                self._annotation == other._annotation)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+
+class BoundArguments(object):
+    '''Result of `Signature.bind` call.  Holds the mapping of arguments
+    to the function's parameters.
+
+    Has the following public attributes:
+
+    * arguments : OrderedDict
+        An ordered mutable mapping of parameters' names to arguments' values.
+        Does not contain arguments' default values.
+    * signature : Signature
+        The Signature object that created this instance.
+    * args : tuple
+        Tuple of positional arguments values.
+    * kwargs : dict
+        Dict of keyword arguments values.
+    '''
+
+    def __init__(self, signature, arguments):
+        self.arguments = arguments
+        self._signature = signature
+
+    @property
+    def signature(self):
+        return self._signature
+
+    @property
+    def args(self):
+        args = []
+        for param_name, param in self._signature.parameters.items():
+            if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
+                                                    param._partial_kwarg):
+                # Keyword arguments mapped by 'functools.partial'
+                # (Parameter._partial_kwarg is True) are mapped
+                # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
+                # KEYWORD_ONLY
+                break
+
+            try:
+                arg = self.arguments[param_name]
+            except KeyError:
+                # We're done here. Other arguments
+                # will be mapped in 'BoundArguments.kwargs'
+                break
+            else:
+                if param.kind == _VAR_POSITIONAL:
+                    # *args
+                    args.extend(arg)
+                else:
+                    # plain argument
+                    args.append(arg)
+
+        return tuple(args)
+
+    @property
+    def kwargs(self):
+        kwargs = {}
+        kwargs_started = False
+        for param_name, param in self._signature.parameters.items():
+            if not kwargs_started:
+                if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
+                                                param._partial_kwarg):
+                    kwargs_started = True
+                else:
+                    if param_name not in self.arguments:
+                        kwargs_started = True
+                        continue
+
+            if not kwargs_started:
+                continue
+
+            try:
+                arg = self.arguments[param_name]
+            except KeyError:
+                pass
+            else:
+                if param.kind == _VAR_KEYWORD:
+                    # **kwargs
+                    kwargs.update(arg)
+                else:
+                    # plain keyword argument
+                    kwargs[param_name] = arg
+
+        return kwargs
+
+    def __hash__(self):
+        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
+        raise TypeError(msg)
+
+    def __eq__(self, other):
+        return (issubclass(other.__class__, BoundArguments) and
+                self.signature == other.signature and
+                self.arguments == other.arguments)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+
+class Signature(object):
+    '''A Signature object represents the overall signature of a function.
+    It stores a Parameter object for each parameter accepted by the
+    function, as well as information specific to the function itself.
+
+    A Signature object has the following public attributes and methods:
+
+    * parameters : OrderedDict
+        An ordered mapping of parameters' names to the corresponding
+        Parameter objects (keyword-only arguments are in the same order
+        as listed in `code.co_varnames`).
+    * return_annotation : object
+        The annotation for the return type of the function if specified.
+        If the function has no annotation for its return type, this
+        attribute is not set.
+    * bind(*args, **kwargs) -> BoundArguments
+        Creates a mapping from positional and keyword arguments to
+        parameters.
+    * bind_partial(*args, **kwargs) -> BoundArguments
+        Creates a partial mapping from positional and keyword arguments
+        to parameters (simulating 'functools.partial' behavior.)
+    '''
+
+    __slots__ = ('_return_annotation', '_parameters')
+
+    _parameter_cls = Parameter
+    _bound_arguments_cls = BoundArguments
+
+    empty = _empty
+
+    def __init__(self, parameters=None, return_annotation=_empty,
+                 __validate_parameters__=True):
+        '''Constructs Signature from the given list of Parameter
+        objects and 'return_annotation'.  All arguments are optional.
+        '''
+
+        if parameters is None:
+            params = OrderedDict()
+        else:
+            if __validate_parameters__:
+                params = OrderedDict()
+                top_kind = _POSITIONAL_ONLY
+
+                for idx, param in enumerate(parameters):
+                    kind = param.kind
+                    if kind < top_kind:
+                        msg = 'wrong parameter order: {0} before {1}'
+                        msg = msg.format(top_kind, param.kind)
+                        raise ValueError(msg)
+                    else:
+                        top_kind = kind
+
+                    name = param.name
+                    if name is None:
+                        name = str(idx)
+                        param = param.replace(name=name)
+
+                    if name in params:
+                        msg = 'duplicate parameter name: {0!r}'.format(name)
+                        raise ValueError(msg)
+                    params[name] = param
+            else:
+                params = OrderedDict(((param.name, param)
+                                                for param in parameters))
+
+        self._parameters = params
+        self._return_annotation = return_annotation
+
+    @classmethod
+    def from_function(cls, func):
+        '''Constructs Signature for the given python function'''
+
+        if not isinstance(func, types.FunctionType):
+            raise TypeError('{0!r} is not a Python function'.format(func))
+
+        Parameter = cls._parameter_cls
+
+        # Parameter information.
+        func_code = func.__code__
+        pos_count = func_code.co_argcount
+        arg_names = func_code.co_varnames
+        positional = tuple(arg_names[:pos_count])
+        keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
+        keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
+        annotations = getattr(func, '__annotations__', {})
+        defaults = func.__defaults__
+        kwdefaults = getattr(func, '__kwdefaults__', None)
+
+        if defaults:
+            pos_default_count = len(defaults)
+        else:
+            pos_default_count = 0
+
+        parameters = []
+
+        # Non-keyword-only parameters w/o defaults.
+        non_default_count = pos_count - pos_default_count
+        for name in positional[:non_default_count]:
+            annotation = annotations.get(name, _empty)
+            parameters.append(Parameter(name, annotation=annotation,
+                                        kind=_POSITIONAL_OR_KEYWORD))
+
+        # ... w/ defaults.
+        for offset, name in enumerate(positional[non_default_count:]):
+            annotation = annotations.get(name, _empty)
+            parameters.append(Parameter(name, annotation=annotation,
+                                        kind=_POSITIONAL_OR_KEYWORD,
+                                        default=defaults[offset]))
+
+        # *args
+        if func_code.co_flags & 0x04:
+            name = arg_names[pos_count + keyword_only_count]
+            annotation = annotations.get(name, _empty)
+            parameters.append(Parameter(name, annotation=annotation,
+                                        kind=_VAR_POSITIONAL))
+
+        # Keyword-only parameters.
+        for name in keyword_only:
+            default = _empty
+            if kwdefaults is not None:
+                default = kwdefaults.get(name, _empty)
+
+            annotation = annotations.get(name, _empty)
+            parameters.append(Parameter(name, annotation=annotation,
+                                        kind=_KEYWORD_ONLY,
+                                        default=default))
+        # **kwargs
+        if func_code.co_flags & 0x08:
+            index = pos_count + keyword_only_count
+            if func_code.co_flags & 0x04:
+                index += 1
+
+            name = arg_names[index]
+            annotation = annotations.get(name, _empty)
+            parameters.append(Parameter(name, annotation=annotation,
+                                        kind=_VAR_KEYWORD))
+
+        return cls(parameters,
+                   return_annotation=annotations.get('return', _empty),
+                   __validate_parameters__=False)
+
+    @property
+    def parameters(self):
+        try:
+            return types.MappingProxyType(self._parameters)
+        except AttributeError:
+            return OrderedDict(self._parameters.items())
+
+    @property
+    def return_annotation(self):
+        return self._return_annotation
+
+    def replace(self, parameters=_void, return_annotation=_void):
+        '''Creates a customized copy of the Signature.
+        Pass 'parameters' and/or 'return_annotation' arguments
+        to override them in the new copy.
+        '''
+
+        if parameters is _void:
+            parameters = self.parameters.values()
+
+        if return_annotation is _void:
+            return_annotation = self._return_annotation
+
+        return type(self)(parameters,
+                          return_annotation=return_annotation)
+
+    def __hash__(self):
+        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
+        raise TypeError(msg)
+
+    def __eq__(self, other):
+        if (not issubclass(type(other), Signature) or
+                    self.return_annotation != other.return_annotation or
+                    len(self.parameters) != len(other.parameters)):
+            return False
+
+        other_positions = dict((param, idx)
+                           for idx, param in enumerate(other.parameters.keys()))
+
+        for idx, (param_name, param) in enumerate(self.parameters.items()):
+            if param.kind == _KEYWORD_ONLY:
+                try:
+                    other_param = other.parameters[param_name]
+                except KeyError:
+                    return False
+                else:
+                    if param != other_param:
+                        return False
+            else:
+                try:
+                    other_idx = other_positions[param_name]
+                except KeyError:
+                    return False
+                else:
+                    if (idx != other_idx or
+                                    param != other.parameters[param_name]):
+                        return False
+
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def _bind(self, args, kwargs, partial=False):
+        '''Private method.  Don't use directly.'''
+
+        arguments = OrderedDict()
+
+        parameters = iter(self.parameters.values())
+        parameters_ex = ()
+        arg_vals = iter(args)
+
+        if partial:
+            # Support for binding arguments to 'functools.partial' objects.
+            # See 'functools.partial' case in 'signature()' implementation
+            # for details.
+            for param_name, param in self.parameters.items():
+                if (param._partial_kwarg and param_name not in kwargs):
+                    # Simulating 'functools.partial' behavior
+                    kwargs[param_name] = param.default
+
+        while True:
+            # Let's iterate through the positional arguments and corresponding
+            # parameters
+            try:
+                arg_val = next(arg_vals)
+            except StopIteration:
+                # No more positional arguments
+                try:
+                    param = next(parameters)
+                except StopIteration:
+                    # No more parameters. That's it. Just need to check that
+                    # we have no `kwargs` after this while loop
+                    break
+                else:
+                    if param.kind == _VAR_POSITIONAL:
+                        # That's OK, just empty *args.  Let's start parsing
+                        # kwargs
+                        break
+                    elif param.name in kwargs:
+                        if param.kind == _POSITIONAL_ONLY:
+                            msg = '{arg!r} parameter is positional only, ' \
+                                  'but was passed as a keyword'
+                            msg = msg.format(arg=param.name)
+                            raise TypeError(msg)
+                        parameters_ex = (param,)
+                        break
+                    elif (param.kind == _VAR_KEYWORD or
+                                                param.default is not _empty):
+                        # That's fine too - we have a default value for this
+                        # parameter.  So, lets start parsing `kwargs`, starting
+                        # with the current parameter
+                        parameters_ex = (param,)
+                        break
+                    else:
+                        if partial:
+                            parameters_ex = (param,)
+                            break
+                        else:
+                            msg = '{arg!r} parameter lacking default value'
+                            msg = msg.format(arg=param.name)
+                            raise TypeError(msg)
+            else:
+                # We have a positional argument to process
+                try:
+                    param = next(parameters)
+                except StopIteration:
+                    raise TypeError('too many positional arguments')
+                else:
+                    if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
+                        # Looks like we have no parameter for this positional
+                        # argument
+                        raise TypeError('too many positional arguments')
+
+                    if param.kind == _VAR_POSITIONAL:
+                        # We have an '*args'-like argument, let's fill it with
+                        # all positional arguments we have left and move on to
+                        # the next phase
+                        values = [arg_val]
+                        values.extend(arg_vals)
+                        arguments[param.name] = tuple(values)
+                        break
+
+                    if param.name in kwargs:
+                        raise TypeError('multiple values for argument '
+                                        '{arg!r}'.format(arg=param.name))
+
+                    arguments[param.name] = arg_val
+
+        # Now, we iterate through the remaining parameters to process
+        # keyword arguments
+        kwargs_param = None
+        for param in itertools.chain(parameters_ex, parameters):
+            if param.kind == _POSITIONAL_ONLY:
+                # This should never happen in case of a properly built
+                # Signature object (but let's have this check here
+                # to ensure correct behaviour just in case)
+                raise TypeError('{arg!r} parameter is positional only, '
+                                'but was passed as a keyword'. \
+                                format(arg=param.name))
+
+            if param.kind == _VAR_KEYWORD:
+                # Memorize that we have a '**kwargs'-like parameter
+                kwargs_param = param
+                continue
+
+            param_name = param.name
+            try:
+                arg_val = kwargs.pop(param_name)
+            except KeyError:
+                # We have no value for this parameter.  It's fine though,
+                # if it has a default value, or it is an '*args'-like
+                # parameter, left alone by the processing of positional
+                # arguments.
+                if (not partial and param.kind != _VAR_POSITIONAL and
+                                                    param.default is _empty):
+                    raise TypeError('{arg!r} parameter lacking default value'. \
+                                    format(arg=param_name))
+
+            else:
+                arguments[param_name] = arg_val
+
+        if kwargs:
+            if kwargs_param is not None:
+                # Process our '**kwargs'-like parameter
+                arguments[kwargs_param.name] = kwargs
+            else:
+                raise TypeError('too many keyword arguments')
+
+        return self._bound_arguments_cls(self, arguments)
+
+    def bind(self, *args, **kwargs):
+        '''Get a BoundArguments object, that maps the passed `args`
+        and `kwargs` to the function's signature.  Raises `TypeError`
+        if the passed arguments can not be bound.
+        '''
+        return self._bind(args, kwargs)
+
+    def bind_partial(self, *args, **kwargs):
+        '''Get a BoundArguments object, that partially maps the
+        passed `args` and `kwargs` to the function's signature.
+        Raises `TypeError` if the passed arguments can not be bound.
+        '''
+        return self._bind(args, kwargs, partial=True)
+
+    def __str__(self):
+        result = []
+        render_kw_only_separator = True
+        for idx, param in enumerate(self.parameters.values()):
+            formatted = str(param)
+
+            kind = param.kind
+            if kind == _VAR_POSITIONAL:
+                # OK, we have an '*args'-like parameter, so we won't need
+                # a '*' to separate keyword-only arguments
+                render_kw_only_separator = False
+            elif kind == _KEYWORD_ONLY and render_kw_only_separator:
+                # We have a keyword-only parameter to render and we haven't
+                # rendered an '*args'-like parameter before, so add a '*'
+                # separator to the parameters list ("foo(arg1, *, arg2)" case)
+                result.append('*')
+                # This condition should be only triggered once, so
+                # reset the flag
+                render_kw_only_separator = False
+
+            result.append(formatted)
+
+        rendered = '({0})'.format(', '.join(result))
+
+        if self.return_annotation is not _empty:
+            anno = formatannotation(self.return_annotation)
+            rendered += ' -> {0}'.format(anno)
+
+        return rendered
diff --git a/astropy/utils/compat/argparse.py b/astropy/utils/compat/argparse.py
index ab42cee..c0790a6 100644
--- a/astropy/utils/compat/argparse.py
+++ b/astropy/utils/compat/argparse.py
@@ -4,7 +4,5 @@ import sys
 
 if sys.version_info[:2] <= (2, 6):
     from ._argparse import *
-elif sys.version_info[0] == 3 and sys.version_info[:2] <= (3, 1):
-    from ._argparse import *
 else:
     from argparse import *
diff --git a/astropy/utils/compat/funcsigs.py b/astropy/utils/compat/funcsigs.py
new file mode 100644
index 0000000..c66b52e
--- /dev/null
+++ b/astropy/utils/compat/funcsigs.py
@@ -0,0 +1,6 @@
+try:
+    from inspect import signature, Parameter, Signature, BoundArguments
+except ImportError:
+    from ._funcsigs import signature, Parameter, Signature, BoundArguments
+
+__all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
diff --git a/astropy/utils/compat/gzip.py b/astropy/utils/compat/gzip.py
index 9671195..1340425 100644
--- a/astropy/utils/compat/gzip.py
+++ b/astropy/utils/compat/gzip.py
@@ -4,18 +4,12 @@ Handles backports of the standard library's `gzip.py`.
 
 Python 2.6 has a `gzip.py` without support for the `with` statement.
 Here, the version that ships with Python 2.7 is used instead.
-
-Python 3.1 has a `gzip.py` that can not be wrapped by an
-`io.TextIOWrapper`.  Here, the version that ships with Python 3.2 is
-used instead.
 """
 
 from __future__ import absolute_import
 
 import sys
-if sys.version_info[:2] == (3, 1):
-    from ._gzip_py3 import *
-elif sys.version_info[:2] == (2, 6):
+if sys.version_info[:2] == (2, 6):
     from ._gzip_py2 import *
 else:
     from gzip import *
diff --git a/astropy/utils/compat/misc.py b/astropy/utils/compat/misc.py
index bff6438..9b56940 100644
--- a/astropy/utils/compat/misc.py
+++ b/astropy/utils/compat/misc.py
@@ -7,11 +7,6 @@ be accessed from there.
 
 Includes the following fixes:
 
-* The `inspect.getmodule` function does not always work in Python 3.1 and 3.2.
-  This package includes a function `inspect_getmodule` that will simply be an
-  alias to `inspect.getmodule` if the stdlib version is correct, but for
-  versions of python with the bug, it uses an internal patched version.
-
 * The `contextlib.ignored` context manager, which is only available in Python
   3.4 or greater.
 
@@ -21,14 +16,12 @@ from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 from ...extern import six
 
-import os
+import functools
 import sys
 
-from functools import wraps
-
 
-__all__ = ['inspect_getmodule', 'invalidate_caches', 'override__dir__',
-           'ignored', 'possible_filename']
+__all__ = ['invalidate_caches', 'override__dir__', 'ignored',
+           'possible_filename']
 
 
 def possible_filename(filename):
@@ -52,75 +45,6 @@ def possible_filename(filename):
     return False
 
 
-def _patched_getmodule(object, _filename=None):
-    """Return the module an object was defined in, or None if not found.
-
-    This replicates the functionality of the stdlib `inspect.getmodule`
-    function but includes a fix for a bug present in Python 3.1 and 3.2.
-    """
-    #these imports mock up what would otherwise have been in inspect
-    from inspect import modulesbyfile, _filesbymodname, getabsfile, ismodule
-
-    if ismodule(object):
-        return object
-    if hasattr(object, '__module__'):
-        return sys.modules.get(object.__module__)
-    # Try the filename to modulename cache
-    if _filename is not None and _filename in modulesbyfile:
-        return sys.modules.get(modulesbyfile[_filename])
-    # Try the cache again with the absolute file name
-    try:
-        file = getabsfile(object, _filename)
-    except TypeError:
-        return None
-    if file in modulesbyfile:
-        return sys.modules.get(modulesbyfile[file])
-    # Update the filename to module name cache and check yet again
-    # Copy sys.modules in order to cope with changes while iterating
-    # This is where the fix is made - the adding of the "list" call:
-    for modname, module in list(sys.modules.items()):
-        if ismodule(module) and hasattr(module, '__file__'):
-            f = module.__file__
-            if f == _filesbymodname.get(modname, None):
-                # Have already mapped this module, so skip it
-                continue
-            _filesbymodname[modname] = f
-            f = getabsfile(module)
-            # Always map to the name the module knows itself by
-            modulesbyfile[f] = modulesbyfile[
-                os.path.realpath(f)] = module.__name__
-    if file in modulesbyfile:
-        return sys.modules.get(modulesbyfile[file])
-    # Check the main module
-    main = sys.modules['__main__']
-    if not hasattr(object, '__name__'):
-        return None
-    if hasattr(main, object.__name__):
-        mainobject = getattr(main, object.__name__)
-        if mainobject is object:
-            return main
-    # Check builtins
-    builtin = sys.modules['builtins']
-    if hasattr(builtin, object.__name__):
-        builtinobject = getattr(builtin, object.__name__)
-        if builtinobject is object:
-            return builtin
-
-inspect_getmodule = None
-"""
-An alias to `inspect.getmodule`, or a patched version that replicates the
-functionality with a bugfix for Python 3.1 and 3.2.
-"""
-
-#This assigns the stdlib inspect.getmodule to the variable name
-#`inspect_getmodule` if it's not buggy, and uses the matched version if it is.
-if sys.version_info[0] < 3 or sys.version_info[1] > 2:
-    #in 2.x everythig is fine, as well as >=3.3
-    from inspect import getmodule as inspect_getmodule
-else:
-    inspect_getmodule = _patched_getmodule
-
-
 # Python 3.3's importlib caches filesystem reads for faster imports in the
 # general case. But sometimes it's necessary to manually invalidate those
 # caches so that the import system can pick up new generated files.  See
@@ -149,7 +73,7 @@ def override__dir__(f):
     if sys.version_info[:2] < (3, 3):
         # There was no straightforward way to do this until Python 3.3, so
         # we have this complex monstrosity
-        @wraps(f)
+        @functools.wraps(f)
         def override__dir__wrapper(self):
             members = set()
             for cls in self.__class__.mro():
@@ -160,7 +84,7 @@ def override__dir__(f):
     else:
         # http://bugs.python.org/issue12166
 
-        @wraps(f)
+        @functools.wraps(f)
         def override__dir__wrapper(self):
             members = set(object.__dir__(self))
             members.update(f(self))
diff --git a/astropy/utils/compat/numpy/__init__.py b/astropy/utils/compat/numpy/__init__.py
new file mode 100644
index 0000000..c28edca
--- /dev/null
+++ b/astropy/utils/compat/numpy/__init__.py
@@ -0,0 +1,10 @@
+# coding: utf-8
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""NumPy functions and classes needed for astropy but not available
+in all supported NumPy versions.  See docs/utils/numpy.rst for details.
+"""
+
+from __future__ import division, absolute_import, unicode_literals
+
+from .lib.stride_tricks import broadcast_arrays
diff --git a/astropy/utils/compat/numpy/lib/__init__.py b/astropy/utils/compat/numpy/lib/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy/utils/compat/numpy/lib/stride_tricks.py b/astropy/utils/compat/numpy/lib/stride_tricks.py
new file mode 100644
index 0000000..0370770
--- /dev/null
+++ b/astropy/utils/compat/numpy/lib/stride_tricks.py
@@ -0,0 +1,164 @@
+# coding: utf-8
+# Licensed like the corresponding numpy file; see licenses/NUMPY_LICENSE.rst
+"""
+Utilities that manipulate strides to achieve desirable effects.
+
+An explanation of strides can be found in the "ndarray.rst" file in the
+NumPy reference guide.
+
+Notes
+-----
+The version provided here ensures broadcast_arrays passes on subclasses
+if one sets ``subok=True``; see https://github.com/numpy/numpy/pull/4622
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = ['broadcast_arrays', 'GE1P10']
+
+
+def GE1P10(function=np.broadcast_arrays):
+    """Test whether the broadcast_arrays function respects subclasses
+
+    By default, ``np.broadcast_arrays`` is checked
+
+    See https://github.com/numpy/numpy/pull/4622
+    """
+
+    class MySubClass(np.ndarray):
+        pass
+
+    try:
+        return isinstance(function(MySubClass((1,)), subok=True)[0],
+                          MySubClass)
+    except TypeError:  # unexpected argument subok
+        return False
+
+
+if GE1P10():
+    from numpy.lib.stride_tricks import broadcast_arrays
+
+else:
+    from numpy.lib.stride_tricks import DummyArray
+
+    def as_strided(x, shape=None, strides=None, subok=False):
+        """ Make an ndarray from the given array with the given shape and strides.
+        """
+        # first convert input to array, possibly keeping subclass
+        x = np.array(x, copy=False, subok=subok)
+        interface = dict(x.__array_interface__)
+        if shape is not None:
+            interface['shape'] = tuple(shape)
+        if strides is not None:
+            interface['strides'] = tuple(strides)
+        array = np.asarray(DummyArray(interface, base=x))
+        # Make sure dtype is correct in case of custom dtype
+        if array.dtype.kind == 'V':
+            array.dtype = x.dtype
+        if type(x) is not type(array):
+            # if input was an ndarray subclass and subclasses were OK,
+            # then view the result as that subclass.
+            array = array.view(type=type(x))
+            # Since we have done something akin to a view from x, we should let
+            # the subclass finalize (if it has it implemented, i.e., is not None).
+            if array.__array_finalize__:
+                array.__array_finalize__(x)
+        return array
+
+    def broadcast_arrays(*args, **kwargs):
+        """
+        Broadcast any number of arrays against each other.
+
+        Parameters
+        ----------
+        `*args` : array_likes
+            The arrays to broadcast.
+
+        subok : bool, optional
+            If True, then sub-classes will be passed-through, otherwise
+            the returned arrays will be forced to be a base-class array (default).
+
+        Returns
+        -------
+        broadcasted : list of arrays
+            These arrays are views on the original arrays.  They are typically
+            not contiguous.  Furthermore, more than one element of a
+            broadcasted array may refer to a single memory location.  If you
+            need to write to the arrays, make copies first.
+
+        Examples
+        --------
+        >>> x = np.array([[1,2,3]])
+        >>> y = np.array([[1],[2],[3]])
+        >>> np.broadcast_arrays(x, y)
+        [array([[1, 2, 3],
+               [1, 2, 3],
+               [1, 2, 3]]), array([[1, 1, 1],
+               [2, 2, 2],
+               [3, 3, 3]])]
+
+        Here is a useful idiom for getting contiguous copies instead of
+        non-contiguous views.
+
+        >>> [np.array(a) for a in np.broadcast_arrays(x, y)]
+        [array([[1, 2, 3],
+               [1, 2, 3],
+               [1, 2, 3]]), array([[1, 1, 1],
+               [2, 2, 2],
+               [3, 3, 3]])]
+
+        """
+        subok = kwargs.pop('subok', False)
+        if kwargs:
+            raise TypeError('broadcast_arrays() got an unexpected keyword '
+                            'argument {}'.format(kwargs.pop()))
+        args = [np.array(_m, copy=False, subok=subok) for _m in args]
+        shapes = [x.shape for x in args]
+        if len(set(shapes)) == 1:
+            # Common case where nothing needs to be broadcasted.
+            return args
+        shapes = [list(s) for s in shapes]
+        strides = [list(x.strides) for x in args]
+        nds = [len(s) for s in shapes]
+        biggest = max(nds)
+        # Go through each array and prepend dimensions of length 1 to each of
+        # the shapes in order to make the number of dimensions equal.
+        for i in range(len(args)):
+            diff = biggest - nds[i]
+            if diff > 0:
+                shapes[i] = [1] * diff + shapes[i]
+                strides[i] = [0] * diff + strides[i]
+        # Chech each dimension for compatibility. A dimension length of 1 is
+        # accepted as compatible with any other length.
+        common_shape = []
+        for axis in range(biggest):
+            lengths = [s[axis] for s in shapes]
+            unique = set(lengths + [1])
+            if len(unique) > 2:
+                # There must be at least two non-1 lengths for this axis.
+                raise ValueError("shape mismatch: two or more arrays have "
+                    "incompatible dimensions on axis %r." % (axis,))
+            elif len(unique) == 2:
+                # There is exactly one non-1 length. The common shape will take
+                # this value.
+                unique.remove(1)
+                new_length = unique.pop()
+                common_shape.append(new_length)
+                # For each array, if this axis is being broadcasted from a
+                # length of 1, then set its stride to 0 so that it repeats its
+                # data.
+                for i in range(len(args)):
+                    if shapes[i][axis] == 1:
+                        shapes[i][axis] = new_length
+                        strides[i][axis] = 0
+            else:
+                # Every array has a length of 1 on this axis. Strides can be
+                # left alone as nothing is broadcasted.
+                common_shape.append(1)
+
+        # Construct the new arrays.
+        broadcasted = [as_strided(x, shape=sh, strides=st, subok=subok)
+                       for (x, sh, st) in zip(args, shapes, strides)]
+        return broadcasted
diff --git a/astropy/utils/compat/numpy/tests/__init__.py b/astropy/utils/compat/numpy/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy/utils/compat/numpy/tests/test_broadcast_arrays.py b/astropy/utils/compat/numpy/tests/test_broadcast_arrays.py
new file mode 100644
index 0000000..410400c
--- /dev/null
+++ b/astropy/utils/compat/numpy/tests/test_broadcast_arrays.py
@@ -0,0 +1,48 @@
+# coding: utf-8
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+Test broadcast_arrays replacement on Quantity class.
+"""
+from __future__ import (absolute_import, unicode_literals, division,
+                        print_function)
+
+import numpy as np
+
+from astropy.tests.helper import pytest
+import astropy.units as u
+
+from ..lib.stride_tricks import broadcast_arrays, GE1P10
+
+
+def test_import():
+    """Check that what is imported from code is what we are testing."""
+    from ... import numpy as anp
+    assert anp.broadcast_arrays is broadcast_arrays
+
+
+def test_test_function():
+    """Test the test function
+
+    The possibly patched version of broadcast_arrays should always be OK
+    The numpy version may be, in which case we just use it, or it may not,
+    it which case we use the patched version.
+    """
+    assert GE1P10(broadcast_arrays) is True
+    if GE1P10():
+        assert broadcast_arrays is np.broadcast_arrays
+    else:
+        assert broadcast_arrays is not np.broadcast_arrays
+
+
+def test_broadcast_quantity():
+    q1 = u.Quantity([1., 2., 3., 4.], u.m)
+    q2 = u.Quantity([5., 6.], u.deg).reshape(-1, 1)
+    ba1, ba2 = broadcast_arrays(q1, q2)
+    assert type(ba1) is np.ndarray
+    assert type(ba2) is np.ndarray
+    bq1, bq2 = broadcast_arrays(q1, q2, subok=True)
+    assert type(bq1) is u.Quantity
+    assert type(bq2) is u.Quantity
+    assert bq1.shape == bq2.shape == (2, 4)
+    with pytest.raises(ValueError):
+        broadcast_arrays(q1, q1[:2], subok=True)
diff --git a/astropy/utils/console.py b/astropy/utils/console.py
index 3636870..cf7fbc7 100644
--- a/astropy/utils/console.py
+++ b/astropy/utils/console.py
@@ -62,7 +62,8 @@ from ..extern import six
 from ..extern.six.moves import range
 from .. import conf
 
-from .misc import deprecated, isiterable
+from .decorators import deprecated
+from .misc import isiterable
 
 
 __all__ = [
@@ -81,7 +82,7 @@ _DEFAULT_ENCODING = 'utf-8'
 
 def _get_stdout(stderr=False):
     """
-    This utility fucntion contains the logic to determine what streams to use
+    This utility function contains the logic to determine what streams to use
     by default for standard out/err.
 
     Typically this will just return `sys.stdout`, but it contains additional
@@ -430,7 +431,7 @@ def human_file_size(size):
     size : str
         A human-friendly representation of the size of the file
     """
-    suffixes = ' kMGTPEH'
+    suffixes = ' kMGTPEZY'
     if size == 0:
         num_scale = 0
     else:
@@ -442,7 +443,9 @@ def human_file_size(size):
     num_scale = int(math.pow(1000, num_scale))
     value = size / num_scale
     str_value = str(value)
-    if str_value[2] == '.':
+    if suffix == ' ':
+        str_value = str_value[:str_value.index('.')]
+    elif str_value[2] == '.':
         str_value = str_value[:2]
     else:
         str_value = str_value[:3]
@@ -464,7 +467,7 @@ class ProgressBar(six.Iterator):
         for item in ProgressBar(items):
             item.process()
     """
-    def __init__(self, total_or_items, file=None):
+    def __init__(self, total_or_items, ipython_widget=False, file=None):
         """
         Parameters
         ----------
@@ -472,6 +475,10 @@ class ProgressBar(six.Iterator):
             If an int, the number of increments in the process being
             tracked.  If a sequence, the items to iterate over.
 
+        ipython_widget : bool, optional
+            If `True`, the progress bar will display as an IPython
+            notebook widget.
+
         file : writable file-like object, optional
             The file to write the progress bar to.  Defaults to
             `sys.stdout`.  If `file` is not a tty (as determined by
@@ -480,10 +487,16 @@ class ProgressBar(six.Iterator):
             completely silent.
         """
 
+        if ipython_widget:
+            # Import only if ipython_widget, i.e., widget in IPython
+            # notebook
+            from IPython.html import widgets
+            from IPython.display import display
+
         if file is None:
             file = _get_stdout()
 
-        if not isatty(file):
+        if not isatty(file) and not ipython_widget:
             self.update = self._silent_update
             self._silent = True
         else:
@@ -502,17 +515,19 @@ class ProgressBar(six.Iterator):
 
         self._file = file
         self._start_time = time.time()
+        self._human_total = human_file_size(self._total)
+        self._ipython_widget = ipython_widget
 
-        self._should_handle_resize = (
-            _CAN_RESIZE_TERMINAL and self._file.isatty())
-        self._handle_resize()
-        if self._should_handle_resize:
-            signal.signal(signal.SIGWINCH, self._handle_resize)
-            self._signal_set = True
-        else:
-            self._signal_set = False
 
-        self._human_total = human_file_size(self._total)
+        self._signal_set = False
+        if not ipython_widget:
+            self._should_handle_resize = (
+                _CAN_RESIZE_TERMINAL and self._file.isatty())
+            self._handle_resize()
+            if self._should_handle_resize:
+                signal.signal(signal.SIGWINCH, self._handle_resize)
+                self._signal_set = True
+
         self.update(0)
 
     def _handle_resize(self, signum=None, frame=None):
@@ -547,13 +562,26 @@ class ProgressBar(six.Iterator):
 
     def update(self, value=None):
         """
-        Update the progress bar to the given value (out of the total
-        given to the constructor).
+        Update progress bar via the console or notebook accordingly.
         """
+
+        # Update self.value
         if value is None:
-            value = self._current_value = self._current_value + 1
+            value = self._current_value + 1
+        self._current_value = value
+
+        # Choose the appropriate environment
+        if self._ipython_widget:
+            self._update_ipython_widget(value)
         else:
-            self._current_value = value
+            self._update_console(value)
+
+    def _update_console(self, value=None):
+        """
+        Update the progress bar to the given value (out of the total
+        given to the constructor).
+        """
+
         if self._total == 0:
             frac = 1.0
         else:
@@ -591,6 +619,31 @@ class ProgressBar(six.Iterator):
             write(human_time(t))
         self._file.flush()
 
+    def _update_ipython_widget(self, value=None):
+        """
+        Update the progress bar to the given value (out of a total
+        given to the constructor).
+
+        This method is for use in the IPython notebook 2+.
+        """
+
+        # Create and display an empty progress bar widget,
+        # if none exists.
+        if not hasattr(self, '_widget'):
+            # Import only if an IPython widget, i.e., widget in iPython NB
+            from IPython.html import widgets
+            from IPython.display import display
+
+            self._widget = widgets.FloatProgressWidget()
+            display(self._widget)
+            self._widget.value = 0
+
+        # Calculate percent completion, and update progress bar
+        percent = (value/self._total) * 100
+        self._widget.value = percent
+        self._widget.description =' ({0:>6s}%)'.format('{0:.2f}'.format(percent))
+
+
     def _silent_update(self, value=None):
         pass
 
@@ -651,40 +704,6 @@ class ProgressBar(six.Iterator):
 
         return results
 
-    @deprecated('0.3', alternative='ProgressBar')
-    @classmethod
-    def iterate(cls, items, file=None):
-        """
-        Iterate over a sequence while indicating progress with a progress
-        bar in the terminal.
-
-        ::
-
-            for item in ProgressBar.iterate(items):
-                pass
-
-        Parameters
-        ----------
-        items : sequence
-            A sequence of items to iterate over
-
-        file : writeable file-like object, optional
-            The file to write the progress bar to.  Defaults to
-            `sys.stdout`.  If `file` is not a tty (as determined by
-            calling its `isatty` member, if any), the scrollbar will
-            be completely silent.
-
-        Returns
-        -------
-        generator :
-            A generator over ``items``.
-        """
-
-        if file is None:
-            file = _get_stdout()
-
-        return cls(items, file=file)
-
 
 class Spinner(object):
     """
@@ -984,8 +1003,10 @@ class _GetchUnix(object):
     def __init__(self):
         import tty
         import sys
-        import termios  # import termios now or else you'll get the Unix
-                        # version on the Mac
+
+        # import termios now or else you'll get the Unix
+        # version on the Mac
+        import termios
 
     def __call__(self):
         import sys
diff --git a/astropy/utils/data.py b/astropy/utils/data.py
index 8d529bb..0507485 100644
--- a/astropy/utils/data.py
+++ b/astropy/utils/data.py
@@ -772,7 +772,7 @@ def _find_pkg_data_path(data_name):
     path.
     """
 
-    from ..utils.misc import find_current_module
+    from ..utils import find_current_module
 
     module = find_current_module(1, True)
     if module is None:
diff --git a/astropy/utils/decorators.py b/astropy/utils/decorators.py
new file mode 100644
index 0000000..d79ab9c
--- /dev/null
+++ b/astropy/utils/decorators.py
@@ -0,0 +1,573 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Sundry function and class decorators."""
+
+from __future__ import print_function
+
+
+import functools
+import inspect
+import sys
+import textwrap
+import types
+import warnings
+
+from .codegen import make_function_with_signature
+from .exceptions import (AstropyDeprecationWarning,
+                         AstropyPendingDeprecationWarning)
+from ..extern import six
+
+
+__all__ = ['deprecated', 'deprecated_attribute', 'lazyproperty',
+           'sharedmethod', 'wraps']
+
+
+def deprecated(since, message='', name='', alternative='', pending=False,
+               obj_type=None):
+    """
+    Used to mark a function or class as deprecated.
+
+    To mark an attribute as deprecated, use `deprecated_attribute`.
+
+    Parameters
+    ------------
+    since : str
+        The release at which this API became deprecated.  This is
+        required.
+
+    message : str, optional
+        Override the default deprecation message.  The format
+        specifier ``func`` may be used for the name of the function,
+        and ``alternative`` may be used in the deprecation message
+        to insert the name of an alternative to the deprecated
+        function. ``obj_type`` may be used to insert a friendly name
+        for the type of object being deprecated.
+
+    name : str, optional
+        The name of the deprecated function or class; if not provided
+        the name is automatically determined from the passed in
+        function or class, though this is useful in the case of
+        renamed functions, where the new function is just assigned to
+        the name of the deprecated function.  For example::
+
+            def new_function():
+                ...
+            oldFunction = new_function
+
+    alternative : str, optional
+        An alternative function or class name that the user may use in
+        place of the deprecated object.  The deprecation warning will
+        tell the user about this alternative if provided.
+
+    pending : bool, optional
+        If True, uses a AstropyPendingDeprecationWarning instead of a
+        AstropyDeprecationWarning.
+
+    obj_type : str, optional
+        The type of this object, if the automatically determined one
+        needs to be overridden.
+    """
+
+    method_types = (classmethod, staticmethod, types.MethodType)
+
+    def deprecate_doc(old_doc, message):
+        """
+        Returns a given docstring with a deprecation message prepended
+        to it.
+        """
+        if not old_doc:
+            old_doc = ''
+        old_doc = textwrap.dedent(old_doc).strip('\n')
+        new_doc = (('\n.. deprecated:: %(since)s'
+                    '\n    %(message)s\n\n' %
+                    {'since': since, 'message': message.strip()}) + old_doc)
+        if not old_doc:
+            # This is to prevent a spurious 'unexpected unindent' warning from
+            # docutils when the original docstring was blank.
+            new_doc += r'\ '
+        return new_doc
+
+    def get_function(func):
+        """
+        Given a function or classmethod (or other function wrapper type), get
+        the function object.
+        """
+        if isinstance(func, method_types):
+            try:
+                func = func.__func__
+            except AttributeError:
+                # classmethods in Python2.6 and below lack the __func__
+                # attribute so we need to hack around to get it
+                method = func.__get__(None, object)
+                if isinstance(method, types.FunctionType):
+                    # For staticmethods anyways the wrapped object is just a
+                    # plain function (not a bound method or anything like that)
+                    func = method
+                elif hasattr(method, '__func__'):
+                    func = method.__func__
+                elif hasattr(method, 'im_func'):
+                    func = method.im_func
+                else:
+                    # Nothing we can do really...  just return the original
+                    # classmethod, etc.
+                    return func
+        return func
+
+    def deprecate_function(func, message):
+        """
+        Returns a wrapped function that displays an
+        ``AstropyDeprecationWarning`` when it is called.
+        """
+
+        if isinstance(func, method_types):
+            func_wrapper = type(func)
+        else:
+            func_wrapper = lambda f: f
+
+        func = get_function(func)
+
+        def deprecated_func(*args, **kwargs):
+            if pending:
+                category = AstropyPendingDeprecationWarning
+            else:
+                category = AstropyDeprecationWarning
+
+            warnings.warn(message, category, stacklevel=2)
+
+            return func(*args, **kwargs)
+
+        # If this is an extension function, we can't call
+        # functools.wraps on it, but we normally don't care.
+        # This crazy way to get the type of a wrapper descriptor is
+        # straight out of the Python 3.3 inspect module docs.
+        if type(func) != type(str.__dict__['__add__']):
+            deprecated_func = functools.wraps(func)(deprecated_func)
+
+        deprecated_func.__doc__ = deprecate_doc(
+            deprecated_func.__doc__, message)
+
+        return func_wrapper(deprecated_func)
+
+    def deprecate_class(cls, message):
+        """
+        Returns a wrapper class with the docstrings updated and an
+        __init__ function that will raise an
+        ``AstropyDeprectationWarning`` warning when called.
+        """
+        # Creates a new class with the same name and bases as the
+        # original class, but updates the dictionary with a new
+        # docstring and a wrapped __init__ method.  __module__ needs
+        # to be manually copied over, since otherwise it will be set
+        # to *this* module (astropy.utils.misc).
+
+        # This approach seems to make Sphinx happy (the new class
+        # looks enough like the original class), and works with
+        # extension classes (which functools.wraps does not, since
+        # it tries to modify the original class).
+
+        # We need to add a custom pickler or you'll get
+        #     Can't pickle <class ..>: it's not found as ...
+        # errors. Picklability is required for any class that is
+        # documented by Sphinx.
+
+        members = cls.__dict__.copy()
+
+        members.update({
+            '__doc__': deprecate_doc(cls.__doc__, message),
+            '__init__': deprecate_function(get_function(cls.__init__),
+                                           message),
+        })
+
+        return type(cls.__name__, cls.__bases__, members)
+
+    def deprecate(obj, message=message, name=name, alternative=alternative,
+                  pending=pending):
+        if obj_type is None:
+            if isinstance(obj, type):
+                obj_type_name = 'class'
+            elif inspect.isfunction(obj):
+                obj_type_name = 'function'
+            elif inspect.ismethod(obj) or isinstance(obj, method_types):
+                obj_type_name = 'method'
+            else:
+                obj_type_name = 'object'
+        else:
+            obj_type_name = obj_type
+
+        if not name:
+            name = get_function(obj).__name__
+
+        altmessage = ''
+        if not message or type(message) == type(deprecate):
+            if pending:
+                message = ('The %(func)s %(obj_type)s will be deprecated in a '
+                           'future version.')
+            else:
+                message = ('The %(func)s %(obj_type)s is deprecated and may '
+                           'be removed in a future version.')
+            if alternative:
+                altmessage = '\n        Use %s instead.' % alternative
+
+        message = ((message % {
+            'func': name,
+            'name': name,
+            'alternative': alternative,
+            'obj_type': obj_type_name}) +
+            altmessage)
+
+        if isinstance(obj, type):
+            return deprecate_class(obj, message)
+        else:
+            return deprecate_function(obj, message)
+
+    if type(message) == type(deprecate):
+        return deprecate(message)
+
+    return deprecate
+
+
+def deprecated_attribute(name, since, message=None, alternative=None,
+                         pending=False):
+    """
+    Used to mark a public attribute as deprecated.  This creates a
+    property that will warn when the given attribute name is accessed.
+    To prevent the warning (i.e. for internal code), use the private
+    name for the attribute by prepending an underscore
+    (i.e. ``self._name``).
+
+    Parameters
+    ----------
+    name : str
+        The name of the deprecated attribute.
+
+    since : str
+        The release at which this API became deprecated.  This is
+        required.
+
+    message : str, optional
+        Override the default deprecation message.  The format
+        specifier ``name`` may be used for the name of the attribute,
+        and ``alternative`` may be used in the deprecation message
+        to insert the name of an alternative to the deprecated
+        function.
+
+    alternative : str, optional
+        An alternative attribute that the user may use in place of the
+        deprecated attribute.  The deprecation warning will tell the
+        user about this alternative if provided.
+
+    pending : bool, optional
+        If True, uses a AstropyPendingDeprecationWarning instead of a
+        AstropyDeprecationWarning.
+
+    Examples
+    --------
+
+    ::
+
+        class MyClass:
+            # Mark the old_name as deprecated
+            old_name = misc.deprecated_attribute('old_name', '0.1')
+
+            def method(self):
+                self._old_name = 42
+    """
+    private_name = '_' + name
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def get(self):
+        return getattr(self, private_name)
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def set(self, val):
+        setattr(self, private_name, val)
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def delete(self):
+        delattr(self, private_name)
+
+    return property(get, set, delete)
+
+
+class lazyproperty(object):
+    """
+    Works similarly to property(), but computes the value only once.
+
+    This essentially memorizes the value of the property by storing the result
+    of its computation in the ``__dict__`` of the object instance.  This is
+    useful for computing the value of some property that should otherwise be
+    invariant.  For example::
+
+        >>> class LazyTest(object):
+        ...     @lazyproperty
+        ...     def complicated_property(self):
+        ...         print('Computing the value for complicated_property...')
+        ...         return 42
+        ...
+        >>> lt = LazyTest()
+        >>> lt.complicated_property
+        Computing the value for complicated_property...
+        42
+        >>> lt.complicated_property
+        42
+
+    As the example shows, the second time ``complicated_property`` is accessed,
+    the ``print`` statement is not executed.  Only the return value from the
+    first access off ``complicated_property`` is returned.
+
+    If a setter for this property is defined, it will still be possible to
+    manually update the value of the property, if that capability is desired.
+
+    Adapted from the recipe at
+    http://code.activestate.com/recipes/363602-lazy-property-evaluation
+    """
+
+    def __init__(self, fget, fset=None, fdel=None, doc=None):
+        self._fget = fget
+        self._fset = fset
+        self._fdel = fdel
+        if doc is None:
+            self.__doc__ = fget.__doc__
+        else:
+            self.__doc__ = doc
+        self._key = self._fget.__name__
+
+    def __get__(self, obj, owner=None):
+        if obj is None:
+            return self
+        try:
+            return obj.__dict__[self._key]
+        except KeyError:
+            val = self._fget(obj)
+            obj.__dict__[self._key] = val
+            return val
+
+    def __set__(self, obj, val):
+        obj_dict = obj.__dict__
+        if self._fset:
+            ret = self._fset(obj, val)
+            if ret is not None and obj_dict.get(self._key) is ret:
+                # By returning the value set the setter signals that it took
+                # over setting the value in obj.__dict__; this mechanism allows
+                # it to override the input value
+                return
+        obj_dict[self._key] = val
+
+    def __delete__(self, obj):
+        if self._fdel:
+            self._fdel(obj)
+        if self._key in obj.__dict__:
+            del obj.__dict__[self._key]
+
+    def getter(self, fget):
+        return self.__ter(fget, 0)
+
+    def setter(self, fset):
+        return self.__ter(fset, 1)
+
+    def deleter(self, fdel):
+        return self.__ter(fdel, 2)
+
+    def __ter(self, f, arg):
+        args = [self._fget, self._fset, self._fdel, self.__doc__]
+        args[arg] = f
+        cls_ns = sys._getframe(1).f_locals
+        for k, v in six.iteritems(cls_ns):
+            if v is self:
+                property_name = k
+                break
+
+        cls_ns[property_name] = lazyproperty(*args)
+
+        return cls_ns[property_name]
+
+
+class sharedmethod(classmethod):
+    """
+    This is a method decorator that allows both an instancemethod and a
+    `classmethod` to share the same name.
+
+    When using `sharedmethod` on a method defined in a class's body, it
+    may be called on an instance, or on a class.  In the former case it
+    behaves like a normal instance method (a reference to the instance is
+    automatically passed as the first ``self`` argument of the method)::
+
+        >>> class Example(object):
+        ...     @sharedmethod
+        ...     def identify(self, *args):
+        ...         print('self was', self)
+        ...         print('additional args were', args)
+        ...
+        >>> ex = Example()
+        >>> ex.identify(1, 2)
+        self was <astropy.utils.decorators.Example object at 0x...>
+        additional args were (1, 2)
+
+    In the latter case, when the `sharedmethod` is called directly from a
+    class, it behaves like a `classmethod`::
+
+        >>> Example.identify(3, 4)
+        self was <class 'astropy.utils.decorators.Example'>
+        additional args were (3, 4)
+
+    This also supports a more advanced usage, where the `classmethod`
+    implementation can be written separately.  If the class's *metaclass*
+    has a method of the same name as the `sharedmethod`, the version on
+    the metaclass is delegated to::
+
+        >>> from astropy.extern.six import add_metaclass
+        >>> class ExampleMeta(type):
+        ...     def identify(self):
+        ...         print('this implements the {0}.identify '
+        ...               'classmethod'.format(self.__name__))
+        ...
+        >>> @add_metaclass(ExampleMeta)
+        ... class Example(object):
+        ...     @sharedmethod
+        ...     def identify(self):
+        ...         print('this implements the instancemethod')
+        ...
+        >>> Example().identify()
+        this implements the instancemethod
+        >>> Example.identify()
+        this implements the Example.identify classmethod
+    """
+
+    if sys.version_info[:2] < (2, 7):
+        # Workaround for Python 2.6 which does not have classmethod.__func__
+        @property
+        def __func__(self):
+            try:
+                meth = classmethod.__get__(self, self.__obj__,
+                                           self.__objtype__)
+            except AttributeError:
+                # self.__obj__ not set when called from __get__, but then it
+                # doesn't matter anyways
+                meth = classmethod.__get__(self, None, object)
+            return meth.__func__
+
+        def __getobjwrapper(orig_get):
+            """
+            Used to temporarily set/unset self.__obj__ and self.__objtype__
+            for use by __func__.
+            """
+            def __get__(self, obj, objtype=None):
+                self.__obj__ = obj
+                self.__objtype__ = objtype
+
+                try:
+                    return orig_get(self, obj, objtype)
+                finally:
+                    del self.__obj__
+                    del self.__objtype__
+
+            return __get__
+    else:
+        def __getobjwrapper(func):
+            return func
+
+    @__getobjwrapper
+    def __get__(self, obj, objtype=None):
+        if obj is None:
+            mcls = type(objtype)
+            clsmeth = getattr(mcls, self.__func__.__name__, None)
+            if callable(clsmeth):
+                if isinstance(clsmeth, types.MethodType):
+                    # This case will generally only apply on Python 2, which
+                    # uses MethodType for unbound methods; Python 3 has no
+                    # particular concept of unbound methods and will just
+                    # return a function
+                    func = clsmeth.__func__
+                else:
+                    func = clsmeth
+            else:
+                func = self.__func__
+
+            return self._make_method(func, objtype)
+        else:
+            return self._make_method(self.__func__, obj)
+
+    del __getobjwrapper
+
+    if six.PY3:
+        # The 'instancemethod' type of Python 2 and the method type of
+        # Python 3 have slightly different constructors
+        @staticmethod
+        def _make_method(func, instance):
+            return types.MethodType(func, instance)
+    else:
+        @staticmethod
+        def _make_method(func, instance):
+            return types.MethodType(func, instance, type(instance))
+
+
+def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+          updated=functools.WRAPPER_UPDATES):
+    """
+    An alternative to `functools.wraps` which also preserves the original
+    function's call signature by way of
+    `~astropy.utils.codegen.make_function_with_signature`.
+
+    The documentation for the original `functools.wraps` follows:
+
+    """
+
+    def wrapper(func):
+        func = make_function_with_signature(func, name=wrapped.__name__,
+                                            **_get_function_args(wrapped))
+        func = functools.update_wrapper(func, wrapped, assigned=assigned,
+                                        updated=updated)
+        return func
+
+    return wrapper
+
+
+wraps.__doc__ += functools.wraps.__doc__
+
+
+if six.PY3:
+    def _get_function_args(func):
+        """
+        Utility function for `wraps`.
+
+        Reads the argspec for the given function and converts it to arguments
+        for `make_function_with_signature`.  This requires different
+        implementations on Python 2 versus Python 3.
+        """
+
+        argspec = inspect.getfullargspec(func)
+
+        if argspec.defaults:
+            args = argspec.args[:-len(argspec.defaults)]
+            kwargs = zip(argspec.args[len(args):], argspec.defaults)
+        else:
+            args = argspec.args
+            kwargs = []
+
+        if argspec.kwonlyargs:
+            kwargs.extend((argname, argspec.kwonlydefaults[argname])
+                          for argname in argspec.kwonlyargs)
+
+        return {'args': args, 'kwargs': kwargs, 'varargs': argspec.varargs,
+                'varkwargs': argspec.varkw}
+else:
+    def _get_function_args(func):
+        """
+        Utility function for `wraps`.
+
+        Reads the argspec for the given function and converts it to arguments
+        for `make_function_with_signature`.  This requires different
+        implementations on Python 2 versus Python 3.
+        """
+
+        argspec = inspect.getargspec(func)
+
+        if argspec.defaults:
+            args = argspec.args[:-len(argspec.defaults)]
+            kwargs = zip(argspec.args[len(args):], argspec.defaults)
+        else:
+            args = argspec.args
+            kwargs = {}
+
+        return {'args': args, 'kwargs': kwargs, 'varargs': argspec.varargs,
+                'varkwargs': argspec.keywords}
diff --git a/astropy/utils/iers/data/eopc04_IAU2000.62-now b/astropy/utils/iers/data/eopc04_IAU2000.62-now
index 7c8e41a..cf7501a 100644
--- a/astropy/utils/iers/data/eopc04_IAU2000.62-now
+++ b/astropy/utils/iers/data/eopc04_IAU2000.62-now
@@ -18685,177 +18685,177 @@
 2013   2  12  56335   0.034936   0.323155   0.2267687   0.0013864   0.000187  -0.000076   0.000022   0.000030  0.0000059  0.0000067    0.000059    0.000073
 2013   2  13  56336   0.034437   0.324038   0.2254403   0.0012154   0.000197  -0.000057   0.000021   0.000035  0.0000012  0.0000066    0.000058    0.000072
 2013   2  14  56337   0.033839   0.324559   0.2242863   0.0010507   0.000219  -0.000002   0.000021   0.000038  0.0000162  0.0000070    0.000049    0.000063
-2013   2  15  56338   0.033896   0.325100   0.2232824   0.0009415   0.000245   0.000057   0.000019   0.000035  0.0000011  0.0000066    0.000037    0.000052
-2013   2  16  56339   0.033934   0.325933   0.2223836   0.0008336   0.000265   0.000057   0.000017   0.000032  0.0000189  0.0000062    0.000038    0.000053
-2013   2  17  56340   0.033677   0.326909   0.2215868   0.0007367   0.000282   0.000029   0.000019   0.000032  0.0000032  0.0000066    0.000042    0.000059
-2013   2  18  56341   0.033328   0.327848   0.2208980   0.0006401   0.000293  -0.000004   0.000019   0.000031  0.0000036  0.0000073    0.000049    0.000064
-2013   2  19  56342   0.033035   0.329142   0.2202777   0.0005919   0.000305  -0.000047   0.000019   0.000031  0.0000017  0.0000073    0.000053    0.000070
-2013   2  20  56343   0.032955   0.330293   0.2196491   0.0006588   0.000325  -0.000058   0.000020   0.000030  0.0000208  0.0000068    0.000056    0.000068
-2013   2  21  56344   0.032780   0.331394   0.2189361   0.0007661   0.000343  -0.000062   0.000020   0.000033  0.0000063  0.0000068    0.000059    0.000066
-2013   2  22  56345   0.032543   0.332411   0.2180799   0.0009389   0.000356  -0.000067   0.000022   0.000035  0.0000013  0.0000076    0.000062    0.000065
-2013   2  23  56346   0.032034   0.333397   0.2170537   0.0011245   0.000351  -0.000100   0.000022   0.000035  0.0000360  0.0000080    0.000061    0.000063
-2013   2  24  56347   0.031539   0.334330   0.2158533   0.0012915   0.000334  -0.000139   0.000022   0.000033  0.0000035  0.0000076    0.000060    0.000061
-2013   2  25  56348   0.030708   0.334905   0.2144766   0.0014607   0.000295  -0.000159   0.000023   0.000032  0.0000033  0.0000073    0.000057    0.000059
-2013   2  26  56349   0.029717   0.335104   0.2129240   0.0016352   0.000270  -0.000190   0.000023   0.000032  0.0000013  0.0000073    0.000056    0.000057
-2013   2  27  56350   0.029301   0.335794   0.2112407   0.0017303   0.000283  -0.000207   0.000028   0.000037  0.0000210  0.0000076    0.000064    0.000063
-2013   2  28  56351   0.029608   0.336794   0.2094895   0.0017399   0.000305  -0.000217   0.000028   0.000037  0.0000062  0.0000076    0.000074    0.000071
-2013   3   1  56352   0.030228   0.338132   0.2077371   0.0017242   0.000325  -0.000220   0.000028   0.000041  0.0000015  0.0000076    0.000084    0.000080
-2013   3   2  56353   0.030504   0.339745   0.2060790   0.0015855   0.000322  -0.000235   0.000026   0.000041  0.0000141  0.0000072    0.000100    0.000105
-2013   3   3  56354   0.030835   0.341230   0.2045416   0.0014922   0.000305  -0.000248   0.000026   0.000041  0.0000035  0.0000080    0.000118    0.000136
-2013   3   4  56355   0.031168   0.342793   0.2030631   0.0014730   0.000280  -0.000253   0.000023   0.000039  0.0000035  0.0000086    0.000138    0.000171
-2013   3   5  56356   0.031606   0.343977   0.2015976   0.0014735   0.000249  -0.000247   0.000023   0.000036  0.0000022  0.0000082    0.000156    0.000203
-2013   3   6  56357   0.032057   0.344980   0.2001138   0.0015136   0.000208  -0.000183   0.000021   0.000036  0.0000104  0.0000083    0.000134    0.000179
-2013   3   7  56358   0.032966   0.345676   0.1985635   0.0016159   0.000164  -0.000104   0.000021   0.000040  0.0000040  0.0000087    0.000103    0.000142
-2013   3   8  56359   0.034227   0.346404   0.1969090   0.0017065   0.000121  -0.000025   0.000021   0.000036  0.0000016  0.0000087    0.000072    0.000106
-2013   3   9  56360   0.035556   0.347362   0.1951480   0.0018239   0.000115   0.000018   0.000019   0.000033  0.0000151  0.0000083    0.000065    0.000095
-2013   3  10  56361   0.036631   0.348518   0.1932916   0.0019075   0.000127   0.000042   0.000019   0.000036  0.0000029  0.0000083    0.000067    0.000094
-2013   3  11  56362   0.037671   0.349957   0.1913827   0.0019055   0.000170   0.000068   0.000020   0.000037  0.0000062  0.0000084    0.000069    0.000094
-2013   3  12  56363   0.038804   0.351869   0.1894875   0.0018686   0.000194   0.000074   0.000018   0.000033  0.0000067  0.0000077    0.000071    0.000092
-2013   3  13  56364   0.039868   0.354087   0.1876517   0.0017802   0.000210   0.000075   0.000018   0.000034  0.0000012  0.0000075    0.000074    0.000092
-2013   3  14  56365   0.040502   0.355956   0.1859185   0.0016696   0.000240   0.000018   0.000018   0.000034  0.0000145  0.0000075    0.000066    0.000081
-2013   3  15  56366   0.040922   0.357387   0.1843097   0.0015444   0.000265  -0.000054   0.000016   0.000034  0.0000013  0.0000075    0.000056    0.000068
-2013   3  16  56367   0.040917   0.358605   0.1828274   0.0014094   0.000286  -0.000105   0.000018   0.000034  0.0000139  0.0000079    0.000059    0.000072
-2013   3  17  56368   0.041048   0.359554   0.1814609   0.0013064   0.000298  -0.000144   0.000020   0.000037  0.0000031  0.0000082    0.000067    0.000083
-2013   3  18  56369   0.041612   0.360244   0.1801933   0.0012257   0.000292  -0.000172   0.000022   0.000046  0.0000032  0.0000084    0.000075    0.000095
-2013   3  19  56370   0.042497   0.360690   0.1790038   0.0011488   0.000286  -0.000190   0.000022   0.000046  0.0000016  0.0000085    0.000083    0.000106
-2013   3  20  56371   0.043576   0.361269   0.1778524   0.0011518   0.000259  -0.000174   0.000021   0.000042  0.0000182  0.0000087    0.000074    0.000093
-2013   3  21  56372   0.044658   0.362180   0.1766940   0.0011941   0.000224  -0.000143   0.000021   0.000042  0.0000076  0.0000087    0.000062    0.000077
-2013   3  22  56373   0.045163   0.363185   0.1754806   0.0012650   0.000190  -0.000108   0.000021   0.000042  0.0000011  0.0000084    0.000050    0.000061
-2013   3  23  56374   0.045712   0.364433   0.1741466   0.0014234   0.000183  -0.000078   0.000021   0.000039  0.0000124  0.0000084    0.000044    0.000055
-2013   3  24  56375   0.046523   0.365546   0.1726579   0.0015763   0.000190  -0.000055   0.000021   0.000039  0.0000033  0.0000084    0.000041    0.000053
-2013   3  25  56376   0.047532   0.366900   0.1710171   0.0017087   0.000199  -0.000040   0.000024   0.000040  0.0000034  0.0000082    0.000032    0.000047
-2013   3  26  56377   0.048050   0.368190   0.1692350   0.0018537   0.000216  -0.000038   0.000024   0.000036  0.0000012  0.0000082    0.000030    0.000045
-2013   3  27  56378   0.048646   0.369461   0.1673193   0.0019571   0.000193  -0.000101   0.000024   0.000032  0.0000003  0.0000081    0.000035    0.000051
-2013   3  28  56379   0.049544   0.370878   0.1653462   0.0019493   0.000200  -0.000151   0.000021   0.000032  0.0000132  0.0000081    0.000035    0.000052
-2013   3  29  56380   0.050462   0.372076   0.1634083   0.0018880   0.000223  -0.000192   0.000021   0.000032  0.0000098  0.0000081    0.000034    0.000049
-2013   3  30  56381   0.051044   0.373287   0.1615621   0.0017866   0.000244  -0.000229   0.000021   0.000032  0.0000066  0.0000081    0.000032    0.000047
-2013   3  31  56382   0.051411   0.374395   0.1598229   0.0016822   0.000261  -0.000258   0.000021   0.000032  0.0000034  0.0000081    0.000031    0.000045
+2013   2  15  56338   0.033897   0.325100   0.2232824   0.0009415   0.000245   0.000057   0.000019   0.000035  0.0000011  0.0000066    0.000037    0.000052
+2013   2  16  56339   0.033941   0.325933   0.2223836   0.0008336   0.000265   0.000057   0.000017   0.000032  0.0000189  0.0000062    0.000038    0.000053
+2013   2  17  56340   0.033665   0.326909   0.2215868   0.0007367   0.000282   0.000029   0.000019   0.000032  0.0000032  0.0000066    0.000042    0.000059
+2013   2  18  56341   0.033343   0.327848   0.2208980   0.0006401   0.000293  -0.000004   0.000019   0.000031  0.0000036  0.0000073    0.000049    0.000064
+2013   2  19  56342   0.033016   0.329142   0.2202777   0.0005919   0.000305  -0.000047   0.000019   0.000031  0.0000017  0.0000073    0.000053    0.000070
+2013   2  20  56343   0.032971   0.330293   0.2196491   0.0006588   0.000325  -0.000058   0.000020   0.000030  0.0000208  0.0000068    0.000056    0.000068
+2013   2  21  56344   0.032764   0.331394   0.2189361   0.0007661   0.000343  -0.000062   0.000020   0.000033  0.0000063  0.0000068    0.000059    0.000066
+2013   2  22  56345   0.032560   0.332411   0.2180799   0.0009389   0.000356  -0.000067   0.000022   0.000035  0.0000013  0.0000076    0.000062    0.000065
+2013   2  23  56346   0.032021   0.333397   0.2170537   0.0011245   0.000351  -0.000100   0.000022   0.000035  0.0000360  0.0000080    0.000061    0.000063
+2013   2  24  56347   0.031547   0.334330   0.2158533   0.0012915   0.000334  -0.000139   0.000022   0.000033  0.0000035  0.0000076    0.000060    0.000061
+2013   2  25  56348   0.030709   0.334905   0.2144766   0.0014607   0.000295  -0.000159   0.000023   0.000032  0.0000033  0.0000073    0.000057    0.000059
+2013   2  26  56349   0.029709   0.335104   0.2129240   0.0016352   0.000270  -0.000190   0.000023   0.000032  0.0000013  0.0000073    0.000056    0.000057
+2013   2  27  56350   0.029307   0.335794   0.2112407   0.0017303   0.000283  -0.000207   0.000028   0.000037  0.0000210  0.0000076    0.000064    0.000063
+2013   2  28  56351   0.029597   0.336794   0.2094895   0.0017399   0.000305  -0.000217   0.000028   0.000037  0.0000062  0.0000076    0.000074    0.000071
+2013   3   1  56352   0.030243   0.338132   0.2077371   0.0017242   0.000325  -0.000220   0.000028   0.000041  0.0000015  0.0000076    0.000084    0.000080
+2013   3   2  56353   0.030488   0.339745   0.2060790   0.0015855   0.000322  -0.000235   0.000026   0.000041  0.0000141  0.0000072    0.000100    0.000105
+2013   3   3  56354   0.030848   0.341230   0.2045416   0.0014922   0.000305  -0.000248   0.000026   0.000041  0.0000035  0.0000080    0.000118    0.000136
+2013   3   4  56355   0.031163   0.342793   0.2030631   0.0014730   0.000280  -0.000253   0.000023   0.000039  0.0000035  0.0000086    0.000138    0.000171
+2013   3   5  56356   0.031611   0.343977   0.2015976   0.0014735   0.000249  -0.000247   0.000023   0.000036  0.0000022  0.0000082    0.000156    0.000203
+2013   3   6  56357   0.032058   0.344980   0.2001138   0.0015136   0.000208  -0.000183   0.000021   0.000036  0.0000104  0.0000083    0.000134    0.000179
+2013   3   7  56358   0.032962   0.345676   0.1985635   0.0016159   0.000164  -0.000104   0.000021   0.000040  0.0000040  0.0000087    0.000103    0.000142
+2013   3   8  56359   0.034232   0.346404   0.1969090   0.0017065   0.000121  -0.000025   0.000021   0.000036  0.0000016  0.0000087    0.000072    0.000106
+2013   3   9  56360   0.035551   0.347362   0.1951480   0.0018239   0.000115   0.000018   0.000019   0.000033  0.0000151  0.0000083    0.000065    0.000095
+2013   3  10  56361   0.036634   0.348518   0.1932916   0.0019075   0.000127   0.000042   0.000019   0.000036  0.0000029  0.0000083    0.000067    0.000094
+2013   3  11  56362   0.037679   0.349957   0.1913827   0.0019055   0.000170   0.000068   0.000020   0.000037  0.0000062  0.0000084    0.000069    0.000094
+2013   3  12  56363   0.038791   0.351869   0.1894875   0.0018686   0.000194   0.000074   0.000018   0.000033  0.0000067  0.0000077    0.000071    0.000092
+2013   3  13  56364   0.039884   0.354087   0.1876517   0.0017802   0.000210   0.000075   0.000018   0.000034  0.0000012  0.0000075    0.000074    0.000092
+2013   3  14  56365   0.040481   0.355956   0.1859185   0.0016696   0.000240   0.000018   0.000018   0.000034  0.0000145  0.0000075    0.000066    0.000081
+2013   3  15  56366   0.040942   0.357387   0.1843097   0.0015444   0.000265  -0.000054   0.000016   0.000034  0.0000013  0.0000075    0.000056    0.000068
+2013   3  16  56367   0.040901   0.358605   0.1828274   0.0014094   0.000286  -0.000105   0.000018   0.000034  0.0000139  0.0000079    0.000059    0.000072
+2013   3  17  56368   0.041061   0.359554   0.1814609   0.0013064   0.000298  -0.000144   0.000020   0.000037  0.0000031  0.0000082    0.000067    0.000083
+2013   3  18  56369   0.041602   0.360244   0.1801933   0.0012257   0.000292  -0.000172   0.000022   0.000046  0.0000032  0.0000084    0.000075    0.000095
+2013   3  19  56370   0.042509   0.360690   0.1790038   0.0011488   0.000286  -0.000190   0.000022   0.000046  0.0000016  0.0000085    0.000083    0.000106
+2013   3  20  56371   0.043558   0.361269   0.1778524   0.0011518   0.000259  -0.000174   0.000021   0.000042  0.0000182  0.0000087    0.000074    0.000093
+2013   3  21  56372   0.044679   0.362180   0.1766940   0.0011941   0.000224  -0.000143   0.000021   0.000042  0.0000076  0.0000087    0.000062    0.000077
+2013   3  22  56373   0.045142   0.363185   0.1754806   0.0012650   0.000190  -0.000108   0.000021   0.000042  0.0000011  0.0000084    0.000050    0.000061
+2013   3  23  56374   0.045731   0.364433   0.1741466   0.0014234   0.000183  -0.000078   0.000021   0.000039  0.0000124  0.0000084    0.000044    0.000055
+2013   3  24  56375   0.046501   0.365546   0.1726579   0.0015763   0.000190  -0.000055   0.000021   0.000039  0.0000033  0.0000084    0.000041    0.000053
+2013   3  25  56376   0.047553   0.366900   0.1710171   0.0017087   0.000199  -0.000040   0.000024   0.000040  0.0000034  0.0000082    0.000032    0.000047
+2013   3  26  56377   0.048035   0.368190   0.1692350   0.0018537   0.000216  -0.000038   0.000024   0.000036  0.0000012  0.0000082    0.000030    0.000045
+2013   3  27  56378   0.048658   0.369461   0.1673193   0.0019571   0.000193  -0.000101   0.000024   0.000032  0.0000003  0.0000081    0.000035    0.000051
+2013   3  28  56379   0.049532   0.370878   0.1653462   0.0019493   0.000200  -0.000151   0.000021   0.000032  0.0000132  0.0000081    0.000035    0.000052
+2013   3  29  56380   0.050475   0.372076   0.1634083   0.0018880   0.000223  -0.000192   0.000021   0.000032  0.0000098  0.0000081    0.000034    0.000049
+2013   3  30  56381   0.051030   0.373287   0.1615621   0.0017866   0.000244  -0.000229   0.000021   0.000032  0.0000066  0.0000081    0.000032    0.000047
+2013   3  31  56382   0.051422   0.374395   0.1598229   0.0016822   0.000261  -0.000258   0.000021   0.000032  0.0000034  0.0000081    0.000031    0.000045
 2013   4   1  56383   0.051214   0.375299   0.1581763   0.0016152   0.000265  -0.000273   0.000023   0.000033  0.0000032  0.0000089    0.000029    0.000044
-2013   4   2  56384   0.050905   0.376037   0.1565882   0.0015642   0.000270  -0.000279   0.000023   0.000033  0.0000026  0.0000089    0.000028    0.000042
-2013   4   3  56385   0.050998   0.376745   0.1550193   0.0015665   0.000269  -0.000274   0.000020   0.000029  0.0000009  0.0000079    0.000027    0.000039
-2013   4   4  56386   0.051506   0.377383   0.1534214   0.0016313   0.000196  -0.000196   0.000020   0.000029  0.0000126  0.0000083    0.000029    0.000039
+2013   4   2  56384   0.050902   0.376037   0.1565882   0.0015642   0.000270  -0.000279   0.000023   0.000033  0.0000026  0.0000089    0.000028    0.000042
+2013   4   3  56385   0.051000   0.376745   0.1550193   0.0015665   0.000269  -0.000274   0.000020   0.000029  0.0000009  0.0000079    0.000027    0.000039
+2013   4   4  56386   0.051505   0.377383   0.1534214   0.0016313   0.000196  -0.000196   0.000020   0.000029  0.0000126  0.0000083    0.000029    0.000039
 2013   4   5  56387   0.052276   0.378082   0.1517328   0.0017658   0.000107  -0.000098   0.000020   0.000029  0.0000010  0.0000083    0.000033    0.000039
-2013   4   6  56388   0.052841   0.378754   0.1499249   0.0018676   0.000119  -0.000077   0.000018   0.000029  0.0000128  0.0000079    0.000030    0.000034
-2013   4   7  56389   0.053136   0.379352   0.1480361   0.0019019   0.000172  -0.000088   0.000018   0.000029  0.0000034  0.0000080    0.000023    0.000027
-2013   4   8  56390   0.053553   0.380052   0.1461365   0.0018727   0.000211  -0.000095   0.000023   0.000031  0.0000034  0.0000084    0.000017    0.000021
-2013   4   9  56391   0.054123   0.381208   0.1442935   0.0018016   0.000268  -0.000118   0.000026   0.000031  0.0000010  0.0000088    0.000010    0.000014
-2013   4  10  56392   0.054952   0.382367   0.1425544   0.0016754   0.000296  -0.000136   0.000023   0.000035  0.0000162  0.0000093    0.000017    0.000026
-2013   4  11  56393   0.055466   0.383473   0.1409548   0.0015061   0.000316  -0.000154   0.000023   0.000035  0.0000078  0.0000087    0.000027    0.000043
-2013   4  12  56394   0.055501   0.384248   0.1395110   0.0013579   0.000331  -0.000175   0.000023   0.000032  0.0000012  0.0000079    0.000037    0.000060
-2013   4  13  56395   0.055469   0.385068   0.1382134   0.0012326   0.000331  -0.000180   0.000023   0.000031  0.0000235  0.0000081    0.000048    0.000076
-2013   4  14  56396   0.055481   0.385646   0.1370305   0.0011411   0.000322  -0.000178   0.000023   0.000031  0.0000040  0.0000085    0.000060    0.000092
-2013   4  15  56397   0.055611   0.386035   0.1359184   0.0010907   0.000303  -0.000168   0.000025   0.000034  0.0000037  0.0000092    0.000072    0.000108
-2013   4  16  56398   0.055924   0.386392   0.1348169   0.0011174   0.000284  -0.000162   0.000025   0.000034  0.0000026  0.0000087    0.000084    0.000124
-2013   4  17  56399   0.056513   0.386975   0.1336791   0.0011618   0.000261  -0.000156   0.000022   0.000034  0.0000017  0.0000082    0.000105    0.000143
-2013   4  18  56400   0.057539   0.387547   0.1325125   0.0011964   0.000282  -0.000164   0.000019   0.000034  0.0000119  0.0000082    0.000080    0.000106
-2013   4  19  56401   0.058626   0.388699   0.1312775   0.0013092   0.000313  -0.000175   0.000019   0.000034  0.0000011  0.0000078    0.000045    0.000055
-2013   4  20  56402   0.059409   0.389916   0.1298980   0.0014732   0.000321  -0.000214   0.000022   0.000034  0.0000146  0.0000078    0.000037    0.000043
-2013   4  21  56403   0.060033   0.390944   0.1283636   0.0015956   0.000316  -0.000260   0.000022   0.000034  0.0000033  0.0000078    0.000039    0.000046
-2013   4  22  56404   0.061029   0.391927   0.1267085   0.0017050   0.000300  -0.000284   0.000018   0.000033  0.0000031  0.0000082    0.000040    0.000050
-2013   4  23  56405   0.062006   0.392789   0.1249559   0.0018000   0.000282  -0.000319   0.000016   0.000031  0.0000010  0.0000086    0.000042    0.000053
-2013   4  24  56406   0.062986   0.393349   0.1231388   0.0018280   0.000248  -0.000337   0.000019   0.000029  0.0000225  0.0000081    0.000094    0.000134
-2013   4  25  56407   0.063896   0.393885   0.1213194   0.0017907   0.000207  -0.000347   0.000022   0.000029  0.0000051  0.0000077    0.000160    0.000234
-2013   4  26  56408   0.064797   0.394217   0.1195726   0.0016971   0.000164  -0.000350   0.000024   0.000029  0.0000029  0.0000081    0.000226    0.000335
-2013   4  27  56409   0.065668   0.394751   0.1179550   0.0015370   0.000139  -0.000354   0.000024   0.000029  0.0000110  0.0000089    0.000206    0.000306
-2013   4  28  56410   0.066128   0.395232   0.1164902   0.0013879   0.000123  -0.000354   0.000024   0.000029  0.0000036  0.0000089    0.000156    0.000229
-2013   4  29  56411   0.066910   0.395496   0.1151226   0.0013580   0.000082  -0.000312   0.000022   0.000033  0.0000031  0.0000086    0.000103    0.000153
-2013   4  30  56412   0.067944   0.395987   0.1137639   0.0013742   0.000071  -0.000293   0.000020   0.000033  0.0000012  0.0000081    0.000051    0.000077
+2013   4   6  56388   0.052845   0.378754   0.1499249   0.0018676   0.000119  -0.000077   0.000018   0.000029  0.0000128  0.0000079    0.000030    0.000034
+2013   4   7  56389   0.053129   0.379352   0.1480361   0.0019019   0.000172  -0.000088   0.000018   0.000029  0.0000034  0.0000080    0.000023    0.000027
+2013   4   8  56390   0.053558   0.380052   0.1461365   0.0018727   0.000211  -0.000095   0.000023   0.000031  0.0000034  0.0000084    0.000017    0.000021
+2013   4   9  56391   0.054118   0.381208   0.1442935   0.0018016   0.000268  -0.000118   0.000026   0.000031  0.0000010  0.0000088    0.000010    0.000014
+2013   4  10  56392   0.054958   0.382367   0.1425544   0.0016754   0.000296  -0.000136   0.000023   0.000035  0.0000162  0.0000093    0.000017    0.000026
+2013   4  11  56393   0.055463   0.383473   0.1409548   0.0015061   0.000316  -0.000154   0.000023   0.000035  0.0000078  0.0000087    0.000027    0.000043
+2013   4  12  56394   0.055503   0.384248   0.1395110   0.0013579   0.000331  -0.000175   0.000023   0.000032  0.0000012  0.0000079    0.000037    0.000060
+2013   4  13  56395   0.055466   0.385068   0.1382134   0.0012326   0.000331  -0.000180   0.000023   0.000031  0.0000235  0.0000081    0.000048    0.000076
+2013   4  14  56396   0.055484   0.385646   0.1370305   0.0011411   0.000322  -0.000178   0.000023   0.000031  0.0000040  0.0000085    0.000060    0.000092
+2013   4  15  56397   0.055607   0.386035   0.1359184   0.0010907   0.000303  -0.000168   0.000025   0.000034  0.0000037  0.0000092    0.000072    0.000108
+2013   4  16  56398   0.055929   0.386392   0.1348169   0.0011174   0.000284  -0.000162   0.000025   0.000034  0.0000026  0.0000087    0.000084    0.000124
+2013   4  17  56399   0.056522   0.386975   0.1336791   0.0011618   0.000261  -0.000156   0.000022   0.000034  0.0000017  0.0000082    0.000105    0.000143
+2013   4  18  56400   0.057528   0.387547   0.1325125   0.0011964   0.000282  -0.000164   0.000019   0.000034  0.0000119  0.0000082    0.000080    0.000106
+2013   4  19  56401   0.058638   0.388699   0.1312775   0.0013092   0.000313  -0.000175   0.000019   0.000034  0.0000011  0.0000078    0.000045    0.000055
+2013   4  20  56402   0.059400   0.389916   0.1298980   0.0014732   0.000321  -0.000214   0.000022   0.000034  0.0000146  0.0000078    0.000037    0.000043
+2013   4  21  56403   0.060039   0.390944   0.1283636   0.0015956   0.000316  -0.000260   0.000022   0.000034  0.0000033  0.0000078    0.000039    0.000046
+2013   4  22  56404   0.061024   0.391927   0.1267085   0.0017050   0.000300  -0.000284   0.000018   0.000033  0.0000031  0.0000082    0.000040    0.000050
+2013   4  23  56405   0.062011   0.392789   0.1249559   0.0018000   0.000282  -0.000319   0.000016   0.000031  0.0000010  0.0000086    0.000042    0.000053
+2013   4  24  56406   0.062979   0.393349   0.1231388   0.0018280   0.000248  -0.000337   0.000019   0.000029  0.0000225  0.0000081    0.000094    0.000134
+2013   4  25  56407   0.063907   0.393885   0.1213194   0.0017907   0.000207  -0.000347   0.000022   0.000029  0.0000051  0.0000077    0.000160    0.000234
+2013   4  26  56408   0.064780   0.394217   0.1195726   0.0016971   0.000164  -0.000350   0.000024   0.000029  0.0000029  0.0000081    0.000226    0.000335
+2013   4  27  56409   0.065690   0.394751   0.1179550   0.0015370   0.000139  -0.000354   0.000024   0.000029  0.0000110  0.0000089    0.000206    0.000306
+2013   4  28  56410   0.066110   0.395232   0.1164902   0.0013879   0.000123  -0.000354   0.000024   0.000029  0.0000036  0.0000089    0.000156    0.000229
+2013   4  29  56411   0.066926   0.395496   0.1151226   0.0013580   0.000082  -0.000312   0.000022   0.000033  0.0000031  0.0000086    0.000103    0.000153
+2013   4  30  56412   0.067935   0.395987   0.1137639   0.0013742   0.000071  -0.000293   0.000020   0.000033  0.0000012  0.0000081    0.000051    0.000077
 2013   5   1  56413   0.069079   0.396187   0.1123734   0.0014241   0.000058  -0.000278   0.000018   0.000031  0.0000133  0.0000077    0.000042    0.000066
-2013   5   2  56414   0.070598   0.396865   0.1108968   0.0015399   0.000051  -0.000261   0.000020   0.000031  0.0000025  0.0000081    0.000044    0.000072
-2013   5   3  56415   0.072196   0.397607   0.1092979   0.0016617   0.000051  -0.000241   0.000022   0.000031  0.0000013  0.0000081    0.000046    0.000078
-2013   5   4  56416   0.073931   0.398142   0.1076280   0.0017014   0.000062  -0.000202   0.000020   0.000031  0.0000133  0.0000077    0.000047    0.000077
+2013   5   2  56414   0.070601   0.396865   0.1108968   0.0015399   0.000051  -0.000261   0.000020   0.000031  0.0000025  0.0000081    0.000044    0.000072
+2013   5   3  56415   0.072194   0.397607   0.1092979   0.0016617   0.000051  -0.000241   0.000022   0.000031  0.0000013  0.0000081    0.000046    0.000078
+2013   5   4  56416   0.073934   0.398142   0.1076280   0.0017014   0.000062  -0.000202   0.000020   0.000031  0.0000133  0.0000077    0.000047    0.000077
 2013   5   5  56417   0.075382   0.398690   0.1059460   0.0016757   0.000080  -0.000156   0.000020   0.000031  0.0000024  0.0000077    0.000047    0.000073
-2013   5   6  56418   0.076730   0.399162   0.1042827   0.0016511   0.000098  -0.000109   0.000021   0.000033  0.0000053  0.0000084    0.000047    0.000069
-2013   5   7  56419   0.077713   0.399520   0.1026651   0.0015729   0.000123  -0.000072   0.000021   0.000033  0.0000059  0.0000084    0.000047    0.000065
-2013   5   8  56420   0.078800   0.399676   0.1011258   0.0014570   0.000147  -0.000041   0.000020   0.000032  0.0000013  0.0000077    0.000045    0.000059
-2013   5   9  56421   0.080181   0.400159   0.0997499   0.0012809   0.000097  -0.000090   0.000017   0.000032  0.0000136  0.0000073    0.000084    0.000101
-2013   5  10  56422   0.081796   0.400479   0.0985505   0.0011247   0.000028  -0.000164   0.000020   0.000032  0.0000021  0.0000077    0.000131    0.000156
-2013   5  11  56423   0.084201   0.400858   0.0974696   0.0010228   0.000054  -0.000180   0.000022   0.000032  0.0000131  0.0000081    0.000127    0.000151
-2013   5  12  56424   0.086355   0.401440   0.0964810   0.0009413   0.000114  -0.000173   0.000020   0.000032  0.0000031  0.0000077    0.000102    0.000123
-2013   5  13  56425   0.088272   0.402161   0.0955606   0.0009037   0.000166  -0.000149   0.000022   0.000032  0.0000034  0.0000079    0.000082    0.000103
-2013   5  14  56426   0.089509   0.403203   0.0946677   0.0009035   0.000218  -0.000142   0.000024   0.000032  0.0000015  0.0000078    0.000056    0.000073
-2013   5  15  56427   0.090692   0.403960   0.0937434   0.0009546   0.000183  -0.000224   0.000022   0.000033  0.0000164  0.0000073    0.000054    0.000075
-2013   5  16  56428   0.091140   0.404564   0.0927334   0.0010329   0.000124  -0.000325   0.000022   0.000033  0.0000061  0.0000077    0.000059    0.000088
-2013   5  17  56429   0.091633   0.404720   0.0916057   0.0011913   0.000062  -0.000418   0.000022   0.000033  0.0000013  0.0000077    0.000063    0.000101
-2013   5  18  56430   0.092305   0.404886   0.0903432   0.0013154   0.000089  -0.000442   0.000022   0.000033  0.0000170  0.0000077    0.000063    0.000100
-2013   5  19  56431   0.093357   0.404814   0.0889580   0.0014222   0.000152  -0.000430   0.000024   0.000033  0.0000031  0.0000077    0.000062    0.000093
-2013   5  20  56432   0.094835   0.404856   0.0874807   0.0015032   0.000109  -0.000393   0.000020   0.000030  0.0000031  0.0000070    0.000128    0.000171
-2013   5  21  56433   0.096650   0.405103   0.0859534   0.0015170   0.000129  -0.000354   0.000020   0.000030  0.0000026  0.0000070    0.000152    0.000195
-2013   5  22  56434   0.098108   0.405783   0.0844501   0.0014488   0.000145  -0.000310   0.000021   0.000027  0.0000040  0.0000072    0.000171    0.000218
-2013   5  23  56435   0.099430   0.406575   0.0830146   0.0013755   0.000149  -0.000249   0.000021   0.000027  0.0001122  0.0000072    0.000146    0.000196
-2013   5  24  56436   0.100669   0.407104   0.0817241   0.0012537   0.000145  -0.000186   0.000019   0.000027  0.0000018  0.0000069    0.000109    0.000162
-2013   5  25  56437   0.101490   0.407171   0.0805331   0.0011307   0.000106  -0.000193   0.000017   0.000027  0.0000250  0.0000069    0.000101    0.000154
-2013   5  26  56438   0.102327   0.407199   0.0794448   0.0010336   0.000053  -0.000224   0.000304   0.000234  0.0000054  0.0000236    0.000105    0.000156
-2013   5  27  56439   0.102864   0.407246   0.0784812   0.0009137  -0.000009  -0.000245   0.000026   0.000030  0.0000031  0.0000075    0.000114    0.000159
-2013   5  28  56440   0.103517   0.407139   0.0775747   0.0009094  -0.000057  -0.000278   0.000026   0.000034  0.0000026  0.0000075    0.000118    0.000161
-2013   5  29  56441   0.104118   0.407196   0.0766735   0.0009130  -0.000094  -0.000310   0.000025   0.000032  0.0000019  0.0000073    0.000118    0.000153
-2013   5  30  56442   0.104913   0.407053   0.0757525   0.0009351  -0.000087  -0.000262   0.000028   0.000031  0.0000112  0.0000077    0.000107    0.000133
-2013   5  31  56443   0.106353   0.406900   0.0748141   0.0009118  -0.000059  -0.000192   0.000028   0.000031  0.0000016  0.0000077    0.000092    0.000107
-2013   6   1  56444   0.108309   0.406628   0.0739569   0.0008131  -0.000001  -0.000158   0.000028   0.000031  0.0000081  0.0000077    0.000084    0.000096
-2013   6   2  56445   0.110225   0.406481   0.0732060   0.0007016   0.000068  -0.000139   0.000028   0.000031  0.0000030  0.0000077    0.000077    0.000091
-2013   6   3  56446   0.111846   0.406343   0.0725254   0.0006471   0.000136  -0.000127   0.000023   0.000030  0.0000029  0.0000074    0.000071    0.000086
-2013   6   4  56447   0.113256   0.405956   0.0719147   0.0005507   0.000197  -0.000121   0.000023   0.000030  0.0000013  0.0000074    0.000064    0.000081
-2013   6   5  56448   0.114176   0.405386   0.0714299   0.0004190   0.000151  -0.000152   0.000022   0.000028  0.0000174  0.0000072    0.000062    0.000085
-2013   6   6  56449   0.114605   0.404595   0.0710683   0.0003198   0.000072  -0.000194   0.000022   0.000028  0.0000059  0.0000072    0.000062    0.000092
-2013   6   7  56450   0.115042   0.403767   0.0707839   0.0002307  -0.000011  -0.000236   0.000022   0.000028  0.0000014  0.0000072    0.000062    0.000100
-2013   6   8  56451   0.115655   0.402894   0.0706110   0.0001381  -0.000001  -0.000257   0.000022   0.000028  0.0000279  0.0000071    0.000060    0.000096
-2013   6   9  56452   0.116356   0.402086   0.0705071   0.0000830   0.000043  -0.000264   0.000307   0.000144  0.0000033  0.0000201    0.000057    0.000089
-2013   6  10  56453   0.117353   0.401350   0.0704022   0.0000989   0.000086  -0.000262   0.000032   0.000025  0.0000027  0.0000082    0.000054    0.000081
-2013   6  11  56454   0.118260   0.401044   0.0702341   0.0001960   0.000126  -0.000255   0.000032   0.000028  0.0000013  0.0000078    0.000051    0.000074
-2013   6  12  56455   0.119228   0.400606   0.0699942   0.0002892   0.000090  -0.000217   0.000034   0.000030  0.0000187  0.0000080    0.000055    0.000075
-2013   6  13  56456   0.120715   0.399987   0.0696499   0.0004153   0.000031  -0.000173   0.000034   0.000030  0.0000028  0.0000084    0.000060    0.000079
-2013   6  14  56457   0.122407   0.399512   0.0691558   0.0005602  -0.000029  -0.000132   0.000031   0.000030  0.0000016  0.0000080    0.000066    0.000083
+2013   5   6  56418   0.076726   0.399162   0.1042827   0.0016511   0.000098  -0.000109   0.000021   0.000033  0.0000053  0.0000084    0.000047    0.000069
+2013   5   7  56419   0.077727   0.399520   0.1026651   0.0015729   0.000123  -0.000072   0.000021   0.000033  0.0000059  0.0000084    0.000047    0.000065
+2013   5   8  56420   0.078782   0.399676   0.1011258   0.0014570   0.000147  -0.000041   0.000020   0.000032  0.0000013  0.0000077    0.000045    0.000059
+2013   5   9  56421   0.080212   0.400159   0.0997499   0.0012809   0.000097  -0.000090   0.000017   0.000032  0.0000136  0.0000073    0.000084    0.000101
+2013   5  10  56422   0.081756   0.400479   0.0985505   0.0011247   0.000028  -0.000164   0.000020   0.000032  0.0000021  0.0000077    0.000131    0.000156
+2013   5  11  56423   0.084245   0.400858   0.0974696   0.0010228   0.000054  -0.000180   0.000022   0.000032  0.0000131  0.0000081    0.000127    0.000151
+2013   5  12  56424   0.086309   0.401440   0.0964810   0.0009413   0.000114  -0.000173   0.000020   0.000032  0.0000031  0.0000077    0.000102    0.000123
+2013   5  13  56425   0.088337   0.402161   0.0955606   0.0009037   0.000166  -0.000149   0.000022   0.000032  0.0000034  0.0000079    0.000082    0.000103
+2013   5  14  56426   0.089451   0.403203   0.0946677   0.0009035   0.000218  -0.000142   0.000024   0.000032  0.0000015  0.0000078    0.000056    0.000073
+2013   5  15  56427   0.090741   0.403960   0.0937434   0.0009546   0.000183  -0.000224   0.000022   0.000033  0.0000164  0.0000073    0.000054    0.000075
+2013   5  16  56428   0.091099   0.404564   0.0927334   0.0010329   0.000124  -0.000325   0.000022   0.000033  0.0000061  0.0000077    0.000059    0.000088
+2013   5  17  56429   0.091665   0.404720   0.0916057   0.0011913   0.000062  -0.000418   0.000022   0.000033  0.0000013  0.0000077    0.000063    0.000101
+2013   5  18  56430   0.092279   0.404886   0.0903432   0.0013154   0.000089  -0.000442   0.000022   0.000033  0.0000170  0.0000077    0.000063    0.000100
+2013   5  19  56431   0.093382   0.404814   0.0889580   0.0014222   0.000152  -0.000430   0.000024   0.000033  0.0000031  0.0000077    0.000062    0.000093
+2013   5  20  56432   0.094812   0.404856   0.0874807   0.0015032   0.000109  -0.000393   0.000020   0.000030  0.0000031  0.0000070    0.000128    0.000171
+2013   5  21  56433   0.096671   0.405103   0.0859534   0.0015170   0.000129  -0.000354   0.000020   0.000030  0.0000026  0.0000070    0.000152    0.000195
+2013   5  22  56434   0.098090   0.405783   0.0844501   0.0014488   0.000145  -0.000310   0.000021   0.000027  0.0000040  0.0000072    0.000171    0.000218
+2013   5  23  56435   0.099439   0.406575   0.0830146   0.0013755   0.000149  -0.000249   0.000021   0.000027  0.0001122  0.0000072    0.000146    0.000196
+2013   5  24  56436   0.100665   0.407104   0.0817241   0.0012537   0.000145  -0.000186   0.000019   0.000027  0.0000018  0.0000069    0.000109    0.000162
+2013   5  25  56437   0.101494   0.407171   0.0805331   0.0011307   0.000106  -0.000193   0.000017   0.000027  0.0000250  0.0000069    0.000101    0.000154
+2013   5  26  56438   0.102303   0.407199   0.0794448   0.0010336   0.000053  -0.000224   0.000304   0.000234  0.0000054  0.0000236    0.000105    0.000156
+2013   5  27  56439   0.102856   0.407246   0.0784812   0.0009137  -0.000009  -0.000245   0.000026   0.000030  0.0000031  0.0000075    0.000114    0.000159
+2013   5  28  56440   0.103519   0.407139   0.0775747   0.0009094  -0.000057  -0.000278   0.000026   0.000034  0.0000026  0.0000075    0.000118    0.000161
+2013   5  29  56441   0.104126   0.407196   0.0766735   0.0009130  -0.000094  -0.000310   0.000025   0.000032  0.0000019  0.0000073    0.000118    0.000153
+2013   5  30  56442   0.104903   0.407053   0.0757525   0.0009351  -0.000087  -0.000262   0.000028   0.000031  0.0000112  0.0000077    0.000107    0.000133
+2013   5  31  56443   0.106365   0.406900   0.0748141   0.0009118  -0.000059  -0.000192   0.000028   0.000031  0.0000016  0.0000077    0.000092    0.000107
+2013   6   1  56444   0.108299   0.406628   0.0739569   0.0008131  -0.000001  -0.000158   0.000028   0.000031  0.0000081  0.0000077    0.000084    0.000096
+2013   6   2  56445   0.110240   0.406481   0.0732060   0.0007016   0.000068  -0.000139   0.000028   0.000031  0.0000030  0.0000077    0.000077    0.000091
+2013   6   3  56446   0.111834   0.406343   0.0725254   0.0006471   0.000136  -0.000127   0.000023   0.000030  0.0000029  0.0000074    0.000071    0.000086
+2013   6   4  56447   0.113268   0.405956   0.0719147   0.0005507   0.000197  -0.000121   0.000023   0.000030  0.0000013  0.0000074    0.000064    0.000081
+2013   6   5  56448   0.114167   0.405386   0.0714299   0.0004190   0.000151  -0.000152   0.000022   0.000028  0.0000174  0.0000072    0.000062    0.000085
+2013   6   6  56449   0.114617   0.404595   0.0710683   0.0003198   0.000072  -0.000194   0.000022   0.000028  0.0000059  0.0000072    0.000062    0.000092
+2013   6   7  56450   0.115025   0.403767   0.0707839   0.0002307  -0.000011  -0.000236   0.000022   0.000028  0.0000014  0.0000072    0.000062    0.000100
+2013   6   8  56451   0.115680   0.402894   0.0706110   0.0001381  -0.000001  -0.000257   0.000022   0.000028  0.0000279  0.0000071    0.000060    0.000096
+2013   6   9  56452   0.116312   0.402086   0.0705071   0.0000830   0.000043  -0.000264   0.000307   0.000144  0.0000033  0.0000201    0.000057    0.000089
+2013   6  10  56453   0.117352   0.401350   0.0704022   0.0000989   0.000086  -0.000262   0.000032   0.000025  0.0000027  0.0000082    0.000054    0.000081
+2013   6  11  56454   0.118269   0.401044   0.0702341   0.0001960   0.000126  -0.000255   0.000032   0.000028  0.0000013  0.0000078    0.000051    0.000074
+2013   6  12  56455   0.119218   0.400606   0.0699942   0.0002892   0.000090  -0.000217   0.000034   0.000030  0.0000187  0.0000080    0.000055    0.000075
+2013   6  13  56456   0.120723   0.399987   0.0696499   0.0004153   0.000031  -0.000173   0.000034   0.000030  0.0000028  0.0000084    0.000060    0.000079
+2013   6  14  56457   0.122404   0.399512   0.0691558   0.0005602  -0.000029  -0.000132   0.000031   0.000030  0.0000016  0.0000080    0.000066    0.000083
 2013   6  15  56458   0.123927   0.398878   0.0685337   0.0006864  -0.000064  -0.000161   0.000027   0.000030  0.0000217  0.0000076    0.000076    0.000091
-2013   6  16  56459   0.125696   0.398557   0.0678080   0.0007759  -0.000085  -0.000216   0.000027   0.000027  0.0000034  0.0000076    0.000090    0.000101
-2013   6  17  56460   0.127391   0.398251   0.0669948   0.0008524  -0.000096  -0.000257   0.000029   0.000024  0.0000034  0.0000082    0.000101    0.000110
-2013   6  18  56461   0.129304   0.397823   0.0661280   0.0008752  -0.000105  -0.000310   0.000032   0.000027  0.0000018  0.0000087    0.000114    0.000120
-2013   6  19  56462   0.131168   0.397852   0.0652819   0.0008272  -0.000095  -0.000318   0.000032   0.000063  0.0000246  0.0000085    0.000091    0.000097
-2013   6  20  56463   0.132630   0.397704   0.0644927   0.0007700  -0.000077  -0.000312   0.000029   0.000063  0.0000027  0.0000081    0.000060    0.000066
-2013   6  21  56464   0.134141   0.397002   0.0637729   0.0006587  -0.000058  -0.000298   0.000029   0.000030  0.0000011  0.0000081    0.000029    0.000035
-2013   6  22  56465   0.135324   0.396487   0.0631683   0.0005846  -0.000068  -0.000297   0.000032   0.000030  0.0000159  0.0000085    0.000029    0.000034
-2013   6  23  56466   0.136121   0.395919   0.0626275   0.0005627  -0.000089  -0.000296   0.000029   0.000030  0.0000026  0.0000085    0.000041    0.000045
-2013   6  24  56467   0.136436   0.395594   0.0620426   0.0005992  -0.000103  -0.000278   0.000029   0.000030  0.0000030  0.0000083    0.000052    0.000055
-2013   6  25  56468   0.136960   0.394965   0.0613753   0.0007043  -0.000122  -0.000264   0.000029   0.000030  0.0000016  0.0000079    0.000063    0.000065
-2013   6  26  56469   0.137560   0.394336   0.0606312   0.0007642  -0.000127  -0.000281   0.000027   0.000030  0.0000155  0.0000078    0.000061    0.000064
-2013   6  27  56470   0.137992   0.393733   0.0598411   0.0007937  -0.000127  -0.000300   0.000027   0.000030  0.0000051  0.0000077    0.000054    0.000061
-2013   6  28  56471   0.138780   0.392827   0.0590512   0.0007557  -0.000126  -0.000315   0.000027   0.000030  0.0000010  0.0000077    0.000047    0.000058
-2013   6  29  56472   0.140183   0.391993   0.0583348   0.0006506  -0.000124  -0.000272   0.000031   0.000030  0.0000299  0.0000082    0.000055    0.000055
-2013   6  30  56473   0.141520   0.391422   0.0577584   0.0004939  -0.000119  -0.000206   0.000031   0.000030  0.0000032  0.0000082    0.000070    0.000052
-2013   7   1  56474   0.142615   0.390794   0.0573666   0.0002946  -0.000050  -0.000215   0.000026   0.000031  0.0000036  0.0000072    0.000025    0.000031
-2013   7   2  56475   0.144086   0.390119   0.0571657   0.0001138  -0.000026  -0.000181   0.000026   0.000030  0.0000026  0.0000088    0.000017    0.000021
-2013   7   3  56476   0.145652   0.389520   0.0571564  -0.0000670  -0.000074  -0.000169   0.000025   0.000030  0.0000015  0.0000084    0.000063    0.000073
-2013   7   4  56477   0.146721   0.388729   0.0572832  -0.0002368  -0.000109  -0.000193   0.000025   0.000030  0.0000094  0.0000084    0.000090    0.000089
-2013   7   5  56478   0.147705   0.387541   0.0575537  -0.0003000  -0.000132  -0.000226   0.000025   0.000030  0.0000087  0.0000087    0.000105    0.000086
-2013   7   6  56479   0.148966   0.386151   0.0579280  -0.0003526  -0.000150  -0.000255   0.000025   0.000030  0.0000096  0.0000090    0.000119    0.000083
-2013   7   7  56480   0.150357   0.384903   0.0583167  -0.0003661  -0.000163  -0.000275   0.000107   0.000099  0.0000163  0.0000110    0.000134    0.000080
-2013   7   8  56481   0.151590   0.383539   0.0585779  -0.0002537  -0.000127  -0.000261   0.000032   0.000032  0.0000125  0.0000085    0.000042    0.000052
-2013   7   9  56482   0.153026   0.382250   0.0587683  -0.0001194  -0.000132  -0.000271   0.000032   0.000032  0.0000044  0.0000085    0.000034    0.000043
-2013   7  10  56483   0.154524   0.381145   0.0588276   0.0000078  -0.000113  -0.000234   0.000030   0.000036  0.0000109  0.0000085    0.000066    0.000078
-2013   7  11  56484   0.156046   0.380732   0.0587437   0.0001635  -0.000091  -0.000208   0.000034   0.000036  0.0000068  0.0000087    0.000099    0.000114
-2013   7  12  56485   0.156895   0.380599   0.0585248   0.0002568  -0.000066  -0.000186   0.000034   0.000036  0.0000038  0.0000087    0.000132    0.000149
-2013   7  13  56486   0.158050   0.380042   0.0582255   0.0003536  -0.000073  -0.000194   0.000030   0.000036  0.0000181  0.0000087    0.000127    0.000144
-2013   7  14  56487   0.159081   0.379385   0.0578480   0.0003991  -0.000087  -0.000215   0.000030   0.000036  0.0000085  0.0000089    0.000108    0.000124
-2013   7  15  56488   0.159936   0.378229   0.0574290   0.0004241  -0.000082  -0.000236   0.000028   0.000035  0.0000093  0.0000087    0.000088    0.000100
-2013   7  16  56489   0.160897   0.377171   0.0569832   0.0004291  -0.000090  -0.000247   0.000031   0.000035  0.0000109  0.0000088    0.000068    0.000080
-2013   7  17  56490   0.161824   0.376243   0.0565385   0.0003878  -0.000092  -0.000249   0.000036   0.000034  0.0000048  0.0000091    0.000049    0.000059
-2013   7  18  56491   0.162549   0.375422   0.0561746   0.0003214  -0.000096  -0.000180   0.000036   0.000034  0.0000094  0.0000091    0.000060    0.000077
-2013   7  19  56492   0.162962   0.374696   0.0558663   0.0002716  -0.000096  -0.000091   0.000033   0.000034  0.0000029  0.0000090    0.000079    0.000105
-2013   7  20  56493   0.163838   0.373849   0.0556151   0.0002333  -0.000127  -0.000085   0.000029   0.000034  0.0000178  0.0000090    0.000078    0.000103
-2013   7  21  56494   0.164551   0.373090   0.0554059   0.0002098  -0.000167  -0.000112   0.000032   0.000034  0.0000067  0.0000090    0.000069    0.000089
-2013   7  22  56495   0.164791   0.371800   0.0551523   0.0002812  -0.000200  -0.000142   0.000034   0.000036  0.0000069  0.0000095    0.000059    0.000075
-2013   7  23  56496   0.165297   0.370338   0.0547829   0.0004291  -0.000224  -0.000176   0.000031   0.000036  0.0000028  0.0000093    0.000051    0.000061
-2013   7  24  56497   0.165995   0.368999   0.0542810   0.0005603  -0.000168  -0.000170   0.000031   0.000033  0.0000166  0.0000089    0.000049    0.000065
-2013   7  25  56498   0.166349   0.367911   0.0536717   0.0006255  -0.000090  -0.000152   0.000034   0.000033  0.0000105  0.0000092    0.000060    0.000084
+2013   6  16  56459   0.125694   0.398557   0.0678080   0.0007759  -0.000085  -0.000216   0.000027   0.000027  0.0000034  0.0000076    0.000090    0.000101
+2013   6  17  56460   0.127398   0.398251   0.0669948   0.0008524  -0.000096  -0.000257   0.000029   0.000024  0.0000034  0.0000082    0.000101    0.000110
+2013   6  18  56461   0.129288   0.397823   0.0661280   0.0008752  -0.000105  -0.000310   0.000032   0.000027  0.0000018  0.0000087    0.000114    0.000120
+2013   6  19  56462   0.131187   0.397852   0.0652819   0.0008272  -0.000095  -0.000318   0.000032   0.000063  0.0000246  0.0000085    0.000091    0.000097
+2013   6  20  56463   0.132607   0.397704   0.0644927   0.0007700  -0.000077  -0.000312   0.000029   0.000063  0.0000027  0.0000081    0.000060    0.000066
+2013   6  21  56464   0.134163   0.397002   0.0637729   0.0006587  -0.000058  -0.000298   0.000029   0.000030  0.0000011  0.0000081    0.000029    0.000035
+2013   6  22  56465   0.135302   0.396487   0.0631683   0.0005846  -0.000068  -0.000297   0.000032   0.000030  0.0000159  0.0000085    0.000029    0.000034
+2013   6  23  56466   0.136143   0.395919   0.0626275   0.0005627  -0.000089  -0.000296   0.000029   0.000030  0.0000026  0.0000085    0.000041    0.000045
+2013   6  24  56467   0.136415   0.395594   0.0620426   0.0005992  -0.000103  -0.000278   0.000029   0.000030  0.0000030  0.0000083    0.000052    0.000055
+2013   6  25  56468   0.136974   0.394965   0.0613753   0.0007043  -0.000122  -0.000264   0.000029   0.000030  0.0000016  0.0000079    0.000063    0.000065
+2013   6  26  56469   0.137552   0.394336   0.0606312   0.0007642  -0.000127  -0.000281   0.000027   0.000030  0.0000155  0.0000078    0.000061    0.000064
+2013   6  27  56470   0.138002   0.393733   0.0598411   0.0007937  -0.000127  -0.000300   0.000027   0.000030  0.0000051  0.0000077    0.000054    0.000061
+2013   6  28  56471   0.138767   0.392827   0.0590512   0.0007557  -0.000126  -0.000315   0.000027   0.000030  0.0000010  0.0000077    0.000047    0.000058
+2013   6  29  56472   0.140194   0.391993   0.0583348   0.0006506  -0.000124  -0.000272   0.000031   0.000030  0.0000299  0.0000082    0.000055    0.000055
+2013   6  30  56473   0.141516   0.391422   0.0577584   0.0004939  -0.000119  -0.000206   0.000031   0.000030  0.0000032  0.0000082    0.000070    0.000052
+2013   7   1  56474   0.142616   0.390794   0.0573666   0.0002946  -0.000050  -0.000215   0.000026   0.000031  0.0000036  0.0000072    0.000025    0.000031
+2013   7   2  56475   0.144079   0.390119   0.0571657   0.0001138  -0.000026  -0.000181   0.000026   0.000030  0.0000026  0.0000088    0.000017    0.000021
+2013   7   3  56476   0.145665   0.389520   0.0571564  -0.0000670  -0.000074  -0.000169   0.000025   0.000030  0.0000015  0.0000084    0.000063    0.000073
+2013   7   4  56477   0.146711   0.388729   0.0572832  -0.0002368  -0.000109  -0.000193   0.000025   0.000030  0.0000094  0.0000084    0.000090    0.000089
+2013   7   5  56478   0.147713   0.387541   0.0575537  -0.0003000  -0.000132  -0.000226   0.000025   0.000030  0.0000087  0.0000087    0.000105    0.000086
+2013   7   6  56479   0.148953   0.386151   0.0579280  -0.0003526  -0.000150  -0.000255   0.000025   0.000030  0.0000096  0.0000090    0.000119    0.000083
+2013   7   7  56480   0.150376   0.384903   0.0583167  -0.0003661  -0.000163  -0.000275   0.000107   0.000099  0.0000163  0.0000110    0.000134    0.000080
+2013   7   8  56481   0.151569   0.383539   0.0585779  -0.0002537  -0.000127  -0.000261   0.000032   0.000032  0.0000125  0.0000085    0.000042    0.000052
+2013   7   9  56482   0.153050   0.382250   0.0587683  -0.0001194  -0.000132  -0.000271   0.000032   0.000032  0.0000044  0.0000085    0.000034    0.000043
+2013   7  10  56483   0.154493   0.381145   0.0588276   0.0000078  -0.000113  -0.000234   0.000030   0.000036  0.0000109  0.0000085    0.000066    0.000078
+2013   7  11  56484   0.156082   0.380732   0.0587437   0.0001635  -0.000091  -0.000208   0.000034   0.000036  0.0000068  0.0000087    0.000099    0.000114
+2013   7  12  56485   0.156863   0.380599   0.0585248   0.0002568  -0.000066  -0.000186   0.000034   0.000036  0.0000038  0.0000087    0.000132    0.000149
+2013   7  13  56486   0.158069   0.380042   0.0582255   0.0003536  -0.000073  -0.000194   0.000030   0.000036  0.0000181  0.0000087    0.000127    0.000144
+2013   7  14  56487   0.159076   0.379385   0.0578480   0.0003991  -0.000087  -0.000215   0.000030   0.000036  0.0000085  0.0000089    0.000108    0.000124
+2013   7  15  56488   0.159931   0.378229   0.0574290   0.0004241  -0.000082  -0.000236   0.000028   0.000035  0.0000093  0.0000087    0.000088    0.000100
+2013   7  16  56489   0.160905   0.377171   0.0569832   0.0004291  -0.000090  -0.000247   0.000031   0.000035  0.0000109  0.0000088    0.000068    0.000080
+2013   7  17  56490   0.161815   0.376243   0.0565385   0.0003878  -0.000092  -0.000249   0.000036   0.000034  0.0000048  0.0000091    0.000049    0.000059
+2013   7  18  56491   0.162565   0.375422   0.0561746   0.0003214  -0.000096  -0.000180   0.000036   0.000034  0.0000094  0.0000091    0.000060    0.000077
+2013   7  19  56492   0.162945   0.374696   0.0558663   0.0002716  -0.000096  -0.000091   0.000033   0.000034  0.0000029  0.0000090    0.000079    0.000105
+2013   7  20  56493   0.163846   0.373849   0.0556151   0.0002333  -0.000127  -0.000085   0.000029   0.000034  0.0000178  0.0000090    0.000078    0.000103
+2013   7  21  56494   0.164553   0.373090   0.0554059   0.0002098  -0.000167  -0.000112   0.000032   0.000034  0.0000067  0.0000090    0.000069    0.000089
+2013   7  22  56495   0.164789   0.371800   0.0551523   0.0002812  -0.000200  -0.000142   0.000034   0.000036  0.0000069  0.0000095    0.000059    0.000075
+2013   7  23  56496   0.165291   0.370338   0.0547829   0.0004291  -0.000224  -0.000176   0.000031   0.000036  0.0000028  0.0000093    0.000051    0.000061
+2013   7  24  56497   0.166002   0.368999   0.0542810   0.0005603  -0.000168  -0.000170   0.000031   0.000033  0.0000166  0.0000089    0.000049    0.000065
+2013   7  25  56498   0.166346   0.367911   0.0536717   0.0006255  -0.000090  -0.000152   0.000034   0.000033  0.0000105  0.0000092    0.000060    0.000084
 2013   7  26  56499   0.166811   0.366676   0.0530071   0.0006567  -0.000012  -0.000130   0.000034   0.000033  0.0000035  0.0000095    0.000072    0.000102
-2013   7  27  56500   0.167708   0.365549   0.0523630   0.0006006   0.000015  -0.000119   0.000034   0.000033  0.0000121  0.0000098    0.000088    0.000126
-2013   7  28  56501   0.168758   0.364738   0.0518197   0.0004764   0.000017  -0.000109   0.000031   0.000033  0.0000108  0.0000098    0.000104    0.000151
-2013   7  29  56502   0.169709   0.363977   0.0513965   0.0003449   0.000011  -0.000085   0.000027   0.000032  0.0000105  0.0000102    0.000125    0.000182
-2013   7  30  56503   0.170580   0.362929   0.0510988   0.0002185   0.000006  -0.000072   0.000028   0.000033  0.0000065  0.0000088    0.000142    0.000208
-2013   7  31  56504   0.171178   0.361742   0.0509293   0.0001075  -0.000047  -0.000055   0.000029   0.000032  0.0000126  0.0000085    0.000098    0.000152
-2013   8   1  56505   0.171589   0.360801   0.0508664   0.0000354  -0.000115  -0.000041   0.000029   0.000032  0.0000116  0.0000088    0.000061    0.000092
-2013   8   2  56506   0.171471   0.359906   0.0508698  -0.0000262  -0.000184  -0.000031   0.000029   0.000032  0.0000021  0.0000088    0.000024    0.000033
-2013   8   3  56507   0.171802   0.358758   0.0508896  -0.0000357  -0.000185  -0.000041   0.000029   0.000032  0.0000159  0.0000088    0.000015    0.000019
-2013   8   4  56508   0.172185   0.357514   0.0508920  -0.0000184  -0.000157  -0.000058   0.000029   0.000029  0.0000092  0.0000091    0.000017    0.000021
+2013   7  27  56500   0.167707   0.365549   0.0523630   0.0006006   0.000015  -0.000119   0.000034   0.000033  0.0000121  0.0000098    0.000088    0.000126
+2013   7  28  56501   0.168765   0.364738   0.0518197   0.0004764   0.000017  -0.000109   0.000031   0.000033  0.0000108  0.0000098    0.000104    0.000151
+2013   7  29  56502   0.169700   0.363977   0.0513965   0.0003449   0.000011  -0.000085   0.000027   0.000032  0.0000105  0.0000102    0.000125    0.000182
+2013   7  30  56503   0.170594   0.362929   0.0510988   0.0002185   0.000006  -0.000072   0.000028   0.000033  0.0000065  0.0000088    0.000142    0.000208
+2013   7  31  56504   0.171158   0.361742   0.0509293   0.0001075  -0.000047  -0.000055   0.000029   0.000032  0.0000126  0.0000085    0.000098    0.000152
+2013   8   1  56505   0.171614   0.360801   0.0508664   0.0000354  -0.000115  -0.000041   0.000029   0.000032  0.0000116  0.0000088    0.000061    0.000092
+2013   8   2  56506   0.171449   0.359906   0.0508698  -0.0000262  -0.000184  -0.000031   0.000029   0.000032  0.0000021  0.0000088    0.000024    0.000033
+2013   8   3  56507   0.171812   0.358758   0.0508896  -0.0000357  -0.000185  -0.000041   0.000029   0.000032  0.0000159  0.0000088    0.000015    0.000019
+2013   8   4  56508   0.172184   0.357514   0.0508920  -0.0000184  -0.000157  -0.000058   0.000029   0.000029  0.0000092  0.0000091    0.000017    0.000021
 2013   8   5  56509   0.172401   0.356273   0.0508653   0.0000659  -0.000111  -0.000073   0.000033   0.000029  0.0000153  0.0000097    0.000019    0.000026
 2013   8   6  56510   0.172554   0.355256   0.0507705   0.0001743  -0.000076  -0.000090   0.000033   0.000032  0.0000055  0.0000096    0.000021    0.000028
 2013   8   7  56511   0.172778   0.354263   0.0505584   0.0002672  -0.000114  -0.000073   0.000030   0.000031  0.0000125  0.0000098    0.000031    0.000044
@@ -19097,4 +19097,262 @@
 2014   3  31  56747   0.042240   0.419457  -0.2034060   0.0016529   0.000171   0.000083   0.000053   0.000057  0.0000095  0.0000116    0.000029    0.000039
 2014   4   1  56748   0.043607   0.420940  -0.2050077   0.0014833   0.000165   0.000100   0.000058   0.000056  0.0000023  0.0000111    0.000033    0.000044
 2014   4   2  56749   0.044731   0.422505  -0.2064734   0.0014041   0.000149   0.000156   0.000064   0.000065  0.0000053  0.0000113    0.000069    0.000033
-2014   4   3  56750   0.045484   0.423843  -0.2078192   0.0013026   0.000180   0.000166   0.000064   0.000065  0.0000092  0.0000116    0.000334    0.000142
+2014   4   3  56750   0.045490   0.423828  -0.2078192   0.0013026   0.000180   0.000166   0.000064   0.000065  0.0000092  0.0000116    0.000334    0.000142
+2014   4   4  56751   0.045979   0.424932  -0.2090728   0.0012096   0.000254   0.000110   0.000065   0.000061  0.0000069  0.0000115    0.000174    0.000076
+2014   4   5  56752   0.046374   0.425656  -0.2102805   0.0012037   0.000322   0.000091   0.000068   0.000060  0.0000079  0.0000117    0.000070    0.000035
+2014   4   6  56753   0.046842   0.426321  -0.2114745   0.0011918   0.000377   0.000088   0.000071   0.000065  0.0000079  0.0000113    0.000055    0.000033
+2014   4   7  56754   0.047736   0.426413  -0.2126716   0.0011774   0.000403   0.000081   0.000067   0.000070  0.0000068  0.0000109    0.000039    0.000031
+2014   4   8  56755   0.049174   0.427200  -0.2138681   0.0011797   0.000434   0.000071   0.000063   0.000067  0.0000018  0.0000110    0.000024    0.000029
+2014   4   9  56756   0.050711   0.428221  -0.2150826   0.0012402   0.000430   0.000044   0.000066   0.000066  0.0000071  0.0000114    0.000039    0.000033
+2014   4  10  56757   0.052168   0.429049  -0.2163479   0.0012906   0.000407   0.000016   0.000069   0.000066  0.0000050  0.0000115    0.000062    0.000039
+2014   4  11  56758   0.053250   0.429803  -0.2176742   0.0013679   0.000369  -0.000010   0.000068   0.000063  0.0000066  0.0000110    0.000086    0.000045
+2014   4  12  56759   0.054234   0.430495  -0.2190704   0.0014091   0.000361  -0.000029   0.000068   0.000066  0.0000055  0.0000109    0.000078    0.000041
+2014   4  13  56760   0.054922   0.430829  -0.2205171   0.0014478   0.000356  -0.000041   0.000064   0.000069  0.0000059  0.0000114    0.000058    0.000034
+2014   4  14  56761   0.055815   0.431117  -0.2219822   0.0014663   0.000362  -0.000059   0.000062   0.000069  0.0000064  0.0000116    0.000060    0.000077
+2014   4  15  56762   0.056685   0.432066  -0.2234228   0.0013816   0.000324  -0.000051   0.000063   0.000067  0.0000019  0.0000114    0.000022    0.000028
+2014   4  16  56763   0.057372   0.432707  -0.2247319   0.0012503   0.000190  -0.000073   0.000059   0.000060  0.0000008  0.0000116    0.000022    0.000033
+2014   4  17  56764   0.058285   0.433345  -0.2259407   0.0011767   0.000134  -0.000076   0.000059   0.000053  0.0000082  0.0000117    0.000025    0.000038
+2014   4  18  56765   0.059603   0.434397  -0.2271293   0.0012051   0.000121  -0.000069   0.000062   0.000064  0.0000066  0.0000110    0.000025    0.000037
+2014   4  19  56766   0.060277   0.435889  -0.2283317   0.0012007   0.000120  -0.000061   0.000062   0.000071  0.0000073  0.0000109    0.000025    0.000037
+2014   4  20  56767   0.061059   0.436854  -0.2295651   0.0012686   0.000129  -0.000053   0.000071   0.000067  0.0000071  0.0000111    0.000025    0.000036
+2014   4  21  56768   0.062226   0.437949  -0.2308723   0.0013612   0.000171  -0.000056   0.000067   0.000064  0.0000089  0.0000106    0.000032    0.000034
+2014   4  22  56769   0.063815   0.438636  -0.2323122   0.0015154   0.000188  -0.000046   0.000060   0.000064  0.0000086  0.0000105    0.000032    0.000033
+2014   4  23  56770   0.065292   0.439387  -0.2339073   0.0016655   0.000398  -0.000026   0.000061   0.000064  0.0000035  0.0000104    0.000039    0.000051
+2014   4  24  56771   0.066921   0.439872  -0.2356245   0.0017816   0.000336  -0.000021   0.000056   0.000064  0.0000095  0.0000109    0.000034    0.000045
+2014   4  25  56772   0.068585   0.440441  -0.2374787   0.0019279   0.000243  -0.000017   0.000055   0.000068  0.0000052  0.0000113    0.000027    0.000037
+2014   4  26  56773   0.070307   0.441005  -0.2394521   0.0020154   0.000232  -0.000013   0.000064   0.000071  0.0000081  0.0000111    0.000033    0.000035
+2014   4  27  56774   0.071805   0.441748  -0.2414476   0.0019383   0.000253  -0.000008   0.000059   0.000067  0.0000087  0.0000111    0.000043    0.000037
+2014   4  28  56775   0.072999   0.442322  -0.2433329   0.0017859   0.000238  -0.000026   0.000059   0.000066  0.0000080  0.0000114    0.000041    0.000028
+2014   4  29  56776   0.074344   0.442647  -0.2450400   0.0016137   0.000226  -0.000030   0.000060   0.000066  0.0000057  0.0000111    0.000046    0.000026
+2014   4  30  56777   0.076138   0.442770  -0.2465381   0.0014115   0.000330  -0.000006   0.000063   0.000057  0.0000050  0.0000106    0.000062    0.000040
+2014   5   1  56778   0.078006   0.443141  -0.2478474   0.0012234   0.000005   0.000001   0.000057   0.000053  0.0000095  0.0000095    0.000092    0.000075
+2014   5   2  56779   0.079752   0.443556  -0.2490245   0.0011077   0.000005   0.000001   0.000054   0.000060  0.0000073  0.0000095    0.000099    0.000087
+2014   5   3  56780   0.081711   0.443986  -0.2501213   0.0010993   0.000005   0.000001   0.000053   0.000059  0.0000072  0.0000101    0.000099    0.000087
+2014   5   4  56781   0.083804   0.444551  -0.2512088   0.0011093   0.000005   0.000001   0.000049   0.000052  0.0000081  0.0000102    0.000099    0.000087
+2014   5   5  56782   0.085264   0.444867  -0.2523436   0.0011428   0.000005   0.000001   0.000053   0.000055  0.0000064  0.0000104    0.000098    0.000087
+2014   5   6  56783   0.086218   0.444993  -0.2535523   0.0012141   0.000005   0.000001   0.000052   0.000058  0.0000057  0.0000099    0.000098    0.000087
+2014   5   7  56784   0.087407   0.445508  -0.2548052   0.0012887   0.000318  -0.000053   0.000049   0.000058  0.0000073  0.0000095    0.000036    0.000016
+2014   5   8  56785   0.088971   0.446127  -0.2561005   0.0013728   0.000217  -0.000046   0.000054   0.000059  0.0000044  0.0000101    0.000035    0.000016
+2014   5   9  56786   0.090412   0.446742  -0.2575155   0.0014254   0.000005   0.000001   0.000054   0.000056  0.0000051  0.0000100    0.000067    0.000052
+2014   5  10  56787   0.091516   0.446842  -0.2589546   0.0014420   0.000005   0.000001   0.000051   0.000053  0.0000053  0.0000094    0.000098    0.000087
+2014   5  11  56788   0.093120   0.446733  -0.2604017   0.0014287   0.000005   0.000001   0.000051   0.000055  0.0000069  0.0000092    0.000098    0.000087
+2014   5  12  56789   0.095450   0.446666  -0.2618137   0.0013658   0.000226  -0.000102   0.000049   0.000059  0.0000063  0.0000092    0.000037    0.000016
+2014   5  13  56790   0.097759   0.447045  -0.2631202   0.0012409   0.000005   0.000001   0.000048   0.000057  0.0000053  0.0000090    0.000068    0.000052
+2014   5  14  56791   0.099823   0.447537  -0.2642922   0.0011385   0.000212  -0.000125   0.000052   0.000055  0.0000048  0.0000093    0.000037    0.000016
+2014   5  15  56792   0.101336   0.447890  -0.2654011   0.0010596   0.000199  -0.000135   0.000064   0.000062  0.0000065  0.0000101    0.000038    0.000016
+2014   5  16  56793   0.102754   0.448019  -0.2664293   0.0010081   0.000189  -0.000145   0.000060   0.000062  0.0000043  0.0000097    0.000038    0.000016
+2014   5  17  56794   0.103945   0.448045  -0.2674262   0.0010066   0.000182  -0.000155   0.000053   0.000058  0.0000062  0.0000091    0.000038    0.000016
+2014   5  18  56795   0.104918   0.447989  -0.2684641   0.0010694   0.000178  -0.000166   0.000052   0.000057  0.0000082  0.0000093    0.000039    0.000016
+2014   5  19  56796   0.105841   0.447812  -0.2696075   0.0012001   0.000192  -0.000189   0.000053   0.000058  0.0000069  0.0000099    0.000039    0.000016
+2014   5  20  56797   0.107248   0.447607  -0.2708827   0.0013548   0.000180  -0.000172   0.000049   0.000051  0.0000054  0.0000099    0.000041    0.000018
+2014   5  21  56798   0.108980   0.447694  -0.2722910   0.0014502   0.000202  -0.000165   0.000049   0.000050  0.0000088  0.0000099    0.000045    0.000021
+2014   5  22  56799   0.110853   0.448038  -0.2737805   0.0014633   0.000209  -0.000144   0.000056   0.000058  0.0000080  0.0000105    0.000049    0.000024
+2014   5  23  56800   0.112172   0.448263  -0.2752375   0.0014086   0.000213  -0.000121   0.000055   0.000061  0.0000094  0.0000106    0.000053    0.000028
+2014   5  24  56801   0.113669   0.448048  -0.2766382   0.0013575   0.000005   0.000001   0.000054   0.000066  0.0000109  0.0000106    0.000087    0.000072
+2014   5  25  56802   0.115160   0.447700  -0.2779007   0.0011867   0.000005   0.000001   0.000047   0.000054  0.0000091  0.0000102    0.000099    0.000088
+2014   5  26  56803   0.116710   0.446966  -0.2790132   0.0010368   0.000005   0.000001   0.000043   0.000046  0.0000079  0.0000097    0.000098    0.000088
+2014   5  27  56804   0.118078   0.446334  -0.2799330   0.0008506   0.000005   0.000001   0.000047   0.000052  0.0000074  0.0000096    0.000098    0.000088
+2014   5  28  56805   0.120155   0.445401  -0.2807038   0.0006872   0.000332  -0.000116   0.000055   0.000056  0.0000071  0.0000101    0.000064    0.000031
+2014   5  29  56806   0.122767   0.444962  -0.2813650   0.0005649   0.000373  -0.000130   0.000059   0.000058  0.0000081  0.0000106    0.000066    0.000031
+2014   5  30  56807   0.125428   0.444159  -0.2818336   0.0004223   0.000418  -0.000148   0.000055   0.000053  0.0000068  0.0000102    0.000068    0.000032
+2014   5  31  56808   0.127751   0.443535  -0.2822270   0.0003843   0.000006   0.000001   0.000051   0.000046  0.0000111  0.0000101    0.000090    0.000071
+2014   6   1  56809   0.129382   0.442901  -0.2826153   0.0003849   0.000005   0.000001   0.000047   0.000041  0.0000105  0.0000101    0.000098    0.000085
+2014   6   2  56810   0.130672   0.441904  -0.2830498   0.0004223   0.000005   0.000001   0.000046   0.000046  0.0000105  0.0000098    0.000097    0.000087
+2014   6   3  56811   0.131670   0.440946  -0.2834950   0.0004593   0.000005   0.000001   0.000048   0.000055  0.0000101  0.0000098    0.000097    0.000087
+2014   6   4  56812   0.133002   0.439682  -0.2839822   0.0005677   0.000005   0.000001   0.000049   0.000052  0.0000102  0.0000097    0.000083    0.000071
+2014   6   5  56813   0.134479   0.438899  -0.2845849   0.0006133   0.000005   0.000001   0.000056   0.000052  0.0000097  0.0000097    0.000097    0.000085
+2014   6   6  56814   0.136334   0.437847  -0.2852332   0.0006729   0.000005   0.000001   0.000055   0.000055  0.0000087  0.0000096    0.000097    0.000085
+2014   6   7  56815   0.138475   0.437411  -0.2859436   0.0007130   0.000005   0.000001   0.000055   0.000057  0.0000082  0.0000100    0.000097    0.000085
+2014   6   8  56816   0.140267   0.436583  -0.2866815   0.0007447   0.000005   0.000001   0.000060   0.000061  0.0000094  0.0000102    0.000097    0.000085
+2014   6   9  56817   0.142193   0.435883  -0.2874153   0.0007165   0.000005   0.000001   0.000054   0.000053  0.0000122  0.0000096    0.000096    0.000084
+2014   6  10  56818   0.143900   0.435273  -0.2880883   0.0006780   0.000005   0.000001   0.000045   0.000045  0.0000106  0.0000096    0.000096    0.000084
+2014   6  11  56819   0.145742   0.434729  -0.2887605   0.0006599   0.000180  -0.000179   0.000045   0.000045  0.0000063  0.0000095    0.000038    0.000042
+2014   6  12  56820   0.147475   0.434263  -0.2893970   0.0006322   0.000005   0.000001   0.000048   0.000046  0.0000064  0.0000095    0.000082    0.000085
+2014   6  13  56821   0.149117   0.433486  -0.2900595   0.0006226   0.000006   0.000001   0.000049   0.000045  0.0000056  0.0000099    0.000094    0.000097
+2014   6  14  56822   0.150723   0.432699  -0.2906988   0.0006710   0.000006   0.000001   0.000054   0.000050  0.0000100  0.0000099    0.000094    0.000097
+2014   6  15  56823   0.152515   0.431573  -0.2914264   0.0007739   0.000005   0.000001   0.000064   0.000070  0.0000104  0.0000153    0.000094    0.000097
+2014   6  16  56824   0.154208   0.430685  -0.2922607   0.0008929   0.000006   0.000001   0.000046   0.000056  0.0000085  0.0000101    0.000097    0.000085
+2014   6  17  56825   0.155920   0.430008  -0.2932405   0.0010466   0.000006   0.000001   0.000049   0.000058  0.0000067  0.0000099    0.000097    0.000085
+2014   6  18  56826   0.157288   0.429487  -0.2943619   0.0011381   0.000095  -0.000091   0.000057   0.000057  0.0000068  0.0000100    0.000045    0.000019
+2014   6  19  56827   0.158508   0.428886  -0.2955058   0.0011686   0.000006   0.000002   0.000058   0.000056  0.0000079  0.0000100    0.000086    0.000070
+2014   6  20  56828   0.159865   0.428145  -0.2966766   0.0011275   0.000006   0.000002   0.000052   0.000057  0.0000153  0.0000099    0.000097    0.000083
+2014   6  21  56829   0.160944   0.427272  -0.2977464   0.0009917   0.000006   0.000001   0.000051   0.000062  0.0000075  0.0000096    0.000097    0.000083
+2014   6  22  56830   0.161869   0.426250  -0.2986589   0.0008190   0.000006   0.000002   0.000053   0.000061  0.0000098  0.0000095    0.000097    0.000083
+2014   6  23  56831   0.163248   0.425126  -0.2994144   0.0006490   0.000006   0.000001   0.000047   0.000046  0.0000083  0.0000089    0.000097    0.000084
+2014   6  24  56832   0.164735   0.423900  -0.2999730   0.0004955   0.000006   0.000001   0.000046   0.000049  0.0000068  0.0000082    0.000097    0.000084
+2014   6  25  56833   0.166018   0.422594  -0.3003881   0.0003608   0.000139  -0.000190   0.000047   0.000055  0.0000054  0.0000085    0.000025    0.000033
+2014   6  26  56834   0.166820   0.421456  -0.3007136   0.0002264   0.000142  -0.000200   0.000046   0.000052  0.0000075  0.0000092    0.000025    0.000033
+2014   6  27  56835   0.167441   0.420226  -0.3008724   0.0001335   0.000145  -0.000210   0.000045   0.000054  0.0000071  0.0000096    0.000025    0.000033
+2014   6  28  56836   0.168132   0.419090  -0.3010209   0.0001572   0.000148  -0.000220   0.000045   0.000054  0.0000071  0.0000096    0.000024    0.000032
+2014   6  29  56837   0.168884   0.417834  -0.3012590   0.0002378   0.000152  -0.000229   0.000046   0.000049  0.0000122  0.0000096    0.000024    0.000032
+2014   6  30  56838   0.169659   0.416477  -0.3015202   0.0003181   0.000235  -0.000362   0.000046   0.000039  0.0000099  0.0000097    0.000023    0.000031
+2014   7   1  56839   0.170584   0.414989  -0.3018256   0.0003530   0.000221  -0.000347   0.000047   0.000037  0.0000065  0.0000097    0.000023    0.000030
+2014   7   2  56840   0.171897   0.413791  -0.3022262   0.0004064   0.000203  -0.000318   0.000050   0.000048  0.0000091  0.0000098    0.000023    0.000032
+2014   7   3  56841   0.173223   0.412770  -0.3026986   0.0004903   0.000171  -0.000272   0.000049   0.000055  0.0000049  0.0000102    0.000022    0.000031
+2014   7   4  56842   0.174571   0.411718  -0.3032319   0.0005509   0.000145  -0.000247   0.000048   0.000055  0.0000097  0.0000106    0.000022    0.000031
+2014   7   5  56843   0.175531   0.410939  -0.3037737   0.0005212   0.000124  -0.000234   0.000047   0.000055  0.0000136  0.0000102    0.000022    0.000030
+2014   7   6  56844   0.176357   0.409851  -0.3042749   0.0004462   0.000108  -0.000226   0.000048   0.000054  0.0000143  0.0000102    0.000022    0.000029
+2014   7   7  56845   0.177000   0.408770  -0.3047022   0.0003692   0.000097  -0.000245   0.000046   0.000054  0.0000130  0.0000101    0.000022    0.000028
+2014   7   8  56846   0.177602   0.407704  -0.3050522   0.0003207   0.000093  -0.000245   0.000043   0.000051  0.0000036  0.0000102    0.000023    0.000029
+2014   7   9  56847   0.178395   0.406780  -0.3053516   0.0002802   0.000119  -0.000230   0.000043   0.000050  0.0000088  0.0000104    0.000027    0.000034
+2014   7  10  56848   0.179056   0.405874  -0.3056398   0.0002773   0.000153  -0.000213   0.000043   0.000047  0.0000084  0.0000102    0.000033    0.000039
+2014   7  11  56849   0.180057   0.404783  -0.3059670   0.0003448   0.000189  -0.000199   0.000044   0.000046  0.0000032  0.0000103    0.000037    0.000045
+2014   7  12  56850   0.181119   0.403702  -0.3063817   0.0004355   0.000195  -0.000203   0.000043   0.000047  0.0000086  0.0000099    0.000037    0.000046
+2014   7  13  56851   0.182012   0.402757  -0.3069373   0.0006108   0.000187  -0.000214   0.000043   0.000042  0.0000108  0.0000099    0.000036    0.000045
+2014   7  14  56852   0.182718   0.401707  -0.3076573   0.0007967   0.000175  -0.000226   0.000044   0.000038  0.0000127  0.0000105    0.000034    0.000044
+2014   7  15  56853   0.183180   0.400689  -0.3085126   0.0008907   0.000160  -0.000236   0.000044   0.000040  0.0000038  0.0000101    0.000032    0.000043
+2014   7  16  56854   0.183580   0.399238  -0.3094304   0.0009331   0.000158  -0.000217   0.000045   0.000048  0.0000105  0.0000104    0.000023    0.000033
+2014   7  17  56855   0.184079   0.397872  -0.3103323   0.0008697   0.000158  -0.000190   0.000045   0.000051  0.0000137  0.0000108    0.000023    0.000034
+2014   7  18  56856   0.184391   0.396246  -0.3111578   0.0007346   0.000159  -0.000165   0.000048   0.000054  0.0000049  0.0000106    0.000024    0.000034
+2014   7  19  56857   0.185390   0.394567  -0.3118721   0.0006134   0.000147  -0.000169   0.000048   0.000055  0.0000062  0.0000107    0.000022    0.000031
+2014   7  20  56858   0.186474   0.393185  -0.3124308   0.0004603   0.000132  -0.000187   0.000045   0.000054  0.0000105  0.0000104    0.000019    0.000027
+2014   7  21  56859   0.187769   0.391873  -0.3128070   0.0002960   0.000122  -0.000207   0.000043   0.000053  0.0000088  0.0000099    0.000016    0.000023
+2014   7  22  56860   0.188753   0.391086  -0.3130140   0.0001491   0.000115  -0.000226   0.000043   0.000050  0.0000022  0.0000104    0.000013    0.000019
+2014   7  23  56861   0.189334   0.390032  -0.3131058   0.0000607   0.000139  -0.000245   0.000044   0.000049  0.0000068  0.0000103    0.000019    0.000029
+2014   7  24  56862   0.189640   0.389271  -0.3131380   0.0000216   0.000170  -0.000261   0.000044   0.000049  0.0000098  0.0000103    0.000029    0.000043
+2014   7  25  56863   0.190008   0.388135  -0.3131560   0.0000270   0.000199  -0.000275   0.000048   0.000050  0.0000056  0.0000104    0.000039    0.000057
+2014   7  26  56864   0.190391   0.387076  -0.3131850   0.0000236   0.000203  -0.000266   0.000049   0.000055  0.0000065  0.0000104    0.000037    0.000055
+2014   7  27  56865   0.190974   0.385960  -0.3132612   0.0000772   0.000193  -0.000248   0.000052   0.000058  0.0000075  0.0000108    0.000032    0.000047
+2014   7  28  56866   0.191997   0.384965  -0.3134196   0.0001990   0.000175  -0.000230   0.000055   0.000058  0.0000085  0.0000110    0.000027    0.000039
+2014   7  29  56867   0.193138   0.383991  -0.3136734   0.0003114   0.000150  -0.000214   0.000051   0.000058  0.0000024  0.0000112    0.000021    0.000031
+2014   7  30  56868   0.194141   0.382918  -0.3140315   0.0004025   0.000100  -0.000209   0.000052   0.000058  0.0000063  0.0000112    0.000033    0.000042
+2014   7  31  56869   0.194699   0.381742  -0.3144677   0.0004273   0.000043  -0.000210   0.000052   0.000053  0.0000080  0.0000111    0.000050    0.000058
+2014   8   1  56870   0.195488   0.380228  -0.3149194   0.0004133  -0.000012  -0.000215   0.000052   0.000060  0.0000047  0.0000106    0.000066    0.000074
+2014   8   2  56871   0.196059   0.379053  -0.3153221   0.0003478  -0.000026  -0.000244   0.000050   0.000064  0.0000091  0.0000106    0.000094    0.000120
+2014   8   3  56872   0.196656   0.377635  -0.3156532   0.0002844  -0.000020  -0.000282   0.000050   0.000057  0.0000122  0.0000105    0.000125    0.000176
+2014   8   4  56873   0.197587   0.376138  -0.3159237   0.0002234  -0.000008  -0.000314   0.000032   0.000051  0.0000120  0.0000101    0.000157    0.000232
+2014   8   5  56874   0.198589   0.374538  -0.3161087   0.0001660   0.000009  -0.000340   0.000028   0.000052  0.0000058  0.0000102    0.000189    0.000288
+2014   8   6  56875   0.199846   0.373215  -0.3162337   0.0000981   0.000012  -0.000319   0.000040   0.000054  0.0000101  0.0000106    0.000159    0.000244
+2014   8   7  56876   0.201159   0.372190  -0.3162889   0.0000444   0.000008  -0.000285   0.000044   0.000053  0.0000124  0.0000109    0.000117    0.000170
+2014   8   8  56877   0.202153   0.371221  -0.3164059   0.0001436   0.000004  -0.000244   0.000052   0.000053  0.0000052  0.0000103    0.000074    0.000097
+2014   8   9  56878   0.203137   0.370129  -0.3166604   0.0003298   0.000002  -0.000206   0.000053   0.000051  0.0000155  0.0000098    0.000299    0.000414
+2014   8  10  56879   0.204271   0.369117  -0.3170662   0.0004803  -0.000002  -0.000167   0.000049   0.000052  0.0000096  0.0000099    0.000621    0.000876
+2014   8  11  56880   0.205468   0.368306  -0.3176599   0.0006307  -0.000047  -0.000138   0.000043   0.000052  0.0000081  0.0000097    0.000992    0.001355
+2014   8  12  56881   0.206550   0.367611  -0.3183990   0.0007513  -0.000065  -0.000107   0.000046   0.000045  0.0000203  0.0000093    0.001331    0.001822
+2014   8  13  56882   0.207368   0.366875  -0.3192062   0.0008270  -0.000084  -0.000095   0.000045   0.000042  0.0000110  0.0000092    0.001038    0.001446
+2014   8  14  56883   0.207974   0.366035  -0.3200319   0.0008146  -0.000093  -0.000103   0.000042   0.000045  0.0000084  0.0000093    0.000603    0.000837
+2014   8  15  56884   0.208833   0.364879  -0.3207940   0.0006881  -0.000096  -0.000121   0.000038   0.000045  0.0000045  0.0000095    0.000167    0.000229
+2014   8  16  56885   0.209661   0.363515  -0.3214326   0.0005603  -0.000074  -0.000160   0.000037   0.000047  0.0000088  0.0000099    0.000043    0.000056
+2014   8  17  56886   0.210175   0.362120  -0.3219427   0.0004528  -0.000040  -0.000207   0.000039   0.000050  0.0000068  0.0000099    0.000034    0.000044
+2014   8  18  56887   0.210355   0.360764  -0.3223478   0.0003616  -0.000004  -0.000253   0.000043   0.000050  0.0000052  0.0000104    0.000024    0.000032
+2014   8  19  56888   0.210028   0.359301  -0.3226678   0.0002524   0.000032  -0.000293   0.000044   0.000050  0.0000014  0.0000106    0.000015    0.000021
+2014   8  20  56889   0.209735   0.357770  -0.3228885   0.0001935   0.000032  -0.000272   0.000044   0.000043  0.0000064  0.0000091    0.000023    0.000035
+2014   8  21  56890   0.209563   0.356134  -0.3230546   0.0001592   0.000017  -0.000229   0.000044   0.000040  0.0000131  0.0000087    0.000035    0.000056
+2014   8  22  56891   0.209708   0.354414  -0.3232201   0.0001612  -0.000001  -0.000178   0.000041   0.000040  0.0000077  0.0000095    0.000048    0.000078
+2014   8  23  56892   0.209551   0.352545  -0.3234237   0.0002217   0.000002  -0.000161   0.000040   0.000038  0.0000074  0.0000102    0.000044    0.000071
+2014   8  24  56893   0.209543   0.350682  -0.3236530   0.0002419   0.000006  -0.000147   0.000044   0.000046  0.0000104  0.0000108    0.000035    0.000055
+2014   8  25  56894   0.209475   0.348842  -0.3239004   0.0002416   0.000015  -0.000140   0.000045   0.000049  0.0000080  0.0000101    0.000025    0.000039
+2014   8  26  56895   0.209267   0.346963  -0.3242013   0.0003364   0.000023  -0.000138   0.000045   0.000055  0.0000019  0.0000105    0.000016    0.000023
+2014   8  27  56896   0.209107   0.344999  -0.3245978   0.0004450   0.000043  -0.000110   0.000045   0.000056  0.0000091  0.0000106    0.000032    0.000048
+2014   8  28  56897   0.208963   0.342830  -0.3250736   0.0004697   0.000063  -0.000082   0.000045   0.000047  0.0000061  0.0000105    0.000056    0.000085
+2014   8  29  56898   0.209048   0.340905  -0.3255686   0.0004805   0.000079  -0.000068   0.000093   0.000037  0.0000031  0.0000102    0.000080    0.000122
+2014   8  30  56899   0.209434   0.339465  -0.3260477   0.0004905   0.000079  -0.000093   0.000141   0.000040  0.0000068  0.0000100    0.000075    0.000115
+2014   8  31  56900   0.209548   0.338221  -0.3265573   0.0004982   0.000069  -0.000137   0.000092   0.000049  0.0000066  0.0000106    0.000059    0.000091
+2014   9   1  56901   0.209607   0.336852  -0.3270923   0.0005358   0.000054  -0.000184   0.000045   0.000049  0.0000071  0.0000105    0.000048    0.000067
+2014   9   2  56902   0.209660   0.335219  -0.3276247   0.0005220   0.000034  -0.000240   0.000045   0.000046  0.0000081  0.0000101    0.000031    0.000043
+2014   9   3  56903   0.209254   0.333379  -0.3281455   0.0005160   0.000011  -0.000293   0.000046   0.000050  0.0000025  0.0000098    0.000014    0.000019
+2014   9   4  56904   0.209037   0.331518  -0.3286822   0.0005560  -0.000023  -0.000355   0.000050   0.000053  0.0000089  0.0000108    0.000021    0.000030
+2014   9   5  56905   0.209082   0.329809  -0.3292906   0.0006680  -0.000059  -0.000410   0.000054   0.000053  0.0000053  0.0000111    0.000036    0.000050
+2014   9   6  56906   0.209238   0.328265  -0.3300434   0.0008406  -0.000078  -0.000440   0.000050   0.000050  0.0000118  0.0000107    0.000037    0.000054
+2014   9   7  56907   0.209075   0.326903  -0.3309869   0.0010189  -0.000089  -0.000448   0.000050   0.000050  0.0000100  0.0000107    0.000034    0.000051
+2014   9   8  56908   0.208594   0.325623  -0.3321229   0.0011916  -0.000076  -0.000421   0.000051   0.000050  0.0000101  0.0000105    0.000029    0.000048
+2014   9   9  56909   0.207951   0.324033  -0.3333963   0.0013135  -0.000087  -0.000403   0.000047   0.000050  0.0000035  0.0000110    0.000026    0.000045
+2014   9  10  56910   0.207098   0.322101  -0.3346955   0.0012470  -0.000194  -0.000425   0.000050   0.000052  0.0000057  0.0000113    0.000026    0.000045
+2014   9  11  56911   0.205714   0.319840  -0.3358990   0.0011095  -0.000318  -0.000445   0.000054   0.000052  0.0000080  0.0000106    0.000027    0.000045
+2014   9  12  56912   0.204830   0.317418  -0.3369328   0.0009286  -0.000427  -0.000456   0.000054   0.000051  0.0000031  0.0000110    0.000029    0.000044
+2014   9  13  56913   0.203746   0.315472  -0.3377885   0.0007454  -0.000426  -0.000412   0.000050   0.000048  0.0000097  0.0000113    0.000031    0.000044
+2014   9  14  56914   0.203351   0.313633  -0.3384975   0.0006390  -0.000371  -0.000343   0.000047   0.000039  0.0000123  0.0000111    0.000032    0.000042
+2014   9  15  56915   0.203062   0.312329  -0.3391027   0.0005878  -0.000294  -0.000265   0.000046   0.000040  0.0000107  0.0000100    0.000035    0.000044
+2014   9  16  56916   0.202703   0.310813  -0.3396742   0.0005895  -0.000207  -0.000192   0.000048   0.000049  0.0000033  0.0000104    0.000036    0.000043
+2014   9  17  56917   0.201975   0.309541  -0.3402700   0.0006144  -0.000129  -0.000175   0.000049   0.000047  0.0000096  0.0000104    0.000059    0.000086
+2014   9  18  56918   0.201157   0.308055  -0.3409300   0.0006713  -0.000056  -0.000175   0.000043   0.000043  0.0000067  0.0000098    0.000088    0.000142
+2014   9  19  56919   0.200493   0.306730  -0.3416089   0.0007017   0.000010  -0.000178   0.000047   0.000043  0.0000033  0.0000096    0.000117    0.000198
+2014   9  20  56920   0.199681   0.304945  -0.3423237   0.0007115   0.000012  -0.000179   0.000048   0.000048  0.0000170  0.0000097    0.000107    0.000180
+2014   9  21  56921   0.198904   0.303294  -0.3430803   0.0007730  -0.000016  -0.000178   0.000095   0.000097  0.0000081  0.0000126    0.000082    0.000135
+2014   9  22  56922   0.198190   0.301444  -0.3439067   0.0008664  -0.000051  -0.000184   0.000054   0.000042  0.0000050  0.0000109    0.000054    0.000087
+2014   9  23  56923   0.197758   0.299623  -0.3448263   0.0009065  -0.000093  -0.000182   0.000054   0.000045  0.0000014  0.0000105    0.000027    0.000039
+2014   9  24  56924   0.196669   0.297934  -0.3457492   0.0009076  -0.000114  -0.000175   0.000049   0.000048  0.0000075  0.0000104    0.000031    0.000035
+2014   9  25  56925   0.196285   0.296429  -0.3466943   0.0009157  -0.000128  -0.000164   0.000049   0.000044  0.0000093  0.0000107    0.000040    0.000035
+2014   9  26  56926   0.195452   0.295342  -0.3475866   0.0008377  -0.000138  -0.000149   0.000051   0.000045  0.0000142  0.0000108    0.000049    0.000036
+2014   9  27  56927   0.194323   0.294143  -0.3483859   0.0007754  -0.000142  -0.000132   0.000051   0.000047  0.0000198  0.0000105    0.000058    0.000036
+2014   9  28  56928   0.193133   0.293124  -0.3491545   0.0007088  -0.000139  -0.000113   0.000051   0.000048  0.0000097  0.0000102    0.000067    0.000037
+2014   9  29  56929   0.192130   0.291847  -0.3498679   0.0006806  -0.000128  -0.000094   0.000051   0.000048  0.0000089  0.0000109    0.000076    0.000037
+2014   9  30  56930   0.190874   0.290408  -0.3505605   0.0006997  -0.000113  -0.000074   0.000047   0.000045  0.0000059  0.0000110    0.000085    0.000037
+2014  10   1  56931   0.189318   0.288872  -0.3513037   0.0007266  -0.000112  -0.000090   0.000044   0.000045  0.0000166  0.0000112    0.000081    0.000040
+2014  10   2  56932   0.187956   0.287386  -0.3520541   0.0008158  -0.000115  -0.000116   0.000044   0.000045  0.0000082  0.0000113    0.000074    0.000043
+2014  10   3  56933   0.186389   0.286356  -0.3529071   0.0009631  -0.000121  -0.000146   0.000047   0.000044  0.0000103  0.0000117    0.000067    0.000046
+2014  10   4  56934   0.184585   0.285100  -0.3540090   0.0011566  -0.000130  -0.000180   0.000046   0.000047  0.0000068  0.0000120    0.000060    0.000048
+2014  10   5  56935   0.182947   0.283920  -0.3553203   0.0013443  -0.000144  -0.000217   0.000117   0.000120  0.0000075  0.0000147    0.000053    0.000051
+2014  10   6  56936   0.180779   0.282637  -0.3567873   0.0014802  -0.000161  -0.000256   0.000166   0.000156  0.0000072  0.0000178    0.000046    0.000054
+2014  10   7  56937   0.178546   0.281129  -0.3583098   0.0015691  -0.000181  -0.000296   0.000152   0.000093  0.0000023  0.0000183    0.000039    0.000057
+2014  10   8  56938   0.176423   0.279499  -0.3599090   0.0015736   0.000006   0.000001   0.000156   0.000093  0.0000062  0.0000211    0.000084    0.000082
+2014  10   9  56939   0.174485   0.277995  -0.3614646   0.0014499   0.000006   0.000001   0.000155   0.000127  0.0000104  0.0000255    0.000096    0.000088
+2014  10  10  56940   0.172103   0.276889  -0.3628205   0.0012442   0.000006   0.000001   0.000121   0.000133  0.0000089  0.0000251    0.000096    0.000088
+2014  10  11  56941   0.169489   0.275710  -0.3639987   0.0011122   0.000006   0.000001   0.000065   0.000153  0.0000142  0.0000185    0.000096    0.000088
+2014  10  12  56942   0.167093   0.274277  -0.3650981   0.0010341   0.000006   0.000001   0.000078   0.000143  0.0000077  0.0000230    0.000096    0.000088
+2014  10  13  56943   0.164890   0.272948  -0.3660845   0.0009275  -0.000255  -0.000206   0.000040   0.000045  0.0000077  0.0000111    0.000090    0.000054
+2014  10  14  56944   0.163203   0.271598  -0.3670167   0.0008701  -0.000280  -0.000207   0.000037   0.000045  0.0000075  0.0000109    0.000099    0.000053
+2014  10  15  56945   0.161813   0.270633  -0.3679266   0.0009070  -0.000230  -0.000181   0.000038   0.000042  0.0000262  0.0000104    0.000046    0.000068
+2014  10  16  56946   0.160357   0.269562  -0.3688523   0.0009337  -0.000254  -0.000169   0.000041   0.000039  0.0000105  0.0000100    0.000040    0.000059
+2014  10  17  56947   0.158884   0.268422  -0.3698265   0.0009569  -0.000264  -0.000149   0.000041   0.000040  0.0000127  0.0000102    0.000034    0.000050
+2014  10  18  56948   0.157651   0.267426  -0.3707948   0.0010416  -0.000259  -0.000123   0.000042   0.000047  0.0000085  0.0000103    0.000028    0.000041
+2014  10  19  56949   0.156177   0.266392  -0.3718466   0.0011161  -0.000242  -0.000094   0.000043   0.000051  0.0000052  0.0000105    0.000022    0.000032
+2014  10  20  56950   0.154958   0.265161  -0.3730119   0.0011923  -0.000200  -0.000064   0.000041   0.000050  0.0000051  0.0000108    0.000017    0.000027
+2014  10  21  56951   0.153574   0.264153  -0.3742853   0.0012885  -0.000180  -0.000036   0.000040   0.000048  0.0000013  0.0000104    0.000010    0.000017
+2014  10  22  56952   0.152558   0.263215  -0.3756440   0.0013639  -0.000193  -0.000039   0.000040   0.000043  0.0000130  0.0000099    0.000015    0.000024
+2014  10  23  56953   0.151228   0.262577  -0.3770165   0.0013355  -0.000214  -0.000052   0.000041   0.000043  0.0000087  0.0000105    0.000022    0.000036
+2014  10  24  56954   0.149374   0.261563  -0.3783068   0.0012539  -0.000234  -0.000069   0.000042   0.000040  0.0000094  0.0000109    0.000029    0.000047
+2014  10  25  56955   0.147315   0.260313  -0.3794935   0.0011371  -0.000249  -0.000087   0.000041   0.000042  0.0000154  0.0000108    0.000037    0.000058
+2014  10  26  56956   0.144800   0.259081  -0.3805876   0.0010363  -0.000257  -0.000103   0.000041   0.000049  0.0000343  0.0000107    0.000044    0.000070
+2014  10  27  56957   0.142599   0.257845  -0.3816146   0.0009852  -0.000257  -0.000140   0.000092   0.000040  0.0000168  0.0000106    0.000068    0.000110
+2014  10  28  56958   0.140679   0.257127  -0.3825948   0.0009811  -0.000253  -0.000132   0.000160   0.000043  0.0000025  0.0000106    0.000064    0.000098
+2014  10  29  56959   0.138887   0.256743  -0.3836041   0.0010379  -0.000248  -0.000132   0.000054   0.000051  0.0000067  0.0000111    0.000055    0.000084
+2014  10  30  56960   0.137040   0.256321  -0.3846753   0.0011158  -0.000245  -0.000130   0.000052   0.000045  0.0000117  0.0000110    0.000051    0.000076
+2014  10  31  56961   0.134912   0.256031  -0.3858180   0.0011950  -0.000238  -0.000123   0.000053   0.000048  0.0000147  0.0000107    0.000046    0.000068
+2014  11   1  56962   0.132543   0.255442  -0.3871212   0.0013869  -0.000226  -0.000113   0.000051   0.000050  0.0000091  0.0000093    0.000041    0.000060
+2014  11   2  56963   0.130232   0.254603  -0.3886438   0.0016138  -0.000210  -0.000100   0.000052   0.000049  0.0000048  0.0000093    0.000037    0.000053
+2014  11   3  56964   0.128111   0.253639  -0.3903200   0.0016976  -0.000164  -0.000106   0.000054   0.000054  0.0000065  0.0000118    0.000031    0.000043
+2014  11   4  56965   0.126579   0.253032  -0.3920232   0.0016614  -0.000167  -0.000073   0.000054   0.000055  0.0000020  0.0000115    0.000028    0.000037
+2014  11   5  56966   0.125141   0.253027  -0.3936596   0.0015815  -0.000159  -0.000058   0.000051   0.000046  0.0000061  0.0000104    0.000036    0.000038
+2014  11   6  56967   0.123815   0.253026  -0.3951745   0.0014250  -0.000152  -0.000049   0.000048   0.000042  0.0000104  0.0000104    0.000047    0.000040
+2014  11   7  56968   0.122208   0.252696  -0.3965413   0.0012620  -0.000152  -0.000043   0.000045   0.000040  0.0000069  0.0000102    0.000057    0.000041
+2014  11   8  56969   0.120656   0.252119  -0.3977463   0.0011065  -0.000160  -0.000042   0.000047   0.000043  0.0000071  0.0000100    0.000068    0.000043
+2014  11   9  56970   0.118629   0.251863  -0.3987699   0.0009636  -0.000174  -0.000044   0.000047   0.000051  0.0000085  0.0000103    0.000078    0.000045
+2014  11  10  56971   0.116099   0.251414  -0.3996746   0.0008574  -0.000161  -0.000002   0.000046   0.000053  0.0000086  0.0000102    0.000051    0.000050
+2014  11  11  56972   0.113500   0.251104  -0.4005178   0.0008228  -0.000151  -0.000007   0.000050   0.000051  0.0000024  0.0000099    0.000041    0.000054
+2014  11  12  56973   0.111312   0.251020  -0.4013658   0.0008665  -0.000162  -0.000024   0.000048   0.000043  0.0000046  0.0000100    0.000039    0.000054
+2014  11  13  56974   0.110003   0.251216  -0.4022707   0.0009353  -0.000177  -0.000044   0.000048   0.000042  0.0000055  0.0000097    0.000038    0.000052
+2014  11  14  56975   0.108964   0.251454  -0.4032264   0.0009816  -0.000186  -0.000065   0.000049   0.000045  0.0000037  0.0000100    0.000037    0.000050
+2014  11  15  56976   0.107343   0.251845  -0.4042241   0.0010274  -0.000188  -0.000083   0.000045   0.000045  0.0000062  0.0000097    0.000036    0.000048
+2014  11  16  56977   0.105169   0.252103  -0.4052751   0.0010661  -0.000184  -0.000098   0.000048   0.000045  0.0000058  0.0000095    0.000035    0.000046
+2014  11  17  56978   0.103098   0.252264  -0.4064355   0.0011845  -0.000152  -0.000102   0.000048   0.000044  0.0000044  0.0000100    0.000035    0.000044
+2014  11  18  56979   0.101176   0.252904  -0.4076894   0.0012749  -0.000153  -0.000110   0.000045   0.000045  0.0000016  0.0000095    0.000035    0.000042
+2014  11  19  56980   0.098823   0.253529  -0.4089491   0.0012414  -0.000169  -0.000115   0.000044   0.000045  0.0000065  0.0000093    0.000044    0.000057
+2014  11  20  56981   0.096626   0.253739  -0.4101760   0.0011773  -0.000188  -0.000116   0.000042   0.000043  0.0000082  0.0000097    0.000058    0.000076
+2014  11  21  56982   0.094796   0.254068  -0.4113379   0.0011179  -0.000202  -0.000111   0.000039   0.000039  0.0000072  0.0000099    0.000071    0.000094
+2014  11  22  56983   0.093033   0.254309  -0.4124443   0.0010844  -0.000210  -0.000102   0.000041   0.000041  0.0000066  0.0000102    0.000085    0.000113
+2014  11  23  56984   0.091069   0.254329  -0.4135151   0.0010236  -0.000210  -0.000090   0.000041   0.000041  0.0000080  0.0000102    0.000098    0.000132
+2014  11  24  56985   0.089517   0.254009  -0.4145452   0.0009802  -0.000188  -0.000085   0.000038   0.000041  0.0000068  0.0000094    0.000111    0.000152
+2014  11  25  56986   0.088570   0.253867  -0.4155369   0.0009914  -0.000187  -0.000063   0.000038   0.000041  0.0000023  0.0000095    0.000124    0.000171
+2014  11  26  56987   0.087552   0.254012  -0.4165109   0.0009976  -0.000183  -0.000036   0.000041   0.000041  0.0000047  0.0000098    0.000120    0.000161
+2014  11  27  56988   0.086952   0.254412  -0.4175503   0.0010687  -0.000178  -0.000006   0.000041   0.000041  0.0000117  0.0000099    0.000112    0.000140
+2014  11  28  56989   0.086367   0.255252  -0.4187293   0.0012598  -0.000175   0.000026   0.000037   0.000037  0.0000138  0.0000094    0.000104    0.000120
+2014  11  29  56990   0.085070   0.256037  -0.4200746   0.0014142  -0.000175   0.000058   0.000032   0.000033  0.0000103  0.0000093    0.000097    0.000100
+2014  11  30  56991   0.083120   0.256681  -0.4215228   0.0014855  -0.000177   0.000089   0.000032   0.000033  0.0000085  0.0000097    0.000089    0.000079
+2014  12   1  56992   0.080978   0.257672  -0.4230186   0.0014738  -0.000181   0.000114   0.000040   0.000042  0.0000066  0.0000092    0.000081    0.000059
+2014  12   2  56993   0.078981   0.258716  -0.4244887   0.0014182  -0.000189   0.000140   0.000044   0.000045  0.0000055  0.0000088    0.000073    0.000038
+2014  12   3  56994   0.076898   0.259439  -0.4258803   0.0013632  -0.000208   0.000163   0.000041   0.000040  0.0000071  0.0000094    0.000074    0.000035
+2014  12   4  56995   0.074791   0.259882  -0.4272193   0.0012881  -0.000228   0.000181   0.000037   0.000037  0.0000105  0.0000086    0.000078    0.000036
+2014  12   5  56996   0.073083   0.260106  -0.4284417   0.0011536  -0.000242   0.000190   0.000037   0.000035  0.0000115  0.0000081    0.000081    0.000037
+2014  12   6  56997   0.072034   0.260884  -0.4295356   0.0010319  -0.000249   0.000191   0.000034   0.000035  0.0000045  0.0000088    0.000084    0.000038
+2014  12   7  56998   0.070757   0.261940  -0.4305244   0.0009414  -0.000246   0.000182   0.000034   0.000037  0.0000060  0.0000092    0.000088    0.000039
+2014  12   8  56999   0.069469   0.262554  -0.4314891   0.0009521  -0.000267   0.000035   0.000037   0.000039  0.0000055  0.0000092    0.000105    0.000138
+2014  12   9  57000   0.067567   0.263597  -0.4324693   0.0010019  -0.000256   0.000006   0.000033   0.000036  0.0000070  0.0000089    0.000118    0.000154
+2014  12  10  57001   0.065145   0.264300  -0.4334848   0.0010511  -0.000233  -0.000030   0.000034   0.000036  0.0000035  0.0000088    0.000125    0.000167
+2014  12  11  57002   0.062825   0.265096  -0.4345401   0.0011038  -0.000198   0.000007   0.000041   0.000039  0.0000098  0.0000088    0.000133    0.000168
+2014  12  12  57003   0.060561   0.266065  -0.4357065   0.0011858  -0.000160   0.000063   0.000041   0.000039  0.0000055  0.0000083    0.000142    0.000164
+2014  12  13  57004   0.058293   0.267322  -0.4369431   0.0012466  -0.000128   0.000123   0.000037   0.000040  0.0000068  0.0000083    0.000151    0.000159
+2014  12  14  57005   0.055679   0.268340  -0.4381812   0.0012168  -0.000103   0.000190   0.000037   0.000040  0.0000064  0.0000089    0.000160    0.000155
+2014  12  15  57006   0.052986   0.269413  -0.4393885   0.0012053  -0.000122   0.000214   0.000038   0.000037  0.0000084  0.0000093    0.000093    0.000161
+2014  12  16  57007   0.050226   0.270617  -0.4406630   0.0012952  -0.000100   0.000248   0.000038   0.000033  0.0000036  0.0000094    0.000084    0.000159
+2014  12  17  57008   0.047395   0.271695  -0.4419529   0.0012994  -0.000120   0.000242   0.000038   0.000036  0.0000136  0.0000093    0.000037    0.000069
diff --git a/astropy/utils/iers/iers.py b/astropy/utils/iers/iers.py
index 5be60a0..1f17c52 100644
--- a/astropy/utils/iers/iers.py
+++ b/astropy/utils/iers/iers.py
@@ -3,8 +3,12 @@
 The astropy.utils.iers package provides access to the tables provided by
 the International Earth Rotation and Reference Systems Service, in
 particular allowing interpolation of published UT1-UTC values for given
-times.  These are used in astropy.time to provide UT1 values.  By
-default, IERS B values provided as part of astropy are used, but
+times.  These are used in `astropy.time` to provide UT1 values.  The polar
+motions are also used for determining earth orientation for
+celestional-to-terrestrial coordinate transformations
+(in `astropy.coordinates`).
+
+By default, IERS B values provided as part of astropy are used, but
 user-downloaded files can be substituted.
 
 Generally, there is no need to invoke the iers classes oneself.  E.g.,
@@ -54,6 +58,7 @@ from __future__ import (absolute_import, division, print_function,
 
 import numpy as np
 
+from ... import units as u
 from ...table import Table
 from ...utils.data import get_pkg_data_filename
 
@@ -86,7 +91,7 @@ class IERS(Table):
     """Generic IERS table class, defining interpolation functions.
 
     Sub-classed from `astropy.table.Table`.  The table should hold columns
-    'MJD' and 'UT1_UTC'.
+    'MJD', 'UT1_UTC', and 'PM_x'/'PM_y'.
     """
 
     iers_table = None
@@ -230,10 +235,85 @@ class IERS(Table):
                                  'by IERS table.')
             return ut1_utc
 
+    def pm_xy(self, jd1, jd2=0., return_status=False):
+        """Interpolate polar motions from IERS Table for given dates.
+
+        Parameters
+        ----------
+        jd1 : float, float array, or Time object
+            first part of two-part JD, or Time object
+        jd2 : float or float array, optional
+            second part of two-part JD (default 0., ignored if jd1 is Time)
+        return_status : bool
+            Whether to return status values.  If False (default),
+            raise `IndexError` if any time is out of the range covered
+            by the IERS table.
+
+        Returns
+        -------
+        PM_x : Quantity with angle units
+            x component of polar motion for the requested times
+        PM_y : Quantity with angle units
+            y component of polar motion for the requested times
+        status : int or int array
+            Status values (if `return_status`=`True`)::
+            `iers.FROM_IERS_B`
+            `iers.FROM_IERS_A`
+            `iers.FROM_IERS_A_PREDICTION`
+            `iers.TIME_BEFORE_IERS_RANGE`
+            `iers.TIME_BEYOND_IERS_RANGE`
+        """
+
+        mjd, utc = self.mjd_utc(jd1, jd2)
+        # enforce array
+        is_scalar = not hasattr(mjd, '__array__') or mjd.ndim == 0
+        if is_scalar:
+            mjd = np.array([mjd])
+            utc = np.array([utc])
+        # For typical format, will always find a match (since MJD are integer)
+        # hence, important to define which side we will be; this ensures
+        # self['MJD'][i-1]<=mjd<self['MJD'][i]
+        i = np.searchsorted(self['MJD'], mjd, side='right')
+        # Get index to MJD at or just below given mjd, clipping to ensure we
+        # stay in range of table (status will be set below for those outside)
+        i1 = np.clip(i, 1, len(self)-1)
+        i0 = i1-1
+        mjd_0, mjd_1 = self['MJD'][i0], self['MJD'][i1]
+        pm_x_0, pm_x_1 = self['PM_x'][i0], self['PM_x'][i1]
+        pm_y_0, pm_y_1 = self['PM_y'][i0], self['PM_y'][i1]
+
+        # Linearly interpolate both components
+        pm_x = u.Quantity(pm_x_0 + (mjd - mjd_0)*(pm_x_1 - pm_x_0)/(mjd_1 - mjd_0), copy=False)
+        pm_y = u.Quantity(pm_y_0 + (mjd - mjd_0)*(pm_y_1 - pm_y_0)/(mjd_1 - mjd_0), copy=False)
+
+        if is_scalar:
+            pm_x = pm_x[0]
+            pm_y = pm_y[0]
+
+        if return_status:
+            # Set status to source, possibly using routine provided by subclass
+            status = self.pm_source(i1)
+            # Check for out of range
+            status[i == 0] = TIME_BEFORE_IERS_RANGE
+            status[i == len(self)] = TIME_BEYOND_IERS_RANGE
+            if is_scalar:
+                status = status[0]
+            return pm_x, pm_y, status
+        else:
+            # Not returning status, so raise an exception for out-of-range
+            if np.any(i1 != i):
+                raise IndexError('(some) times are outside of range covered '
+                                 'by IERS table.')
+            return pm_x, pm_y
+
     def ut1_utc_source(self, i):
         """Source for UT1-UTC.  To be overridden by subclass."""
         return np.zeros_like(i)
 
+    def pm_source(self, i):
+        """Source for polar motion.  To be overridden by subclass."""
+        return np.zeros_like(i)
+
 
 class IERS_A(IERS):
     """IERS Table class targeted to IERS A, provided by USNO.
@@ -264,6 +344,18 @@ class IERS_A(IERS):
         table['UT1Flag'] = np.where(table['UT1_UTC_B'].mask,
                                     table['UT1Flag_A'].data,
                                     'B')
+        #repeat for polar motions
+        table['PM_x'] = np.where(table['PM_X_B'].mask,
+                                 table['PM_x_A'].data,
+                                 table['PM_X_B'].data)
+        table['PM_x'].unit = table['PM_x_A'].unit  # needed for Quantity-ing
+        table['PM_y'] = np.where(table['PM_Y_B'].mask,
+                                 table['PM_y_A'].data,
+                                 table['PM_Y_B'].data)
+        table['PM_y'].unit = table['PM_y_A'].unit  # needed for Quantity-ing
+        table['PolPMFlag'] = np.where(table['PM_X_B'].mask,
+                                      table['PolPMFlag_A'].data,
+                                      'B')
         super(IERS_A, self).__init__(table.filled())
 
     @classmethod
@@ -299,6 +391,14 @@ class IERS_A(IERS):
         source[ut1flag == 'P'] = FROM_IERS_A_PREDICTION
         return source
 
+    def pm_source(self, i):
+        """Set polar motion source flag for entries in IERS table"""
+        pmflag = self['PolPMFlag'][i]
+        source = np.ones_like(i) * FROM_IERS_B
+        source[pmflag == 'I'] = FROM_IERS_A
+        source[pmflag == 'P'] = FROM_IERS_A_PREDICTION
+        return source
+
 
 class IERS_B(IERS):
     """IERS Table class targeted to IERS B, provided by IERS itself.
@@ -348,5 +448,9 @@ class IERS_B(IERS):
         """Set UT1-UTC source flag for entries in IERS table"""
         return np.ones_like(i) * FROM_IERS_B
 
+    def pm_source(self, i):
+        """Set PM source flag for entries in IERS table"""
+        return np.ones_like(i) * FROM_IERS_B
+
 # by default for IERS class, read IERS-B table
 IERS.read = IERS_B.read
diff --git a/astropy/utils/introspection.py b/astropy/utils/introspection.py
new file mode 100644
index 0000000..6a77f4d
--- /dev/null
+++ b/astropy/utils/introspection.py
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""Functions related to Python runtime introspection."""
+
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+
+import inspect
+import sys
+import types
+
+from ..extern import six
+
+
+__all__ = ['find_current_module', 'isinstancemethod']
+
+
+__doctest_skip__ = ['find_current_module']
+
+
+def find_current_module(depth=1, finddiff=False):
+    """
+    Determines the module/package from which this function is called.
+
+    This function has two modes, determined by the ``finddiff`` option. it
+    will either simply go the requested number of frames up the call
+    stack (if ``finddiff`` is False), or it will go up the call stack until
+    it reaches a module that is *not* in a specified set.
+
+    Parameters
+    ----------
+    depth : int
+        Specifies how far back to go in the call stack (0-indexed, so that
+        passing in 0 gives back `astropy.utils.misc`).
+    finddiff : bool or list
+        If False, the returned ``mod`` will just be ``depth`` frames up from
+        the current frame. Otherwise, the function will start at a frame
+        ``depth`` up from current, and continue up the call stack to the
+        first module that is *different* from those in the provided list.
+        In this case, ``finddiff`` can be a list of modules or modules
+        names. Alternatively, it can be True, which will use the module
+        ``depth`` call stack frames up as the module the returned module
+        most be different from.
+
+    Returns
+    -------
+    mod : module or None
+        The module object or None if the package cannot be found. The name of
+        the module is available as the ``__name__`` attribute of the returned
+        object (if it isn't None).
+
+    Raises
+    ------
+    ValueError
+        If ``finddiff`` is a list with an invalid entry.
+
+    Examples
+    --------
+    The examples below assume that there are two modules in a package named
+    ``pkg``. ``mod1.py``::
+
+        def find1():
+            from astropy.utils import find_current_module
+            print find_current_module(1).__name__
+        def find2():
+            from astropy.utils import find_current_module
+            cmod = find_current_module(2)
+            if cmod is None:
+                print 'None'
+            else:
+                print cmod.__name__
+        def find_diff():
+            from astropy.utils import find_current_module
+            print find_current_module(0,True).__name__
+
+    ``mod2.py``::
+
+        def find():
+            from .mod1 import find2
+            find2()
+
+    With these modules in place, the following occurs::
+
+        >>> from pkg import mod1, mod2
+        >>> from astropy.utils import find_current_module
+        >>> mod1.find1()
+        pkg.mod1
+        >>> mod1.find2()
+        None
+        >>> mod2.find()
+        pkg.mod2
+        >>> find_current_module(0)
+        <module 'astropy.utils.misc' from 'astropy/utils/misc.py'>
+        >>> mod1.find_diff()
+        pkg.mod1
+
+    """
+
+    frm = inspect.currentframe()
+    for i in range(depth):
+        frm = frm.f_back
+        if frm is None:
+            return None
+
+    if finddiff:
+        currmod = inspect.getmodule(frm)
+        if finddiff is True:
+            diffmods = [currmod]
+        else:
+            diffmods = []
+            for fd in finddiff:
+                if inspect.ismodule(fd):
+                    diffmods.append(fd)
+                elif isinstance(fd, six.string_types):
+                    diffmods.append(__import__(fd))
+                elif fd is True:
+                    diffmods.append(currmod)
+                else:
+                    raise ValueError('invalid entry in finddiff')
+
+        while frm:
+            frmb = frm.f_back
+            modb = inspect.getmodule(frmb)
+            if modb not in diffmods:
+                return modb
+            frm = frmb
+    else:
+        return inspect.getmodule(frm)
+
+
+def find_mod_objs(modname, onlylocals=False):
+    """ Returns all the public attributes of a module referenced by name.
+
+    .. note::
+        The returned list *not* include subpackages or modules of
+        ``modname``, nor does it include private attributes (those that
+        begin with '_' or are not in `__all__`).
+
+    Parameters
+    ----------
+    modname : str
+        The name of the module to search.
+    onlylocals : bool or list of str
+        If `True`, only attributes that are either members of ``modname`` OR
+        one of its modules or subpackages will be included. If it is a list
+        of strings, those specify the possible packages that will be
+        considered "local".
+
+    Returns
+    -------
+    localnames : list of str
+        A list of the names of the attributes as they are named in the
+        module ``modname`` .
+    fqnames : list of str
+        A list of the full qualified names of the attributes (e.g.,
+        ``astropy.utils.introspection.find_mod_objs``). For attributes that are
+        simple variables, this is based on the local name, but for functions or
+        classes it can be different if they are actually defined elsewhere and
+        just referenced in ``modname``.
+    objs : list of objects
+        A list of the actual attributes themselves (in the same order as
+        the other arguments)
+
+    """
+
+    __import__(modname)
+    mod = sys.modules[modname]
+
+    if hasattr(mod, '__all__'):
+        pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__]
+    else:
+        pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_']
+
+    # filter out modules and pull the names and objs out
+    ismodule = inspect.ismodule
+    localnames = [k for k, v in pkgitems if not ismodule(v)]
+    objs = [v for k, v in pkgitems if not ismodule(v)]
+
+    # fully qualified names can be determined from the object's module
+    fqnames = []
+    for obj, lnm in zip(objs, localnames):
+        if hasattr(obj, '__module__') and hasattr(obj, '__name__'):
+            fqnames.append(obj.__module__ + '.' + obj.__name__)
+        else:
+            fqnames.append(modname + '.' + lnm)
+
+    if onlylocals:
+        if onlylocals is True:
+            onlylocals = [modname]
+        valids = [any([fqn.startswith(nm) for nm in onlylocals]) for fqn in fqnames]
+        localnames = [e for i, e in enumerate(localnames) if valids[i]]
+        fqnames = [e for i, e in enumerate(fqnames) if valids[i]]
+        objs = [e for i, e in enumerate(objs) if valids[i]]
+
+    return localnames, fqnames, objs
+
+
+# Note: I would have preferred call this is_instancemethod, but this naming is
+# for consistency with other functions in the `inspect` module
+def isinstancemethod(cls, obj):
+    """
+    Returns `True` if the given object is an instance method of the class
+    it is defined on (as opposed to a `staticmethod` or a `classmethod`).
+
+    This requires both the class the object is a member of as well as the
+    object itself in order to make this determination.
+
+    Parameters
+    ----------
+    cls : `type`
+        The class on which this method was defined.
+    obj : `object`
+        A member of the provided class (the membership is not checked directly,
+        but this function will always return `False` if the given object is not
+        a member of the given class).
+
+    Examples
+    --------
+    >>> from astropy.extern import six
+    >>> class MetaClass(type):
+    ...     def a_classmethod(cls): pass
+    ...
+    >>> @six.add_metaclass(MetaClass)
+    ... class MyClass(object):
+    ...     __metaclass__ = MetaClass
+    ...     def an_instancemethod(self): pass
+    ...     @classmethod
+    ...     def another_classmethod(cls): pass
+    ...     @staticmethod
+    ...     def a_staticmethod(): pass
+    ...
+    >>> isinstancemethod(MyClass, MyClass.a_classmethod)
+    False
+    >>> isinstancemethod(MyClass, MyClass.another_classmethod)
+    False
+    >>> isinstancemethod(MyClass, MyClass.a_staticmethod)
+    False
+    >>> isinstancemethod(MyClass, MyClass.an_instancemethod)
+    True
+    """
+
+    return _isinstancemethod(cls, obj)
+
+
+if six.PY3:
+    def _isinstancemethod(cls, obj):
+        if not isinstance(obj, types.FunctionType):
+            return False
+
+        # Unfortunately it seems the easiest way to get to the original
+        # staticmethod object is to look in the class's __dict__, though we
+        # also need to look up the MRO in case the method is not in the given
+        # class's dict
+        name = obj.__name__
+        for basecls in cls.mro():  # This includes cls
+            if name in basecls.__dict__:
+                return not isinstance(basecls.__dict__[name], staticmethod)
+
+        # This shouldn't happen, though this is the most sensible response if
+        # it does.
+        raise AttributeError(name)
+else:
+    def _isinstancemethod(cls, obj):
+        return isinstance(obj, types.MethodType) and obj.im_class is cls
+
diff --git a/astropy/utils/metadata.py b/astropy/utils/metadata.py
index 3f50ea6..518d3b9 100644
--- a/astropy/utils/metadata.py
+++ b/astropy/utils/metadata.py
@@ -61,7 +61,7 @@ def merge(left, right, merge_func=concat, metadata_conflicts='warn'):
     """
     Merge the ``left`` and ``right`` metadata objects.
 
-    This is a simplistic and limited implemenation at this point.
+    This is a simplistic and limited implementation at this point.
     """
     if not _both_isinstance(left, right, dict):
         raise MergeConflictError('Can only merge two dict-based objects')
@@ -104,7 +104,7 @@ def merge(left, right, merge_func=concat, metadata_conflicts='warn'):
                         raise MergeConflictError('Cannot merge meta key {0!r} types {1!r} and {2!r}'
                                                  .format(key, type(left[key]), type(right[key])))
                     elif metadata_conflicts != 'silent':
-                        raise ValueError('metadata_conflict argument must be one of "silent", "warn", or "error"')
+                        raise ValueError('metadata_conflicts argument must be one of "silent", "warn", or "error"')
                     out[key] = right[key]
                 else:
                     out[key] = right[key]
diff --git a/astropy/utils/misc.py b/astropy/utils/misc.py
index d35c7c7..eb09df1 100644
--- a/astropy/utils/misc.py
+++ b/astropy/utils/misc.py
@@ -11,212 +11,22 @@ from __future__ import (absolute_import, division, print_function,
 
 import contextlib
 import difflib
-import functools
 import inspect
 import json
 import os
+import re
 import signal
 import sys
-import textwrap
 import traceback
-import types
 import unicodedata
-import warnings
-
-from .exceptions import (AstropyDeprecationWarning,
-                         AstropyPendingDeprecationWarning)
 
 from ..extern import six
 from ..extern.six.moves import urllib
 
 
-__all__ = ['find_current_module', 'isiterable', 'deprecated', 'lazyproperty',
-           'deprecated_attribute', 'silence', 'format_exception',
-           'NumpyRNGContext', 'find_api_page', 'is_path_hidden',
-           'walk_skip_hidden', 'JsonCustomEncoder', 'indent',
-           'InheritDocstrings']
-
-__doctest_skip__ = ['find_current_module']
-
-
-def find_current_module(depth=1, finddiff=False):
-    """ Determines the module/package from which this function is called.
-
-    This function has two modes, determined by the ``finddiff`` option. it
-    will either simply go the requested number of frames up the call
-    stack (if ``finddiff`` is False), or it will go up the call stack until
-    it reaches a module that is *not* in a specified set.
-
-    Parameters
-    ----------
-    depth : int
-        Specifies how far back to go in the call stack (0-indexed, so that
-        passing in 0 gives back `astropy.utils.misc`).
-    finddiff : bool or list
-        If False, the returned ``mod`` will just be ``depth`` frames up from
-        the current frame. Otherwise, the function will start at a frame
-        ``depth`` up from current, and continue up the call stack to the
-        first module that is *different* from those in the provided list.
-        In this case, ``finddiff`` can be a list of modules or modules
-        names. Alternatively, it can be True, which will use the module
-        ``depth`` call stack frames up as the module the returned module
-        most be different from.
-
-    Returns
-    -------
-    mod : module or None
-        The module object or None if the package cannot be found. The name of
-        the module is available as the ``__name__`` attribute of the returned
-        object (if it isn't None).
-
-    Raises
-    ------
-    ValueError
-        If ``finddiff`` is a list with an invalid entry.
-
-    Examples
-    --------
-    The examples below assume that there are two modules in a package named
-    ``pkg``. ``mod1.py``::
-
-        def find1():
-            from astropy.utils import find_current_module
-            print find_current_module(1).__name__
-        def find2():
-            from astropy.utils import find_current_module
-            cmod = find_current_module(2)
-            if cmod is None:
-                print 'None'
-            else:
-                print cmod.__name__
-        def find_diff():
-            from astropy.utils import find_current_module
-            print find_current_module(0,True).__name__
-
-    ``mod2.py``::
-
-        def find():
-            from .mod1 import find2
-            find2()
-
-    With these modules in place, the following occurs::
-
-        >>> from pkg import mod1, mod2
-        >>> from astropy.utils import find_current_module
-        >>> mod1.find1()
-        pkg.mod1
-        >>> mod1.find2()
-        None
-        >>> mod2.find()
-        pkg.mod2
-        >>> find_current_module(0)
-        <module 'astropy.utils.misc' from 'astropy/utils/misc.py'>
-        >>> mod1.find_diff()
-        pkg.mod1
-
-    """
-
-    # using a patched version of getmodule because the py 3.1 and 3.2 stdlib
-    # is broken if the list of modules changes during import
-    from .compat import inspect_getmodule
-
-    frm = inspect.currentframe()
-    for i in range(depth):
-        frm = frm.f_back
-        if frm is None:
-            return None
-
-    if finddiff:
-        currmod = inspect_getmodule(frm)
-        if finddiff is True:
-            diffmods = [currmod]
-        else:
-            diffmods = []
-            for fd in finddiff:
-                if inspect.ismodule(fd):
-                    diffmods.append(fd)
-                elif isinstance(fd, six.string_types):
-                    diffmods.append(__import__(fd))
-                elif fd is True:
-                    diffmods.append(currmod)
-                else:
-                    raise ValueError('invalid entry in finddiff')
-
-        while frm:
-            frmb = frm.f_back
-            modb = inspect_getmodule(frmb)
-            if modb not in diffmods:
-                return modb
-            frm = frmb
-    else:
-        return inspect_getmodule(frm)
-
-
-def find_mod_objs(modname, onlylocals=False):
-    """ Returns all the public attributes of a module referenced by name.
-
-    .. note::
-        The returned list *not* include subpackages or modules of
-        ``modname``, nor does it include private attributes (those that
-        beginwith '_' or are not in `__all__`).
-
-    Parameters
-    ----------
-    modname : str
-        The name of the module to search.
-    onlylocals : bool or list of str
-        If `True`, only attributes that are either members of ``modname`` OR
-        one of its modules or subpackages will be included. If it is a list
-        of strings, those specify the possible packages that will be
-        considered "local".
-
-    Returns
-    -------
-    localnames : list of str
-        A list of the names of the attributes as they are named in the
-        module ``modname`` .
-    fqnames : list of str
-        A list of the full qualified names of the attributes (e.g.,
-        ``astropy.utils.misc.find_mod_objs``). For attributes that are
-        simple variables, this is based on the local name, but for
-        functions or classes it can be different if they are actually
-        defined elsewhere and just referenced in ``modname``.
-    objs : list of objects
-        A list of the actual attributes themselves (in the same order as
-        the other arguments)
-
-    """
-
-    __import__(modname)
-    mod = sys.modules[modname]
-
-    if hasattr(mod, '__all__'):
-        pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__]
-    else:
-        pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_']
-
-    # filter out modules and pull the names and objs out
-    ismodule = inspect.ismodule
-    localnames = [k for k, v in pkgitems if not ismodule(v)]
-    objs = [v for k, v in pkgitems if not ismodule(v)]
-
-    # fully qualified names can be determined from the object's module
-    fqnames = []
-    for obj, lnm in zip(objs, localnames):
-        if hasattr(obj, '__module__') and hasattr(obj, '__name__'):
-            fqnames.append(obj.__module__ + '.' + obj.__name__)
-        else:
-            fqnames.append(modname + '.' + lnm)
-
-    if onlylocals:
-        if onlylocals is True:
-            onlylocals = [modname]
-        valids = [any([fqn.startswith(nm) for nm in onlylocals]) for fqn in fqnames]
-        localnames = [e for i, e in enumerate(localnames) if valids[i]]
-        fqnames = [e for i, e in enumerate(fqnames) if valids[i]]
-        objs = [e for i, e in enumerate(objs) if valids[i]]
-
-    return localnames, fqnames, objs
+__all__ = ['isiterable', 'silence', 'format_exception', 'NumpyRNGContext',
+           'find_api_page', 'is_path_hidden', 'walk_skip_hidden',
+           'JsonCustomEncoder', 'indent', 'InheritDocstrings']
 
 
 def isiterable(obj):
@@ -240,362 +50,6 @@ def indent(s, shift=1, width=4):
     return indented
 
 
-class lazyproperty(object):
-    """
-    Works similarly to property(), but computes the value only once.
-
-    This essentially memoizes the value of the property by storing the result
-    of its computation in the ``__dict__`` of the object instance.  This is
-    useful for computing the value of some property that should otherwise be
-    invariant.  For example::
-
-        >>> class LazyTest(object):
-        ...     @lazyproperty
-        ...     def complicated_property(self):
-        ...         print('Computing the value for complicated_property...')
-        ...         return 42
-        ...
-        >>> lt = LazyTest()
-        >>> lt.complicated_property
-        Computing the value for complicated_property...
-        42
-        >>> lt.complicated_property
-        42
-
-    If a setter for this property is defined, it will still be possible to
-    manually update the value of the property, if that capability is desired.
-
-    Adapted from the recipe at
-    http://code.activestate.com/recipes/363602-lazy-property-evaluation
-    """
-
-    def __init__(self, fget, fset=None, fdel=None, doc=None):
-        self._fget = fget
-        self._fset = fset
-        self._fdel = fdel
-        if doc is None:
-            self.__doc__ = fget.__doc__
-        else:
-            self.__doc__ = doc
-        self._key = self._fget.__name__
-
-    def __get__(self, obj, owner=None):
-        if obj is None:
-            return self
-        try:
-            return obj.__dict__[self._key]
-        except KeyError:
-            val = self._fget(obj)
-            obj.__dict__[self._key] = val
-            return val
-
-    def __set__(self, obj, val):
-        obj_dict = obj.__dict__
-        if self._fset:
-            ret = self._fset(obj, val)
-            if ret is not None and obj_dict.get(self._key) is ret:
-                # By returning the value set the setter signals that it took
-                # over setting the value in obj.__dict__; this mechanism allows
-                # it to override the input value
-                return
-        obj_dict[self._key] = val
-
-    def __delete__(self, obj):
-        if self._fdel:
-            self._fdel(obj)
-        if self._key in obj.__dict__:
-            del obj.__dict__[self._key]
-
-    def getter(self, fget):
-        return self.__ter(fget, 0)
-
-    def setter(self, fset):
-        return self.__ter(fset, 1)
-
-    def deleter(self, fdel):
-        return self.__ter(fdel, 2)
-
-    def __ter(self, f, arg):
-        args = [self._fget, self._fset, self._fdel, self.__doc__]
-        args[arg] = f
-        cls_ns = sys._getframe(1).f_locals
-        for k, v in six.iteritems(cls_ns):
-            if v is self:
-                property_name = k
-                break
-
-        cls_ns[property_name] = lazyproperty(*args)
-
-        return cls_ns[property_name]
-
-
-def deprecated(since, message='', name='', alternative='', pending=False,
-               obj_type=None):
-    """
-    Used to mark a function or class as deprecated.
-
-    To mark an attribute as deprecated, use `deprecated_attribute`.
-
-    Parameters
-    ------------
-    since : str
-        The release at which this API became deprecated.  This is
-        required.
-
-    message : str, optional
-        Override the default deprecation message.  The format
-        specifier ``func`` may be used for the name of the function,
-        and ``alternative`` may be used in the deprecation message
-        to insert the name of an alternative to the deprecated
-        function. ``obj_type`` may be used to insert a friendly name
-        for the type of object being deprecated.
-
-    name : str, optional
-        The name of the deprecated function or class; if not provided
-        the name is automatically determined from the passed in
-        function or class, though this is useful in the case of
-        renamed functions, where the new function is just assigned to
-        the name of the deprecated function.  For example::
-
-            def new_function():
-                ...
-            oldFunction = new_function
-
-    alternative : str, optional
-        An alternative function or class name that the user may use in
-        place of the deprecated object.  The deprecation warning will
-        tell the user about this alternative if provided.
-
-    pending : bool, optional
-        If True, uses a AstropyPendingDeprecationWarning instead of a
-        AstropyDeprecationWarning.
-
-    obj_type : str, optional
-        The type of this object, if the automatically determined one
-        needs to be overridden.
-    """
-
-    method_types = (classmethod, staticmethod, types.MethodType)
-
-    def deprecate_doc(old_doc, message):
-        """
-        Returns a given docstring with a deprecation message prepended
-        to it.
-        """
-        if not old_doc:
-            old_doc = ''
-        old_doc = textwrap.dedent(old_doc).strip('\n')
-        new_doc = (('\n.. deprecated:: %(since)s'
-                    '\n    %(message)s\n\n' %
-                    {'since': since, 'message': message.strip()}) + old_doc)
-        if not old_doc:
-            # This is to prevent a spurious 'unexected unindent' warning from
-            # docutils when the original docstring was blank.
-            new_doc += r'\ '
-        return new_doc
-
-    def get_function(func):
-        """
-        Given a function or classmethod (or other function wrapper type), get
-        the function object.
-        """
-        if isinstance(func, method_types):
-            try:
-                func = func.__func__
-            except AttributeError:
-                # classmethods in Python2.6 and below lack the __func__
-                # attribute so we need to hack around to get it
-                method = func.__get__(None, object)
-                if isinstance(method, types.FunctionType):
-                    # For staticmethods anyways the wrapped object is just a
-                    # plain function (not a bound method or anything like that)
-                    func = method
-                elif hasattr(method, '__func__'):
-                    func = method.__func__
-                elif hasattr(method, 'im_func'):
-                    func = method.im_func
-                else:
-                    # Nothing we can do really...  just return the original
-                    # classmethod, etc.
-                    return func
-        return func
-
-    def deprecate_function(func, message):
-        """
-        Returns a wrapped function that displays an
-        ``AstropyDeprecationWarning`` when it is called.
-        """
-
-        if isinstance(func, method_types):
-            func_wrapper = type(func)
-        else:
-            func_wrapper = lambda f: f
-
-        func = get_function(func)
-
-        def deprecated_func(*args, **kwargs):
-            if pending:
-                category = AstropyPendingDeprecationWarning
-            else:
-                category = AstropyDeprecationWarning
-
-            warnings.warn(message, category, stacklevel=2)
-
-            return func(*args, **kwargs)
-
-        # If this is an extension function, we can't call
-        # functools.wraps on it, but we normally don't care.
-        # This crazy way to get the type of a wrapper descriptor is
-        # straight out of the Python 3.3 inspect module docs.
-        if type(func) != type(str.__dict__['__add__']):
-            deprecated_func = functools.wraps(func)(deprecated_func)
-
-        deprecated_func.__doc__ = deprecate_doc(
-            deprecated_func.__doc__, message)
-
-        return func_wrapper(deprecated_func)
-
-    def deprecate_class(cls, message):
-        """
-        Returns a wrapper class with the docstrings updated and an
-        __init__ function that will raise an
-        ``AstropyDeprectationWarning`` warning when called.
-        """
-        # Creates a new class with the same name and bases as the
-        # original class, but updates the dictionary with a new
-        # docstring and a wrapped __init__ method.  __module__ needs
-        # to be manually copied over, since otherwise it will be set
-        # to *this* module (astropy.utils.misc).
-
-        # This approach seems to make Sphinx happy (the new class
-        # looks enough like the original class), and works with
-        # extension classes (which functools.wraps does not, since
-        # it tries to modify the original class).
-
-        # We need to add a custom pickler or you'll get
-        #     Can't pickle <class ..>: it's not found as ...
-        # errors. Picklability is required for any class that is
-        # documented by Sphinx.
-
-        members = cls.__dict__.copy()
-
-        members.update({
-            '__doc__': deprecate_doc(cls.__doc__, message),
-            '__init__': deprecate_function(get_function(cls.__init__),
-                                           message),
-        })
-
-        return type(cls.__name__, cls.__bases__, members)
-
-    def deprecate(obj, message=message, name=name, alternative=alternative,
-                  pending=pending):
-        if obj_type is None:
-            if isinstance(obj, type):
-                obj_type_name = 'class'
-            elif inspect.isfunction(obj):
-                obj_type_name = 'function'
-            elif inspect.ismethod(obj) or isinstance(obj, method_types):
-                obj_type_name = 'method'
-            else:
-                obj_type_name = 'object'
-        else:
-            obj_type_name = obj_type
-
-        if not name:
-            name = get_function(obj).__name__
-
-        altmessage = ''
-        if not message or type(message) == type(deprecate):
-            if pending:
-                message = ('The %(func)s %(obj_type)s will be deprecated in a '
-                           'future version.')
-            else:
-                message = ('The %(func)s %(obj_type)s is deprecated and may '
-                           'be removed in a future version.')
-            if alternative:
-                altmessage = '\n        Use %s instead.' % alternative
-
-        message = ((message % {
-            'func': name,
-            'name': name,
-            'alternative': alternative,
-            'obj_type': obj_type_name}) +
-            altmessage)
-
-        if isinstance(obj, type):
-            return deprecate_class(obj, message)
-        else:
-            return deprecate_function(obj, message)
-
-    if type(message) == type(deprecate):
-        return deprecate(message)
-
-    return deprecate
-
-
-def deprecated_attribute(name, since, message=None, alternative=None,
-                         pending=False):
-    """
-    Used to mark a public attribute as deprecated.  This creates a
-    property that will warn when the given attribute name is accessed.
-    To prevent the warning (i.e. for internal code), use the private
-    name for the attribute by prepending an underscore
-    (i.e. ``self._name``).
-
-    Parameters
-    ----------
-    name : str
-        The name of the deprecated attribute.
-
-    since : str
-        The release at which this API became deprecated.  This is
-        required.
-
-    message : str, optional
-        Override the default deprecation message.  The format
-        specifier ``name`` may be used for the name of the attribute,
-        and ``alternative`` may be used in the deprecation message
-        to insert the name of an alternative to the deprecated
-        function.
-
-    alternative : str, optional
-        An alternative attribute that the user may use in place of the
-        deprecated attribute.  The deprecation warning will tell the
-        user about this alternative if provided.
-
-    pending : bool, optional
-        If True, uses a AstropyPendingDeprecationWarning instead of a
-        AstropyDeprecationWarning.
-
-    Examples
-    --------
-
-    ::
-
-        class MyClass:
-            # Mark the old_name as deprecated
-            old_name = misc.deprecated_attribute('old_name', '0.1')
-
-            def method(self):
-                self._old_name = 42
-    """
-    private_name = '_' + name
-
-    @deprecated(since, name=name, obj_type='attribute')
-    def get(self):
-        return getattr(self, private_name)
-
-    @deprecated(since, name=name, obj_type='attribute')
-    def set(self, val):
-        setattr(self, private_name, val)
-
-    @deprecated(since, name=name, obj_type='attribute')
-    def delete(self):
-        delattr(self, private_name)
-
-    return property(get, set, delete)
-
-
 class _DummyFile(object):
     """A noop writeable object."""
 
@@ -932,7 +386,7 @@ def strip_accents(s):
         if unicodedata.category(c) != 'Mn')
 
 
-def did_you_mean(s, candidates, n=3, cutoff=0.8):
+def did_you_mean(s, candidates, n=3, cutoff=0.8, fix=None):
     """
     When a string isn't found in a set of candidates, we can be nice
     to provide a list of alternatives in the exception.  This
@@ -953,6 +407,11 @@ def did_you_mean(s, candidates, n=3, cutoff=0.8):
         that similar to word are ignored.  See
         `difflib.get_close_matches`.
 
+    fix : callable
+        A callable to modify the results after matching.  It should
+        take a single string and return a sequence of strings
+        containing the fixed matches.
+
     Returns
     -------
     message : str
@@ -984,13 +443,22 @@ def did_you_mean(s, candidates, n=3, cutoff=0.8):
         capitalized_matches = set()
         for match in matches:
             capitalized_matches.update(candidates_lower[match])
+        matches = capitalized_matches
 
-        matches = sorted(capitalized_matches)
+        if fix is not None:
+            mapped_matches = []
+            for match in matches:
+                mapped_matches.extend(fix(match))
+            matches = mapped_matches
+
+        matches = list(set(matches))
+        matches = sorted(matches)
 
         if len(matches) == 1:
             matches = matches[0]
         else:
-            matches = ', '.join(matches[:-1]) + ' or ' + matches[-1]
+            matches = (', '.join(matches[:-1]) + ' or ' +
+                       matches[-1])
         return 'Did you mean {0}?'.format(matches)
 
     return ''
@@ -1023,6 +491,7 @@ class InheritDocstrings(type):
         >>> B.wiggle.__doc__
         u'Wiggle the thingamajig'
     """
+
     def __init__(cls, name, bases, dct):
         def is_public_member(key):
             return (
@@ -1039,3 +508,5 @@ class InheritDocstrings(type):
                     if super_method is not None:
                         val.__doc__ = super_method.__doc__
                         break
+
+        super(InheritDocstrings, cls).__init__(name, bases, dct)
diff --git a/astropy/utils/release.py b/astropy/utils/release.py
index d328837..2b86863 100644
--- a/astropy/utils/release.py
+++ b/astropy/utils/release.py
@@ -104,6 +104,139 @@ def releaser_middle(data):
     Releaser._sdist_options = _my_sdist_options
 
 
+_NEW_CHANGELOG_TEMPLATE = str("""\
+New Features
+^^^^^^^^^^^^
+
+- ``astropy.config``
+
+- ``astropy.constants``
+
+- ``astropy.convolution``
+
+- ``astropy.coordinates``
+
+- ``astropy.cosmology``
+
+- ``astropy.io.ascii``
+
+- ``astropy.io.fits``
+
+- ``astropy.io.misc``
+
+- ``astropy.io.registry``
+
+- ``astropy.io.votable``
+
+- ``astropy.modeling``
+
+- ``astropy.nddata``
+
+- ``astropy.stats``
+
+- ``astropy.sphinx``
+
+- ``astropy.table``
+
+- ``astropy.time``
+
+- ``astropy.units``
+
+- ``astropy.utils``
+
+- ``astropy.vo``
+
+- ``astropy.wcs``
+
+API Changes
+^^^^^^^^^^^
+
+- ``astropy.config``
+
+- ``astropy.constants``
+
+- ``astropy.convolution``
+
+- ``astropy.coordinates``
+
+- ``astropy.cosmology``
+
+- ``astropy.io.ascii``
+
+- ``astropy.io.fits``
+
+- ``astropy.io.misc``
+
+- ``astropy.io.registry``
+
+- ``astropy.io.votable``
+
+- ``astropy.modeling``
+
+- ``astropy.nddata``
+
+- ``astropy.stats``
+
+- ``astropy.table``
+
+- ``astropy.time``
+
+- ``astropy.units``
+
+- ``astropy.utils``
+
+- ``astropy.vo``
+
+- ``astropy.wcs``
+
+Bug Fixes
+^^^^^^^^^
+
+- ``astropy.config``
+
+- ``astropy.constants``
+
+- ``astropy.convolution``
+
+- ``astropy.coordinates``
+
+- ``astropy.cosmology``
+
+- ``astropy.io.ascii``
+
+- ``astropy.io.fits``
+
+- ``astropy.io.misc``
+
+- ``astropy.io.registry``
+
+- ``astropy.io.votable``
+
+- ``astropy.modeling``
+
+- ``astropy.nddata``
+
+- ``astropy.stats``
+
+- ``astropy.table``
+
+- ``astropy.time``
+
+- ``astropy.units``
+
+- ``astropy.utils``
+
+- ``astropy.vo``
+
+- ``astropy.wcs``
+
+Other Changes and Additions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Nothing changed yet.
+""".rstrip())
+
+
 def postreleaser_before(data):
     """
     postreleaser.before hook to set a different dev_version_template from the
@@ -115,6 +248,7 @@ def postreleaser_before(data):
         return
 
     data['dev_version_template'] = '%(new_version)s.dev'
+    data['nothing_changed_yet'] = _NEW_CHANGELOG_TEMPLATE
 
 
 def postreleaser_middle(data):
diff --git a/astropy/utils/tests/test_codegen.py b/astropy/utils/tests/test_codegen.py
new file mode 100644
index 0000000..c7f8c1a
--- /dev/null
+++ b/astropy/utils/tests/test_codegen.py
@@ -0,0 +1,42 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import sys
+import traceback
+
+from ..codegen import make_function_with_signature
+from ...tests.helper import pytest
+
+
+def test_make_function_with_signature_lineno():
+    """
+    Tests that a function made with ``make_function_with_signature`` is give
+    the correct line number into the module it was created from (i.e. the line
+    ``make_function_with_signature`` was called from).
+    """
+
+    def crashy_function(*args, **kwargs):
+        1 / 0
+
+    # Make a wrapper around this function with the signature:
+    # crashy_function(a, b)
+    # Note: the signature is not really relevant to this test
+    wrapped = make_function_with_signature(crashy_function, ('a', 'b'))
+    line = """
+    wrapped = make_function_with_signature(crashy_function, ('a', 'b'))
+    """.strip()
+
+    try:
+        wrapped(1, 2)
+    except:
+        exc_cls, exc, tb = sys.exc_info()
+        assert exc_cls is ZeroDivisionError
+        # The *last* line in the traceback should be the 1 / 0 line in
+        # crashy_function; the next line up should be the line that the
+        # make_function_with_signature call was one
+        tb_lines = traceback.format_tb(tb)
+        assert '1 / 0' in tb_lines[-1]
+        assert line in tb_lines[-2] and 'line =' not in tb_lines[-2]
+    else:
+        pytest.fail('This should have caused an exception')
diff --git a/astropy/utils/tests/test_console.py b/astropy/utils/tests/test_console.py
index 96f27a1..c3e04a9 100644
--- a/astropy/utils/tests/test_console.py
+++ b/astropy/utils/tests/test_console.py
@@ -163,7 +163,7 @@ def test_progress_bar():
 
 
 def test_progress_bar2():
-    for x in console.ProgressBar.iterate(xrange(50)):
+    for x in console.ProgressBar(xrange(50)):
         pass
 
 
@@ -202,3 +202,14 @@ def test_human_time(seconds, string):
     human_time = console.human_time(seconds)
     assert human_time == string
 
+ at pytest.mark.parametrize("size,string",
+       [(8640882,"8.6M"),
+       (187213, "187k"),
+       (3905,   "3.9k"),
+       (64,     " 64 "),
+       (2,      "  2 ")]
+)
+def test_human_file_size(size, string):
+    human_time = console.human_file_size(size)
+    assert human_time == string
+
diff --git a/astropy/utils/tests/test_decorators.py b/astropy/utils/tests/test_decorators.py
new file mode 100644
index 0000000..e617fd1
--- /dev/null
+++ b/astropy/utils/tests/test_decorators.py
@@ -0,0 +1,252 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+import inspect
+import pickle
+
+from ..decorators import deprecated_attribute, deprecated, wraps, sharedmethod
+from ..exceptions import AstropyDeprecationWarning
+from ...extern import six
+from ...tests.helper import pytest, catch_warnings
+
+
+def test_wraps():
+    """
+    Tests the compatibility replacement for functools.wraps which supports
+    argument preservation across all supported Python versions.
+    """
+
+    def foo(a, b, c=1, d=2, e=3, **kwargs):
+        """A test function."""
+
+        return a, b, c, d, e, kwargs
+
+    @wraps(foo)
+    def bar(*args, **kwargs):
+        return ('test',) + foo(*args, **kwargs)
+
+    expected = ('test', 1, 2, 3, 4, 5, {'f': 6, 'g': 7})
+    assert bar(1, 2, 3, 4, 5, f=6, g=7) == expected
+    assert bar.__name__ == 'foo'
+    assert bar.__doc__ == "A test function."
+
+    if hasattr(foo, '__qualname__'):
+        assert bar.__qualname__ == foo.__qualname__
+
+    if six.PY2:
+        argspec = inspect.getargspec(bar)
+        assert argspec.keywords == 'kwargs'
+    else:
+        argspec = inspect.getfullargspec(bar)
+        assert argspec.varkw == 'kwargs'
+
+    assert argspec.args == ['a', 'b', 'c', 'd', 'e']
+    assert argspec.defaults == (1, 2, 3)
+
+
+def test_deprecated_attribute():
+    class DummyClass:
+        def __init__(self):
+            self._foo = 42
+
+        def set_private(self):
+            self._foo = 100
+
+        foo = deprecated_attribute('foo', '0.2')
+
+    dummy = DummyClass()
+
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        x = dummy.foo
+
+    assert len(w) == 1
+    assert str(w[0].message) == ("The foo attribute is deprecated and may be "
+                                 "removed in a future version.")
+
+    with catch_warnings() as w:
+        dummy.set_private()
+
+    assert len(w) == 0
+
+
+# This needs to be defined outside of the test function, because we
+# want to try to pickle it.
+ at deprecated('100.0')
+class TestA(object):
+    """
+    This is the class docstring.
+    """
+    def __init__(self):
+        """
+        This is the __init__ docstring
+        """
+        pass
+
+
+def test_deprecated_class():
+    orig_A = TestA.__bases__[0]
+
+    # The only thing that should be different about the new class
+    # is __doc__, __init__, __bases__ and __subclasshook__.
+    for x in dir(orig_A):
+        if x not in ('__doc__', '__init__', '__bases__', '__dict__',
+                     '__subclasshook__'):
+            assert getattr(TestA, x) == getattr(orig_A, x)
+
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        TestA()
+
+    assert len(w) == 1
+    assert 'function' not in TestA.__doc__
+    assert 'deprecated' in TestA.__doc__
+    assert 'function' not in TestA.__init__.__doc__
+    assert 'deprecated' in TestA.__init__.__doc__
+
+    # Make sure the object is picklable
+    pickle.dumps(TestA)
+
+
+def test_deprecated_class_with_super():
+    """
+    Regression test for an issue where classes that used `super()` in their
+    ``__init__`` did not actually call the correct class's ``__init__`` in the
+    MRO.
+    """
+
+    @deprecated('100.0')
+    class TestB(object):
+        def __init__(self, a, b):
+            super(TestB, self).__init__()
+
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        TestB(1, 2)
+
+    assert len(w) == 1
+    assert 'function' not in TestB.__doc__
+    assert 'deprecated' in TestB.__doc__
+    assert 'function' not in TestB.__init__.__doc__
+    assert 'deprecated' in TestB.__init__.__doc__
+
+
+def test_deprecated_static_and_classmethod():
+    """
+    Regression test for issue introduced by
+    https://github.com/astropy/astropy/pull/2811 and mentioned also here:
+    https://github.com/astropy/astropy/pull/2580#issuecomment-51049969
+    where it appears that deprecated staticmethods didn't work on Python 2.6.
+    """
+
+    class A(object):
+        @deprecated('1.0')
+        @staticmethod
+        def B():
+            pass
+
+        @deprecated('1.0')
+        @classmethod
+        def C(cls):
+            pass
+
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        A.B()
+
+    assert len(w) == 1
+    assert 'deprecated' in A.B.__doc__
+
+    with catch_warnings(AstropyDeprecationWarning) as w:
+        A.C()
+
+    assert len(w) == 1
+    assert 'deprecated' in A.C.__doc__
+
+
+ at pytest.mark.skipif('six.PY3')
+def test_sharedmethod_imfunc():
+    """
+    Test that the im_func of a sharedmethod always points to the correct
+    underlying function.
+
+    This only applies to Python 2 as Python 3 does not have an im_func
+    attribute on methods.
+    """
+
+    # The original function
+    def foo(self): pass
+    actual_foo = foo
+
+    class Bar(object):
+        foo = sharedmethod(actual_foo)
+
+    assert Bar.foo.im_func is actual_foo
+    assert Bar().foo.im_func is actual_foo
+
+    # Now test the case where there the metaclass has a separate
+    # implementation
+    def foo(cls): pass
+    actual_foo_2 = foo
+
+    class MetaBar(type):
+        foo = actual_foo_2
+
+    class Bar(object):
+        __metaclass__ = MetaBar
+
+        foo = sharedmethod(actual_foo)
+
+    assert Bar.foo.im_func is actual_foo_2
+    assert Bar().foo.im_func is actual_foo
+
+    # Finally, test case where the metaclass also has an attribute called
+    # 'foo', but it is not a method (hence sharedmethod should ignore it)
+    class MetaBar(type):
+        foo = None
+
+    class Bar(object):
+        __metaclass__ = MetaBar
+
+        foo = sharedmethod(actual_foo)
+
+    assert Bar.foo.im_func is actual_foo
+    assert Bar().foo.im_func is actual_foo
+
+
+def test_sharedmethod_reuse_on_subclasses():
+    """
+    Regression test for an issue where sharedmethod would bind to one class
+    for all time, causing the same method not to work properly on other
+    subclasses of that class.
+
+    It has the same problem when the same sharedmethod is called on different
+    instances of some class as well.
+    """
+
+    class AMeta(type):
+        def foo(cls):
+            return cls.x
+
+    six.add_metaclass(AMeta)
+    class A(object):
+        x = 3
+
+        def __init__(self, x):
+            self.x = x
+
+        @sharedmethod
+        def foo(self):
+            return self.x
+
+    a1 = A(1)
+    a2 = A(2)
+
+    assert a1.foo() == 1
+    assert a2.foo() == 2
+
+    # Similar test now, but for multiple subclasses using the same sharedmethod
+    # as a classmethod
+    assert A.foo() == 3
+
+    class B(A):
+        x = 5
+
+    assert B.foo() == 5
diff --git a/astropy/utils/tests/test_introspection.py b/astropy/utils/tests/test_introspection.py
new file mode 100644
index 0000000..ea11932
--- /dev/null
+++ b/astropy/utils/tests/test_introspection.py
@@ -0,0 +1,94 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+#namedtuple is needed for find_mod_objs so it can have a non-local module
+from collections import namedtuple
+
+from ...extern import six
+from ...tests.helper import pytest
+from .. import introspection
+from ..introspection import (find_current_module, find_mod_objs,
+                             isinstancemethod)
+
+
+def test_pkg_finder():
+    """
+    Tests that the `find_current_module` function works. Note that
+    this also implicitly tests compat.misc._patched_getmodule
+    """
+    mod1 = 'astropy.utils.introspection'
+    mod2 = 'astropy.utils.tests.test_introspection'
+    mod3 = 'astropy.utils.tests.test_introspection'
+    assert find_current_module(0).__name__ == mod1
+    assert find_current_module(1).__name__ == mod2
+    assert find_current_module(0, True).__name__ == mod3
+
+
+def test_find_current_mod():
+    from sys import getrecursionlimit
+
+    thismodnm = __name__
+
+    assert find_current_module(0) is introspection
+    assert find_current_module(1).__name__ == thismodnm
+    assert find_current_module(getrecursionlimit() + 1) is None
+
+    assert find_current_module(0, True).__name__ == thismodnm
+    assert find_current_module(0, [introspection]).__name__ == thismodnm
+    assert find_current_module(0, ['astropy.utils.introspection']).__name__ == thismodnm
+
+    with pytest.raises(ImportError):
+        find_current_module(0, ['faddfdsasewrweriopunjlfiurrhujnkflgwhu'])
+
+
+def test_find_mod_objs():
+    lnms, fqns, objs = find_mod_objs('astropy')
+
+    # this import  is after the above call intentionally to make sure
+    # find_mod_objs properly imports astropy on its own
+    import astropy
+
+    # just check for astropy.test ... other things might be added, so we
+    # shouldn't check that it's the only thing
+    assert 'test' in lnms
+    assert astropy.test in objs
+
+    lnms, fqns, objs = find_mod_objs(__name__, onlylocals=False)
+    assert 'namedtuple' in lnms
+    assert 'collections.namedtuple' in fqns
+    assert namedtuple in objs
+
+    lnms, fqns, objs = find_mod_objs(__name__, onlylocals=True)
+    assert 'namedtuple' not in lnms
+    assert 'collections.namedtuple' not in fqns
+    assert namedtuple not in objs
+
+
+def test_isinstancemethod():
+    """
+    Note, this is an exact copy of the doctest in `isinstancemethod`'s
+    docstring.
+
+    It is included here as well so that it can be tested on Python 2 and 3
+    which require very different implementations.  Once we enable running
+    doctests on Python 3 this extra test can be dropped.
+    """
+
+    class MetaClass(type):
+        def a_classmethod(cls): pass
+
+    @six.add_metaclass(MetaClass)
+    class MyClass(object):
+        def an_instancemethod(self): pass
+
+        @classmethod
+        def another_classmethod(cls): pass
+
+        @staticmethod
+        def a_staticmethod(): pass
+
+    assert not isinstancemethod(MyClass, MyClass.a_classmethod)
+    assert not isinstancemethod(MyClass, MyClass.another_classmethod)
+    assert not isinstancemethod(MyClass, MyClass.a_staticmethod)
+    assert isinstancemethod(MyClass, MyClass.an_instancemethod)
diff --git a/astropy/utils/tests/test_misc.py b/astropy/utils/tests/test_misc.py
index 7e13751..075f596 100644
--- a/astropy/utils/tests/test_misc.py
+++ b/astropy/utils/tests/test_misc.py
@@ -4,75 +4,14 @@ from __future__ import (absolute_import, division, print_function,
 
 import json
 import os
-import pickle
-
-#namedtuple is needed for find_mod_objs so it can have a non-local module
-from collections import namedtuple
 
 import numpy as np
 
 from .. import data, misc
-from ..exceptions import AstropyDeprecationWarning
-from ...tests.helper import remote_data, catch_warnings
+from ...tests.helper import remote_data
 from ...extern import six
 
 
-def test_pkg_finder():
-    """
-    Tests that the `utils.misc.find_current_module` function works. Note that
-    this also implicitly tests compat.misc._patched_getmodule
-    """
-    mod1 = 'astropy.utils.misc'
-    mod2 = 'astropy.utils.tests.test_misc'
-    mod3 = 'astropy.utils.tests.test_misc'
-    assert misc.find_current_module(0).__name__ == mod1
-    assert misc.find_current_module(1).__name__ == mod2
-    assert misc.find_current_module(0, True).__name__ == mod3
-
-
-def test_find_mod_objs():
-    lnms, fqns, objs = misc.find_mod_objs('astropy')
-
-    # this import  is after the above call intentionally to make sure
-    # find_mod_objs properly imports astropy on its own
-    import astropy
-
-    # just check for astropy.test ... other things might be added, so we
-    # shouldn't check that it's the only thing
-    assert 'test' in lnms
-    assert astropy.test in objs
-
-    lnms, fqns, objs = misc.find_mod_objs('astropy.utils.tests.test_misc',
-                                          onlylocals=False)
-    assert 'namedtuple' in lnms
-    assert 'collections.namedtuple' in fqns
-    assert namedtuple in objs
-
-    lnms, fqns, objs = misc.find_mod_objs('astropy.utils.tests.test_misc',
-                                          onlylocals=True)
-    assert 'namedtuple' not in lnms
-    assert 'collections.namedtuple' not in fqns
-    assert namedtuple not in objs
-
-
-def test_find_current_mod():
-    from sys import getrecursionlimit
-    from ...tests.helper import pytest
-
-    thismodnm = __name__
-
-    assert misc.find_current_module(0) is misc
-    assert misc.find_current_module(1).__name__ == thismodnm
-    assert misc.find_current_module(getrecursionlimit() + 1) is None
-
-    assert misc.find_current_module(0, True).__name__ == thismodnm
-    assert misc.find_current_module(0, [misc]).__name__ == thismodnm
-    assert misc.find_current_module(0, ['astropy.utils.misc']).__name__ == thismodnm
-
-    with pytest.raises(ImportError):
-        misc.find_current_module(0, ['faddfdsasewrweriopunjlfiurrhujnkflgwhu'])
-
-
 def test_isiterable():
     assert misc.isiterable(2) is False
     assert misc.isiterable([2]) is True
@@ -81,122 +20,6 @@ def test_isiterable():
     assert misc.isiterable(np.array([1, 2, 3])) is True
 
 
-def test_deprecated_attribute():
-    class DummyClass:
-        def __init__(self):
-            self._foo = 42
-
-        def set_private(self):
-            self._foo = 100
-
-        foo = misc.deprecated_attribute('foo', '0.2')
-
-    dummy = DummyClass()
-
-    with catch_warnings(AstropyDeprecationWarning) as w:
-        x = dummy.foo
-
-    assert len(w) == 1
-    assert str(w[0].message) == ("The foo attribute is deprecated and may be "
-                                 "removed in a future version.")
-
-    with catch_warnings() as w:
-        dummy.set_private()
-
-    assert len(w) == 0
-
-
-# This needs to be defined outside of the test function, because we
-# want to try to pickle it.
- at misc.deprecated('100.0')
-class TestA(object):
-    """
-    This is the class docstring.
-    """
-    def __init__(self):
-        """
-        This is the __init__ docstring
-        """
-        pass
-
-
-def test_deprecated_class():
-    orig_A = TestA.__bases__[0]
-
-    # The only thing that should be different about the new class
-    # is __doc__, __init__, __bases__ and __subclasshook__.
-    for x in dir(orig_A):
-        if x not in ('__doc__', '__init__', '__bases__', '__dict__',
-                     '__subclasshook__'):
-            assert getattr(TestA, x) == getattr(orig_A, x)
-
-    with catch_warnings(AstropyDeprecationWarning) as w:
-        TestA()
-
-    assert len(w) == 1
-    assert 'function' not in TestA.__doc__
-    assert 'deprecated' in TestA.__doc__
-    assert 'function' not in TestA.__init__.__doc__
-    assert 'deprecated' in TestA.__init__.__doc__
-
-    # Make sure the object is picklable
-    pickle.dumps(TestA)
-
-
-def test_deprecated_class_with_super():
-    """
-    Regression test for an issue where classes that used `super()` in their
-    ``__init__`` did not actually call the correct class's ``__init__`` in the
-    MRO.
-    """
-
-    @misc.deprecated('100.0')
-    class TestB(object):
-        def __init__(self, a, b):
-            super(TestB, self).__init__()
-
-    with catch_warnings(AstropyDeprecationWarning) as w:
-        TestB(1, 2)
-
-    assert len(w) == 1
-    assert 'function' not in TestB.__doc__
-    assert 'deprecated' in TestB.__doc__
-    assert 'function' not in TestB.__init__.__doc__
-    assert 'deprecated' in TestB.__init__.__doc__
-
-
-def test_deprecated_static_and_classmethod():
-    """
-    Regression test for issue introduced by
-    https://github.com/astropy/astropy/pull/2811 and mentioned also here:
-    https://github.com/astropy/astropy/pull/2580#issuecomment-51049969
-    where it appears that deprecated staticmethods didn't work on Python 2.6.
-    """
-
-    class A(object):
-        @misc.deprecated('1.0')
-        @staticmethod
-        def B():
-            pass
-
-        @misc.deprecated('1.0')
-        @classmethod
-        def C(cls):
-            pass
-
-    with catch_warnings(AstropyDeprecationWarning) as w:
-        A.B()
-
-    assert len(w) == 1
-    assert 'deprecated' in A.B.__doc__
-
-    with catch_warnings(AstropyDeprecationWarning) as w:
-        A.C()
-
-    assert len(w) == 1
-    assert 'deprecated' in A.C.__doc__
-
-
 @remote_data
 def test_api_lookup():
     strurl = misc.find_api_page('astropy.utils.misc', 'dev', False, timeout=3)
diff --git a/astropy/utils/timer.py b/astropy/utils/timer.py
index 14b1fd8..e814261 100644
--- a/astropy/utils/timer.py
+++ b/astropy/utils/timer.py
@@ -242,7 +242,7 @@ class RunTimePredictor(object):
 
         Returns
         -------
-        a : array_like
+        a : array-like
             Fitted `~astropy.modeling.FittableModel` parameters.
 
         Raises
diff --git a/astropy/utils/xml/writer.py b/astropy/utils/xml/writer.py
index 89709f3..9d52cb5 100644
--- a/astropy/utils/xml/writer.py
+++ b/astropy/utils/xml/writer.py
@@ -150,11 +150,16 @@ class XMLWriter:
     @contextlib.contextmanager
     def tag(self, tag, attrib={}, **extra):
         """
-        A convenience method for use with the ``with`` statement::
+        A convenience method for creating wrapper elements using the
+        ``with`` statement.
 
-            with writer.tag('foo'):
-                writer.element('bar')
-            # </foo> is implicitly closed here
+        Examples
+        --------
+
+        >>> with writer.tag('foo'):  # doctest: +SKIP
+        ...     writer.element('bar')
+        ... # </foo> is implicitly closed here
+        ...
 
         Parameters are the same as to `start`.
         """
diff --git a/astropy/version.py b/astropy/version.py
index a74225e..0ccd628 100644
--- a/astropy/version.py
+++ b/astropy/version.py
@@ -1,4 +1,4 @@
-# Autogenerated by Astropy's setup.py on 2015-01-21 15:31:29.849330
+# Autogenerated by Astropy's setup.py on 2015-01-27 18:05:50.861457
 
 
 import locale
@@ -145,17 +145,17 @@ def get_git_devstr(sha=False, show_warning=True, path=None):
     else:
         return _decode_stdio(stdout).strip()
 
-_last_generated_version = '0.4.4'
-_last_githash = u'e4cd1a71feae16cc0c3d390bcd8f040984f37c50'
+_last_generated_version = '1.0rc1'
+_last_githash = u'd0548e3964464853083fd1ba8ae2b99056924368'
 
 version = update_git_devstr(_last_generated_version)
 githash = get_git_devstr(sha=True, show_warning=False,
                          path=__file__) or _last_githash
 
 
-major = 0
-minor = 4
-bugfix = 4
+major = 1
+minor = 0
+bugfix = 0
 
 release = True
 debug = False
diff --git a/astropy/version_helpers.py b/astropy/version_helpers.py
deleted file mode 100644
index 35e569c..0000000
--- a/astropy/version_helpers.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-
-##############################################################################
-# Note: this file exists only for backward-compatibility purposes - the      #
-#       contents have been moved to the separate astropy-helpers package,    #
-#       located at https://github.com/astropy/astropy-helpers. Any new       #
-#       development or bug fixes should be done there.                       #
-##############################################################################
-
-"""
-Utilities for generating the version string for Astropy (or an affiliated
-package) and the version.py module, which contains version info for the
-package.
-
-Within the generated astropy.version module, the `major`, `minor`, and `bugfix`
-variables hold the respective parts of the version number (bugfix is '0' if
-absent). The `release` variable is True if this is a release, and False if this
-is a development version of astropy. For the actual version string, use::
-
-    from astropy.version import version
-
-or::
-
-    from astropy import __version__
-
-"""
-
-from __future__ import division
-
-import datetime
-import imp
-import os
-import subprocess
-import sys
-
-from distutils import log
-from warnings import warn
-
-
-def _version_split(version):
-    """
-    Split a version string into major, minor, and bugfix numbers (with bugfix
-    optional, defaulting to 0).
-    """
-
-    for prerel in ('.dev', 'a', 'b', 'rc'):
-        if prerel in version:
-            version = version.split(prerel)[0]
-
-    versplit = version.split('.')
-    major = int(versplit[0])
-    minor = int(versplit[1])
-    bugfix = 0 if len(versplit) < 3 else int(versplit[2])
-    return major, minor, bugfix
-
-
-def update_git_devstr(version, path=None):
-    """
-    Updates the git revision string if and only if the path is being imported
-    directly from a git working copy.  This ensures that the revision number in
-    the version string is accurate.
-    """
-
-    try:
-        # Quick way to determine if we're in git or not - returns '' if not
-        devstr = get_git_devstr(sha=True, show_warning=False, path=path)
-    except OSError:
-        return version
-
-    if not devstr:
-        # Probably not in git so just pass silently
-        return version
-
-    if 'dev' in version:  # update to the current git revision
-        version_base = version.split('.dev', 1)[0]
-        devstr = get_git_devstr(sha=False, show_warning=False, path=path)
-
-        return version_base + '.dev' + devstr
-    else:
-        #otherwise it's already the true/release version
-        return version
-
-
-def get_git_devstr(sha=False, show_warning=True, path=None):
-    """
-    Determines the number of revisions in this repository.
-
-    Parameters
-    ----------
-    sha : bool
-        If True, the full SHA1 hash will be returned. Otherwise, the total
-        count of commits in the repository will be used as a "revision
-        number".
-
-    show_warning : bool
-        If True, issue a warning if git returns an error code, otherwise errors
-        pass silently.
-
-    path : str or None
-        If a string, specifies the directory to look in to find the git
-        repository.  If None, the location of the file this function is in
-        is used to infer the git repository location.  If given a filename it
-        uses the directory containing that file.
-
-    Returns
-    -------
-    devversion : str
-        Either a string with the revsion number (if `sha` is False), the
-        SHA1 hash of the current commit (if `sha` is True), or an empty string
-        if git version info could not be identified.
-
-    """
-
-    from .utils import find_current_module
-
-    if path is None:
-        try:
-            mod = find_current_module(1, finddiff=True)
-            path = os.path.abspath(mod.__file__)
-        except (ValueError, AttributeError):
-            path = __file__
-    if not os.path.isdir(path):
-        path = os.path.abspath(os.path.split(path)[0])
-
-    if sha:
-        cmd = 'rev-parse'  # Faster for getting just the hash of HEAD
-    else:
-        cmd = 'rev-list'
-
-    try:
-        p = subprocess.Popen(['git', cmd, 'HEAD'], cwd=path,
-                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                             stdin=subprocess.PIPE)
-        stdout, stderr = p.communicate()
-    except OSError as e:
-        if show_warning:
-            warn('Error running git: ' + str(e))
-        return ''
-
-    if p.returncode == 128:
-        if show_warning:
-            warn('No git repository present! Using default dev version.')
-        return ''
-    elif p.returncode != 0:
-        if show_warning:
-            warn('Git failed while determining revision count: ' + stderr)
-        return ''
-
-    if sha:
-        return stdout.decode('utf-8')[:40]
-    else:
-        nrev = stdout.decode('utf-8').count('\n')
-        return  str(nrev)
-
-
-# This is used by setup.py to create a new version.py - see that file for
-# details. Note that the imports have to be absolute, since this is also used
-# by affiliated packages.
-
-_FROZEN_VERSION_PY_TEMPLATE = """
-# Autogenerated by {packagename}'s setup.py on {timestamp}
-
-from astropy.version_helpers import update_git_devstr, get_git_devstr
-
-_last_generated_version = {verstr!r}
-
-version = update_git_devstr(_last_generated_version)
-githash = get_git_devstr(sha=True, show_warning=False)
-
-major = {major}
-minor = {minor}
-bugfix = {bugfix}
-
-release = {rel}
-debug = {debug}
-
-try:
-    from .utils._compiler import compiler
-except ImportError:
-    compiler = "unknown"
-
-try:
-    from .cython_version import cython_version
-except ImportError:
-    cython_version = "unknown"
-"""[1:]
-
-
-def _get_version_py_str(packagename, version, release, debug):
-    timestamp = str(datetime.datetime.now())
-    major, minor, bugfix = _version_split(version)
-    if packagename.lower() == 'astropy':
-        packagename = 'Astropy'
-    else:
-        packagename = 'Astropy-affiliated package ' + packagename
-    return _FROZEN_VERSION_PY_TEMPLATE.format(packagename=packagename,
-                                              timestamp=timestamp,
-                                              verstr=version,
-                                              major=major,
-                                              minor=minor,
-                                              bugfix=bugfix,
-                                              rel=release, debug=debug)
-
-
-def generate_version_py(packagename, version, release=None, debug=None):
-    """Regenerate the version.py module if necessary."""
-
-    from .setup_helpers import is_distutils_display_option
-    from .utils.compat.misc import invalidate_caches
-
-    try:
-        version_module = __import__(packagename + '.version',
-                                    fromlist=['_last_generated_version',
-                                              'version', 'release', 'debug'])
-        try:
-            last_generated_version = version_module._last_generated_version
-        except AttributeError:
-            # Older version.py with no _last_generated_version; this will
-            # ensure a new version.py is written
-            last_generated_version = None
-        current_release = version_module.release
-        current_debug = version_module.debug
-    except ImportError:
-        version_module = None
-        last_generated_version = None
-        current_release = None
-        current_debug = None
-
-    if release is None:
-        # Keep whatever the current value is, if it exists
-        release = bool(current_release)
-
-    if debug is None:
-        # Likewise, keep whatever the current value is, if it exists
-        debug = bool(current_debug)
-
-    version_py = os.path.join(packagename, 'version.py')
-
-    if (last_generated_version != version or current_release != release or
-        current_debug != debug):
-        if '-q' not in sys.argv and '--quiet' not in sys.argv:
-            log.set_threshold(log.INFO)
-
-        if is_distutils_display_option():
-            # Always silence unnecessary log messages when display options are
-            # being used
-            log.set_threshold(log.WARN)
-
-        log.info('Freezing version number to {0}'.format(version_py))
-
-        with open(version_py, 'w') as f:
-            # This overwrites the actual version.py
-            f.write(_get_version_py_str(packagename, version, release, debug))
-
-        invalidate_caches()
-
-        if version_module:
-            imp.reload(version_module)
diff --git a/astropy/visualization/__init__.py b/astropy/visualization/__init__.py
new file mode 100644
index 0000000..bb003ea
--- /dev/null
+++ b/astropy/visualization/__init__.py
@@ -0,0 +1,7 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from .stretch import *
+from .interval import *
+from .transform import *
+from .ui import *
+from .mpl_style import *
diff --git a/astropy/visualization/interval.py b/astropy/visualization/interval.py
new file mode 100644
index 0000000..dc78f98
--- /dev/null
+++ b/astropy/visualization/interval.py
@@ -0,0 +1,142 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Classes that deal with computing intervals from arrays of values based on
+various criteria.
+"""
+
+from __future__ import division, print_function
+
+import abc
+import numpy as np
+
+from .transform import BaseTransform
+
+__all__ = ['BaseInterval', 'ManualInterval', 'MinMaxInterval',
+           'PercentileInterval', 'AsymmetricPercentileInterval']
+
+
+class BaseInterval(BaseTransform):
+    """
+    Base class for the interval classes, which, when called with an array of
+    values, return an interval computed following different algorithms.
+    """
+
+    @abc.abstractmethod
+    def get_limits(self, values):
+        """
+        Return the minimum and maximum value in the interval based on the values provided.
+        """
+
+    def __call__(self, values, clip=True, out=None):
+
+        vmin, vmax = self.get_limits(values)
+
+        if out is None:
+            values = np.subtract(values, float(vmin))
+        else:
+            if out.dtype.kind != 'f':
+                raise TypeError("Can only do in-place scaling for floating-point arrays")
+            values = np.subtract(values, float(vmin), out=out)
+
+        if (vmax - vmin) != 0:
+            np.true_divide(values, vmax - vmin, out=values)
+
+        if clip:
+            np.clip(values, 0., 1., out=values)
+
+        return values
+
+
+class ManualInterval(BaseInterval):
+    """
+    Interval based on user-specified values.
+
+    Parameters
+    ----------
+    vmin : float
+        The minimum value in the scaling
+    vmax : float
+        The maximum value in the scaling
+    """
+
+    def __init__(self, vmin, vmax):
+        self.vmin = vmin
+        self.vmax = vmax
+
+    def get_limits(self, values):
+        return self.vmin, self.vmax
+
+
+class MinMaxInterval(BaseInterval):
+    """
+    Interval based on the minimum and maximum values in the data.
+    """
+
+    def get_limits(self, values):
+        return np.min(values), np.max(values)
+
+
+class AsymmetricPercentileInterval(BaseInterval):
+    """
+    Interval based on a keeping a specified fraction of pixels (can be asymmetric).
+
+    Parameters
+    ----------
+    lower_percentile : float
+        The lower percentile below which to ignore pixels.
+    upper_percentile : float
+        The upper percentile above which to ignore pixels.
+    n_samples : int, optional
+        Maximum number of values to use. If this is specified, and there are
+        more values in the dataset as this, then values are randomly sampled
+        from the array (with replacement)
+    """
+
+    def __init__(self, lower_percentile, upper_percentile, n_samples=None):
+        self.lower_percentile = lower_percentile
+        self.upper_percentile = upper_percentile
+        self.n_samples = n_samples
+
+    def get_limits(self, values):
+
+        # Make sure values is a Numpy array
+        values = np.asarray(values).ravel()
+
+        # If needed, limit the number of samples. We sample with replacement
+        # since this is much faster.
+        if self.n_samples is not None and values.size > self.n_samples:
+            try:
+                values = np.random.choice(values, self.n_samples)
+            except AttributeError:  # Numpy 1.6.x
+                values = values[np.random.randint(0, values.size, self.n_samples)]
+
+        # Filter out invalid values (inf, nan)
+        values = values[np.isfinite(values)]
+
+        # Determine values at percentiles
+        vmin, vmax = np.percentile(values, (self.lower_percentile,
+                                            self.upper_percentile))
+
+        return vmin, vmax
+
+
+class PercentileInterval(AsymmetricPercentileInterval):
+    """
+    Interval based on a keeping a specified fraction of pixels.
+
+    Parameters
+    ----------
+    percentile : float
+        The fraction of pixels to keep. The same fraction of pixels is
+        eliminated from both ends.
+    n_samples : int, optional
+        Maximum number of values to use. If this is specified, and there are
+        more values in the dataset as this, then values are randomly sampled
+        from the array (with replacement)
+    """
+
+    def __init__(self, percentile, n_samples=None):
+        lower_percentile = (100 - percentile) * 0.5
+        upper_percentile = 100 - lower_percentile
+        super(PercentileInterval, self).__init__(lower_percentile, upper_percentile, n_samples=n_samples)
diff --git a/astropy/visualization/mpl_normalize.py b/astropy/visualization/mpl_normalize.py
new file mode 100644
index 0000000..7d574f6
--- /dev/null
+++ b/astropy/visualization/mpl_normalize.py
@@ -0,0 +1,85 @@
+"""
+Normalization class for Matplotlib that can be used to produce colorbars.
+"""
+
+from __future__ import division, print_function
+
+import numpy as np
+from numpy import ma
+
+try:
+    from matplotlib.colors import Normalize
+except ImportError:
+    class Normalize(object):
+        def __init__(self, *args, **kwargs):
+            raise ImportError("matplotlib is required in order to use this class")
+
+__all__ = ['ImageNormalize']
+
+
+class ImageNormalize(Normalize):
+    """
+    Normalization class to be used with Matplotlib.
+
+    Parameters
+    ----------
+    vmin, vmax : float
+        The minimum and maximum levels to show for the data
+    stretch : :class:`~astropy.visualization.BaseStretch` instance
+        The stretch to use for the normalization
+    clip : bool, optional
+        Whether to clip the output values to the [0:1] range
+    """
+
+    def __init__(self, vmin=None, vmax=None, stretch=None, clip=False):
+
+        super(ImageNormalize, self).__init__(vmin=vmin, vmax=vmax, clip=clip)
+
+        self.vmin = vmin
+        self.vmax = vmax
+        self.stretch = stretch
+        self.inverse_stretch = stretch.inverse
+
+    def __call__(self, values, clip=None):
+
+        if clip is None:
+            clip = self.clip
+
+        if isinstance(values, ma.MaskedArray):
+            if clip:
+                mask = False
+            else:
+                mask = values.mask
+            values = values.filled(self.vmax)
+        else:
+            mask = False
+
+        # Make sure scalars get broadcast to 1-d
+        if np.isscalar(values):
+            values = np.array([values], dtype=float)
+        else:
+            # copy because of in-place operations after
+            values = np.array(values, copy=True, dtype=float)
+
+        # Normalize based on vmin and vmax
+        np.subtract(values, self.vmin, out=values)
+
+        np.true_divide(values, self.vmax - self.vmin, out=values)
+
+        # Clip to the 0 to 1 range
+        if self.clip:
+            values = np.clip(values, 0., 1., out=values)
+
+        # Stretch values
+        values = self.stretch(values, out=values, clip=False)
+
+        # Convert to masked array for matplotlib
+        return ma.array(values, mask=mask)
+
+    def inverse(self, values):
+
+        # Find unstretched values in range 0 to 1
+        values_norm = self.inverse_stretch(values, clip=False)
+
+        # Scale to original range
+        return values_norm * (self.vmax - self.vmin) + self.vmin
diff --git a/astropy/visualization/mpl_style.py b/astropy/visualization/mpl_style.py
new file mode 100644
index 0000000..f23f435
--- /dev/null
+++ b/astropy/visualization/mpl_style.py
@@ -0,0 +1,113 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+__doctest_requires__ = {'*': ['matplotlib']}
+
+""" This module contains dictionaries that can be used to set a
+matplotlib plotting style.
+It is mostly here to allow a consistent plotting style in tutorials,
+but can be used to prepare any matplotlib figure.
+
+Using a matplotlib version > 1.4 you can do::
+
+    >>> import matplotlib.pyplot as plt
+    >>> from astropy.visualization import astropy_mpl_style
+    >>> plt.style.use(astropy_mpl_style)
+
+for older versions of matplotlib the following works::
+
+    >>> import matplotlib as mpl
+    >>> from astropy.visualization import astropy_mpl_style
+    >>> mpl.rcParams.update(astropy_mpl_style)
+
+This applies the astropy style on top of your existing matplotlib
+default parameters. If you want an exactly reproducible plot (again, this
+is useful if you are writing teaching material and you want the plot
+to come out exactly the same, independent of the users configuration for
+example), you should reset the matplotlib settings to the library defaults
+*before* applying the astropy style, e.g.::
+
+    >>> import matplotlib as mpl
+    >>> from astropy.visualization import astropy_mpl_style
+    >>> mpl.rcdefaults()
+    >>> mpl.rcParams.update(astropy_mpl_style)
+"""
+
+
+astropy_mpl_style_1 = {
+
+    # Lines
+    'lines.linewidth': 1.7,
+    'lines.antialiased': True,
+
+    # Patches
+    'patch.linewidth': 1.0,
+    'patch.facecolor': '#348ABD',
+    'patch.edgecolor': '#CCCCCC',
+    'patch.antialiased': True,
+
+    # images
+    'image.cmap': 'gist_heat',
+    'image.origin': 'upper',
+
+    # Font
+    'font.size': 12.0,
+
+    # Axes
+    'axes.facecolor': '#FFFFFF',
+    'axes.edgecolor': '#AAAAAA',
+    'axes.linewidth': 1.0,
+    'axes.grid': True,
+    'axes.titlesize': 'x-large',
+    'axes.labelsize': 'large',
+    'axes.labelcolor': '#FFFFFF',
+    'axes.axisbelow': True,
+    'axes.color_cycle': ['#348ABD',   # blue
+                         '#7A68A6',   # purple
+                         '#A60628',   # red
+                         '#467821',   # green
+                         '#CF4457',   # pink
+                         '#188487',   # turquoise
+                         '#E24A33'],  # orange
+
+    # Ticks
+    'xtick.major.size': 0,
+    'xtick.minor.size': 0,
+    'xtick.major.pad': 6,
+    'xtick.minor.pad': 6,
+    'xtick.color': '#565656',
+    'xtick.direction': 'in',
+    'ytick.major.size': 0,
+    'ytick.minor.size': 0,
+    'ytick.major.pad': 6,
+    'ytick.minor.pad': 6,
+    'ytick.color': '#565656',
+    'ytick.direction': 'in',
+
+    # Legend
+    'legend.fancybox': True,
+    'legend.loc': 'best',
+
+    # Figure
+    'figure.figsize': [8, 6],
+    'figure.facecolor': '1.0',
+    'figure.edgecolor': '0.50',
+    'figure.subplot.hspace': 0.5,
+
+    # Other
+    'savefig.dpi': 72,
+    'interactive': True,
+    'toolbar': 'toolbar2',
+    'timezone': 'UTC'
+}
+'''
+Version 1 astropy plotting style for matplotlib.
+
+This style improves some settings over the matplotlib default.
+'''
+
+astropy_mpl_style = astropy_mpl_style_1
+'''
+Most recent version of the astropy plotting style for matplotlib.
+
+This style improves some settings over the matplotlib default.
+'''
diff --git a/astropy/visualization/scripts/__init__.py b/astropy/visualization/scripts/__init__.py
new file mode 100644
index 0000000..9dce85d
--- /dev/null
+++ b/astropy/visualization/scripts/__init__.py
@@ -0,0 +1 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
diff --git a/astropy/visualization/scripts/fits2bitmap.py b/astropy/visualization/scripts/fits2bitmap.py
new file mode 100644
index 0000000..7e6db78
--- /dev/null
+++ b/astropy/visualization/scripts/fits2bitmap.py
@@ -0,0 +1,138 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+
+from ... import log
+from ...io import fits
+
+from ..ui import scale_image
+
+
+def fits2bitmap(filename, ext=0, out_fn=None, scale='linear',
+                power=1.0, asinh_a=0.1, min_cut=None, max_cut=None,
+                min_percent=None, max_percent=None, percent=None,
+                cmap='Greys_r'):
+    """
+    Create a bitmap file from a FITS image, applying a
+    scaling/stretching transform between minimum and maximum cut levels
+    and a matplotlib colormap.
+
+    Parameters
+    ----------
+    filename : str
+        The filename of the FITS file.
+    ext : int
+        FITS extension number of the image to convert.  The default is 0.
+    out_fn : str
+        The filename of the output bitmap image.  The type of bitmap
+        is determined by the filename extension (e.g. '.jpg', '.png').
+        The default is a PNG file with the same name as the FITS file.
+    scale : {{'linear', 'sqrt', 'power', log', 'asinh'}}
+        The scaling/stretch function to apply to the image.  The default
+        is 'linear'.
+    power : float, optional
+        The power index for ``scale='power'`` image scaling.  The
+        default is 1.0.
+    asinh_a : float, optional
+        For ``scale='asinh'`` image scaling, the value where the asinh
+        curve transitions from linear to logarithmic behavior, expressed
+        as a fraction of the normalized image.  Must be in the range
+        between 0 and 1.
+    min_cut : float, optional
+        The pixel value of the minimum cut level.  Data values less than
+        ``min_cut`` will set to ``min_cut`` before scaling the image.
+        The default is the image minimum.  ``min_cut`` overrides
+        ``min_percent``.
+    max_cut : float, optional
+        The pixel value of the maximum cut level.  Data values greater
+        than ``min_cut`` will set to ``min_cut`` before scaling the
+        image.  The default is the image maximum.  ``max_cut`` overrides
+        ``max_percent``.
+    min_percent : float, optional
+        The percentile value used to determine the pixel value of
+        minimum cut level.  The default is 0.0.  ``min_percent``
+        overrides ``percent``.
+    max_percent : float, optional
+        The percentile value used to determine the pixel value of
+        maximum cut level.  The default is 100.0.  ``max_percent``
+        overrides ``percent``.
+    percent : float, optional
+        The percentage of the image values used to determine the pixel
+        values of the minimum and maximum cut levels.  The lower cut
+        level will set at the ``(100 - percent) / 2`` percentile, while
+        the upper cut level will be set at the ``(100 + percent) / 2``
+        percentile.  The default is 100.0.  ``percent`` is ignored if
+        either ``min_percent`` or ``max_percent`` is input.
+    cmap : str
+        The matplotlib color map name.  The default is 'Greys_r'.
+    """
+
+    import matplotlib.cm as cm
+    import matplotlib.image as mimg
+
+    hdulist = fits.open(filename)
+    image = hdulist[ext].data
+    hdulist.close()
+    if out_fn is None:
+        out_fn = filename.replace('.fits', '.png')
+    if cmap not in cm.datad.keys():
+        log.critical('{0} is not a valid matplotlib colormap '
+                     'name'.format(cmap))
+        raise SystemExit()
+
+    image_scaled = scale_image(image, scale=scale, power=power,
+                               asinh_a=asinh_a, min_cut=min_cut,
+                               max_cut=max_cut, min_percent=min_percent,
+                               max_percent=max_percent, percent=percent)
+
+    mimg.imsave(out_fn, image_scaled, cmap=cmap)
+    log.info('Saved file to {0}'.format(out_fn))
+
+
+def main(args=None):
+
+    from ...utils.compat import argparse
+
+    parser = argparse.ArgumentParser(
+        description='Create a bitmap file from a FITS image.')
+    parser.add_argument('-e', '--ext', metavar='hdu', type=int, default=0,
+                        help='specify the HDU extension number or name')
+    parser.add_argument('-o', metavar='filename', type=str, default=None,
+                        help='Filename for the output image (Default is a '
+                        'PNG file with the same name as the FITS file)')
+    parser.add_argument('--scale', type=str, default='linear',
+                        help='Type of image scaling ("linear", "sqrt", '
+                        '"power", "log", or "asinh")')
+    parser.add_argument('--power', type=float, default=1.0,
+                        help='Power index for "power" scaling')
+    parser.add_argument('--asinh_a', type=float, default=0.1,
+                        help=('The value in normalized image where the asinh '
+                              'curve transitions from linear to logarithmic '
+                              'behavior (used only for "asinh" scaling)'))
+    parser.add_argument('--min_cut', type=float, default=None,
+                        help='The pixel value of the minimum cut level')
+    parser.add_argument('--max_cut', type=float, default=None,
+                        help='The pixel value of the maximum cut level')
+    parser.add_argument('--min_percent', type=float, default=None,
+                        help=('The percentile value used to determine the '
+                              'minimum cut level'))
+    parser.add_argument('--max_percent', type=float, default=None,
+                        help=('The percentile value used to determine the '
+                              'maximum cut level'))
+    parser.add_argument('--percent', type=float, default=None,
+                        help=('The percentage of the image values used to '
+                              'determine the pixel values of the minimum and '
+                              'maximum cut levels'))
+    parser.add_argument('--cmap', metavar='colormap_name', type=str,
+                        default='Greys_r', help='matplotlib color map name')
+    parser.add_argument('filename', nargs='+',
+                        help='Path to one or more FITS files to convert')
+    args = parser.parse_args(args)
+
+    for filename in args.filename:
+        fits2bitmap(filename, ext=args.ext, out_fn=args.o,
+                    scale=args.scale, min_cut=args.min_cut,
+                    max_cut=args.max_cut, min_percent=args.min_percent,
+                    max_percent=args.max_percent, percent=args.percent,
+                    power=args.power, asinh_a=args.asinh_a, cmap=args.cmap)
diff --git a/astropy/visualization/scripts/tests/__init__.py b/astropy/visualization/scripts/tests/__init__.py
new file mode 100644
index 0000000..9dce85d
--- /dev/null
+++ b/astropy/visualization/scripts/tests/__init__.py
@@ -0,0 +1 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
diff --git a/astropy/visualization/scripts/tests/test_fits2bitmap.py b/astropy/visualization/scripts/tests/test_fits2bitmap.py
new file mode 100644
index 0000000..1d04ac6
--- /dev/null
+++ b/astropy/visualization/scripts/tests/test_fits2bitmap.py
@@ -0,0 +1,27 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+
+from ....tests.helper import pytest
+from ....io import fits
+
+try:
+    import matplotlib
+    HAS_MATPLOTLIB = True
+    from ..fits2bitmap import fits2bitmap, main
+except:
+    HAS_MATPLOTLIB = False
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_fits2bitmap_function(tmpdir):
+    filename = tmpdir.join('test.fits').strpath
+    fits.writeto(filename, np.ones((128, 128)))
+    fits2bitmap(filename)
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_fits2bitmap_script(tmpdir):
+    filename = tmpdir.join('test.fits').strpath
+    fits.writeto(filename, np.ones((128, 128)))
+    main([filename, '-e', '0'])
diff --git a/astropy/visualization/stretch.py b/astropy/visualization/stretch.py
new file mode 100644
index 0000000..1fefb9a
--- /dev/null
+++ b/astropy/visualization/stretch.py
@@ -0,0 +1,468 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Classes that deal with stretching, i.e. mapping a range of [0:1] values onto
+another set of [0:1] values with a transformation
+"""
+
+from __future__ import division, print_function
+
+import numpy as np
+
+from ..extern import six
+from ..utils.misc import InheritDocstrings
+
+from .transform import BaseTransform
+
+__all__ = ["BaseStretch", "LinearStretch", "SqrtStretch", "PowerStretch",
+           "PowerDistStretch", "SquaredStretch", "LogStretch", "AsinhStretch",
+           "SinhStretch", "HistEqStretch", "ContrastBiasStretch"]
+
+
+def logn(n, x, out=None):
+    # We define this because numpy.lib.scimath.logn doesn't support out=
+    if out is None:
+        return np.log(x) / np.log(n)
+    else:
+        np.log(x, out=out)
+        np.true_divide(out, np.log(n), out=out)
+        return out
+
+
+def _prepare(values, out=None, clip=True):
+    """
+    Prepare the data by optionally clipping and copying, and return the array
+    that should be subsequently used for in-place calculations.
+    """
+    if clip:
+        return np.clip(values, 0., 1., out=out)
+    else:
+        if out is None:
+            return np.array(values, copy=True)
+        else:
+            out[:] = np.asarray(values)
+            return out
+
+
+ at six.add_metaclass(InheritDocstrings)
+class BaseStretch(BaseTransform):
+    """
+    Base class for the stretch classes, which, when called with an array of
+    values in the range [0:1], return an transformed array of values, also in
+    the range [0:1].
+    """
+
+    def __call__(self, values, out=None, clip=True):
+        """
+        Transform values using this stretch.
+
+        Parameters
+        ----------
+        values : `~numpy.ndarray` or list
+            The input values, which should already be normalized to the [0:1]
+            range.
+        out : `~numpy.ndarray`, optional
+            If specified, the output values will be placed in this array
+            (typically used for in-place calculations).
+        clip : bool, optional
+            If `True` (default), values outside the [0:1] range are clipped to
+            the [0:1] range.
+
+        Returns
+        -------
+        new_values : `~numpy.ndarray`
+            The transformed values.
+        """
+
+    @property
+    def inverse(self):
+        """
+        Return a stretch that performs the inverse operation.
+        """
+
+
+class LinearStretch(BaseStretch):
+    """
+    A linear stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = x
+    """
+
+    def __call__(self, values, out=None, clip=True):
+
+        return _prepare(values, out=out, clip=clip)
+
+    @property
+    def inverse(self):
+        return LinearStretch()
+
+
+class SqrtStretch(BaseStretch):
+    r"""
+    A square root stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = \sqrt{x}
+    """
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.sqrt(values, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return PowerStretch(2)
+
+
+class PowerStretch(BaseStretch):
+    r"""
+    A power stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = x^a
+    """
+
+    def __init__(self, a):
+        super(PowerStretch, self).__init__()
+        self.power = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.power(values, self.power, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return PowerStretch(1. / self.power)
+
+
+class PowerDistStretch(BaseStretch):
+    r"""
+    An alternative power stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = \frac{a^x - 1}{a - 1}
+    """
+
+    def __init__(self, a=1000.0):
+        if a == 1:  # singularity
+            raise ValueError("a cannot be set to 1")
+        super(PowerDistStretch, self).__init__()
+        self.exp = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.power(self.exp, values, out=values)
+        np.subtract(values, 1, out=values)
+        np.true_divide(values, self.exp - 1.0, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return InvertedPowerDistStretch(a=self.exp)
+
+
+class InvertedPowerDistStretch(BaseStretch):
+    """
+    Inverse transformation for `~astropy.image.scaling.PowerDistStretch`.
+    """
+
+    def __init__(self, a=1000.0):
+        if a == 1:  # singularity
+            raise ValueError("a cannot be set to 1")
+        super(InvertedPowerDistStretch, self).__init__()
+        self.exp = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.multiply(values, self.exp - 1.0, out=values)
+        np.add(values, 1, out=values)
+        logn(self.exp, values, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return PowerDistStretch(a=self.exp)
+
+
+class SquaredStretch(PowerStretch):
+    r"""
+    A convenience class for a power stretch of 2.
+
+    The stretch is given by:
+
+    .. math::
+        y = x^2
+    """
+
+    def __init__(self):
+        super(SquaredStretch, self).__init__(2)
+
+    @property
+    def inverse(self):
+        return SqrtStretch()
+
+
+class LogStretch(BaseStretch):
+    r"""
+    A log stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = \frac{\log{(a x + 1)}}{\log{(a + 1)}}.
+    """
+
+    def __init__(self, a=1000.0):
+        super(LogStretch, self).__init__()
+        self.exp = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.multiply(values, self.exp, out=values)
+        np.add(values, 1., out=values)
+        np.log(values, out=values)
+        np.true_divide(values, np.log(self.exp + 1.), out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return InvertedLogStretch(self.exp)
+
+
+class InvertedLogStretch(BaseStretch):
+    """
+    Inverse transformation for `~astropy.image.scaling.LogStretch`.
+    """
+
+    def __init__(self, a):
+        super(InvertedLogStretch, self).__init__()
+        self.exp = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.multiply(values, np.log(self.exp + 1.), out=values)
+        np.exp(values, out=values)
+        np.subtract(values, 1., out=values)
+        np.true_divide(values, self.exp, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return LogStretch(self.exp)
+
+
+class AsinhStretch(BaseStretch):
+    r"""
+    An asinh stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = \frac{{\rm asinh}(x / a)}{{\rm asinh}(1 / a)}.
+    """
+
+    def __init__(self, a=0.1):
+        super(AsinhStretch, self).__init__()
+        self.a = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.true_divide(values, self.a, out=values)
+        np.arcsinh(values, out=values)
+        np.true_divide(values, np.arcsinh(1. / self.a), out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return SinhStretch(a=1. / np.arcsinh(1. / self.a))
+
+
+class SinhStretch(BaseStretch):
+    r"""
+    A sinh stretch.
+
+    The stretch is given by:
+
+    .. math::
+        y = \frac{{\rm sinh}(x / a)}{{\rm sinh}(1 / a)}
+    """
+
+    def __init__(self, a=1. / 3.):
+        super(SinhStretch, self).__init__()
+        self.a = a
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        np.true_divide(values, self.a, out=values)
+        np.sinh(values, out=values)
+        np.true_divide(values, np.sinh(1. / self.a), out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return AsinhStretch(a=1. / np.sinh(1. / self.a))
+
+
+class HistEqStretch(BaseStretch):
+    """
+    A histogram equalization stretch.
+
+    Parameters
+    ----------
+    data : float
+        The data defining the equalization
+    """
+
+    def __init__(self, data, values=None):
+
+        # Assume data is not necessarily normalized at this point
+        self.data = np.sort(data.ravel())
+        vmin = self.data.min()
+        vmax = self.data.max()
+        self.data = (self.data - vmin) / (vmax - vmin)
+
+        # Compute relative position of each pixel
+        if values is None:
+            self.values = np.linspace(0., 1., len(self.data))
+        else:
+            self.values = values
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        values[:] = np.interp(values, self.data, self.values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return InvertedHistEqStretch(self.data, values=self.values)
+
+
+class InvertedHistEqStretch(BaseStretch):
+    """
+    Inverse transformation for `~astropy.image.scaling.HistEqStretch`.
+    """
+
+    def __init__(self, data, values=None):
+        self.data = data
+        if values is None:
+            self.values = np.linspace(0., 1., len(self.data))
+        else:
+            self.values = values
+
+    def __call__(self, values, out=None, clip=True):
+
+        values = _prepare(values, out=out, clip=clip)
+
+        values[:] = np.interp(values, self.values, self.data)
+
+        return values
+
+    @property
+    def inverse(self):
+        return HistEqStretch(self.data, values=self.values)
+
+
+class ContrastBiasStretch(BaseStretch):
+    """
+    A stretch that takes into account contrast and bias.
+
+    The stretch is given by:
+
+    .. math::
+        y = (x - {\\rm bias}) * {\\rm contrast} + 0.5
+
+    and the output values are clipped to the [0:1] range.
+    """
+
+    def __init__(self, contrast, bias):
+        super(ContrastBiasStretch, self).__init__()
+        self.contrast = contrast
+        self.bias = bias
+
+    def __call__(self, values, out=None, clip=True):
+
+        # As a special case here, we only clip *after* the transformation since
+        # it does not map [0:1] to [0:1]
+        values = _prepare(values, out=out, clip=False)
+
+        np.subtract(values, self.bias, out=values)
+        np.multiply(values, self.contrast, out=values)
+        np.add(values, 0.5, out=values)
+
+        if clip:
+            np.clip(values, 0, 1, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return InvertedContrastBiasStretch(self.contrast, self.bias)
+
+
+class InvertedContrastBiasStretch(BaseStretch):
+    """
+    Inverse transformation for ContrastBiasStretch.
+    """
+
+    def __init__(self, contrast, bias):
+        super(InvertedContrastBiasStretch, self).__init__()
+        self.contrast = contrast
+        self.bias = bias
+
+    def __call__(self, values, out=None, clip=True):
+
+        # As a special case here, we only clip *after* the transformation since
+        # it does not map [0:1] to [0:1]
+
+        values = _prepare(values, out=out, clip=False)
+
+        np.subtract(values, 0.5, out=values)
+        np.true_divide(values, self.contrast, out=values)
+        np.add(values, self.bias, out=values)
+
+        if clip:
+            np.clip(values, 0, 1, out=values)
+
+        return values
+
+    @property
+    def inverse(self):
+        return ContrastBiasStretch(self.contrast, self.bias)
diff --git a/astropy/visualization/tests/__init__.py b/astropy/visualization/tests/__init__.py
new file mode 100644
index 0000000..9dce85d
--- /dev/null
+++ b/astropy/visualization/tests/__init__.py
@@ -0,0 +1 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
diff --git a/astropy/visualization/tests/test_interval.py b/astropy/visualization/tests/test_interval.py
new file mode 100644
index 0000000..84eba3d
--- /dev/null
+++ b/astropy/visualization/tests/test_interval.py
@@ -0,0 +1,89 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+
+from ...tests.helper import pytest
+from ...utils import NumpyRNGContext
+
+from ..interval import (ManualInterval, MinMaxInterval, PercentileInterval,
+                        AsymmetricPercentileInterval)
+
+
+class TestInterval(object):
+
+    data = np.linspace(-20., 60., 100)
+
+    def test_manual(self):
+        interval = ManualInterval(-10., +15.)
+        vmin, vmax = interval.get_limits(self.data)
+        np.testing.assert_allclose(vmin, -10.)
+        np.testing.assert_allclose(vmax, +15.)
+
+    def test_minmax(self):
+        interval = MinMaxInterval()
+        vmin, vmax = interval.get_limits(self.data)
+        np.testing.assert_allclose(vmin, -20.)
+        np.testing.assert_allclose(vmax, +60.)
+
+    def test_percentile(self):
+        interval = PercentileInterval(62.2)
+        vmin, vmax = interval.get_limits(self.data)
+        np.testing.assert_allclose(vmin, -4.88)
+        np.testing.assert_allclose(vmax, 44.88)
+
+    def test_asymmetric_percentile(self):
+        interval = AsymmetricPercentileInterval(10.5, 70.5)
+        vmin, vmax = interval.get_limits(self.data)
+        np.testing.assert_allclose(vmin, -11.6)
+        np.testing.assert_allclose(vmax, 36.4)
+
+    def test_asymmetric_percentile_nsamples(self):
+        with NumpyRNGContext(12345):
+            interval = AsymmetricPercentileInterval(10.5, 70.5, n_samples=20)
+            vmin, vmax = interval.get_limits(self.data)
+        np.testing.assert_allclose(vmin, -14.367676767676768)
+        np.testing.assert_allclose(vmax, 40.266666666666666)
+
+
+class TestIntervalList(TestInterval):
+
+    # Make sure intervals work with lists
+
+    data = np.linspace(-20., 60., 100).tolist()
+
+
+class TestInterval2D(TestInterval):
+
+    # Make sure intervals work with 2d arrays
+
+    data = np.linspace(-20., 60., 100).reshape(100, 1)
+
+
+def test_integers():
+
+    # Need to make sure integers get cast to float
+    interval = MinMaxInterval()
+    values = interval([1, 3, 4, 5, 6])
+    np.testing.assert_allclose(values, [0., 0.4, 0.6, 0.8, 1.0])
+
+    # Don't accept integer array in output
+    out = np.zeros(5, dtype=int)
+    with pytest.raises(TypeError) as exc:
+        values = interval([1, 3, 4, 5, 6], out=out)
+    assert exc.value.args[0] == "Can only do in-place scaling for floating-point arrays"
+
+    # But integer input and floating point output is fine
+    out = np.zeros(5, dtype=float)
+    interval([1, 3, 4, 5, 6], out=out)
+    np.testing.assert_allclose(out, [0., 0.4, 0.6, 0.8, 1.0])
+
+
+def test_constant_data():
+    """Test intervals with constant data (avoiding divide-by-zero)."""
+    shape = (10, 10)
+    data = np.ones(shape)
+    interval = MinMaxInterval()
+    limits = interval.get_limits(data)
+    values = interval(data)
+    np.testing.assert_allclose(limits, (1., 1.))
+    np.testing.assert_allclose(values, np.zeros(shape))
diff --git a/astropy/visualization/tests/test_norm.py b/astropy/visualization/tests/test_norm.py
new file mode 100644
index 0000000..07146d5
--- /dev/null
+++ b/astropy/visualization/tests/test_norm.py
@@ -0,0 +1,89 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+from numpy import ma
+
+from numpy.testing import assert_allclose
+
+try:
+    import matplotlib
+    HAS_MATPLOTLIB = True
+except:
+    HAS_MATPLOTLIB = False
+
+from ..mpl_normalize import ImageNormalize
+
+from ...tests.helper import pytest
+from ..stretch import SqrtStretch
+
+
+ at pytest.mark.skipif('HAS_MATPLOTLIB')
+def test_error_message():
+    with pytest.raises(ImportError) as exc:
+        ImageNormalize()
+    assert exc.value.args[0] == "matplotlib is required in order to use this class"
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_normalize_scalar():
+
+    n = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True)
+
+    assert_allclose(n(6), 0.70710678)
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_normalize_clip():
+
+    data = np.linspace(0., 15., 6)
+    n = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True)
+
+    output = n(data)
+
+    assert_allclose(output, [0., 0.35355339, 0.70710678, 0.93541435, 1., 1.])
+
+    assert_allclose(output.mask, [0, 0, 0, 0, 0, 0])
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_normalize_noclip():
+
+    data = np.linspace(0., 15., 6)
+    n = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=False)
+
+    output = n(data)
+
+    assert_allclose(output, [np.nan, 0.35355339, 0.70710678, 0.93541435, 1.11803399, 1.27475488])
+
+    assert_allclose(output.mask, [0, 0, 0, 0, 0, 0])
+
+    assert_allclose(n.inverse(n(data))[1:], data[1:])
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_masked_normalize_clip():
+
+    data = np.linspace(0., 15., 6)
+    mdata = ma.array(data, mask=[0, 0, 1, 0, 0, 0])
+
+    n = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True)
+
+    output = n(mdata)
+
+    assert_allclose(output.filled(-10), [0., 0.35355339, 1., 0.93541435, 1., 1.])
+    assert_allclose(output.mask, [0, 0, 0, 0, 0, 0])
+
+
+ at pytest.mark.skipif('not HAS_MATPLOTLIB')
+def test_masked_normalize_noclip():
+
+    data = np.linspace(0., 15., 6)
+    mdata = ma.array(data, mask=[0, 0, 1, 0, 0, 0])
+    n = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=False)
+
+    output = n(mdata)
+
+    assert_allclose(output.filled(-10), [np.nan, 0.35355339, -10, 0.93541435, 1.11803399, 1.27475488])
+    assert_allclose(output.mask, [0, 0, 1, 0, 0, 0])
+
+    assert_allclose(n.inverse(n(data))[1:], data[1:])
diff --git a/astropy/visualization/tests/test_stretch.py b/astropy/visualization/tests/test_stretch.py
new file mode 100644
index 0000000..0ae9993
--- /dev/null
+++ b/astropy/visualization/tests/test_stretch.py
@@ -0,0 +1,108 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+
+from ...tests.helper import pytest
+
+from ..stretch import (LinearStretch, SqrtStretch, PowerStretch,
+                       PowerDistStretch, SquaredStretch, LogStretch,
+                       AsinhStretch, SinhStretch, HistEqStretch,
+                       ContrastBiasStretch)
+
+
+DATA = np.array([0.00, 0.25, 0.50, 0.75, 1.00])
+
+RESULTS = {}
+RESULTS[LinearStretch()] = np.array([0.00, 0.25, 0.50, 0.75, 1.00])
+RESULTS[SqrtStretch()] = np.array([0., 0.5, 0.70710678, 0.8660254, 1.])
+RESULTS[SquaredStretch()] = np.array([0., 0.0625, 0.25, 0.5625, 1.])
+RESULTS[PowerStretch(0.5)] = np.array([0., 0.5, 0.70710678, 0.8660254, 1.])
+RESULTS[PowerDistStretch()] = np.array([0., 0.004628, 0.030653, 0.177005, 1.])
+RESULTS[LogStretch()] = np.array([0., 0.799776, 0.899816, 0.958408, 1.])
+RESULTS[AsinhStretch()] = np.array([0., 0.549402, 0.77127, 0.904691, 1.])
+RESULTS[SinhStretch()] = np.array([0., 0.082085, 0.212548, 0.46828, 1.])
+RESULTS[ContrastBiasStretch(contrast=2., bias=0.4)] = np.array([-0.3, 0.2, 0.7, 1.2, 1.7])
+RESULTS[HistEqStretch(DATA)] = DATA
+RESULTS[HistEqStretch(DATA[::-1])] = DATA
+RESULTS[HistEqStretch(DATA ** 0.5)] = np.array([0., 0.125, 0.25, 0.5674767, 1.])
+
+
+class TestStretch(object):
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_no_clip(self, stretch):
+
+        np.testing.assert_allclose(stretch(DATA, clip=False),
+                                   RESULTS[stretch], atol=1.e-6)
+
+    @pytest.mark.parametrize('ndim', [2,3])
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_clip_ndimensional(self, stretch, ndim):
+
+        new_shape = DATA.shape + (1,) * ndim
+
+        np.testing.assert_allclose(stretch(DATA.reshape(new_shape), clip=True).ravel(),
+                                   np.clip(RESULTS[stretch], 0., 1), atol=1.e-6)
+
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_clip(self, stretch):
+
+        np.testing.assert_allclose(stretch(DATA, clip=True),
+                                   np.clip(RESULTS[stretch], 0., 1), atol=1.e-6)
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_inplace(self, stretch):
+
+        data_in = DATA.copy()
+        result = np.zeros(DATA.shape)
+        stretch(data_in, out=result, clip=False)
+        np.testing.assert_allclose(result, RESULTS[stretch], atol=1.e-6)
+        np.testing.assert_allclose(data_in, DATA)
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_round_trip(self, stretch):
+
+        np.testing.assert_allclose(stretch.inverse(stretch(DATA, clip=False), clip=False),
+                                   DATA)
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_inplace_roundtrip(self, stretch):
+
+        result = np.zeros(DATA.shape)
+        stretch(DATA, out=result, clip=False)
+        stretch.inverse(result, out=result, clip=False)
+        np.testing.assert_allclose(result, DATA)
+
+    @pytest.mark.parametrize('stretch', RESULTS.keys())
+    def test_double_inverse(self, stretch):
+        np.testing.assert_allclose(stretch.inverse.inverse(DATA), stretch(DATA), atol=1.e-6)
+
+    def test_inverted(self):
+        stretch_1 = SqrtStretch().inverse
+        stretch_2 = PowerStretch(2)
+        np.testing.assert_allclose(stretch_1(DATA),
+                                   stretch_2(DATA))
+
+    def test_chaining(self):
+
+        stretch_1 = SqrtStretch() + SqrtStretch()
+        stretch_2 = PowerStretch(0.25)
+        stretch_3 = PowerStretch(4.)
+
+        np.testing.assert_allclose(stretch_1(DATA),
+                                   stretch_2(DATA))
+
+        np.testing.assert_allclose(stretch_1.inverse(DATA),
+                                   stretch_3(DATA))
+
+
+def test_clip_invalid():
+
+    stretch = SqrtStretch()
+
+    values = stretch([-1., 0., 0.5, 1., 1.5])
+    np.testing.assert_allclose(values, [0., 0., 0.70710678, 1., 1.])
+
+    values = stretch([-1., 0., 0.5, 1., 1.5], clip=False)
+    np.testing.assert_allclose(values, [np.nan, 0., 0.70710678, 1., 1.2247448])
diff --git a/astropy/visualization/tests/test_ui.py b/astropy/visualization/tests/test_ui.py
new file mode 100644
index 0000000..d64b196
--- /dev/null
+++ b/astropy/visualization/tests/test_ui.py
@@ -0,0 +1,46 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+from numpy.testing import assert_allclose
+
+from ..ui import scale_image
+
+DATA = np.array([0, 1., 2.])
+DATASCL = 0.5 * DATA
+
+
+class TestImageScaling(object):
+
+    def test_linear(self):
+        """Test linear scaling."""
+        img = scale_image(DATA, scale='linear')
+        assert_allclose(img, DATASCL, atol=0, rtol=1.e-5)
+
+    def test_sqrt(self):
+        """Test sqrt scaling."""
+        img = scale_image(DATA, scale='sqrt')
+        assert_allclose(img, np.sqrt(DATASCL), atol=0, rtol=1.e-5)
+
+    def test_power(self):
+        """Test power scaling."""
+        power = 3.0
+        img = scale_image(DATA, scale='power', power=power)
+        assert_allclose(img, DATASCL ** power, atol=0, rtol=1.e-5)
+
+    def test_log(self):
+        """Test log10 scaling."""
+        img = scale_image(DATA, scale='log')
+        ref = np.log10(1000 * DATASCL + 1.0) / np.log10(1001.0)
+        assert_allclose(img, ref, atol=0, rtol=1.e-5)
+
+    def test_asinh(self):
+        """Test asinh scaling."""
+        a = 0.1
+        img = scale_image(DATA, scale='asinh', asinh_a=a)
+        ref = np.arcsinh(DATASCL / a) / np.arcsinh(1. / a)
+        assert_allclose(img, ref, atol=0, rtol=1.e-5)
+
+    def test_min(self):
+        """Test linear scaling."""
+        img = scale_image(DATA, scale='linear', min_cut=1.)
+        assert_allclose(img, [0., 0., 1.], atol=0, rtol=1.e-5)
diff --git a/astropy/visualization/transform.py b/astropy/visualization/transform.py
new file mode 100644
index 0000000..f0fdd0c
--- /dev/null
+++ b/astropy/visualization/transform.py
@@ -0,0 +1,42 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+from __future__ import division, print_function
+
+__all__ = ['BaseTransform', 'CompositeTransform']
+
+
+class BaseTransform(object):
+    """
+    A transformation object.
+
+    This is used to construct transformations such as scaling, stretching, and
+    so on.
+    """
+    def __add__(self, other):
+        return CompositeTransform(other, self)
+
+
+class CompositeTransform(BaseTransform):
+    """
+    A combination of two transforms.
+
+    Parameters
+    ----------
+    transform_1: :class:`astropy.visualization.BaseTransform`
+        The first transform to apply.
+    transform_2: :class:`astropy.visualization.BaseTransform`
+        The second transform to apply.
+    """
+
+    def __init__(self, transform_1, transform_2):
+        super(CompositeTransform, self).__init__()
+        self.transform_1 = transform_1
+        self.transform_2 = transform_2
+
+    def __call__(self, values, clip=True):
+        return self.transform_2(self.transform_1(values, clip=clip), clip=clip)
+
+    @property
+    def inverse(self):
+        return CompositeTransform(self.transform_2.inverse,
+                                  self.transform_1.inverse)
diff --git a/astropy/visualization/ui.py b/astropy/visualization/ui.py
new file mode 100644
index 0000000..e4b7916
--- /dev/null
+++ b/astropy/visualization/ui.py
@@ -0,0 +1,102 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import numpy as np
+
+from .interval import (PercentileInterval, AsymmetricPercentileInterval,
+                       ManualInterval, MinMaxInterval)
+
+from .stretch import (LinearStretch, SqrtStretch, PowerStretch, LogStretch,
+                      AsinhStretch)
+
+
+def scale_image(image, scale='linear', power=1.0, asinh_a=0.1, min_cut=None,
+                max_cut=None, min_percent=None, max_percent=None,
+                percent=None, clip=True):
+    """
+    Perform scaling/stretching of an image between minimum and maximum
+    cut levels.
+
+    Parameters
+    ----------
+    image : array-like
+        The array of values.
+
+    scale : {{'linear', 'sqrt', 'power', log', 'asinh'}}
+        The scaling/stretch function to apply to the image.  The default
+        is 'linear'.
+
+    power : float, optional
+        The power index for ``scale='power'`` image scaling.  The
+        default is 1.0.
+
+    asinh_a : float, optional
+        For ``scale='asinh'`` image scaling, the value where the asinh
+        curve transitions from linear to logarithmic behavior, expressed
+        as a fraction of the normalized image.  Must be in the range
+        between 0 and 1.
+
+    min_cut : float, optional
+        The pixel value of the minimum cut level.  Data values less than
+        ``min_cut`` will set to ``min_cut`` before scaling the image.
+        The default is the image minimum.  ``min_cut`` overrides
+        ``min_percent``.
+
+    max_cut : float, optional
+        The pixel value of the maximum cut level.  Data values greater
+        than ``min_cut`` will set to ``min_cut`` before scaling the
+        image.  The default is the image maximum.  ``max_cut`` overrides
+        ``max_percent``.
+
+    min_percent : float, optional
+        The percentile value used to determine the pixel value of
+        minimum cut level.  The default is 0.0.  ``min_percent``
+        overrides ``percent``.
+
+    max_percent : float, optional
+        The percentile value used to determine the pixel value of
+        maximum cut level.  The default is 100.0.  ``max_percent``
+        overrides ``percent``.
+
+    percent : float, optional
+        The percentage of the image values used to determine the pixel
+        values of the minimum and maximum cut levels.  The lower cut
+        level will set at the ``(100 - percent) / 2`` percentile, while
+        the upper cut level will be set at the ``(100 + percent) / 2``
+        percentile.  The default is 100.0.  ``percent`` is ignored if
+        either ``min_percent`` or ``max_percent`` is input.
+
+    clip : bool, optional
+        Whether to clip the result to the range [0:1].
+
+    Returns
+    -------
+    image : ndarray
+        The array of the scaled/stretched image with a minimum of 0.0
+        and a maximum of 1.0.
+    """
+
+    if percent is not None:
+        interval = PercentileInterval(percent)
+    elif min_percent is not None or max_percent is not None:
+        interval = AsymmetricPercentileInterval(min_percent or 0.,
+                                                max_percent or 100.)
+    elif min_cut is not None or max_cut is not None:
+        interval = ManualInterval(min_cut or np.min(image),
+                                  max_cut or np.max(image))
+    else:
+        interval = MinMaxInterval()
+
+    if scale == 'linear':
+        stretch = LinearStretch()
+    elif scale == 'sqrt':
+        stretch = SqrtStretch()
+    elif scale == 'power':
+        stretch = PowerStretch(power)
+    elif scale == 'log':
+        stretch = LogStretch()
+    elif scale == 'asinh':
+        stretch = AsinhStretch(asinh_a)
+    else:
+        raise ValueError('Unknown scale: {0}'.format(scale))
+
+    return (stretch + interval)(image, clip=clip)
diff --git a/astropy/vo/client/async.py b/astropy/vo/client/async.py
index bbfbd6a..3f32856 100644
--- a/astropy/vo/client/async.py
+++ b/astropy/vo/client/async.py
@@ -14,7 +14,7 @@ class AsyncBase(object):
     using :py:class:`concurrent.futures.ThreadPoolExecutor`.
 
     Service request will be forced to run in silent
-    mode by setting ``verbose=False``. Warnings are controled
+    mode by setting ``verbose=False``. Warnings are controlled
     by :py:mod:`warnings` module.
 
     .. note::
diff --git a/astropy/vo/client/conesearch.py b/astropy/vo/client/conesearch.py
index 15f2289..0318a68 100644
--- a/astropy/vo/client/conesearch.py
+++ b/astropy/vo/client/conesearch.py
@@ -193,7 +193,7 @@ def conesearch(center, radius, verb=1, **kwargs):
 
 class AsyncSearchAll(AsyncBase):
     """Perform a Cone Search asynchronously, storing all results
-    instead of just the result from first successfull query.
+    instead of just the result from first successful query.
 
     .. note::
 
diff --git a/astropy/vo/samp/client.py b/astropy/vo/samp/client.py
index 63328fe..9ba9150 100644
--- a/astropy/vo/samp/client.py
+++ b/astropy/vo/samp/client.py
@@ -362,7 +362,7 @@ class SAMPClient(object):
 
         Returns
         -------
-        confimation : str
+        confirmation : str
             Any confirmation string.
         """
         return self._handle_call(private_key, sender_id, msg_id, message)
@@ -471,7 +471,7 @@ class SAMPClient(object):
         Parameters
         ----------
         mtype : str
-            MType to be catched.
+            MType to be caught.
 
         function : callable
             Application function to be used when ``mtype`` is received.
@@ -514,7 +514,7 @@ class SAMPClient(object):
         Parameters
         ----------
         mtype : str
-            MType to be catched.
+            MType to be caught.
 
         function : callable
             Application function to be used when ``mtype`` is received.
@@ -554,7 +554,7 @@ class SAMPClient(object):
         Parameters
         ----------
         msg_tag : str
-            Message-tag to be catched.
+            Message-tag to be caught.
 
         function : callable
             Application function to be used when ``msg_tag`` is received.
@@ -598,7 +598,7 @@ class SAMPClient(object):
 
         declare : bool
             Specify whether the client must be automatically declared as
-            unsubscribed from the MType (see alse
+            unsubscribed from the MType (see also
             :meth:`~astropy.vo.samp.client.SAMPClient.declare_subscriptions`).
         """
         if self._callable:
@@ -658,11 +658,11 @@ class SAMPClient(object):
             result = self.hub.register(self.hub.lockfile["samp.secret"])
 
             if result["samp.self-id"] == "":
-                raise SAMPClientError("Registation failed - "
+                raise SAMPClientError("Registration failed - "
                                       "samp.self-id was not set by the hub.")
 
             if result["samp.private-key"] == "":
-                raise SAMPClientError("Registation failed - "
+                raise SAMPClientError("Registration failed - "
                                       "samp.private-key was not set by the hub.")
 
             self._public_id = result["samp.self-id"]
@@ -731,7 +731,7 @@ class SAMPClient(object):
         Parameters
         ----------
         metadata : dict, optional
-            Dictionary containig the client application metadata as defined in
+            Dictionary containing the client application metadata as defined in
             the SAMP definition document. If omitted, then no metadata are
             declared.
         """
diff --git a/astropy/vo/samp/lockfile_helpers.py b/astropy/vo/samp/lockfile_helpers.py
index f180b48..f1d359a 100644
--- a/astropy/vo/samp/lockfile_helpers.py
+++ b/astropy/vo/samp/lockfile_helpers.py
@@ -224,7 +224,7 @@ def check_running_hub(lockfilename):
     is_running = False
     lockfiledict = {}
 
-    # Check whether a lockfile alredy exists
+    # Check whether a lockfile already exists
     try:
         lockfiledict = read_lockfile(lockfilename)
     except IOError:
@@ -241,7 +241,7 @@ def check_running_hub(lockfilename):
             # but the server is alive
             is_running = True
         except SSL_EXCEPTIONS:
-            # SSL connection refused for certifcate reasons...
+            # SSL connection refused for certificate reasons...
             # anyway the server is alive
             is_running = True
         except socket.error:
diff --git a/astropy/vo/samp/standard_profile.py b/astropy/vo/samp/standard_profile.py
index 7086431..f544b8f 100644
--- a/astropy/vo/samp/standard_profile.py
+++ b/astropy/vo/samp/standard_profile.py
@@ -36,9 +36,7 @@ class SAMPSimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
             self.end_headers()
             self.wfile.write(SAMP_ICON)
 
-    if ((six.PY2 and sys.version_info[:2] >= (2,7))
-        or (six.PY3 and sys.version_info[:2] >= (3,2))):
-
+    if sys.version_info[:2] >= (2, 7):
         def do_POST(self):
             """
             Handles the HTTP POST request.
diff --git a/astropy/vo/samp/tests/test_standard_profile.py b/astropy/vo/samp/tests/test_standard_profile.py
index c10f42d..21507bb 100644
--- a/astropy/vo/samp/tests/test_standard_profile.py
+++ b/astropy/vo/samp/tests/test_standard_profile.py
@@ -25,8 +25,6 @@ TEST_KEY1 = get_pkg_data_filename('data/test1.key')
 TEST_CERT2 = get_pkg_data_filename('data/test2.crt')
 TEST_KEY2 = get_pkg_data_filename('data/test2.key')
 
-PY31 = sys.version_info[:2] == (3, 1)
-
 
 class TestStandardProfile(object):
 
diff --git a/astropy/vo/samp/web_profile.py b/astropy/vo/samp/web_profile.py
index 0cd5f3b..44b53a1 100644
--- a/astropy/vo/samp/web_profile.py
+++ b/astropy/vo/samp/web_profile.py
@@ -3,8 +3,6 @@
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-import warnings
-
 from ...extern.six.moves.urllib.parse import parse_qs
 from ...extern.six.moves.urllib.request import urlopen
 from ...extern.six.moves import input
@@ -12,7 +10,6 @@ from ...utils.data import get_pkg_data_contents
 
 from .standard_profile import (SAMPSimpleXMLRPCRequestHandler,
                                ThreadingXMLRPCServer)
-from .errors import SAMPWarning
 
 __all__ = []
 
diff --git a/astropy/vo/validator/inspect.py b/astropy/vo/validator/inspect.py
index 1a83421..c8f82ac 100644
--- a/astropy/vo/validator/inspect.py
+++ b/astropy/vo/validator/inspect.py
@@ -114,7 +114,7 @@ class ConeSearchResults(object):
                 out_ws = cat_db['validate_warnings']
 
             # Warning types contains None if some other Exception was thrown.
-            # There should be only 1 occurence for each warning type.
+            # There should be only 1 occurrence for each warning type.
             # But will put in a loop anyway, just in case.
             while None in out_wt:  # pragma: no cover
                 out_wt[out_wt.index(None)] = 'None'
diff --git a/astropy/vo/validator/tests/test_validate.py b/astropy/vo/validator/tests/test_validate.py
index e0d562c..eef38f1 100644
--- a/astropy/vo/validator/tests/test_validate.py
+++ b/astropy/vo/validator/tests/test_validate.py
@@ -29,9 +29,6 @@ from ....utils import data
 __doctest_skip__ = ['*']
 
 
-PY3 = sys.version_info[0] == 3
-
-
 @remote_data
 class TestConeSearchValidation(object):
     """Validation on a small subset of Cone Search sites."""
@@ -55,8 +52,6 @@ class TestConeSearchValidation(object):
         db2 = VOSDatabase.from_json(fname2)
         assert db1.list_catalogs() == db2.list_catalogs()
 
-    @pytest.mark.xfail(sys.platform == "win32" and not PY3,
-                       reason='see issue #2970 on GitHub')
     @pytest.mark.parametrize(('parallel'), [True, False])
     def test_validation(self, parallel):
         if os.path.exists(self.out_dir):
diff --git a/astropy/wcs/docstrings.py b/astropy/wcs/docstrings.py
index 1184ba0..53f2223 100644
--- a/astropy/wcs/docstrings.py
+++ b/astropy/wcs/docstrings.py
@@ -200,7 +200,7 @@ cd = """
 matrix.
 
 For historical compatibility, three alternate specifications of the
-linear transforations are available in wcslib.  The canonical
+linear transformations are available in wcslib.  The canonical
 ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated
 ``CROTAia`` keywords.  Although the latter may not formally co-exist
 with ``PCi_ja``, the approach here is simply to ignore them if given
@@ -287,7 +287,7 @@ It should be set to zero for an image header or pixel list.
 """
 
 compare = """
-compare(other, cmp=0)
+compare(other, cmp=0, tolerance=0.0)
 
 Compare two Wcsprm objects for equality.
 
@@ -318,6 +318,12 @@ cmp : int, optional
       map projection but may not align on the same grid map.
       Overrides ``WCSCOMPARE_TILING``.
 
+tolerance : float, optional
+    The amount of tolerance required.  For example, for a value of
+    1e-6, all floating-point values in the objects must be equal to
+    the first 6 decimal places.  The default value of 0.0 implies
+    exact equality.
+
 Returns
 -------
 equal : bool
@@ -370,7 +376,7 @@ crota = """
 axis.
 
 For historical compatibility, three alternate specifications of the
-linear transforations are available in wcslib.  The canonical
+linear transformations are available in wcslib.  The canonical
 ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated
 ``CROTAia`` keywords.  Although the latter may not formally co-exist
 with ``PCi_ja``, the approach here is simply to ignore them if given
@@ -1305,7 +1311,7 @@ InvalidTransformError
 See also
 --------
 astropy.wcs.Wcsprm.lat, astropy.wcs.Wcsprm.lng
-    Definition of the latitude andlongitude axes
+    Definition of the latitude and longitude axes
 """.format(__.ORIGIN())
 
 p4_pix2foc = """
@@ -1345,7 +1351,7 @@ The order is::
    [PC2_1, PC2_2]]
 
 For historical compatibility, three alternate specifications of the
-linear transforations are available in wcslib.  The canonical
+linear transformations are available in wcslib.  The canonical
 ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated
 ``CROTAia`` keywords.  Although the latter may not formally co-exist
 with ``PCi_ja``, the approach here is simply to ignore them if given
@@ -2100,7 +2106,7 @@ Wcs(*sip, cpdis, wcsprm, det2im*)
 Wcs objects amalgamate basic WCS (as provided by `wcslib`_), with
 `SIP`_ and `Paper IV`_ distortion operations.
 
-To perform all distortion corrections and WCS tranformation, use
+To perform all distortion corrections and WCS transformation, use
 ``all_pix2world``.
 
 Parameters
diff --git a/astropy/wcs/include/astropy_wcs/docstrings.h b/astropy/wcs/include/astropy_wcs/docstrings.h
index 81afc05..598a76f 100644
--- a/astropy/wcs/include/astropy_wcs/docstrings.h
+++ b/astropy/wcs/include/astropy_wcs/docstrings.h
@@ -22,7 +22,7 @@ extern char doc_NonseparableSubimageCoordinateSystem[88];
 extern char doc_SingularMatrix[70];
 extern char doc_Sip[1040];
 extern char doc_Tabprm[234];
-extern char doc_Wcs[515];
+extern char doc_Wcs[516];
 extern char doc_WcsError[39];
 extern char doc_Wcsprm[2459];
 extern char doc_Wtbarr[202];
@@ -38,7 +38,7 @@ extern char doc_b_order[60];
 extern char doc_bounds_check[469];
 extern char doc_bp[276];
 extern char doc_bp_order[61];
-extern char doc_cd[1058];
+extern char doc_cd[1059];
 extern char doc_cdelt[308];
 extern char doc_cdfix[480];
 extern char doc_cel_offset[176];
@@ -46,14 +46,14 @@ extern char doc_celfix[171];
 extern char doc_cname[76];
 extern char doc_colax[91];
 extern char doc_colnum[290];
-extern char doc_compare[1006];
+extern char doc_compare[1271];
 extern char doc_convert[121];
 extern char doc_coord[277];
 extern char doc_copy[40];
 extern char doc_cpdis1[106];
 extern char doc_cpdis2[106];
 extern char doc_crder[123];
-extern char doc_crota[1054];
+extern char doc_crota[1055];
 extern char doc_crpix[88];
 extern char doc_crval[93];
 extern char doc_crval_tabprm[94];
@@ -111,9 +111,9 @@ extern char doc_nc[172];
 extern char doc_ndim[67];
 extern char doc_obsgeo[187];
 extern char doc_p0[244];
-extern char doc_p2s[2005];
+extern char doc_p2s[2006];
 extern char doc_p4_pix2foc[652];
-extern char doc_pc[1125];
+extern char doc_pc[1126];
 extern char doc_phi0[289];
 extern char doc_pix2foc[636];
 extern char doc_piximg_matrix[128];
diff --git a/astropy/wcs/include/astropy_wcs/wcsconfig.h b/astropy/wcs/include/astropy_wcs/wcsconfig.h
index 957aa4c..b5962bb 100644
--- a/astropy/wcs/include/astropy_wcs/wcsconfig.h
+++ b/astropy/wcs/include/astropy_wcs/wcsconfig.h
@@ -1,6 +1,6 @@
 
     /* WCSLIB library version number. */
-    #define WCSLIB_VERSION 4.20
+    #define WCSLIB_VERSION 4.25
 
     /* 64-bit integer data type. */
     #define WCSLIB_INT64 long long int
diff --git a/astropy/wcs/include/wcsconfig.h b/astropy/wcs/include/wcsconfig.h
index 957aa4c..b5962bb 100644
--- a/astropy/wcs/include/wcsconfig.h
+++ b/astropy/wcs/include/wcsconfig.h
@@ -1,6 +1,6 @@
 
     /* WCSLIB library version number. */
-    #define WCSLIB_VERSION 4.20
+    #define WCSLIB_VERSION 4.25
 
     /* 64-bit integer data type. */
     #define WCSLIB_INT64 long long int
diff --git a/astropy/wcs/include/wcslib/cel.h b/astropy/wcs/include/wcslib/cel.h
index 054422a..e2bd3d5 100644
--- a/astropy/wcs/include/wcslib/cel.h
+++ b/astropy/wcs/include/wcslib/cel.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: cel.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: cel.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/astropy/wcs/include/wcslib/lin.h b/astropy/wcs/include/wcslib/lin.h
index b278ea6..0eff754 100644
--- a/astropy/wcs/include/wcslib/lin.h
+++ b/astropy/wcs/include/wcslib/lin.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: lin.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: lin.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/astropy/wcs/include/wcslib/prj.h b/astropy/wcs/include/wcslib/prj.h
index 06cc4e8..5b143f2 100644
--- a/astropy/wcs/include/wcslib/prj.h
+++ b/astropy/wcs/include/wcslib/prj.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: prj.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: prj.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spherical map projections
+* WCSLIB 4.25 - C routines that implement the spherical map projections
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/astropy/wcs/include/wcslib/spc.h b/astropy/wcs/include/wcslib/spc.h
index f63e6c8..85f19ee 100644
--- a/astropy/wcs/include/wcslib/spc.h
+++ b/astropy/wcs/include/wcslib/spc.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spc.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spc.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spectral coordinate systems
+* WCSLIB 4.25 - C routines that implement the spectral coordinate systems
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/astropy/wcs/include/wcslib/spx.h b/astropy/wcs/include/wcslib/spx.h
index 0d93978..27d7247 100644
--- a/astropy/wcs/include/wcslib/spx.h
+++ b/astropy/wcs/include/wcslib/spx.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spx.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spx.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spectral coordinate systems
+* WCSLIB 4.25 - C routines that implement the spectral coordinate systems
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/astropy/wcs/include/wcslib/tab.h b/astropy/wcs/include/wcslib/tab.h
index f0531e2..1b55fcc 100644
--- a/astropy/wcs/include/wcslib/tab.h
+++ b/astropy/wcs/include/wcslib/tab.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: tab.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: tab.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement tabular coordinate systems as
+* WCSLIB 4.25 - C routines that implement tabular coordinate systems as
 * defined by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
@@ -193,6 +193,11 @@
 *                       indicating a strict comparison.  In the future, other
 *                       options may be added.
 *
+*   tol       double    Tolerance for comparison of floating-point values.
+*                       For example, for tol == 1e-6, all floating-point
+*                       values in the structs must be equal to the first 6
+*                       decimal places.  A value of 0 implies exact equality.
+*
 *   tab1      const struct tabprm*
 *                       The first tabprm struct to compare.
 *
@@ -576,8 +581,8 @@ int tabmem(struct tabprm *tab);
 
 int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst);
 
-int tabcmp(int cmp, const struct tabprm *tab1, const struct tabprm *tab2,
-           int *equal);
+int tabcmp(int cmp, double tol, const struct tabprm *tab1,
+           const struct tabprm *tab2, int *equal);
 
 int tabfree(struct tabprm *tab);
 
diff --git a/astropy/wcs/include/wcslib/wcs.h b/astropy/wcs/include/wcslib/wcs.h
index 4dd84e2..14a17b6 100644
--- a/astropy/wcs/include/wcslib/wcs.h
+++ b/astropy/wcs/include/wcslib/wcs.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcs.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcs.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
@@ -334,6 +334,11 @@
 *                           of the same map projection but may not align on
 *                           the same grid map.  Overrides WCSCOMPARE_TILING.
 *
+*   tol       double    Tolerance for comparison of floating-point values.
+*                       For example, for tol == 1e-6, all floating-point
+*                       values in the structs must be equal to the first 6
+*                       decimal places.  A value of 0 implies exact equality.
+*
 *   wcs1      const struct wcsprm*
 *                       The first wcsprm struct to compare.
 *
@@ -1568,8 +1573,8 @@ int wcsini(int alloc, int naxis, struct wcsprm *wcs);
 int wcssub(int alloc, const struct wcsprm *wcssrc, int *nsub, int axes[],
            struct wcsprm *wcsdst);
 
-int wcscompare(int cmp, const struct wcsprm *wcs1, const struct wcsprm *wcs2,
-               int *equal);
+int wcscompare(int cmp, double tol, const struct wcsprm *wcs1,
+               const struct wcsprm *wcs2, int *equal);
 
 int wcsfree(struct wcsprm *wcs);
 
diff --git a/astropy/wcs/include/wcslib/wcserr.h b/astropy/wcs/include/wcslib/wcserr.h
index 6421a35..7508809 100644
--- a/astropy/wcs/include/wcslib/wcserr.h
+++ b/astropy/wcs/include/wcslib/wcserr.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -23,7 +23,7 @@
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   Module author: Michael Droettboom
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcserr.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcserr.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of the wcserr routines
diff --git a/astropy/wcs/include/wcslib/wcsmath.h b/astropy/wcs/include/wcslib/wcsmath.h
index cc2758b..3dc321d 100644
--- a/astropy/wcs/include/wcslib/wcsmath.h
+++ b/astropy/wcs/include/wcslib/wcsmath.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsmath.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsmath.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of wcsmath.h
diff --git a/astropy/wcs/include/wcslib/wcsprintf.h b/astropy/wcs/include/wcslib/wcsprintf.h
index 10ecad1..6c94991 100644
--- a/astropy/wcs/include/wcslib/wcsprintf.h
+++ b/astropy/wcs/include/wcslib/wcsprintf.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsprintf.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsprintf.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.
 *
 * Summary of the wcsprintf routines
diff --git a/astropy/wcs/setup_package.py b/astropy/wcs/setup_package.py
index f49df8c..55f2a0f 100644
--- a/astropy/wcs/setup_package.py
+++ b/astropy/wcs/setup_package.py
@@ -19,7 +19,7 @@ from astropy_helpers import setup_helpers
 from astropy.extern import six
 
 WCSROOT = os.path.relpath(os.path.dirname(__file__))
-WCSVERSION = "4.20"
+WCSVERSION = "4.25"
 
 
 def b(s):
@@ -199,8 +199,7 @@ def get_extensions():
         ('ECHO', None),
         ('WCSTRIG_MACRO', None),
         ('ASTROPY_WCS_BUILD', None),
-        ('_GNU_SOURCE', None),
-        ('WCSVERSION', WCSVERSION)])
+        ('_GNU_SOURCE', None)])
 
     if (not setup_helpers.use_system_library('wcslib') or
         sys.platform == 'win32'):
diff --git a/astropy/wcs/src/docstrings.c b/astropy/wcs/src/docstrings.c
index 8e3cc90..3a79c6f 100644
--- a/astropy/wcs/src/docstrings.c
+++ b/astropy/wcs/src/docstrings.c
@@ -280,7 +280,7 @@ char doc_Tabprm[234] = {
     0x61, 0x62, 0x60, 0x2e, 0x0a, 0x00, 
     };
 
-char doc_Wcs[515] = {
+char doc_Wcs[516] = {
     0x57, 0x63, 0x73, 0x28, 0x2a, 0x73, 0x69, 0x70, 0x2c, 0x20, 0x63, 0x70, 
     0x64, 0x69, 0x73, 0x2c, 0x20, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2c, 
     0x20, 0x64, 0x65, 0x74, 0x32, 0x69, 0x6d, 0x2a, 0x29, 0x0a, 0x0a, 0x57, 
@@ -297,33 +297,33 @@ char doc_Wcs[515] = {
     0x72, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 
     0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 
     0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x57, 0x43, 
-    0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 
-    0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x0a, 0x60, 0x60, 0x61, 
-    0x6c, 0x6c, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 0x64, 
-    0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 
-    0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 
-    0x2d, 0x2d, 0x0a, 0x73, 0x69, 0x70, 0x20, 0x3a, 0x20, 0x60, 0x7e, 0x61, 
-    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 
-    0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, 
-    0x72, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x0a, 0x0a, 0x63, 0x70, 
-    0x64, 0x69, 0x73, 0x20, 0x3a, 0x20, 0x41, 0x20, 0x70, 0x61, 0x69, 0x72, 
-    0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 
-    0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 
-    0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 
-    0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 
-    0x2c, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x60, 0x60, 0x28, 0x4e, 0x6f, 
-    0x6e, 0x65, 0x2c, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x60, 0x60, 0x2e, 
-    0x0a, 0x0a, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x3a, 0x20, 0x60, 
-    0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 
-    0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x6f, 0x62, 0x6a, 
-    0x65, 0x63, 0x74, 0x0a, 0x0a, 0x64, 0x65, 0x74, 0x32, 0x69, 0x6d, 0x20, 
-    0x3a, 0x20, 0x41, 0x20, 0x70, 0x61, 0x69, 0x72, 0x20, 0x6f, 0x66, 0x20, 
+    0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 
+    0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x0a, 0x60, 0x60, 
+    0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 
+    0x64, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 
+    0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 
+    0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x69, 0x70, 0x20, 0x3a, 0x20, 0x60, 0x7e, 
+    0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 
+    0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 
+    0x6f, 0x72, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x0a, 0x0a, 0x63, 
+    0x70, 0x64, 0x69, 0x73, 0x20, 0x3a, 0x20, 0x41, 0x20, 0x70, 0x61, 0x69, 
+    0x72, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
+    0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 
+    0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 
+    0x61, 0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+    0x73, 0x2c, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x60, 0x60, 0x28, 0x4e, 
+    0x6f, 0x6e, 0x65, 0x2c, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x60, 0x60, 
+    0x2e, 0x0a, 0x0a, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x3a, 0x20, 
     0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 
-    0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 
-    0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 
-    0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2c, 0x20, 0x6f, 0x72, 
-    0x0a, 0x20, 0x20, 0x20, 0x60, 0x60, 0x28, 0x4e, 0x6f, 0x6e, 0x65, 0x2c, 
-    0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x00, 
+    0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x6f, 0x62, 
+    0x6a, 0x65, 0x63, 0x74, 0x0a, 0x0a, 0x64, 0x65, 0x74, 0x32, 0x69, 0x6d, 
+    0x20, 0x3a, 0x20, 0x41, 0x20, 0x70, 0x61, 0x69, 0x72, 0x20, 0x6f, 0x66, 
+    0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
+    0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 
+    0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 
+    0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2c, 0x20, 0x6f, 
+    0x72, 0x0a, 0x20, 0x20, 0x20, 0x60, 0x60, 0x28, 0x4e, 0x6f, 0x6e, 0x65, 
+    0x2c, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x00, 
     };
 
 char doc_WcsError[39] = {
@@ -953,7 +953,7 @@ char doc_bp_order[61] = {
     0x00, 
     };
 
-char doc_cd[1058] = {
+char doc_cd[1059] = {
     0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 
     0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x5b, 0x6e, 0x61, 
     0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 
@@ -967,82 +967,82 @@ char doc_cd[1058] = {
     0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 
     0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 
     0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 
-    0x73, 0x66, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 
-    0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 
-    0x20, 0x69, 0x6e, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 
-    0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 
-    0x61, 0x6c, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 
-    0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 
-    0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 
-    0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 
-    0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 
-    0x65, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 
-    0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 
-    0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 
-    0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 
-    0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 
-    0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 
-    0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 
-    0x61, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 
-    0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 
-    0x73, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 
-    0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 
-    0x69, 0x66, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 
-    0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 
-    0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 
-    0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 
+    0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 
+    0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 
+    0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 
+    0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 
+    0x63, 0x61, 0x6c, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 
+    0x60, 0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 
+    0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 
+    0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 
+    0x74, 0x65, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 
+    0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 
+    0x2e, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 
+    0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 
+    0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 
+    0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 
+    0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 
+    0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 
+    0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 
+    0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 
+    0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 
+    0x20, 0x69, 0x66, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 
+    0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 
+    0x6a, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 
+    0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 
+    0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 
+    0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
+    0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 
+    0x73, 0x5f, 0x63, 0x64, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 
+    0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 
+    0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 
+    0x72, 0x6f, 0x74, 0x61, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 
+    0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 
+    0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 
+    0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 
+    0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 
+    0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 
+    0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 
+    0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 
+    0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 
+    0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 
+    0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 
+    0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 
+    0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 
+    0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 
+    0x60, 0x60, 0x20, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 
     0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 
-    0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 
-    0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 
-    0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 
-    0x5f, 0x63, 0x64, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 
-    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 
-    0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 
-    0x6f, 0x74, 0x61, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 
-    0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 
-    0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 
-    0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 
-    0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 
-    0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 
-    0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 
-    0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 
-    0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 
-    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 
-    0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 
-    0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 
-    0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 
-    0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 
-    0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 
-    0x74, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 
-    0x60, 0x20, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
+    0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 
+    0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 
+    0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 
+    0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 
+    0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 
+    0x20, 0x20, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 
+    0x6c, 0x61, 0x72, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
     0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 
-    0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 
-    0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 
-    0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 
-    0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 
-    0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 
-    0x20, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 
-    0x61, 0x72, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 
-    0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 
-    0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 
-    0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
-    0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 
-    0x65, 0x6c, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 
-    0x79, 0x0a, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 
-    0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 
-    0x6e, 0x74, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 
-    0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 
-    0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 
-    0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 
-    0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 
-    0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 
-    0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 
-    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 
-    0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 
-    0x65, 0x76, 0x65, 0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 
-    0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 
-    0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 
-    0x0a, 0x00, 
+    0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 
+    0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 
+    0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 
+    0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 
+    0x74, 0x79, 0x0a, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 
+    0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 
+    0x65, 0x6e, 0x74, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 
+    0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 
+    0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 
+    0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 
+    0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 
+    0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 
+    0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 
+    0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 
+    0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 
+    0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 
+    0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 
+    0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 
+    0x2e, 0x0a, 0x00, 
     };
 
 char doc_cdelt[308] = {
@@ -1202,91 +1202,113 @@ char doc_colnum[290] = {
     0x0a, 0x00, 
     };
 
-char doc_compare[1006] = {
+char doc_compare[1271] = {
     0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x28, 0x6f, 0x74, 0x68, 0x65, 
-    0x72, 0x2c, 0x20, 0x63, 0x6d, 0x70, 0x3d, 0x30, 0x29, 0x0a, 0x0a, 0x43, 
-    0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 
-    0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
-    0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 
-    0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 
-    0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 
-    0x2d, 0x2d, 0x0a, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x3a, 0x20, 
-    0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 
-    0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x57, 0x63, 0x73, 
-    0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 
-    0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 
-    0x2e, 0x0a, 0x0a, 0x63, 0x6d, 0x70, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 
-    0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 
-    0x20, 0x20, 0x20, 0x41, 0x20, 0x62, 0x69, 0x74, 0x20, 0x66, 0x69, 0x65, 
-    0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 
-    0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 
-    0x74, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 
-    0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x2e, 
-    0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 
-    0x20, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 
-    0x6c, 0x74, 0x29, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x69, 0x65, 
-    0x6c, 0x64, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 
-    0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2e, 0x0a, 0x0a, 
-    0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 
-    0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 
-    0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6f, 
-    0x72, 0x27, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 
-    0x72, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x20, 
-    0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x70, 
-    0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 
-    0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 
-    0x41, 0x52, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x49, 0x4c, 0x4c, 0x41, 0x52, 
-    0x59, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x73, 
-    0x20, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, 0x20, 0x6b, 
-    0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 
-    0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 
-    0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 
-    0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 
-    0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x73, 0x75, 0x63, 0x68, 
-    0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 
-    0x42, 0x53, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 
-    0x20, 0x20, 0x60, 0x60, 0x45, 0x51, 0x55, 0x49, 0x4e, 0x4f, 0x58, 0x60, 
-    0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 
-    0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x54, 
-    0x49, 0x4c, 0x49, 0x4e, 0x47, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 
-    0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 
-    0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 
+    0x72, 0x2c, 0x20, 0x63, 0x6d, 0x70, 0x3d, 0x30, 0x2c, 0x20, 0x74, 0x6f, 
+    0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x30, 0x2e, 0x30, 0x29, 
+    0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x20, 0x74, 0x77, 
+    0x6f, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 
+    0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x71, 0x75, 
+    0x61, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 
+    0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 
+    0x20, 0x3a, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x0a, 0x20, 0x20, 
+    0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 
+    0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+    0x74, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 
+    0x20, 0x74, 0x6f, 0x2e, 0x0a, 0x0a, 0x63, 0x6d, 0x70, 0x20, 0x3a, 0x20, 
+    0x69, 0x6e, 0x74, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 
+    0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x20, 0x62, 0x69, 0x74, 0x20, 
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 
+    0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 
+    0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 
+    0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 
+    0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x30, 0x2c, 
+    0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 
+    0x66, 0x61, 0x75, 0x6c, 0x74, 0x29, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x20, 
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 
+    0x62, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x6c, 
+    0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 
+    0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 
+    0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 
+    0x65, 0x20, 0x6f, 0x72, 0x27, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x67, 0x65, 
+    0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x6f, 0x73, 
+    0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 
+    0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 
+    0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 
+    0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x49, 0x4c, 
+    0x4c, 0x41, 0x52, 0x59, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 
+    0x72, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 
+    0x79, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x74, 
+    0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x0a, 0x20, 0x20, 
+    0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 
+    0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 
+    0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x73, 
+    0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 
+    0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x0a, 0x20, 
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x45, 0x51, 0x55, 0x49, 0x4e, 
+    0x4f, 0x58, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 
+    0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 
+    0x45, 0x5f, 0x54, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x60, 0x60, 0x3a, 0x20, 
+    0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 
+    0x72, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 
+    0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 
+    0x20, 0x60, 0x60, 0x43, 0x52, 0x50, 0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 
+    0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 
+    0x68, 0x65, 0x20, 0x27, 0x74, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x27, 0x20, 
+    0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x77, 
+    0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 
+    0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x76, 
+    0x65, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 
+    0x20, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 
+    0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x70, 
+    0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 
+    0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x6e, 
+    0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 
+    0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x67, 0x72, 0x69, 0x64, 
+    0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 
+    0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x52, 
+    0x50, 0x49, 0x58, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 
+    0x65, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 
+    0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6c, 
     0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 
     0x43, 0x52, 0x50, 0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 
-    0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 
-    0x27, 0x74, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x63, 0x6f, 0x6e, 
-    0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 
-    0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x65, 0x73, 0x0a, 
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x20, 
-    0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x72, 0x65, 
-    0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 
-    0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x70, 0x72, 
-    0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 
-    0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 
-    0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 
-    0x20, 0x6d, 0x61, 0x70, 0x20, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x0a, 0x0a, 
-    0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 
-    0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x52, 0x50, 0x49, 0x58, 
-    0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x61, 
-    0x6e, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 
-    0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x69, 0x6e, 
-    0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x43, 0x52, 0x50, 
-    0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 
-    0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x65, 0x73, 0x20, 0x63, 
-    0x6f, 0x76, 0x65, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 
-    0x6e, 0x74, 0x20, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 
-    0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x0a, 0x20, 
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x70, 0x72, 0x6f, 
-    0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x74, 0x20, 
-    0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x69, 0x67, 
-    0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 
-    0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x70, 0x2e, 0x0a, 
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 
-    0x64, 0x65, 0x73, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 
-    0x50, 0x41, 0x52, 0x45, 0x5f, 0x54, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x60, 
-    0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x65, 0x71, 0x75, 0x61, 
-    0x6c, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x00, 
+    0x54, 0x68, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x65, 
+    0x73, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 
+    0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 
+    0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 
+    0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x70, 0x20, 
+    0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 
+    0x75, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 
+    0x6c, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 
+    0x73, 0x61, 0x6d, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x6d, 0x61, 
+    0x70, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x76, 0x65, 
+    0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 
+    0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x54, 0x49, 0x4c, 0x49, 
+    0x4e, 0x47, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x74, 0x6f, 0x6c, 0x65, 0x72, 
+    0x61, 0x6e, 0x63, 0x65, 0x20, 0x3a, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 
+    0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 
+    0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 
+    0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 
+    0x63, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 
+    0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 
+    0x65, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 
+    0x75, 0x65, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x31, 0x65, 
+    0x2d, 0x36, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 
+    0x74, 0x69, 0x6e, 0x67, 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x76, 
+    0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 
+    0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6d, 0x75, 0x73, 
+    0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 
+    0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 
+    0x72, 0x73, 0x74, 0x20, 0x36, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 
+    0x6c, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 
+    0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 
+    0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x30, 0x2e, 0x30, 0x20, 
+    0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 
+    0x65, 0x78, 0x61, 0x63, 0x74, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 
+    0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x65, 0x71, 0x75, 
+    0x61, 0x6c, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x00, 
     };
 
 char doc_convert[121] = {
@@ -1375,7 +1397,7 @@ char doc_crder[123] = {
     0x2e, 0x0a, 0x00, 
     };
 
-char doc_crota[1054] = {
+char doc_crota[1055] = {
     0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 
     0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 
     0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 
@@ -1389,81 +1411,81 @@ char doc_crota[1054] = {
     0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 
     0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x69, 0x6e, 
     0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 
-    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 
-    0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 
-    0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 
-    0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 
-    0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 
-    0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 
-    0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 
-    0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 
-    0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 
-    0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 
-    0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 
-    0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 
-    0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 
-    0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 
-    0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 
-    0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 
-    0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 
-    0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 
-    0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 
-    0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 
-    0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 
-    0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 
-    0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 
-    0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 
-    0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 
-    0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 
-    0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 
-    0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 
-    0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
-    0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 
-    0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 
-    0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 
-    0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 
-    0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 
+    0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 
+    0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 
+    0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 
+    0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 
+    0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 
+    0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 
+    0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 
+    0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 
+    0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 
+    0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 
+    0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 
+    0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 
+    0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 
+    0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 
+    0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 
+    0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 
+    0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 
+    0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 
+    0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 
+    0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 
+    0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 
+    0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 
+    0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 
+    0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 
+    0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 
+    0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 
+    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 
+    0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 
+    0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 
+    0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 
+    0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 
+    0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 
+    0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 
+    0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 
+    0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 
+    0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 
+    0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 
+    0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 
     0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 
-    0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 
-    0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 
-    0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 
-    0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 
-    0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 
-    0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 
-    0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 
-    0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 
-    0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 
-    0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 
-    0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 
-    0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 
-    0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
+    0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 
+    0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 
+    0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 
+    0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 
+    0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 
+    0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 
+    0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 
+    0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 
+    0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 
+    0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 
+    0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 
+    0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 
+    0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 
+    0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 
+    0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 
+    0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 
+    0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
     0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 
-    0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 
-    0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 
-    0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 
-    0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 
-    0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 
-    0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 
-    0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 
-    0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 
-    0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 
-    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 
-    0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 
-    0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 
-    0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 
-    0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 
-    0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 
-    0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 
-    0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 
-    0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 
-    0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 
-    0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 
-    0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
-    0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 
-    0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 
-    0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 
-    0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 
-    0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, 
+    0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 
+    0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 
+    0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 
+    0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 
+    0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 
+    0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 
+    0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 
+    0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 
+    0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 
+    0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 
+    0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 
+    0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 
+    0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 
+    0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 
+    0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 
+    0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 
+    0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 
+    0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, 
     };
 
 char doc_crpix[88] = {
@@ -3465,7 +3487,7 @@ char doc_p0[244] = {
     0x60, 0x2e, 0x0a, 0x00, 
     };
 
-char doc_p2s[2005] = {
+char doc_p2s[2006] = {
     0x70, 0x32, 0x73, 0x28, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 
     0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 
     0x76, 0x65, 0x72, 0x74, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 
@@ -3631,9 +3653,9 @@ char doc_p2s[2005] = {
     0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x6e, 0x67, 0x0a, 0x20, 
     0x20, 0x20, 0x20, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 
     0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 
-    0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x6c, 0x6f, 0x6e, 
-    0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x0a, 
-    0x00, 
+    0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 
+    0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 
+    0x0a, 0x00, 
     };
 
 char doc_p4_pix2foc[652] = {
@@ -3694,7 +3716,7 @@ char doc_p4_pix2foc[652] = {
     0x73, 0x2e, 0x0a, 0x00, 
     };
 
-char doc_pc[1125] = {
+char doc_pc[1126] = {
     0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 
     0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x5b, 0x6e, 0x61, 
     0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 
@@ -3713,82 +3735,82 @@ char doc_pc[1125] = {
     0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 
     0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 
     0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 
-    0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x61, 
-    0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 
-    0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 
-    0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 
-    0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 0x60, 
-    0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 0x74, 
-    0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 
-    0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 
-    0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 
-    0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 0x60, 
-    0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 
-    0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x74, 
-    0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 
-    0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 
-    0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 
-    0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 
-    0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 
-    0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 
-    0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 
-    0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 
-    0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 0x69, 
-    0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 
-    0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 
-    0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x0a, 
-    0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
-    0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 
-    0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 
-    0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 
-    0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 0x20, 
-    0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 
-    0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 
-    0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 0x20, 
-    0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 
-    0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 
-    0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 
+    0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 
+    0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 
+    0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 
+    0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 
+    0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 
+    0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 
+    0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 
+    0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 
+    0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 
+    0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 
+    0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 
+    0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 
+    0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 
+    0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 
+    0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 
+    0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 
+    0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 
+    0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 
+    0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 
+    0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 
+    0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 
+    0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 
+    0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 
+    0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 
+    0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 
+    0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 
+    0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 
+    0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
+    0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 
+    0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 
+    0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 
+    0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 
+    0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 
+    0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 
+    0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 
+    0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 
+    0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 
     0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 
-    0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 
-    0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 
-    0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 
-    0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 
-    0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 
-    0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 
-    0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 
-    0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 
-    0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 
-    0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 
-    0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 
-    0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 0x20, 
+    0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 
+    0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 
+    0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 
+    0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 
+    0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 
+    0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 
+    0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 
+    0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 
+    0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 
+    0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 
+    0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 
+    0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 
+    0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 
+    0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 
+    0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 
+    0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 
     0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 
     0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 
-    0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 
-    0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 
-    0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 
-    0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 
-    0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x70, 
-    0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 0x60, 
-    0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 
-    0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 
-    0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 
-    0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 
-    0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 
-    0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 0x20, 
-    0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 
-    0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x61, 
-    0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 
-    0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 
-    0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 
-    0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 
-    0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 
-    0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 
-    0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 
-    0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 
-    0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 
-    0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 
-    0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 
-    0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, 
+    0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 
+    0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 
+    0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 
+    0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 
+    0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 
+    0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 
+    0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 
+    0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 
+    0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 
+    0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 
+    0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 
+    0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 
+    0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 
+    0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 
+    0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 
+    0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 
+    0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 
+    0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, 
     };
 
 char doc_phi0[289] = {
diff --git a/astropy/wcs/src/unit_list_proxy.c b/astropy/wcs/src/unit_list_proxy.c
index 4ed351c..b3e7195 100644
--- a/astropy/wcs/src/unit_list_proxy.c
+++ b/astropy/wcs/src/unit_list_proxy.c
@@ -147,20 +147,20 @@ _get_unit(
 
   PyObject *args;
   PyObject *kw;
-  PyObject *fits;
   PyObject *result;
 
+  kw = Py_BuildValue("{s:s,s:s}", "format", "fits", "parse_strict", "warn");
+  if (kw == NULL) {
+      return NULL;
+  }
+
   args = PyTuple_New(1);
   PyTuple_SetItem(args, 0, unit);
   Py_INCREF(unit);
-  fits = PyUnicode_FromStringAndSize("fits", 4);
-  kw = PyDict_New();
-  PyDict_SetItemString(kw, "format", fits);
 
   result = PyObject_Call(unit_class, args, kw);
 
   Py_DECREF(args);
-  Py_DECREF(fits);
   Py_DECREF(kw);
   return result;
 }
diff --git a/astropy/wcs/src/wcslib_wrap.c b/astropy/wcs/src/wcslib_wrap.c
index 9826c6b..12605f4 100644
--- a/astropy/wcs/src/wcslib_wrap.c
+++ b/astropy/wcs/src/wcslib_wrap.c
@@ -737,21 +737,22 @@ PyWcsprm_compare(
 
   int cmp = 0;
   PyWcsprm *other;
+  double tolerance = 0.0;
   int equal;
   int status;
 
-  const char* keywords[] = {"other", "cmp", NULL};
+  const char* keywords[] = {"other", "cmp", "tolerance", NULL};
 
   if (!PyArg_ParseTupleAndKeywords(
-          args, kwds, "O!|i:compare", (char **)keywords,
-          &PyWcsprmType, &other, &cmp)) {
+          args, kwds, "O!|id:compare", (char **)keywords,
+          &PyWcsprmType, &other, &cmp, &tolerance)) {
     return NULL;
   }
 
 
   wcsprm_python2c(&self->x);
   wcsprm_python2c(&other->x);
-  status = wcscompare(cmp, &self->x, &other->x, &equal);
+  status = wcscompare(cmp, tolerance, &self->x, &other->x, &equal);
   wcsprm_c2python(&self->x);
   wcsprm_c2python(&other->x);
 
@@ -1697,7 +1698,7 @@ PyObject *PyWcsprm_richcompare(PyObject *a, PyObject *b, int op) {
     wcsprm_python2c(ax);
     wcsprm_python2c(bx);
     status = wcscompare(
-        WCSCOMPARE_ANCILLARY,
+        WCSCOMPARE_ANCILLARY, 0.0,
         ax, bx, &equal);
     wcsprm_c2python(ax);
     wcsprm_c2python(bx);
@@ -1732,9 +1733,7 @@ PyWcsprm_sub(
   PyObject*  py_axes        = NULL;
   PyWcsprm*  py_dest_wcs    = NULL;
   PyObject*  element        = NULL;
-  #if PY3K
   PyObject*  element_utf8   = NULL;
-  #endif
   char*      element_str    = NULL;
   int        element_val    = 0;
   int        nsub           = 0;
@@ -1769,19 +1768,19 @@ PyWcsprm_sub(
         goto exit;
       }
 
-      #if PY3K
-      if (PyUnicode_Check(element)) {
-        element_utf8 = PyUnicode_AsUTF8String(element);
-        if (element_utf8 == NULL) {
-          goto exit;
+      if (PyUnicode_Check(element) || PyBytes_Check(element)) {
+        if (PyUnicode_Check(element)) {
+          element_utf8 = PyUnicode_AsUTF8String(element);
+          if (element_utf8 == NULL) {
+            goto exit;
+          }
+
+          element_str = PyBytes_AsString(element_utf8);
+          Py_DECREF(element_utf8); element_utf8 = NULL;
+        } else if (PyBytes_Check(element)) {
+          element_str = PyBytes_AsString(element);
         }
-        element_str = PyBytes_AsString(element_utf8);
-        Py_DECREF(element_utf8); element_utf8 = NULL;
-      #else
-      if (PyString_Check(element)) {
-        /* Doesn't return NULL, because we already known it's a string */
-        element_str = PyString_AsString(element);
-      #endif
+
         if (strncmp(element_str, "longitude", 10) == 0) {
           element_val = WCSSUB_LONGITUDE;
         } else if (strncmp(element_str, "latitude", 9) == 0) {
@@ -3435,6 +3434,9 @@ PyTypeObject PyWcsprmType = {
 
 #define CONSTANT(a) PyModule_AddIntConstant(m, #a, a)
 
+#define XSTRINGIFY(s) STRINGIFY(s)
+#define STRINGIFY(s) #s
+
 int
 _setup_wcsprm_type(
     PyObject* m) {
@@ -3448,6 +3450,10 @@ _setup_wcsprm_type(
   wcsprintf_set(NULL);
   wcserr_enable(1);
 
+  if (PyModule_AddStringConstant(m, "__version__", XSTRINGIFY(WCSLIB_VERSION))) {
+      return -1;
+  }
+
   return (
     PyModule_AddObject(m, "Wcsprm", (PyObject *)&PyWcsprmType) ||
     CONSTANT(WCSSUB_LONGITUDE) ||
diff --git a/astropy/wcs/tests/data/j94f05bgq_flt.fits b/astropy/wcs/tests/data/j94f05bgq_flt.fits
new file mode 100644
index 0000000..502a5b3
--- /dev/null
+++ b/astropy/wcs/tests/data/j94f05bgq_flt.fits
@@ -0,0 +1 @@
+SIMPLE  =                    T / Fits standard                                  BITPIX  =                   16 / Bits per pixel                                 NAXIS   =                    0 / Number of axes                                 EXTEND  =                    T / File may contain extensions                    ORIGIN  = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator        IRAF-TLM= '10:43:32 (18/12/2008)' / Time of last modification                   NEXTEND =    [...]
\ No newline at end of file
diff --git a/astropy/wcs/tests/extension/test_extension.py b/astropy/wcs/tests/extension/test_extension.py
index 9fe7d45..a1b0b51 100644
--- a/astropy/wcs/tests/extension/test_extension.py
+++ b/astropy/wcs/tests/extension/test_extension.py
@@ -40,7 +40,7 @@ def test_wcsapi_extension(tmpdir):
     try:
         stdout, stderr = stdout.decode('utf8'), stderr.decode('utf8')
     except UnicodeDecodeError:
-       # Don't try to guess about encoding; just display the text
+        # Don't try to guess about encoding; just display the text
         stdout, stderr = stdout.decode('latin1'), stderr.decode('latin1')
 
     # If compilation fails, we can skip this test, since the
diff --git a/astropy/wcs/tests/test_utils.py b/astropy/wcs/tests/test_utils.py
index 744e638..93dc4f4 100644
--- a/astropy/wcs/tests/test_utils.py
+++ b/astropy/wcs/tests/test_utils.py
@@ -1,9 +1,17 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 from __future__ import absolute_import, division, print_function, unicode_literals
+
+from ...utils.data import get_pkg_data_contents, get_pkg_data_filename
 from ...wcs import WCS
 from .. import utils
-from ...tests.helper import pytest
+from ..utils import proj_plane_pixel_scales, non_celestial_pixel_scales
+from ...tests.helper import pytest, catch_warnings
+from ...utils.exceptions import AstropyUserWarning
+from ... import units as u
+
 import numpy as np
+from numpy.testing import assert_almost_equal
+from numpy.testing import assert_allclose
 
 def test_wcs_dropping():
     wcs = WCS(naxis=4)
@@ -135,10 +143,251 @@ def test_invalid_slice():
 
 def test_axis_names():
     mywcs = WCS(naxis=4)
-    mywcs.wcs.ctype = ['RA---TAN','DEC---TAN','VOPT-LSR','STOKES']
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN','VOPT-LSR','STOKES']
+
+    assert mywcs.axis_type_names == ['RA','DEC','VOPT','STOKES']
+
+    mywcs.wcs.cname = ['RA','DEC','VOPT','STOKES']
 
     assert mywcs.axis_type_names == ['RA','DEC','VOPT','STOKES']
 
-    mywcs.wcs.cname = ['RA','DEC','VOPT-LSR','STOKES']
+def test_celestial():
+    mywcs = WCS(naxis=4)
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN','VOPT','STOKES']
+    cel = mywcs.celestial
+    assert list(cel.wcs.ctype) == ['RA---TAN','DEC--TAN']
+    assert cel.axis_type_names == ['RA','DEC']
+
+def test_wcs_to_celestial_frame():
+
+    from ...coordinates.builtin_frames import ICRS, FK5, FK4, Galactic
+    from ...time import Time
+
+    mywcs = WCS(naxis=2)
+    with pytest.raises(ValueError) as exc:
+        assert utils.wcs_to_celestial_frame(mywcs) is None
+    assert exc.value.args[0] == "Could not determine celestial frame corresponding to the specified WCS object"
+
+    mywcs.wcs.ctype = ['XOFFSET', 'YOFFSET']
+    with pytest.raises(ValueError):
+        assert utils.wcs_to_celestial_frame(mywcs) is None
+
+    mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN']
+    frame = utils.wcs_to_celestial_frame(mywcs)
+    assert isinstance(frame, ICRS)
+
+    mywcs.wcs.equinox = 1987.
+    frame = utils.wcs_to_celestial_frame(mywcs)
+    assert isinstance(frame, FK5)
+    assert frame.equinox == Time(1987., format='jyear')
+
+    mywcs.wcs.equinox = 1982
+    frame = utils.wcs_to_celestial_frame(mywcs)
+    assert isinstance(frame, FK4)
+    assert frame.equinox == Time(1982., format='byear')
+
+    mywcs.wcs.equinox = np.nan
+    mywcs.wcs.ctype = ['GLON-SIN', 'GLAT-SIN']
+    frame = utils.wcs_to_celestial_frame(mywcs)
+    assert isinstance(frame, Galactic)
+
+    mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN']
+    mywcs.wcs.radesys = 'ICRS'
+
+    for equinox in [np.nan, 1987, 1982]:
+        mywcs.wcs.equinox = equinox
+        frame = utils.wcs_to_celestial_frame(mywcs)
+        assert isinstance(frame, ICRS)
+
+    # Flipped order
+    mywcs = WCS(naxis=2)
+    mywcs.wcs.ctype = ['DEC--TAN', 'RA---TAN']
+    assert isinstance(frame, ICRS)
+
+    # More than two dimensions
+    mywcs = WCS(naxis=3)
+    mywcs.wcs.ctype = ['DEC--TAN', 'VELOCITY', 'RA---TAN']
+    assert isinstance(frame, ICRS)
+
+
+def test_wcs_to_celestial_frame_extend():
+
+    from ...coordinates.builtin_frames import ICRS, FK5, FK4, Galactic
+    from ...time import Time
+
+    mywcs = WCS(naxis=2)
+    mywcs.wcs.ctype = ['XOFFSET', 'YOFFSET']
+    with pytest.raises(ValueError):
+        utils.wcs_to_celestial_frame(mywcs)
+
+    class OffsetFrame(object):
+        pass
+
+    def identify_offset(wcs):
+        if wcs.wcs.ctype[0].endswith('OFFSET') and wcs.wcs.ctype[1].endswith('OFFSET'):
+            return OffsetFrame()
+
+    from ..utils import custom_frame_mappings
+
+    with custom_frame_mappings(identify_offset):
+        frame = utils.wcs_to_celestial_frame(mywcs)
+    assert isinstance(frame, OffsetFrame)
+
+    # Check that things are back to normal after the context manager
+    with pytest.raises(ValueError):
+        utils.wcs_to_celestial_frame(mywcs)
+
+def test_pixscale_nodrop():
+    mywcs = WCS(naxis=2)
+    mywcs.wcs.cdelt = [0.1,0.2]
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN']
+    assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2))
+
+    mywcs.wcs.cdelt = [-0.1,0.2]
+    assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2))
+
+def test_pixscale_withdrop():
+    mywcs = WCS(naxis=3)
+    mywcs.wcs.cdelt = [0.1,0.2,1]
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN','VOPT']
+    assert_almost_equal(proj_plane_pixel_scales(mywcs.celestial), (0.1, 0.2))
+
+    mywcs.wcs.cdelt = [-0.1,0.2,1]
+    assert_almost_equal(proj_plane_pixel_scales(mywcs.celestial), (0.1, 0.2))
+
+
+def test_pixscale_cd():
+    mywcs = WCS(naxis=2)
+    mywcs.wcs.cd = [[-0.1,0],[0,0.2]]
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN']
+    assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2))
+
+
+ at pytest.mark.parametrize('angle',
+                         (30,45,60,75))
+def test_pixscale_cd_rotated(angle):
+    mywcs = WCS(naxis=2)
+    rho = angle/180.*np.pi
+    scale = 0.1
+    mywcs.wcs.cd = [[scale*np.cos(rho), -scale*np.sin(rho)],
+                    [scale*np.sin(rho), scale*np.cos(rho)]]
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN']
+    assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.1))
+
+ at pytest.mark.parametrize('angle',
+                         (30,45,60,75))
+def test_pixscale_pc_rotated(angle):
+    mywcs = WCS(naxis=2)
+    rho = angle/180.*np.pi
+    scale = 0.1
+    mywcs.wcs.cdelt = [-scale, scale]
+    mywcs.wcs.pc = [[np.cos(rho), -np.sin(rho)],
+                    [np.sin(rho), np.cos(rho)]]
+    mywcs.wcs.ctype = ['RA---TAN','DEC--TAN']
+    assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.1))
+
+ at pytest.mark.parametrize(('cdelt','pc','pccd'),
+                         (([0.1,0.2], np.eye(2), np.diag([0.1,0.2])),
+                          ([0.1,0.2,0.3], np.eye(3), np.diag([0.1,0.2,0.3])),
+                          ([1,1,1], np.diag([0.1,0.2,0.3]), np.diag([0.1,0.2,0.3])),
+                         ))
+def test_pixel_scale_matrix(cdelt, pc, pccd):
+
+    mywcs = WCS(naxis=(len(cdelt)))
+    mywcs.wcs.cdelt = cdelt
+    mywcs.wcs.pc = pc
+
+    assert_almost_equal(mywcs.pixel_scale_matrix, pccd)
+
+ at pytest.mark.parametrize(('ctype', 'cel'),
+                         ((['RA---TAN','DEC--TAN'], True),
+                          (['RA---TAN','DEC--TAN','FREQ'], False),
+                          (['RA---TAN','FREQ'], False),))
+def test_is_celestial(ctype, cel):
+    mywcs = WCS(naxis=len(ctype))
+    mywcs.wcs.ctype = ctype
+
+    assert mywcs.is_celestial == cel
+
+ at pytest.mark.parametrize(('ctype', 'cel'),
+                         ((['RA---TAN','DEC--TAN'], True),
+                          (['RA---TAN','DEC--TAN','FREQ'], True),
+                          (['RA---TAN','FREQ'], False),))
+def test_has_celestial(ctype, cel):
+    mywcs = WCS(naxis=len(ctype))
+    mywcs.wcs.ctype = ctype
+
+    assert mywcs.has_celestial == cel
+
+ at pytest.mark.parametrize(('cdelt','pc','cd'),
+                         ((np.array([0.1,0.2]), np.eye(2), np.eye(2)),
+                          (np.array([1,1]), np.diag([0.1,0.2]), np.eye(2)),
+                          (np.array([0.1,0.2]), np.eye(2), None),
+                          (np.array([0.1,0.2]), None, np.eye(2)),
+                          )
+                        )
+def test_noncelestial_scale(cdelt, pc, cd):
+    mywcs = WCS(naxis=2)
+    if cd is not None:
+        mywcs.wcs.cd = cd
+    if pc is not None:
+        mywcs.wcs.pc = pc
+    mywcs.wcs.cdelt = cdelt
+
+    mywcs.wcs.ctype = ['RA---TAN','FREQ']
+
+    ps = non_celestial_pixel_scales(mywcs)
+
+    assert_almost_equal(ps.to(u.deg).value, np.array([0.1,0.2]))
+
+ at pytest.mark.parametrize('mode', ['all', 'wcs'])
+def test_skycoord_to_pixel(mode):
+
+    from ... import units as u
+    from ...coordinates import SkyCoord
+    from ..utils import skycoord_to_pixel, pixel_to_skycoord
+
+    header = get_pkg_data_contents('maps/1904-66_TAN.hdr', encoding='binary')
+    wcs = WCS(header)
+
+    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')
+
+    xp, yp = skycoord_to_pixel(ref, wcs, mode=mode)
+
+    # WCS is in FK5 so we need to transform back to ICRS
+    new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs')
+
+    assert_allclose(new.ra.degree, ref.ra.degree)
+    assert_allclose(new.dec.degree, ref.dec.degree)
+
+    # Make sure you can specify a different class using ``cls`` keyword
+    class SkyCoord2(SkyCoord):
+        pass
+
+    new2 = pixel_to_skycoord(xp, yp, wcs, mode=mode,
+                             cls=SkyCoord2).transform_to('icrs')
+
+    assert new2.__class__ is SkyCoord2
+    assert_allclose(new2.ra.degree, ref.ra.degree)
+    assert_allclose(new2.dec.degree, ref.dec.degree)
+
+
+ at pytest.mark.parametrize('mode', ['all', 'wcs'])
+def test_skycoord_to_pixel_distortions(mode):
+
+    from ... import units as u
+    from ...coordinates import SkyCoord
+    from ..utils import skycoord_to_pixel, pixel_to_skycoord
+
+    header = get_pkg_data_filename('data/sip.fits')
+    wcs = WCS(header)
+
+    ref = SkyCoord(202.50 * u.deg, 47.19 * u.deg, frame='icrs')
+
+    xp, yp = skycoord_to_pixel(ref, wcs, mode=mode)
+
+    # WCS is in FK5 so we need to transform back to ICRS
+    new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs')
 
-    assert mywcs.axis_type_names == ['RA','DEC','VOPT-LSR','STOKES']
+    assert_allclose(new.ra.degree, ref.ra.degree)
+    assert_allclose(new.dec.degree, ref.dec.degree)
diff --git a/astropy/wcs/tests/test_wcs.py b/astropy/wcs/tests/test_wcs.py
index 9ba6cef..1217b24 100644
--- a/astropy/wcs/tests/test_wcs.py
+++ b/astropy/wcs/tests/test_wcs.py
@@ -9,6 +9,7 @@ from ...extern import six
 import io
 import os
 import warnings
+from datetime import datetime
 
 import numpy as np
 from numpy.testing import (
@@ -21,12 +22,6 @@ from ...utils.data import (
 from ...utils.misc import NumpyRNGContext
 from ...io import fits
 
-try:
-    import scipy  # pylint: disable=W0611
-except ImportError:
-    HAS_SCIPY = False
-else:
-    HAS_SCIPY = True
 
 # test_maps() is a generator
 def test_maps():
@@ -90,10 +85,8 @@ def test_spectra():
         header = get_pkg_data_contents(
             os.path.join("spectra", filename), encoding='binary')
 
-        wcsobj = wcs.WCS(header)
-
-        all = wcs.find_all_wcs(header)
-        assert len(all) == 9
+        all_wcs = wcs.find_all_wcs(header)
+        assert len(all_wcs) == 9
 
     # get the list of the hdr files that we want to test
     hdr_file_list = list(get_pkg_data_filenames("spectra", "*.hdr"))
@@ -201,8 +194,8 @@ def test_pix2world():
 
 
 def test_load_fits_path():
-    fits = get_pkg_data_filename('data/sip.fits')
-    w = wcs.WCS(fits)
+    fits_name = get_pkg_data_filename('data/sip.fits')
+    w = wcs.WCS(fits_name)
 
 
 def test_dict_init():
@@ -324,10 +317,12 @@ def test_invalid_shape():
     xy = np.random.random((2, 3))
     with pytest.raises(ValueError) as exc:
         xy2 = w.wcs_pix2world(xy, 1)
+    assert exc.value.args[0] == 'When providing two arguments, the array must be of shape (N, 2)'
 
     xy = np.random.random((2, 1))
     with pytest.raises(ValueError) as exc:
         xy2 = w.wcs_pix2world(xy, 1)
+    assert exc.value.args[0] == 'When providing two arguments, the array must be of shape (N, 2)'
 
 
 def test_warning_about_defunct_keywords():
@@ -366,7 +361,11 @@ def test_to_header_string():
 
 def test_to_fits():
     w = wcs.WCS()
-    w.to_fits()
+    header_string = w.to_header()
+    wfits = w.to_fits()
+    assert isinstance(wfits, fits.HDUList)
+    assert isinstance(wfits[0], fits.PrimaryHDU)
+    assert header_string == wfits[0].header[-8:]
 
 
 @raises(wcs.InvalidTransformError)
@@ -398,26 +397,112 @@ def test_validate_with_2_wcses():
     assert "WCS key 'A':" in six.text_type(results)
 
 
- at pytest.mark.skipif(str('not HAS_SCIPY'))
-def test_all_world2pix():
+def test_all_world2pix(fname=None, ext=0,
+                       tolerance=1.0e-4, origin=0,
+                       random_npts=25000,
+                       adaptive=False, maxiter=20,
+                       detect_divergence=True):
     """Test all_world2pix, iterative inverse of all_pix2world"""
-    fits = get_pkg_data_filename('data/sip.fits')
-    w = wcs.WCS(fits)
 
-    tolerance = 1e-6
+    # Open test FITS file:
+    if fname is None:
+        fname = get_pkg_data_filename('data/j94f05bgq_flt.fits')
+        ext = ('SCI',1)
+    if not os.path.isfile(fname):
+        raise IOError("Input file '{:s}' to 'test_all_world2pix' not found."
+                      .format(fname))
+    h = fits.open(fname)
+    w = wcs.WCS(h[ext].header, h)
+    h.close()
+    del h
+
+    crpix = w.wcs.crpix
+    ncoord = crpix.shape[0]
+
+    # Assume that CRPIX is at the center of the image and that the image has
+    # a power-of-2 number of pixels along each axis. Only use the central
+    # 1/64 for this testing purpose:
+    naxesi_l = list((7./16*crpix).astype(np.int))
+    naxesi_u = list((9./16*crpix).astype(np.int))
+
+    # Generate integer indices of pixels (image grid):
+    img_pix = np.dstack([i.flatten() for i in
+                         np.meshgrid(*map(range, naxesi_l, naxesi_u))])[0]
+
+    # Generage random data (in image coordinates):
     with NumpyRNGContext(123456789):
-        world = 0.1 * np.random.randn(100, 2)
-        for i in range(len(w.wcs.crval)):
-            world[:, i] += w.wcs.crval[i]
-        all_pix = w.all_world2pix(world, 0, tolerance=tolerance)
-        wcs_pix = w.wcs_world2pix(world, 0)
-        all_world = w.all_pix2world(all_pix, 0)
-
-        # First, check that the SIP distortion correction at least produces
-        # some different answers from the WCS-only transform.
-        assert np.any(all_pix != wcs_pix)
-
-        assert_allclose(all_world, world, rtol=0, atol=tolerance)
+        rnd_pix = np.random.rand(random_npts, ncoord)
+
+    # Scale random data to cover the central part of the image
+    mwidth = 2 * (crpix * 1./8)
+    rnd_pix = crpix - 0.5*mwidth + (mwidth-1) * rnd_pix
+
+    # Reference pixel coordinates in image coordinate system (CS):
+    test_pix = np.append(img_pix, rnd_pix, axis=0)
+    # Reference pixel coordinates in sky CS using forward transformation:
+    all_world = w.all_pix2world(test_pix, origin)
+
+    try:
+        runtime_begin = datetime.now()
+        # Apply the inverse iterative process to pixels in world coordinates
+        # to recover the pixel coordinates in image space.
+        all_pix = w.all_world2pix(
+            all_world, origin, tolerance=tolerance, adaptive=adaptive,
+            maxiter=maxiter, detect_divergence=detect_divergence)
+        runtime_end = datetime.now()
+    except wcs.wcs.NoConvergence as e:
+        runtime_end = datetime.now()
+        ndiv = 0
+        if e.divergent is not None:
+            ndiv = e.divergent.shape[0]
+            print("There are {} diverging solutions.".format(ndiv))
+            print("Indices of diverging solutions:\n{}"
+                  .format(e.divergent))
+            print("Diverging solutions:\n{}\n"
+                  .format(e.best_solution[e.divergent]))
+            print("Mean radius of the diverging solutions: {}"
+                  .format(np.mean(
+                      np.linalg.norm(e.best_solution[e.divergent], axis=1))))
+            print("Mean accuracy of the diverging solutions: {}\n"
+                  .format(np.mean(
+                      np.linalg.norm(e.accuracy[e.divergent], axis=1))))
+        else:
+            print("There are no diverging solutions.")
+
+        nslow = 0
+        if e.slow_conv is not None:
+            nslow = e.slow_conv.shape[0]
+            print("There are {} slowly converging solutions."
+                  .format(nslow))
+            print("Indices of slowly converging solutions:\n{}"
+                  .format(e.slow_conv))
+            print("Slowly converging solutions:\n{}\n"
+                  .format(e.best_solution[e.slow_conv]))
+        else:
+            print("There are no slowly converging solutions.\n")
+
+        print("There are {} converged solutions."
+              .format(e.best_solution.shape[0] - ndiv - nslow))
+        print("Best solutions (all points):\n{}"
+              .format(e.best_solution))
+        print("Accuracy:\n{}\n".format(e.accuracy))
+        print("\nFinished running 'test_all_world2pix' with errors.\n"
+              "ERROR: {}\nRun time: {}\n"
+              .format(e.args[0], runtime_end - runtime_begin))
+        raise e
+
+    # Compute differences between reference pixel coordinates and
+    # pixel coordinates (in image space) recovered from reference
+    # pixels in world coordinates:
+    errors = np.sqrt(np.sum(np.power(all_pix - test_pix, 2), axis=1))
+    meanerr = np.mean(errors)
+    maxerr = np.amax(errors)
+    print("\nFinished running 'test_all_world2pix'.\n"
+          "Mean error = {0:e}  (Max error = {1:e})\n"
+          "Run time: {2}\n"
+          .format(meanerr, maxerr, runtime_end - runtime_begin))
+
+    assert(maxerr < 2.0*tolerance)
 
 
 def test_scamp_sip_distortion_parameters():
@@ -469,7 +554,6 @@ def test_validate_faulty_wcs():
     """
     From github issue #2053
     """
-    from ...io import fits
     h = fits.Header()
     # Illegal WCS:
     h['RADESYSA'] = 'ICRS'
diff --git a/astropy/wcs/tests/test_wcsprm.py b/astropy/wcs/tests/test_wcsprm.py
index bde422f..980df07 100644
--- a/astropy/wcs/tests/test_wcsprm.py
+++ b/astropy/wcs/tests/test_wcsprm.py
@@ -3,6 +3,7 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from distutils.version import LooseVersion
 import gc
 import locale
 import re
@@ -10,7 +11,7 @@ import re
 from numpy.testing import assert_array_equal
 import numpy as np
 
-from ...tests.helper import pytest, raises
+from ...tests.helper import pytest, raises, catch_warnings
 from ...io import fits
 from .. import wcs
 from .. import _wcs
@@ -245,16 +246,21 @@ def test_cunit():
     assert w.cunit[1] == u.km
 
 
- at raises(ValueError)
 def test_cunit_invalid():
     w = _wcs.Wcsprm()
-    w.cunit[0] = 'foo'
+    with catch_warnings() as warns:
+        w.cunit[0] = 'foo'
+    assert len(warns) == 1
+    assert 'foo' in str(warns[0].message)
 
 
- at raises(ValueError)
 def test_cunit_invalid2():
     w = _wcs.Wcsprm()
-    w.cunit = ['foo', 'bar']
+    with catch_warnings() as warns:
+        w.cunit = ['foo', 'bar']
+    assert len(warns) == 2
+    assert 'foo' in str(warns[0].message)
+    assert 'bar' in str(warns[1].message)
 
 
 def test_unit():
@@ -747,6 +753,15 @@ def test_wcs_sub_error_message():
     assert str(e).endswith("axes must None, a sequence or an integer")
 
 
+def test_wcs_sub():
+    # Issue #3356
+    w = _wcs.Wcsprm()
+    w.sub(['latitude'])
+
+    w = _wcs.Wcsprm()
+    w.sub([b'latitude'])
+
+
 def test_compare():
     header = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary')
     w = _wcs.Wcsprm(header)
@@ -759,3 +774,115 @@ def test_compare():
 
     assert not w.compare(w2)
     assert w.compare(w2, _wcs.WCSCOMPARE_ANCILLARY)
+
+    w = _wcs.Wcsprm(header)
+    w2 = _wcs.Wcsprm(header)
+
+    w.cdelt[0] = np.float32(0.00416666666666666666666666)
+    w2.cdelt[0] = np.float64(0.00416666666666666666666666)
+
+    assert not w.compare(w2)
+    assert w.compare(w2, tolerance=1e-6)
+
+
+ at pytest.mark.xfail(
+    LooseVersion(_wcs.__version__) < LooseVersion("4.25"),
+    reason="wcslib < 4.25")
+def test_radesys_defaults():
+    w = _wcs.Wcsprm()
+    w.ctype = ['RA---TAN', 'DEC--TAN']
+    w.set()
+    assert w.radesys == "ICRS"
+
+ at pytest.mark.xfail(
+    LooseVersion(_wcs.__version__) < LooseVersion("4.25"),
+    reason="wcslib < 4.25")
+def test_radesys_defaults_full():
+
+    # As described in Section 3.1 of the FITS standard "Equatorial and ecliptic
+    # coordinates", for those systems the RADESYS keyword can be used to
+    # indicate the equatorial/ecliptic frame to use. From the standard:
+
+    # "For RADESYSa values of FK4 and FK4-NO-E, any stated equinox is Besselian
+    # and, if neither EQUINOXa nor EPOCH are given, a default of 1950.0 is to
+    # be taken. For FK5, any stated equinox is Julian and, if neither keyword
+    # is given, it defaults to 2000.0.
+
+    # "If the EQUINOXa keyword is given it should always be accompanied by
+    # RADESYS a. However, if it should happen to ap- pear by itself then
+    # RADESYSa defaults to FK4 if EQUINOXa < 1984.0, or to FK5 if EQUINOXa
+    # 1984.0. Note that these defaults, while probably true of older files
+    # using the EPOCH keyword, are not required of them.
+
+    # By default RADESYS is empty
+    w = _wcs.Wcsprm(naxis=2)
+    assert w.radesys == ''
+    assert np.isnan(w.equinox)
+
+    # For non-ecliptic or equatorial systems it is still empty
+    w = _wcs.Wcsprm(naxis=2)
+    for ctype in [('GLON-CAR', 'GLAT-CAR'),
+                  ('SLON-SIN', 'SLAT-SIN')]:
+        w.ctype = ctype
+        w.set()
+        assert w.radesys == ''
+        assert np.isnan(w.equinox)
+
+    for ctype in [('RA---TAN', 'DEC--TAN'),
+                  ('ELON-TAN', 'ELAT-TAN'),
+                  ('DEC--TAN', 'RA---TAN'),
+                  ('ELAT-TAN', 'ELON-TAN')]:
+
+        # Check defaults for RADESYS
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.set()
+        assert w.radesys == 'ICRS'
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.equinox = 1980
+        w.set()
+        assert w.radesys == 'FK4'
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.equinox = 1984
+        w.set()
+        assert w.radesys == 'FK5'
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.radesys = 'foo'
+        w.set()
+        assert w.radesys == 'foo'
+
+        # Check defaults for EQUINOX
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.set()
+        assert np.isnan(w.equinox)  # frame is ICRS, no equinox
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.radesys = 'ICRS'
+        w.set()
+        assert np.isnan(w.equinox)
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.radesys = 'FK5'
+        w.set()
+        assert w.equinox == 2000.
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.radesys = 'FK4'
+        w.set()
+        assert w.equinox == 1950
+
+        w = _wcs.Wcsprm(naxis=2)
+        w.ctype = ctype
+        w.radesys = 'FK4-NO-E'
+        w.set()
+        assert w.equinox == 1950
diff --git a/astropy/wcs/utils.py b/astropy/wcs/utils.py
index 8e98daa..f405d98 100644
--- a/astropy/wcs/utils.py
+++ b/astropy/wcs/utils.py
@@ -1,6 +1,21 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import numpy as np
+import warnings
+from .. import units as u
+from ..utils.exceptions import AstropyUserWarning
+
+__doctest_skip__ = ['wcs_to_celestial_frame']
+
+__all__ = ['add_stokes_axis_to_wcs',
+           'custom_frame_mappings',
+           'wcs_to_celestial_frame', 'proj_plane_pixel_scales',
+           'proj_plane_pixel_area',
+           'non_celestial_pixel_scales', 'skycoord_to_pixel',
+           'pixel_to_skycoord']
+
+
 def add_stokes_axis_to_wcs(wcs, add_before_ind):
     """
     Add a new Stokes axis that is uncorrelated with any other axes.
@@ -19,9 +34,407 @@ def add_stokes_axis_to_wcs(wcs, add_before_ind):
     A new `~astropy.wcs.WCS` instance with an additional axis
     """
 
-    inds = [i+1 for i in range(wcs.wcs.naxis)]
+    inds = [i + 1 for i in range(wcs.wcs.naxis)]
     inds.insert(add_before_ind, 0)
     newwcs = wcs.sub(inds)
     newwcs.wcs.ctype[add_before_ind] = 'STOKES'
     newwcs.wcs.cname[add_before_ind] = 'STOKES'
     return newwcs
+
+
+def _wcs_to_celestial_frame_builtin(wcs):
+
+    from ..coordinates import FK4, FK4NoETerms, FK5, ICRS, Galactic
+    from ..time import Time
+    from . import WCSSUB_CELESTIAL
+
+    # Keep only the celestial part of the axes
+    wcs = wcs.sub([WCSSUB_CELESTIAL])
+
+    if wcs.wcs.lng == -1 or wcs.wcs.lat == -1:
+        return None
+
+    radesys = wcs.wcs.radesys
+
+    if np.isnan(wcs.wcs.equinox):
+        equinox = None
+    else:
+        equinox = wcs.wcs.equinox
+
+    xcoord = wcs.wcs.ctype[0][:4]
+    ycoord = wcs.wcs.ctype[1][:4]
+
+    # Apply logic from FITS standard to determine the default radesys
+    if radesys == '' and xcoord == 'RA--' and ycoord == 'DEC-':
+        if equinox is None:
+            radesys = "ICRS"
+        elif equinox < 1984.:
+            radesys = "FK4"
+        else:
+            radesys = "FK5"
+
+    if radesys == 'FK4':
+        if equinox is not None:
+            equinox = Time(equinox, format='byear')
+        frame = FK4(equinox=equinox)
+    elif radesys == 'FK4-NO-E':
+        if equinox is not None:
+            equinox = Time(equinox, format='byear')
+        frame = FK4NoETerms(equinox=equinox)
+    elif radesys == 'FK5':
+        if equinox is not None:
+            equinox = Time(equinox, format='jyear')
+        frame = FK5(equinox=equinox)
+    elif radesys == 'ICRS':
+        frame = ICRS()
+    else:
+        if xcoord == 'GLON' and ycoord == 'GLAT':
+            frame = Galactic()
+        else:
+            frame = None
+
+    return frame
+
+
+WCS_FRAME_MAPPINGS = [[_wcs_to_celestial_frame_builtin]]
+
+
+class custom_frame_mappings(object):
+    def __init__(self, mappings=[]):
+        if hasattr(mappings, '__call__'):
+            mappings = [mappings]
+        WCS_FRAME_MAPPINGS.append(mappings)
+
+    def __enter__(self):
+        pass
+
+    def __exit__(self, type, value, tb):
+        WCS_FRAME_MAPPINGS.pop()
+
+
+def wcs_to_celestial_frame(wcs):
+    """
+    For a given WCS, return the coordinate frame that matches the celestial
+    component of the WCS.
+
+    Parameters
+    ----------
+    wcs : :class:`~astropy.wcs.WCS` instance
+        The WCS to find the frame for
+
+    Returns
+    -------
+    frame : :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance
+        An instance of a :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame`
+        subclass instance that best matches the specified WCS.
+
+    Notes
+    -----
+
+    To extend this function to frames not defined in astropy.coordinates, you
+    can write your own function which should take a :class:`~astropy.wcs.WCS`
+    instance and should return either an instance of a frame, or `None` if no
+    matching frame was found. You can register this function temporarily with::
+
+        >>> from astropy.wcs.utils import wcs_to_celestial_frame, custom_frame_mappings
+        >>> with custom_frame_mappings(my_function):
+        ...     wcs_to_celestial_frame(...)
+
+    """
+    for mapping_set in WCS_FRAME_MAPPINGS:
+        for func in mapping_set:
+            frame = func(wcs)
+            if frame is not None:
+                return frame
+    raise ValueError("Could not determine celestial frame corresponding to "
+                     "the specified WCS object")
+
+
+def proj_plane_pixel_scales(wcs):
+    """
+    For a WCS returns pixel scales along each axis of the image pixel at
+    the ``CRPIX`` location once it is projected onto the
+    "plane of intermediate world coordinates" as defined in
+    `Greisen & Calabretta 2002, A&A, 395, 1061 <http://adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.
+
+    .. note::
+        This function is concerned **only** about the transformation
+        "image plane"->"projection plane" and **not** about the
+        transformation "celestial sphere"->"projection plane"->"image plane".
+        Therefore, this function ignores distortions arising due to
+        non-linear nature of most projections.
+
+    .. note::
+        In order to compute the scales corresponding to celestial axes only,
+        make sure that the input `~astropy.wcs.WCS` object contains
+        celestial axes only, e.g., by passing in the
+        `~astropy.wcs.WCS.celestial` WCS object.
+
+    Parameters
+    ----------
+    wcs : `~astropy.wcs.WCS`
+        A world coordinate system object.
+
+    Returns
+    -------
+    scale : `~numpy.ndarray`
+        A vector (`~numpy.ndarray`) of projection plane increments
+        corresponding to each pixel side (axis). The units of the returned
+        results are the same as the units of `~astropy.wcs.Wcsprm.cdelt`,
+        `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` for
+        the celestial WCS and can be obtained by inquiring the value
+        of `~astropy.wcs.Wcsprm.cunit` property of the input
+        `~astropy.wcs.WCS` WCS object.
+
+    See Also
+    --------
+    astropy.wcs.utils.proj_plane_pixel_area
+
+    """
+    return np.sqrt((wcs.pixel_scale_matrix**2).sum(axis=0, dtype=np.float))
+
+
+def proj_plane_pixel_area(wcs):
+    """
+    For a **celestial** WCS (see `astropy.wcs.WCS.celestial`) returns pixel
+    area of the image pixel at the ``CRPIX`` location once it is projected
+    onto the "plane of intermediate world coordinates" as defined in
+    `Greisen & Calabretta 2002, A&A, 395, 1061 <http://adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.
+
+    .. note::
+        This function is concerned **only** about the transformation
+        "image plane"->"projection plane" and **not** about the
+        transformation "celestial sphere"->"projection plane"->"image plane".
+        Therefore, this function ignores distortions arising due to
+        non-linear nature of most projections.
+
+    .. note::
+        In order to compute the area of pixels corresponding to celestial
+        axes only, this function uses the `~astropy.wcs.WCS.celestial` WCS
+        object of the input ``wcs``.  This is different from the
+        `~astropy.wcs.utils.proj_plane_pixel_scales` function
+        that computes the scales for the axes of the input WCS itself.
+
+    Parameters
+    ----------
+    wcs : `~astropy.wcs.WCS`
+        A world coordinate system object.
+
+    Returns
+    -------
+    area : float
+        Area (in the projection plane) of the pixel at ``CRPIX`` location.
+        The units of the returned result are the same as the units of
+        the `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`,
+        and `~astropy.wcs.Wcsprm.cd` for the celestial WCS and can be
+        obtained by inquiring the value of `~astropy.wcs.Wcsprm.cunit`
+        property of the `~astropy.wcs.WCS.celestial` WCS object.
+
+    Raises
+    ------
+    ValueError
+        Pixel area is defined only for 2D pixels. Most likely the
+        `~astropy.wcs.Wcsprm.cd` matrix of the `~astropy.wcs.WCS.celestial`
+        WCS is not a square matrix of second order.
+
+    Notes
+    -----
+
+    Depending on the application, square root of the pixel area can be used to
+    represent a single pixel scale of an equivalent square pixel
+    whose area is equal to the area of a generally non-square pixel.
+
+    See Also
+    --------
+    astropy.wcs.utils.proj_plane_pixel_scales
+
+    """
+    psm = wcs.celestial.pixel_scale_matrix
+    if psm.shape != (2, 2):
+        raise ValueError("Pixel area is defined only for 2D pixels.")
+    return np.abs(np.linalg.det(psm))
+
+
+def non_celestial_pixel_scales(inwcs):
+    """
+    For a non-celestial WCS, e.g. one with mixed spectral and spatial axes, it
+    is still sometimes possible to define a pixel scale.
+
+    Parameters
+    ----------
+    inwcs : `~astropy.wcs.WCS`
+        The world coordinate system object
+
+    Returns
+    -------
+    scale : `numpy.ndarray`
+        The pixel scale along each axis
+    """
+
+    if inwcs.is_celestial:
+        raise ValueError("WCS is celestial, use celestial_pixel_scales instead")
+
+    pccd = inwcs.pixel_scale_matrix
+
+    if np.allclose(np.extract(1-np.eye(*pccd.shape), pccd), 0):
+        return np.abs(np.diagonal(pccd))*u.deg
+    else:
+        raise ValueError("WCS is rotated, cannot determine consistent pixel scales")
+
+
+def _has_distortion(wcs):
+    """
+    `True` if contains any SIP or image distortion components.
+    """
+    return any(getattr(wcs, dist_attr) is not None
+               for dist_attr in ['cpdis1', 'cpdis2', 'det2im1', 'det2im2', 'sip'])
+
+
+# TODO: in future, we should think about how the following two functions can be
+# integrated better into the WCS class.
+
+def skycoord_to_pixel(coords, wcs, origin=0, mode='all'):
+    """
+    Convert a set of SkyCoord coordinates into pixels.
+
+    Parameters
+    ----------
+    coords : `~astropy.coordinates.SkyCoord`
+        The coordinates to convert.
+    wcs : `~astropy.wcs.WCS`
+        The WCS transformation to use.
+    origin : int
+        Whether to return 0 or 1-based pixel coordinates.
+    mode : 'all' or 'wcs'
+        Whether to do the transformation including distortions (``'all'``) or
+        only including only the core WCS transformation (``'wcs'``).
+
+    Returns
+    -------
+    xp, yp : `numpy.ndarray`
+        The pixel coordinates
+
+    See Also
+    --------
+    astropy.coordinates.SkyCoord.from_pixel
+    """
+
+    from .. import units as u
+    from . import WCSSUB_CELESTIAL
+
+    if _has_distortion(wcs) and wcs.naxis != 2:
+        raise ValueError("Can only handle WCS with distortions for 2-dimensional WCS")
+
+    # Keep only the celestial part of the axes, also re-orders lon/lat
+    wcs = wcs.sub([WCSSUB_CELESTIAL])
+
+    if wcs.naxis != 2:
+        raise ValueError("WCS should contain celestial component")
+
+    # Check which frame the WCS uses
+    frame = wcs_to_celestial_frame(wcs)
+
+    # Check what unit the WCS needs
+    xw_unit = u.Unit(wcs.wcs.cunit[0])
+    yw_unit = u.Unit(wcs.wcs.cunit[1])
+
+    # Convert positions to frame
+    coords = coords.transform_to(frame)
+
+    # Extract longitude and latitude. We first try and use lon/lat directly,
+    # but if the representation is not spherical or unit spherical this will
+    # fail. We should then force the use of the unit spherical
+    # representation. We don't do that directly to make sure that we preserve
+    # custom lon/lat representations if available.
+    try:
+        lon = coords.data.lon.to(xw_unit)
+        lat = coords.data.lat.to(yw_unit)
+    except AttributeError:
+        lon = coords.spherical.lon.to(xw_unit)
+        lat = coords.spherical.lat.to(yw_unit)
+
+    # Convert to pixel coordinates
+    if mode == 'all':
+        xp, yp = wcs.all_world2pix(lon.value, lat.value, origin)
+    elif mode == 'wcs':
+        xp, yp = wcs.wcs_world2pix(lon.value, lat.value, origin)
+    else:
+        raise ValueError("mode should be either 'all' or 'wcs'")
+
+    return xp, yp
+
+
+def pixel_to_skycoord(xp, yp, wcs, origin=0, mode='all', cls=None):
+    """
+    Convert a set of pixel coordinates into a `~astropy.coordinates.SkyCoord`
+    coordinate.
+
+    Parameters
+    ----------
+    xp, yp : float or `numpy.ndarray`
+        The coordinates to convert.
+    wcs : `~astropy.wcs.WCS`
+        The WCS transformation to use.
+    origin : int
+        Whether to return 0 or 1-based pixel coordinates.
+    mode : 'all' or 'wcs'
+        Whether to do the transformation including distortions (``'all'``) or
+        only including only the core WCS transformation (``'wcs'``).
+    cls : class or None
+        The class of object to create.  Should be a
+        `~astropy.coordinates.SkyCoord` subclass.  If None, defaults to
+        `~astropy.coordinates.SkyCoord`.
+
+    Returns
+    -------
+    coords : Whatever ``cls`` is (a subclass of `~astropy.coordinates.SkyCoord`)
+        The celestial coordinates
+
+    See Also
+    --------
+    astropy.coordinates.SkyCoord.from_pixel
+    """
+
+    from .. import units as u
+    from . import WCSSUB_CELESTIAL
+    from ..coordinates import SkyCoord, UnitSphericalRepresentation
+
+    # we have to do this instead of actually setting the default to SkyCoord
+    # because importing SkyCoord at the module-level leads to circular
+    # dependencies.
+    if cls is None:
+        cls = SkyCoord
+
+    if _has_distortion(wcs) and wcs.naxis != 2:
+        raise ValueError("Can only handle WCS with distortions for 2-dimensional WCS")
+
+    # Keep only the celestial part of the axes, also re-orders lon/lat
+    wcs = wcs.sub([WCSSUB_CELESTIAL])
+
+    if wcs.naxis != 2:
+        raise ValueError("WCS should contain celestial component")
+
+    # Check which frame the WCS uses
+    frame = wcs_to_celestial_frame(wcs)
+
+    # Check what unit the WCS gives
+    lon_unit = u.Unit(wcs.wcs.cunit[0])
+    lat_unit = u.Unit(wcs.wcs.cunit[1])
+
+    # Convert pixel coordinates to celestial coordinates
+    if mode == 'all':
+        lon, lat = wcs.all_pix2world(xp, yp, origin)
+    elif mode == 'wcs':
+        lon, lat = wcs.wcs_pix2world(xp, yp, origin)
+    else:
+        raise ValueError("mode should be either 'all' or 'wcs'")
+
+    # Add units to longitude/latitude
+    lon = lon * lon_unit
+    lat = lat * lat_unit
+
+    # Create a SkyCoord-like object
+    data = UnitSphericalRepresentation(lon=lon, lat=lat)
+    coords = cls(frame.realize_frame(data))
+
+    return coords
diff --git a/astropy/wcs/wcs.py b/astropy/wcs/wcs.py
index 68c3d24..b6184f2 100644
--- a/astropy/wcs/wcs.py
+++ b/astropy/wcs/wcs.py
@@ -34,6 +34,7 @@ import io
 import os
 import textwrap
 import warnings
+import platform
 
 # THIRD-PARTY
 import numpy as np
@@ -70,6 +71,10 @@ __all__ = ['FITSFixedWarning', 'WCS', 'find_all_wcs',
            'NoWcsKeywordsFoundError', 'InvalidTabularParametersError']
 
 
+if six.PY3 or platform.system() == 'Windows':
+    __doctest_skip__ = ['WCS.all_world2pix']
+
+
 if _wcs is not None:
     WCSBase = _wcs._Wcs
     DistortionLookupTable = _wcs.DistortionLookupTable
@@ -136,6 +141,50 @@ def _parse_keysel(keysel):
     return keysel_flags
 
 
+class NoConvergence(Exception):
+    """
+    An error class used to report non-convergence and/or divergence
+    of numerical methods. It is used to report errors in the
+    iterative solution used by
+    the :py:meth:`~astropy.wcs.WCS.all_world2pix`.
+
+    Attributes
+    ----------
+
+    best_solution : numpy.ndarray
+        Best solution achieved by the numerical method.
+
+    accuracy : numpy.ndarray
+        Accuracy of the :py:attr:`best_solution`.
+
+    niter : int
+        Number of iterations performed by the numerical method
+        to compute :py:attr:`best_solution`.
+
+    divergent : None, numpy.ndarray
+        Indices of the points in :py:attr:`best_solution` array
+        for which the solution appears to be divergent. If the
+        solution does not diverge, `divergent` will be set to `None`.
+
+    slow_conv : None, numpy.ndarray
+        Indices of the solutions in :py:attr:`best_solution` array
+        for which the solution failed to converge within the
+        specified maximum number of iterations. If there are no
+        non-converging solutions (i.e., if the required accuracy
+        has been achieved for all input data points)
+        then `slow_conv` will be set to `None`.
+
+    """
+    def __init__(self, *args, **kwargs):
+        super(NoConvergence, self).__init__(*args)
+
+        self.best_solution = kwargs.pop('best_solution', None)
+        self.accuracy = kwargs.pop('accuracy', None)
+        self.niter = kwargs.pop('niter', None)
+        self.divergent = kwargs.pop('divergent', None)
+        self.slow_conv = kwargs.pop('slow_conv', None)
+
+
 class FITSFixedWarning(AstropyWarning):
     """
     The warning raised when the contents of the FITS header have been
@@ -540,11 +589,6 @@ naxis kwarg.
                         format(key, val),
                         FITSFixedWarning)
 
-    @deprecated("0.4", name="calcFootprint", alternative="calc_footprint")
-    def calcFootprint(self, header=None, undistort=True, axes=None):
-        return self.calc_footprint(header=header, undistort=undistort, axes=axes,
-                                   center=True)
-
     def calc_footprint(self, header=None, undistort=True, axes=None, center=True):
         """
         Calculates the footprint of the image on the sky.
@@ -1231,36 +1275,433 @@ naxis kwarg.
                    __.RA_DEC_ORDER(8),
                    __.RETURNS('world coordinates, in degrees', 8))
 
-    def _all_world2pix(self, world, origin, tolerance, **kwargs):
-        import scipy.optimize
-        pix = []
-        for i in range(len(world)):
-            x0 = self.wcs_world2pix(np.atleast_2d(world[i]), origin,
-                **kwargs).flatten()
-            func = lambda pix: (self.all_pix2world(np.atleast_2d(pix),
-                origin, **kwargs) - world[i]).flatten()
-            # Use Broyden inverse because it is (a) present in a wide range of
-            # Scipy version, (b) provides an option for the absolute tolerance,
-            # and (c) is suitable for small-scale problems (i.e., a few
-            # variables, rather than hundreds of variables).
-            soln = scipy.optimize.broyden1(func, x0, x_tol=tolerance)
-            pix.append(soln.flatten())
-        return np.asarray(pix)
+
+    def _all_world2pix(self, world, origin, tolerance, maxiter, adaptive,
+                       detect_divergence, quiet):
+        #############################################################
+        ##          DESCRIPTION OF THE NUMERICAL METHOD            ##
+        #############################################################
+        # In this section I will outline the method of solving
+        # the inverse problem of converting world coordinates to
+        # pixel coordinates (*inverse* of the direct transformation
+        # `all_pix2world`) and I will summarize some of the aspects
+        # of the method proposed here and some of the issues of the
+        # original `all_world2pix` (in relation to this method)
+        # discussed in https://github.com/astropy/astropy/issues/1977
+        # A more detailed discussion can be found here:
+        # https://github.com/astropy/astropy/pull/2373
+        #
+        #
+        #                  ### Background ###
+        #
+        #
+        # I will refer here to the [SIP Paper]
+        # (http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf).
+        # According to this paper, the effect of distortions as
+        # described in *their* equation (1) is:
+        #
+        # (1)   x = CD*(u+f(u)),
+        #
+        # where `x` is a *vector* of "intermediate spherical
+        # coordinates" (equivalent to (x,y) in the paper) and `u`
+        # is a *vector* of "pixel coordinates", and `f` is a vector
+        # function describing geometrical distortions
+        # (see equations 2 and 3 in SIP Paper.
+        # However, I prefer to use `w` for "intermediate world
+        # coordinates", `x` for pixel coordinates, and assume that
+        # transformation `W` performs the **linear**
+        # (CD matrix + projection onto celestial sphere) part of the
+        # conversion from pixel coordinates to world coordinates.
+        # Then we can re-write (1) as:
+        #
+        # (2)   w = W*(x+f(x)) = T(x)
+        #
+        # In `astropy.wcs.WCS` transformation `W` is represented by
+        # the `wcs_pix2world` member, while the combined ("total")
+        # transformation (linear part + distortions) is performed by
+        # `all_pix2world`. Below I summarize the notations and their
+        # equivalents in `astropy.wcs.WCS`:
+        #
+        #| Equation term | astropy.WCS/meaning          |
+        #| ------------- | ---------------------------- |
+        #| `x`           | pixel coordinates            |
+        #| `w`           | world coordinates            |
+        #| `W`           | `wcs_pix2world()`            |
+        #| `W^{-1}`      | `wcs_world2pix()`            |
+        #| `T`           | `all_pix2world()`            |
+        #| `x+f(x)`      | `pix2foc()`                  |
+        #
+        #
+        #      ### Direct Solving of Equation (2)  ###
+        #
+        #
+        # In order to find the pixel coordinates that correspond to
+        # given world coordinates `w`, it is necessary to invert
+        # equation (2): `x=T^{-1}(w)`, or solve equation `w==T(x)`
+        # for `x`. However, this approach has the following
+        # disadvantages:
+        #    1. It requires unnecessary transformations (see next
+        #       section).
+        #    2. It is prone to "RA wrapping" issues as described in
+        # https://github.com/astropy/astropy/issues/1977
+        # (essentially because `all_pix2world` may return points with
+        # a different phase than user's input `w`).
+        #
+        #
+        #      ### Description of the Method Used here ###
+        #
+        #
+        # By applying inverse linear WCS transformation (`W^{-1}`)
+        # to both sides of equation (2) and introducing notation `x'`
+        # (prime) for the pixels coordinates obtained from the world
+        # coordinates by applying inverse *linear* WCS transformation
+        # ("focal plane coordinates"):
+        #
+        # (3)   x' = W^{-1}(w)
+        #
+        # we obtain the following equation:
+        #
+        # (4)   x' = x+f(x),
+        #
+        # or,
+        #
+        # (5)   x = x'-f(x)
+        #
+        # This equation is well suited for solving using the method
+        # of fixed-point iterations
+        # (http://en.wikipedia.org/wiki/Fixed-point_iteration):
+        #
+        # (6)   x_{i+1} = x'-f(x_i)
+        #
+        # As an initial value of the pixel coordinate `x_0` we take
+        # "focal plane coordinate" `x'=W^{-1}(w)=wcs_world2pix(w)`.
+        # We stop iterations when `|x_{i+1}-x_i|<tolerance`. We also
+        # consider the process to be diverging if
+        # `|x_{i+1}-x_i|>|x_i-x_{i-1}|`
+        # **when** `|x_{i+1}-x_i|>=tolerance` (when current
+        # approximation is close to the true solution,
+        # `|x_{i+1}-x_i|>|x_i-x_{i-1}|` may be due to rounding errors
+        # and we ignore such "divergences" when
+        # `|x_{i+1}-x_i|<tolerance`). It may appear that checking for
+        # `|x_{i+1}-x_i|<tolerance` in order to ignore divergence is
+        # unnecessary since the iterative process should stop anyway,
+        # however, the proposed implementation of this iterative
+        # process is completely vectorized and, therefore, we may
+        # continue iterating over *some* points even though they have
+        # converged to within a specified tolerance (while iterating
+        # over other points that have not yet converged to
+        # a solution).
+        #
+        # In order to efficiently implement iterative process (6)
+        # using available methods in `astropy.wcs.WCS`, we add and
+        # subtract `x_i` from the right side of equation (6):
+        #
+        # (7)   x_{i+1} = x'-(x_i+f(x_i))+x_i = x'-pix2foc(x_i)+x_i,
+        #
+        # where `x'=wcs_world2pix(w)` and it is computed only *once*
+        # before the beginning of the iterative process (and we also
+        # set `x_0=x'`). By using `pix2foc` at each iteration instead
+        # of `all_pix2world` we get about 25% increase in performance
+        # (by not performing the linear `W` transformation at each
+        # step) and we also avoid the "RA wrapping" issue described
+        # above (by working in focal plane coordinates and avoiding
+        # pix->world transformations).
+        #
+        # As an added benefit, the process converges to the correct
+        # solution in just one iteration when distortions are not
+        # present (compare to
+        # https://github.com/astropy/astropy/issues/1977 and
+        # https://github.com/astropy/astropy/pull/2294): in this case
+        # `pix2foc` is the identical transformation
+        # `x_i=pix2foc(x_i)` and from equation (7) we get:
+        #
+        # x' = x_0 = wcs_world2pix(w)
+        # x_1 = x' - pix2foc(x_0) + x_0 = x' - pix2foc(x') + x' = x'
+        #     = wcs_world2pix(w) = x_0
+        # =>
+        # |x_1-x_0| = 0 < tolerance (with tolerance > 0)
+        #
+        # However, for performance reasons, it is still better to
+        # avoid iterations altogether and return the exact linear
+        # solution (`wcs_world2pix`) right-away when non-linear
+        # distortions are not present by checking that attributes
+        # `sip`, `cpdis1`, `cpdis2`, `det2im1`, and `det2im2` are
+        # *all* `None`.
+        #
+        #
+        #         ### Outline of the Algorithm ###
+        #
+        #
+        # While the proposed code is relatively long (considering
+        # the simplicity of the algorithm), this is due to: 1)
+        # checking if iterative solution is necessary at all; 2)
+        # checking for divergence; 3) re-implementation of the
+        # completely vectorized algorithm as an "adaptive" vectorized
+        # algorithm (for cases when some points diverge for which we
+        # want to stop iterations). In my tests, the adaptive version
+        # of the algorithm is about 50% slower than non-adaptive
+        # version for all HST images.
+        #
+        # The essential part of the vectorized non-adaptive algorithm
+        # (without divergence and other checks) can be described
+        # as follows:
+        #
+        #     pix0 = self.wcs_world2pix(world, origin)
+        #     pix  = pix0.copy() # 0-order solution
+        #
+        #     for k in range(maxiter):
+        #         # find correction to the previous solution:
+        #         dpix = self.pix2foc(pix, origin) - pix0
+        #
+        #         # compute norm (L2) of the correction:
+        #         dn = np.linalg.norm(dpix, axis=1)
+        #
+        #         # apply correction:
+        #         pix -= dpix
+        #
+        #         # check convergence:
+        #         if np.max(dn) < tolerance:
+        #             break
+        #
+        #    return pix
+        #
+        # Here, the input parameter `world` can be a `MxN` array
+        # where `M` is the number of coordinate axes in WCS and `N`
+        # is the number of points to be converted simultaneously to
+        # image coordinates.
+        #
+        #
+        #                ###  IMPORTANT NOTE:  ###
+        #
+        # If, in the future releases of the `~astropy.wcs`,
+        # `pix2foc` will not apply all the required distortion
+        # corrections then in the code below, calls to `pix2foc` will
+        # have to be replaced with
+        # wcs_world2pix(all_pix2world(pix_list, origin), origin)
+        #
+
+        #############################################################
+        ##            INITIALIZE ITERATIVE PROCESS:                ##
+        #############################################################
+
+        # initial approximation (linear WCS based only)
+        pix0 = self.wcs_world2pix(world, origin)
+
+        # Check that an iterative solution is required at all
+        # (when any of the non-CD-matrix-based corrections are
+        # present). If not required return the initial
+        # approximation (pix0).
+        if self.sip is None and \
+           self.cpdis1 is None and self.cpdis2 is None and \
+           self.det2im1 is None and self.det2im2 is None:
+            # No non-WCS corrections detected so
+            # simply return initial approximation:
+            return pix0
+
+        pix = pix0.copy()  # 0-order solution
+
+        # initial correction:
+        dpix = self.pix2foc(pix, origin) - pix0
+
+        # Update initial solution:
+        pix -= dpix
+
+        # Norm (L2) squared of the correction:
+        dn = np.sum(dpix*dpix, axis=1)
+        dnprev = dn.copy()  # if adaptive else dn
+        tol2 = tolerance**2
+
+        # Prepare for iterative process
+        k = 1
+        ind = None
+        inddiv = None
+
+        # Turn off numpy runtime warnings for 'invalid' and 'over':
+        old_invalid = np.geterr()['invalid']
+        old_over = np.geterr()['over']
+        np.seterr(invalid='ignore', over='ignore')
+
+        #############################################################
+        ##                NON-ADAPTIVE ITERATIONS:                 ##
+        #############################################################
+        if not adaptive:
+            # Fixed-point iterations:
+            while (np.nanmax(dn) >= tol2 and k < maxiter):
+                # Find correction to the previous solution:
+                dpix = self.pix2foc(pix, origin) - pix0
+
+                # Compute norm (L2) squared of the correction:
+                dn = np.sum(dpix*dpix, axis=1)
+
+                # Check for divergence (we do this in two stages
+                # to optimize performance for the most common
+                # scenario when successive approximations converge):
+                if detect_divergence:
+                    divergent = (dn >= dnprev)
+                    if np.any(divergent):
+                        # Find solutions that have not yet converged:
+                        slowconv = (dn >= tol2)
+                        inddiv, = np.where(divergent & slowconv)
+
+                        if inddiv.shape[0] > 0:
+                            # Update indices of elements that
+                            # still need correction:
+                            conv = (dn < dnprev)
+                            iconv = np.where(conv)
+
+                            # Apply correction:
+                            dpixgood = dpix[iconv]
+                            pix[iconv] -= dpixgood
+                            dpix[iconv] = dpixgood
+
+                            # For the next iteration choose
+                            # non-divergent points that have not yet
+                            # converged to the requested accuracy:
+                            ind, = np.where(slowconv & conv)
+                            pix0 = pix0[ind]
+                            dnprev[ind] = dn[ind]
+                            k += 1
+
+                            # Switch to adaptive iterations:
+                            adaptive = True
+                            break
+                    # Save current correction magnitudes for later:
+                    dnprev = dn
+
+                # Apply correction:
+                pix -= dpix
+                k += 1
+
+        #############################################################
+        ##                  ADAPTIVE ITERATIONS:                   ##
+        #############################################################
+        if adaptive:
+            if ind is None:
+                ind, = np.where(np.isfinite(pix).all(axis=1))
+                pix0 = pix0[ind]
+
+            # "Adaptive" fixed-point iterations:
+            while (ind.shape[0] > 0 and k < maxiter):
+                # Find correction to the previous solution:
+                dpixnew = self.pix2foc(pix[ind], origin) - pix0
+
+                # Compute norm (L2) of the correction:
+                dnnew = np.sum(np.square(dpixnew), axis=1)
+
+                # Bookeeping of corrections:
+                dnprev[ind] = dn[ind].copy()
+                dn[ind] = dnnew
+
+                if detect_divergence:
+                    # Find indices of pixels that are converging:
+                    conv = (dnnew < dnprev[ind])
+                    iconv = np.where(conv)
+                    iiconv = ind[iconv]
+
+                    # Apply correction:
+                    dpixgood = dpixnew[iconv]
+                    pix[iiconv] -= dpixgood
+                    dpix[iiconv] = dpixgood
+
+                    # Find indices of solutions that have not yet
+                    # converged to the requested accuracy
+                    # AND that do not diverge:
+                    subind, = np.where((dnnew >= tol2) & conv)
+
+                else:
+                    # Apply correction:
+                    pix[ind] -= dpixnew
+                    dpix[ind] = dpixnew
+
+                    # Find indices of solutions that have not yet
+                    # converged to the requested accuracy:
+                    subind, = np.where(dnnew >= tol2)
+
+                # Choose solutions that need more iterations:
+                ind = ind[subind]
+                pix0 = pix0[subind]
+
+                k += 1
+
+        #############################################################
+        ##         FINAL DETECTION OF INVALID, DIVERGING,          ##
+        ##         AND FAILED-TO-CONVERGE POINTS                   ##
+        #############################################################
+        # Identify diverging and/or invalid points:
+        invalid = ((~np.all(np.isfinite(pix), axis=1)) &
+                   (np.all(np.isfinite(world), axis=1)))
+
+        # When detect_divergence==False, dnprev is outdated
+        # (it is the norm of the very first correction).
+        # Still better than nothing...
+        inddiv, = np.where(((dn >= tol2) & (dn >= dnprev)) | invalid)
+        if inddiv.shape[0] == 0:
+            inddiv = None
+
+        # Identify points that did not converge within 'maxiter'
+        # iterations:
+        if k >= maxiter:
+            ind, = np.where((dn >= tol2) & (dn < dnprev) & (~invalid))
+            if ind.shape[0] == 0:
+                ind = None
+        else:
+            ind = None
+
+        # Restore previous numpy error settings:
+        np.seterr(invalid=old_invalid, over=old_over)
+
+        #############################################################
+        ##  RAISE EXCEPTION IF DIVERGING OR TOO SLOWLY CONVERGING  ##
+        ##  DATA POINTS HAVE BEEN DETECTED:                        ##
+        #############################################################
+        if (ind is not None or inddiv is not None) and not quiet:
+            if inddiv is None:
+                raise NoConvergence(
+                    "'WCS.all_world2pix' failed to "
+                    "converge to the requested accuracy after {:d} "
+                    "iterations.".format(k), best_solution=pix,
+                    accuracy=np.abs(dpix), niter=k,
+                    slow_conv=ind, divergent=None)
+            else:
+                raise NoConvergence(
+                    "'WCS.all_world2pix' failed to "
+                    "converge to the requested accuracy.\n"
+                    "After {0:d} iterations, the solution is diverging "
+                    "at least for one input point."
+                    .format(k), best_solution=pix,
+                    accuracy=np.abs(dpix), niter=k,
+                    slow_conv=ind, divergent=inddiv)
+
+        return pix
 
     def all_world2pix(self, *args, **kwargs):
         if self.wcs is None:
             raise ValueError("No basic WCS settings were created.")
-        tolerance = kwargs.pop('tolerance', 1e-6)
-        return self._array_converter(lambda *args, **kwargs:
-            self._all_world2pix(*args, tolerance=tolerance, **kwargs),
-            'input', *args,
-            **kwargs)
+
+        tolerance  = kwargs.pop('tolerance', 1e-4)
+        maxiter    = kwargs.pop('maxiter', 20)
+        adaptive   = kwargs.pop('adaptive', False)
+        detect_div = kwargs.pop('detect_divergence', True)
+        quiet      = kwargs.pop('quiet', False)
+
+        return self._array_converter(
+            lambda *args, **kwargs:
+            self._all_world2pix(
+                *args, tolerance=tolerance, maxiter=maxiter,
+                adaptive=adaptive, detect_divergence=detect_div,
+                quiet=quiet),
+            'input', *args, **kwargs
+        )
+
     all_world2pix.__doc__ = """
-        Transforms world coordinates to pixel coordinates, using numerical
-        iteration to invert the method `~astropy.wcs.WCS.all_pix2world` within a
-        tolerance of 1e-6 pixels.
+        all_world2pix(*arg, accuracy=1.0e-4, maxiter=20,
+        adaptive=False, detect_divergence=True, quiet=False)
+
+        Transforms world coordinates to pixel coordinates, using
+        numerical iteration to invert the full forward transformation
+        `~astropy.wcs.WCS.all_pix2world` with complete
+        distortion model.
 
-        Note that to use this function, you must have Scipy installed.
 
         Parameters
         ----------
@@ -1271,10 +1712,130 @@ naxis kwarg.
 
         {1}
 
-        tolerance : float, optional
-            Tolerance of solution. Iteration terminates when the iterative
-            solver estimates that the true solution is within this many pixels
-            current estimate. Default value is 1e-6 (pixels).
+        tolerance : float, optional (Default = 1.0e-4)
+            Tolerance of solution. Iteration terminates when the
+            iterative solver estimates that the "true solution" is
+            within this many pixels current estimate, more
+            specifically, when the correction to the solution found
+            during the previous iteration is smaller
+            (in the sense of the L2 norm) than ``tolerance``.
+
+        maxiter : int, optional (Default = 20)
+            Maximum number of iterations allowed to reach a solution.
+
+        quiet : bool, optional (Default = False)
+            Do not throw :py:class:``NoConvergence`` exceptions when
+            the method does not converge to a solution with the
+            required accuracy within a specified number of maximum
+            iterations set by ``maxiter`` parameter. Instead,
+            simply return the found solution.
+
+        Other Parameters
+        ----------------
+        adaptive : bool, optional (Default = False)
+            Specifies whether to adaptively select only points that
+            did not converge to a solution within the required
+            accuracy for the next iteration. Default is recommended
+            for HST as well as most other instruments.
+
+            .. note::
+               The :py:meth:`all_world2pix` uses a vectorized
+               implementation of the method of consecutive
+               approximations (see ``Notes`` section below) in which it
+               iterates over *all* input points *regardless* until
+               the required accuracy has been reached for *all* input
+               points. In some cases it may be possible that
+               *almost all* points have reached the required accuracy
+               but there are only a few of input data points for
+               which additional iterations may be needed (this
+               depends mostly on the characteristics of the geometric
+               distortions for a given instrument). In this situation
+               it may be advantageous to set ``adaptive`` = `True` in
+               which case :py:meth:`all_world2pix` will continue
+               iterating *only* over the points that have not yet
+               converged to the required accuracy. However, for the
+               HST's ACS/WFC detector, which has the strongest
+               distortions of all HST instruments, testing has
+               shown that enabling this option would lead to a about
+               50-100\% penalty in computational time (depending on
+               specifics of the image, geometric distortions, and
+               number of input points to be converted). Therefore,
+               for HST and possibly instruments, it is recommended
+               to set ``adaptive`` = `False`. The only danger in
+               getting this setting wrong will be a performance
+               penalty.
+
+            .. note::
+               When ``detect_divergence`` is `True`,
+               :py:meth:`all_world2pix` will automatically switch
+               to the adaptive algorithm once divergence has been
+               detected.
+
+        detect_divergence : bool, optional (Default = True)
+            Specifies whether to perform a more detailed analysis
+            of the convergence to a solution. Normally
+            :py:meth:`all_world2pix` may not achieve the required
+            accuracy if either the ``tolerance`` or ``maxiter`` arguments
+            are too low. However, it may happen that for some
+            geometric distortions the conditions of convergence for
+            the the method of consecutive approximations used by
+            :py:meth:`all_world2pix` may not be satisfied, in which
+            case consecutive approximations to the solution will
+            diverge regardless of the ``tolerance`` or ``maxiter``
+            settings.
+
+            When ``detect_divergence`` is `False`, these divergent
+            points will be detected as not having achieved the
+            required accuracy (without further details). In addition,
+            if ``adaptive`` is `False` then the algorithm will not
+            know that the solution (for specific points) is diverging
+            and will continue iterating and trying to "improve"
+            diverging solutions. This may result in ``NaN`` or
+            ``Inf`` values in the return results (in addition to a
+            performance penalties). Even when ``detect_divergence``
+            is `False`, :py:meth:`all_world2pix`, at the end of the
+            iterative process, will identify invalid results
+            (``NaN`` or ``Inf``) as "diverging" solutions and will
+            raise :py:class:``NoConvergence`` unless the ``quiet``
+            parameter is set to `True`.
+
+            When ``detect_divergence`` is `True`,
+            :py:meth:`all_world2pix` will detect points for which
+            current correction to the coordinates is larger than
+            the correction applied during the previous iteration
+            **if** the requested accuracy **has not yet been
+            achieved**. In this case, if ``adaptive`` is `True`,
+            these points will be excluded from further iterations and
+            if ``adaptive`` is `False`, :py:meth:`all_world2pix` will
+            automatically switch to the adaptive algorithm. Thus, the
+            reported divergent solution will be the latest converging
+            solution computed immediately *before* divergence
+            has been detected.
+
+            .. note::
+               When accuracy has been achieved, small increases in
+               current corrections may be possible due to rounding
+               errors (when ``adaptive`` is `False`) and such
+               increases will be ignored.
+
+            .. note::
+               Based on our testing using HST ACS/WFC images, setting
+               ``detect_divergence`` to `True` will incur about 5-20\%
+               performance penalty with the larger penalty
+               corresponding to ``adaptive`` set to `True`.
+               Because the benefits of enabling this
+               feature outweigh the small performance penalty,
+               especially when ``adaptive`` = `False`, it is
+               recommended to set ``detect_divergence`` to `True`,
+               unless extensive testing of the distortion models for
+               images from specific instruments show a good stability
+               of the numerical method for a wide range of
+               coordinates (even outside the image itself).
+
+            .. note::
+               Indices of the diverging inverse solutions will be
+               reported in the ``divergent`` attribute of the
+               raised :py:class:``NoConvergence`` exception object.
 
         Returns
         -------
@@ -1287,11 +1848,40 @@ naxis kwarg.
         the ``CTYPEia`` keywords in the FITS header, therefore it may
         not always be of the form (*ra*, *dec*).  The
         `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`,
-        `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp`
+        `~astropy.wcs.Wcsprm.lattyp`, and
+        `~astropy.wcs.Wcsprm.lngtyp`
         members can be used to determine the order of the axes.
 
+        Using the method of fixed-point iterations approximations we
+        iterate starting with the initial approximation, which is
+        computed using the non-distortion-aware
+        :py:meth:`wcs_world2pix` (or equivalent).
+
+        The :py:meth:`all_world2pix` function uses a vectorized
+        implementation of the method of consecutive approximations and
+        therefore it is highly efficient (>30x) when *all* data points
+        that need to be converted from sky coordinates to image
+        coordinates are passed at *once*. Therefore, it is advisable,
+        whenever possible, to pass as input a long array of all points
+        that need to be converted to :py:meth:`all_world2pix` instead
+        of calling :py:meth:`all_world2pix` for each data point. Also
+        see the note to the ``adaptive`` parameter.
+
         Raises
         ------
+        NoConvergence
+            The method did not converge to a
+            solution to the required accuracy within a specified
+            number of maximum iterations set by the ``maxiter``
+            parameter. To turn off this exception, set ``quiet`` to
+            `True`. Indices of the points for which the requested
+            accuracy was not achieved (if any) will be listed in the
+            ``slow_conv`` attribute of the
+            raised :py:class:``NoConvergence`` exception object.
+
+            See :py:class:``NoConvergence`` documentation for
+            more details.
+
         MemoryError
             Memory allocation failed.
 
@@ -1315,10 +1905,121 @@ naxis kwarg.
 
         InvalidTransformError
             Ill-conditioned coordinate transformation parameters.
+
+        Examples
+        --------
+        >>> import astropy.io.fits as fits
+        >>> import astropy.wcs as wcs
+        >>> import numpy as np
+        >>> import os
+
+        >>> filename = os.path.join(wcs.__path__[0], 'tests/data/j94f05bgq_flt.fits')
+        >>> hdulist = fits.open(filename)
+        >>> w = wcs.WCS(hdulist[('sci',1)].header, hdulist)
+        >>> hdulist.close()
+
+        >>> ra, dec = w.all_pix2world([1,2,3], [1,1,1], 1)
+        >>> print(ra)
+        [ 5.52645627  5.52649663  5.52653698]
+        >>> print(dec)
+        [-72.05171757 -72.05171276 -72.05170795]
+        >>> radec = w.all_pix2world([[1,1], [2,1], [3,1]], 1)
+        >>> print(radec)
+        [[  5.52645627 -72.05171757]
+         [  5.52649663 -72.05171276]
+         [  5.52653698 -72.05170795]]
+        >>> x, y = w.all_world2pix(ra, dec, 1)
+        >>> print(x)
+        [ 1.00000238  2.00000237  3.00000236]
+        >>> print(y)
+        [ 0.99999996  0.99999997  0.99999997]
+        >>> xy = w.all_world2pix(radec, 1)
+        >>> print(xy)
+        [[ 1.00000238  0.99999996]
+         [ 2.00000237  0.99999997]
+         [ 3.00000236  0.99999997]]
+        >>> xy = w.all_world2pix(radec, 1, maxiter=3,
+        ...                      tolerance=1.0e-10, quiet=False)
+        Traceback (most recent call last):
+        ...
+        NoConvergence: 'WCS.all_world2pix' failed to converge to the
+        requested accuracy. After 3 iterations, the solution is
+        diverging at least for one input point.
+
+        >>> # Now try to use some diverging data:
+        >>> divradec = w.all_pix2world([[1.0, 1.0],
+        ...                             [10000.0, 50000.0],
+        ...                             [3.0, 1.0]], 1)
+        >>> print(divradec)
+        [[  5.52645627 -72.05171757]
+         [  7.15976932 -70.8140779 ]
+         [  5.52653698 -72.05170795]]
+
+        >>> # First, turn detect_divergence on:
+        >>> try:
+        ...   xy = w.all_world2pix(divradec, 1, maxiter=20,
+        ...                        tolerance=1.0e-4, adaptive=False,
+        ...                        detect_divergence=True,
+        ...                        quiet=False)
+        ... except wcs.wcs.NoConvergence as e:
+        ...   print("Indices of diverging points: {{0}}"
+        ...         .format(e.divergent))
+        ...   print("Indices of poorly converging points: {{0}}"
+        ...         .format(e.slow_conv))
+        ...   print("Best solution:\\n{{0}}".format(e.best_solution))
+        ...   print("Achieved accuracy:\\n{{0}}".format(e.accuracy))
+        Indices of diverging points: [1]
+        Indices of poorly converging points: None
+        Best solution:
+        [[  1.00000238e+00   9.99999965e-01]
+         [ -1.99441636e+06   1.44309097e+06]
+         [  3.00000236e+00   9.99999966e-01]]
+        Achieved accuracy:
+        [[  6.13968380e-05   8.59638593e-07]
+         [  8.59526812e+11   6.61713548e+11]
+         [  6.09398446e-05   8.38759724e-07]]
+        >>> raise e
+        Traceback (most recent call last):
+        ...
+        NoConvergence: 'WCS.all_world2pix' failed to converge to the
+        requested accuracy.  After 5 iterations, the solution is
+        diverging at least for one input point.
+
+        >>> # This time turn detect_divergence off:
+        >>> try:
+        ...   xy = w.all_world2pix(divradec, 1, maxiter=20,
+        ...                        tolerance=1.0e-4, adaptive=False,
+        ...                        detect_divergence=False,
+        ...                        quiet=False)
+        ... except wcs.wcs.NoConvergence as e:
+        ...   print("Indices of diverging points: {{0}}"
+        ...         .format(e.divergent))
+        ...   print("Indices of poorly converging points: {{0}}"
+        ...         .format(e.slow_conv))
+        ...   print("Best solution:\\n{{0}}".format(e.best_solution))
+        ...   print("Achieved accuracy:\\n{{0}}".format(e.accuracy))
+        Indices of diverging points: [1]
+        Indices of poorly converging points: None
+        Best solution:
+        [[ 1.00000009  1.        ]
+         [        nan         nan]
+         [ 3.00000009  1.        ]]
+        Achieved accuracy:
+        [[  2.29417358e-06   3.21222995e-08]
+         [             nan              nan]
+         [  2.27407877e-06   3.13005639e-08]]
+        >>> raise e
+        Traceback (most recent call last):
+        ...
+        NoConvergence: 'WCS.all_world2pix' failed to converge to the
+        requested accuracy.  After 6 iterations, the solution is
+        diverging at least for one input point.
+
         """.format(__.TWO_OR_MORE_ARGS('naxis', 8),
                    __.RA_DEC_ORDER(8),
                    __.RETURNS('pixel coordinates', 8))
 
+
     def wcs_world2pix(self, *args, **kwargs):
         if self.wcs is None:
             raise ValueError("No basic WCS settings were created.")
@@ -1910,10 +2611,10 @@ naxis kwarg.
 
         Parameters
         ----------
-        wcs: `~astropy.wcs.WCS`
+        wcs : `~astropy.wcs.WCS`
             The WCS to have its axes swapped
-        ax0: int
-        ax1: int
+        ax0 : int
+        ax1 : int
             The indices of the WCS to be swapped, counting from 0 (i.e., python
             convention, not FITS convention)
 
@@ -2026,6 +2727,79 @@ naxis kwarg.
             names[i] = types[i].split('-')[0]
         return names
 
+    @property
+    def celestial(self):
+        """
+        A copy of the current WCS with only the celestial axes included
+        """
+        return self.sub([WCSSUB_CELESTIAL])
+
+    @property
+    def is_celestial(self):
+        return self.has_celestial and self.naxis==2
+
+    @property
+    def has_celestial(self):
+        try:
+            return self.celestial.naxis == 2
+        except InconsistentAxisTypesError:
+            return False
+
+    @property
+    def pixel_scale_matrix(self):
+
+        try:
+            cdelt = np.matrix(np.diag(self.wcs.get_cdelt()))
+            pc = np.matrix(self.wcs.get_pc())
+        except InconsistentAxisTypesError:
+            try:
+                # for non-celestial axes, get_cdelt doesn't work
+                cdelt = np.matrix(self.wcs.cd) * np.matrix(np.diag(self.wcs.cdelt))
+            except AttributeError:
+                cdelt = np.matrix(np.diag(self.wcs.cdelt))
+
+            try:
+                pc = np.matrix(self.wcs.pc)
+            except AttributeError:
+                pc = 1
+
+        pccd = np.array(cdelt * pc)
+
+        return pccd
+
+    def _as_mpl_axes(self):
+        """
+        Compatibility hook for Matplotlib and WCSAxes.
+
+        This functionality requires the WCSAxes package to work. The reason
+        we include this here is that it allows users to use WCSAxes without
+        having to explicitly import WCSAxes, which means that if in future we
+        merge WCSAxes into the Astropy core package, the API will remain the
+        same. With this method, one can do:
+
+            from astropy.wcs import WCS
+            import matplotlib.pyplot as plt
+
+            wcs = WCS('filename.fits')
+
+            fig = plt.figure()
+            ax = fig.add_axes([0.15, 0.1, 0.8, 0.8], projection=wcs)
+            ...
+
+        and this will generate a plot with the correct WCS coordinates on the
+        axes. See http://wcsaxes.readthedocs.org for more information.
+        """
+
+        try:
+            from wcsaxes import WCSAxes
+        except ImportError:
+            raise ImportError("Using WCS instances as Matplotlib projections "
+                              "requires the WCSAxes package to be installed. "
+                              "See http://wcsaxes.readthedocs.org for more "
+                              "details.")
+        else:
+            return WCSAxes, {'wcs': self}
+
 
 def __WCS_unpickle__(cls, dct, fits_data):
     """
diff --git a/astropy_helpers/.coveragerc b/astropy_helpers/.coveragerc
new file mode 100644
index 0000000..a7bdfb4
--- /dev/null
+++ b/astropy_helpers/.coveragerc
@@ -0,0 +1,21 @@
+[run]
+source =
+    astropy_helpers
+    ah_bootstrap
+
+omit = astropy_helpers/tests*
+
+[report]
+exclude_lines =
+   # Have to re-enable the standard pragma
+   pragma: no cover
+
+   # Don't complain about packages we have installed
+   except ImportError
+
+   # Don't complain if tests don't hit assertions
+   raise AssertionError
+   raise NotImplementedError
+
+   # Don't complain about script hooks
+   def main\(.*\):
diff --git a/astropy_helpers/.travis.yml b/astropy_helpers/.travis.yml
new file mode 100644
index 0000000..54c885a
--- /dev/null
+++ b/astropy_helpers/.travis.yml
@@ -0,0 +1,57 @@
+# We set the language to c because python isn't supported on the MacOS X nodes
+# on Travis. However, the language ends up being irrelevant anyway, since we
+# install Python ourselves using conda.
+language: c
+
+os:
+    - osx
+    - linux
+
+env:
+  matrix:
+    - PYTHON_VERSION=2.6
+    - PYTHON_VERSION=2.7
+    - PYTHON_VERSION=3.3
+    - PYTHON_VERSION=3.4
+  global:
+      - SETUPTOOLS_VERSION=stable
+
+matrix:
+    include:
+        - os: linux
+          env: PYTHON_VERSION=2.7 SETUPTOOLS_VERSION=dev
+
+before_install:
+
+    # Use utf8 encoding. Should be default, but this is insurance against
+    # future changes
+    - export PYTHONIOENCODING=UTF8
+
+    # Install conda
+    - source continuous-integration/travis/install_conda_$TRAVIS_OS_NAME.sh
+
+    # Install graphviz
+    - source continuous-integration/travis/install_graphviz_$TRAVIS_OS_NAME.sh
+
+install:
+    - conda create --yes -n test python=$PYTHON_VERSION
+    - source activate test
+    - conda install --yes pip "pytest<2.6" sphinx cython numpy
+    - pip install coveralls pytest-cov
+    # We cannot install the developer version of setuptools using pip because
+    # pip tries to remove the previous version of setuptools before the
+    # installation is complete, which causes issues. Instead, we just install
+    # setuptools manually.
+    - if [[ $SETUPTOOLS_VERSION == dev ]]; then conda install --yes mercurial mock; fi
+    - if [[ $SETUPTOOLS_VERSION == dev ]]; then hg clone https://bitbucket.org/pypa/setuptools; cd setuptools; python setup.py install; cd ..; fi
+
+before_script:
+    # Some of the tests use git commands that require a user to be configured
+    - git config --global user.name "A U Thor"
+    - git config --global user.email "author at example.com"
+
+script:
+    - py.test --cov astropy_helpers astropy_helpers
+
+after_success:
+    - coveralls
diff --git a/astropy_helpers/CHANGES.rst b/astropy_helpers/CHANGES.rst
new file mode 100644
index 0000000..d374280
--- /dev/null
+++ b/astropy_helpers/CHANGES.rst
@@ -0,0 +1,156 @@
+astropy-helpers Changelog
+=========================
+
+
+0.5 (unreleased)
+----------------
+
+- Added new pre-/post-command hook points for ``setup.py`` commands.  Now any
+  package can define code to run before and/or after any ``setup.py`` command
+  without having to manually subclass that command by adding
+  ``pre_<command_name>_hook`` and ``post_<command_name>_hook`` callables to
+  the package's ``setup_package.py`` module.  See the PR for more details.
+  [#112]
+
+- The following objects in the ``astropy_helpers.setup_helpers`` module have
+  been relocated:
+
+  - ``get_dummy_distribution``, ``get_distutils_*``, ``get_compiler_option``,
+    ``add_command_option``, ``is_distutils_display_option`` ->
+    ``astropy_helpers.distutils_helpers``
+
+  - ``should_build_with_cython``, ``generate_build_ext_command`` ->
+    ``astropy_helpers.commands.build_ext``
+
+  - ``AstropyBuildPy`` -> ``astropy_helpers.commands.build_py``
+
+  - ``AstropyBuildSphinx`` -> ``astropy_helpers.commands.build_sphinx``
+
+  - ``AstropyInstall`` -> ``astropy_helpers.commands.install``
+
+  - ``AstropyInstallLib`` -> ``astropy_helpers.commands.install_lib``
+
+  - ``AstropyRegister`` -> ``astropy_helpers.commands.register``
+
+  - ``get_pkg_version_module`` -> ``astropy_helpers.version_helpers``
+
+  - ``write_if_different``, ``import_file``, ``get_numpy_include_path`` ->
+    ``astropy_helpers.utils``
+
+  All of these are "soft" deprecations in the sense that they are still
+  importable from ``astropy_helpers.setup_helpers`` for now, and there is
+  no (easy) way to produce deprecation warnings when importing these objects
+  from ``setup_helpers`` rather than directly from the modules they are
+  defined in.  But please consider updating any imports to these objects.
+  [#110]
+
+- Use of the ``astropy.sphinx.ext.astropyautosummary`` extension is deprecated
+  for use with Sphinx < 1.2.  Instead it should suffice to remove this
+  extension for the ``extensions`` list in your ``conf.py`` and add the stock
+  ``sphinx.ext.autosummary`` instead. [#131]
+
+
+0.4.5 (unreleased)
+------------------
+
+- Added some additional object reference link corrections for Python 3
+  when building docs. [#123]
+
+- Added a workaround for documentation of properties in the rare case
+  where the class's metaclass has a property of the same name. [#130]
+
+
+0.4.4 (2014-12-31)
+------------------
+
+- More improvements for building the documentation using Python 3.x. [#100]
+
+- Additional minor fixes to Python 3 support. [#115]
+
+- Updates to support new test features in Astropy [#92, #106]
+
+
+0.4.3 (2014-10-22)
+------------------
+
+- The generated ``version.py`` file now preserves the git hash of installed
+  copies of the package as well as when building a source distribution.  That
+  is, the git hash of the changeset that was installed/released is preserved.
+  [#87]
+
+- In smart resolver add resolution for class links when they exist in the
+  intersphinx inventory, but not the mapping of the current package
+  (e.g. when an affiliated package uses an astropy core class of which
+  "actual" and "documented" location differs) [#88]
+
+- Fixed a bug that could occur when running ``setup.py`` for the first time
+  in a repository that uses astropy-helpers as a submodule:
+  ``AttributeError: 'NoneType' object has no attribute 'mkdtemp'`` [#89]
+
+- Fixed a bug where optional arguments to the ``doctest-skip`` Sphinx
+  directive were sometimes being left in the generated documentation output.
+  [#90]
+
+- Improved support for building the documentation using Python 3.x. [#96]
+
+- Avoid error message if .git directory is not present. [#91]
+
+
+0.4.2 (2014-08-09)
+------------------
+
+- Fixed some CSS issues in generated API docs. [#69]
+
+- Fixed the warning message that could be displayed when generating a
+  version number with some older versions of git. [#77]
+
+- Fixed automodsumm to work with new versions of Sphinx (>= 1.2.2). [#80]
+
+
+0.4.1 (2014-08-08)
+------------------
+
+- Fixed git revision count on systems with git versions older than v1.7.2.
+  [#70]
+
+- Fixed display of warning text when running a git command fails (previously
+  the output of stderr was not being decoded properly). [#70]
+
+- The ``--offline`` flag to ``setup.py`` understood by ``ah_bootstrap.py``
+  now also prevents git from going online to fetch submodule updates. [#67]
+
+- The Sphinx extension for converting issue numbers to links in the changelog
+  now supports working on arbitrary pages via a new ``conf.py`` setting:
+  ``changelog_links_docpattern``.  By default it affects the ``changelog``
+  and ``whatsnew`` pages in one's Sphinx docs. [#61]
+
+- Fixed crash that could result from users with missing/misconfigured
+  locale settings. [#58]
+
+- The font used for code examples in the docs is now the
+  system-defined ``monospace`` font, rather than ``Minaco``, which is
+  not available on all platforms. [#50]
+
+
+0.4 (2014-07-15)
+----------------
+
+- Initial release of astropy-helpers.  See `APE4
+  <https://github.com/astropy/astropy-APEs/blob/master/APE4.rst>`_ for
+  details of the motivation and design of this package.
+
+- The ``astropy_helpers`` package replaces the following modules in the
+  ``astropy`` package:
+
+  - ``astropy.setup_helpers`` -> ``astropy_helpers.setup_helpers``
+
+  - ``astropy.version_helpers`` -> ``astropy_helpers.version_helpers``
+
+  - ``astropy.sphinx`` - > ``astropy_helpers.sphinx``
+
+  These modules should be considered deprecated in ``astropy``, and any new,
+  non-critical changes to those modules will be made in ``astropy_helpers``
+  instead.  Affiliated packages wishing to make use those modules (as in the
+  Astropy package-template) should use the versions from ``astropy_helpers``
+  instead, and include the ``ah_bootstrap.py`` script in their project, for
+  bootstrapping the ``astropy_helpers`` package in their setup.py script.
diff --git a/astropy_helpers/CONTRIBUTING.md b/astropy_helpers/CONTRIBUTING.md
new file mode 100644
index 0000000..de6973c
--- /dev/null
+++ b/astropy_helpers/CONTRIBUTING.md
@@ -0,0 +1,20 @@
+Contributing to astropy-helpers
+===============================
+
+The guidelines for contributing to ``astropy-helpers`` are generally the same
+as the [contributing guidelines for the astropy core
+package](http://github.com/astropy/astropy/blob/master/CONTRIBUTING.md).
+Basically, report relevant issues in the ``astropy-helpers`` issue tracker, and
+we welcome pull requests that broadly follow the [Astropy coding
+guidelines](http://docs.astropy.org/en/latest/development/codeguide.html).
+
+The key subtlety lies in understanding the relationship between ``astropy`` and
+``astropy-helpers``.  This package contains the build, installation, and
+documentation tools used by astropy.  It also includes support for the
+``setup.py test`` command, though Astropy is still required for this to
+function (it does not currently include the full Astropy test runner).  So
+issues or improvements to that functionality should be addressed in this
+package. Any other aspect of the [astropy core
+package](http://github.com/astropy/astropy) (or any other package that uses
+``astropy-helpers``) should be addressed in the github repository for that
+package.
diff --git a/astropy_helpers/LICENSE.rst b/astropy_helpers/LICENSE.rst
new file mode 100644
index 0000000..b618744
--- /dev/null
+++ b/astropy_helpers/LICENSE.rst
@@ -0,0 +1,26 @@
+Copyright (c) 2014, Astropy Developers
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+* Neither the name of the Astropy Team nor the names of its contributors may be
+  used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/astropy_helpers/MANIFEST.in b/astropy_helpers/MANIFEST.in
new file mode 100644
index 0000000..b12416c
--- /dev/null
+++ b/astropy_helpers/MANIFEST.in
@@ -0,0 +1,10 @@
+include README.rst
+include CHANGES.rst
+include LICENSE.rst
+
+include ez_setup.py
+include ah_bootstrap.py
+
+exclude *.pyc *.o
+prune build
+prune astropy_helpers/tests
diff --git a/astropy_helpers/README.rst b/astropy_helpers/README.rst
new file mode 100644
index 0000000..cbf7faf
--- /dev/null
+++ b/astropy_helpers/README.rst
@@ -0,0 +1,32 @@
+astropy-helpers
+===============
+
+This project provides a Python package, ``astropy_helpers``, which includes
+many build, installation, and documentation-related tools used by the Astropy
+project, but packaged separately for use by other projects that wish to
+leverage this work.  The motivation behind this package and details of its
+implementation are in the accepted 
+`Astropy Proposal for Enhancement (APE) 4 <https://github.com/astropy/astropy-APEs/blob/master/APE4.rst>`_.
+
+``astropy_helpers`` includes a special "bootstrap" module called
+``ah_bootstrap.py`` which is intended to be used by a project's setup.py in
+order to ensure that the ``astropy_helpers`` package is available for
+build/installation.  This is similar to the ``ez_setup.py`` module that is
+shipped with some projects to bootstrap `setuptools
+<https://bitbucket.org/pypa/setuptools>`_.
+
+As described in APE4, the version numbers for ``astropy_helpers`` follow the
+corresponding major/minor version of the `astropy core package
+<http://www.astropy.org/>`_, but with an independent sequence of micro (bugfix)
+version numbers. Hence, the initial release is 0.4, in parallel with Astropy
+v0.4, which will be the first version  of Astropy to use ``astropy-helpers``.
+
+For examples of how to implement ``astropy-helpers`` in a project,
+see the ``setup.py`` and ``setup.cfg`` files of the 
+`Affiliated package template <https://github.com/astropy/package-template>`_.
+
+.. image:: https://travis-ci.org/astropy/astropy-helpers.png
+    :target: https://travis-ci.org/astropy/astropy-helpers
+
+.. image:: https://coveralls.io/repos/astropy/astropy-helpers/badge.png
+    :target: https://coveralls.io/r/astropy/astropy-helpers
diff --git a/astropy_helpers/ah_bootstrap.py b/astropy_helpers/ah_bootstrap.py
new file mode 100644
index 0000000..6281e4f
--- /dev/null
+++ b/astropy_helpers/ah_bootstrap.py
@@ -0,0 +1,897 @@
+"""
+This bootstrap module contains code for ensuring that the astropy_helpers
+package will be importable by the time the setup.py script runs.  It also
+includes some workarounds to ensure that a recent-enough version of setuptools
+is being used for the installation.
+
+This module should be the first thing imported in the setup.py of distributions
+that make use of the utilities in astropy_helpers.  If the distribution ships
+with its own copy of astropy_helpers, this module will first attempt to import
+from the shipped copy.  However, it will also check PyPI to see if there are
+any bug-fix releases on top of the current version that may be useful to get
+past platform-specific bugs that have been fixed.  When running setup.py, use
+the ``--offline`` command-line option to disable the auto-upgrade checks.
+
+When this module is imported or otherwise executed it automatically calls a
+main function that attempts to read the project's setup.cfg file, which it
+checks for a configuration section called ``[ah_bootstrap]`` the presences of
+that section, and options therein, determine the next step taken:  If it
+contains an option called ``auto_use`` with a value of ``True``, it will
+automatically call the main function of this module called
+`use_astropy_helpers` (see that function's docstring for full details).
+Otherwise no further action is taken (however,
+``ah_bootstrap.use_astropy_helpers`` may be called manually from within the
+setup.py script).
+
+Additional options in the ``[ah_boostrap]`` section of setup.cfg have the same
+names as the arguments to `use_astropy_helpers`, and can be used to configure
+the bootstrap script when ``auto_use = True``.
+
+See https://github.com/astropy/astropy-helpers for more details, and for the
+latest version of this module.
+"""
+
+import contextlib
+import errno
+import imp
+import io
+import locale
+import os
+import re
+import subprocess as sp
+import sys
+
+try:
+    from ConfigParser import ConfigParser, RawConfigParser
+except ImportError:
+    from configparser import ConfigParser, RawConfigParser
+
+
+if sys.version_info[0] < 3:
+    _str_types = (str, unicode)
+    _text_type = unicode
+    PY3 = False
+else:
+    _str_types = (str, bytes)
+    _text_type = str
+    PY3 = True
+
+# Some pre-setuptools checks to ensure that either distribute or setuptools >=
+# 0.7 is used (over pre-distribute setuptools) if it is available on the path;
+# otherwise the latest setuptools will be downloaded and bootstrapped with
+# ``ez_setup.py``.  This used to be included in a separate file called
+# setuptools_bootstrap.py; but it was combined into ah_bootstrap.py
+try:
+    import pkg_resources
+    _setuptools_req = pkg_resources.Requirement.parse('setuptools>=0.7')
+    # This may raise a DistributionNotFound in which case no version of
+    # setuptools or distribute is properly installed
+    _setuptools = pkg_resources.get_distribution('setuptools')
+    if _setuptools not in _setuptools_req:
+        # Older version of setuptools; check if we have distribute; again if
+        # this results in DistributionNotFound we want to give up
+        _distribute = pkg_resources.get_distribution('distribute')
+        if _setuptools != _distribute:
+            # It's possible on some pathological systems to have an old version
+            # of setuptools and distribute on sys.path simultaneously; make
+            # sure distribute is the one that's used
+            sys.path.insert(1, _distribute.location)
+            _distribute.activate()
+            imp.reload(pkg_resources)
+except:
+    # There are several types of exceptions that can occur here; if all else
+    # fails bootstrap and use the bootstrapped version
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+from distutils import log
+from distutils.debug import DEBUG
+
+
+# In case it didn't successfully import before the ez_setup checks
+import pkg_resources
+
+from setuptools import Distribution
+from setuptools.package_index import PackageIndex
+from setuptools.sandbox import run_setup
+
+# Note: The following import is required as a workaround to
+# https://github.com/astropy/astropy-helpers/issues/89; if we don't import this
+# module now, it will get cleaned up after `run_setup` is called, but that will
+# later cause the TemporaryDirectory class defined in it to stop working when
+# used later on by setuptools
+try:
+    import setuptools.py31compat
+except ImportError:
+    pass
+
+# TODO: Maybe enable checking for a specific version of astropy_helpers?
+DIST_NAME = 'astropy-helpers'
+PACKAGE_NAME = 'astropy_helpers'
+
+# Defaults for other options
+DOWNLOAD_IF_NEEDED = True
+INDEX_URL = 'https://pypi.python.org/simple'
+USE_GIT = True
+OFFLINE = False
+AUTO_UPGRADE = True
+
+# A list of all the configuration options and their required types
+CFG_OPTIONS = [
+    ('auto_use', bool), ('path', str), ('download_if_needed', bool),
+    ('index_url', str), ('use_git', bool), ('offline', bool),
+    ('auto_upgrade', bool)
+]
+
+
+class _Bootstrapper(object):
+    """
+    Bootstrapper implementation.  See ``use_astropy_helpers`` for parameter
+    documentation.
+    """
+
+    def __init__(self, path=None, index_url=None, use_git=None, offline=None,
+                 download_if_needed=None, auto_upgrade=None):
+
+        if path is None:
+            path = PACKAGE_NAME
+
+        if not (isinstance(path, _str_types) or path is False):
+            raise TypeError('path must be a string or False')
+
+        if PY3 and not isinstance(path, _text_type):
+            fs_encoding = sys.getfilesystemencoding()
+            path = path.decode(fs_encoding)  # path to unicode
+
+        self.path = path
+
+        # Set other option attributes, using defaults where necessary
+        self.index_url = index_url if index_url is not None else INDEX_URL
+        self.offline = offline if offline is not None else OFFLINE
+
+        # If offline=True, override download and auto-upgrade
+        if self.offline:
+            download_if_needed = False
+            auto_upgrade = False
+
+        self.download = (download_if_needed
+                         if download_if_needed is not None
+                         else DOWNLOAD_IF_NEEDED)
+        self.auto_upgrade = (auto_upgrade
+                             if auto_upgrade is not None else AUTO_UPGRADE)
+
+        # If this is a release then the .git directory will not exist so we
+        # should not use git.
+        git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git'))
+        if use_git is None and not git_dir_exists:
+            use_git = False
+
+        self.use_git = use_git if use_git is not None else USE_GIT
+        # Declared as False by default--later we check if astropy-helpers can be
+        # upgraded from PyPI, but only if not using a source distribution (as in
+        # the case of import from a git submodule)
+        self.is_submodule = False
+
+    @classmethod
+    def main(cls, argv=None):
+        if argv is None:
+            argv = sys.argv
+
+        config = cls.parse_config()
+        config.update(cls.parse_command_line(argv))
+
+        auto_use = config.pop('auto_use', False)
+        bootstrapper = cls(**config)
+
+        if auto_use:
+            # Run the bootstrapper, otherwise the setup.py is using the old
+            # use_astropy_helpers() interface, in which case it will run the
+            # bootstrapper manually after reconfiguring it.
+            bootstrapper.run()
+
+        return bootstrapper
+
+    @classmethod
+    def parse_config(cls):
+        if not os.path.exists('setup.cfg'):
+            return {}
+
+        cfg = ConfigParser()
+
+        try:
+            cfg.read('setup.cfg')
+        except Exception as e:
+            if DEBUG:
+                raise
+
+            log.error(
+                "Error reading setup.cfg: {0!r}\n{1} will not be "
+                "automatically bootstrapped and package installation may fail."
+                "\n{2}".format(e, PACKAGE_NAME, _err_help_msg))
+            return {}
+
+        if not cfg.has_section('ah_bootstrap'):
+            return {}
+
+        config = {}
+
+        for option, type_ in CFG_OPTIONS:
+            if not cfg.has_option('ah_bootstrap', option):
+                continue
+
+            if type_ is bool:
+                value = cfg.getboolean('ah_bootstrap', option)
+            else:
+                value = cfg.get('ah_bootstrap', option)
+
+            config[option] = value
+
+        return config
+
+    @classmethod
+    def parse_command_line(cls, argv=None):
+        if argv is None:
+            argv = sys.argv
+
+        config = {}
+
+        # For now we just pop recognized ah_bootstrap options out of the
+        # arg list.  This is imperfect; in the unlikely case that a setup.py
+        # custom command or even custom Distribution class defines an argument
+        # of the same name then we will break that.  However there's a catch22
+        # here that we can't just do full argument parsing right here, because
+        # we don't yet know *how* to parse all possible command-line arguments.
+        if '--no-git' in argv:
+            config['use_git'] = False
+            argv.remove('--no-git')
+
+        if '--offline' in argv:
+            config['offline'] = True
+            argv.remove('--offline')
+
+        return config
+
+    def run(self):
+        strategies = ['local_directory', 'local_file', 'index']
+        dist = None
+
+        # Check to see if the path is a submodule
+        self.is_submodule = self._check_submodule()
+
+        for strategy in strategies:
+            method = getattr(self, 'get_{0}_dist'.format(strategy))
+            dist = method()
+            if dist is not None:
+                break
+        else:
+            raise _AHBootstrapSystemExit(
+                "No source found for the {0!r} package; {0} must be "
+                "available and importable as a prerequisite to building "
+                "or installing this package.".format(PACKAGE_NAME))
+
+        # Otherwise we found a version of astropy-helpers, so we're done
+        # Just active the found distribution on sys.path--if we did a
+        # download this usually happens automatically but it doesn't hurt to
+        # do it again
+        # Note: Adding the dist to the global working set also activates it
+        # (makes it importable on sys.path) by default
+        pkg_resources.working_set.add(dist)
+
+    @property
+    def config(self):
+        """
+        A `dict` containing the options this `_Bootstrapper` was configured
+        with.
+        """
+
+        return dict((optname, getattr(self, optname))
+                    for optname, _ in CFG_OPTIONS if hasattr(self, optname))
+
+    def get_local_directory_dist(self):
+        """
+        Handle importing a vendored package from a subdirectory of the source
+        distribution.
+        """
+
+        if not os.path.isdir(self.path):
+            return
+
+        log.info('Attempting to import astropy_helpers from {0} {1!r}'.format(
+                 'submodule' if self.is_submodule else 'directory',
+                 self.path))
+
+        dist = self._directory_import()
+
+        if dist is None:
+            log.warn(
+                'The requested path {0!r} for importing {1} does not '
+                'exist, or does not contain a copy of the {1} '
+                'package.'.format(self.path, PACKAGE_NAME))
+        elif self.auto_upgrade and not self.is_submodule:
+            # A version of astropy-helpers was found on the available path, but
+            # check to see if a bugfix release is available on PyPI
+            upgrade = self._do_upgrade(dist)
+            if upgrade is not None:
+                dist = upgrade
+
+        return dist
+
+    def get_local_file_dist(self):
+        """
+        Handle importing from a source archive; this also uses setup_requires
+        but points easy_install directly to the source archive.
+        """
+
+        if not os.path.isfile(self.path):
+            return
+
+        log.info('Attempting to unpack and import astropy_helpers from '
+                 '{0!r}'.format(self.path))
+
+        try:
+            dist = self._do_download(find_links=[self.path])
+        except Exception as e:
+            if DEBUG:
+                raise
+
+            log.warn(
+                'Failed to import {0} from the specified archive {1!r}: '
+                '{2}'.format(PACKAGE_NAME, self.path, str(e)))
+            dist = None
+
+        if dist is not None and self.auto_upgrade:
+            # A version of astropy-helpers was found on the available path, but
+            # check to see if a bugfix release is available on PyPI
+            upgrade = self._do_upgrade(dist)
+            if upgrade is not None:
+                dist = upgrade
+
+        return dist
+
+    def get_index_dist(self):
+        if not self.download:
+            log.warn('Downloading {0!r} disabled.'.format(DIST_NAME))
+            return False
+
+        log.warn(
+            "Downloading {0!r}; run setup.py with the --offline option to "
+            "force offline installation.".format(DIST_NAME))
+
+        try:
+            dist = self._do_download()
+        except Exception as e:
+            if DEBUG:
+                raise
+            log.warn(
+                'Failed to download and/or install {0!r} from {1!r}:\n'
+                '{2}'.format(DIST_NAME, self.index_url, str(e)))
+            dist = None
+
+        # No need to run auto-upgrade here since we've already presumably
+        # gotten the most up-to-date version from the package index
+        return dist
+
+    def _directory_import(self):
+        """
+        Import astropy_helpers from the given path, which will be added to
+        sys.path.
+
+        Must return True if the import succeeded, and False otherwise.
+        """
+
+        # Return True on success, False on failure but download is allowed, and
+        # otherwise raise SystemExit
+        path = os.path.abspath(self.path)
+
+        # Use an empty WorkingSet rather than the man
+        # pkg_resources.working_set, since on older versions of setuptools this
+        # will invoke a VersionConflict when trying to install an upgrade
+        ws = pkg_resources.WorkingSet([])
+        ws.add_entry(path)
+        dist = ws.by_key.get(DIST_NAME)
+
+        if dist is None:
+            # We didn't find an egg-info/dist-info in the given path, but if a
+            # setup.py exists we can generate it
+            setup_py = os.path.join(path, 'setup.py')
+            if os.path.isfile(setup_py):
+                with _silence():
+                    run_setup(os.path.join(path, 'setup.py'),
+                              ['egg_info'])
+
+                for dist in pkg_resources.find_distributions(path, True):
+                    # There should be only one...
+                    return dist
+
+        return dist
+
+    def _do_download(self, version='', find_links=None):
+        if find_links:
+            allow_hosts = ''
+            index_url = None
+        else:
+            allow_hosts = None
+            index_url = self.index_url
+
+        # Annoyingly, setuptools will not handle other arguments to
+        # Distribution (such as options) before handling setup_requires, so it
+        # is not straightforward to programmatically augment the arguments which
+        # are passed to easy_install
+        class _Distribution(Distribution):
+            def get_option_dict(self, command_name):
+                opts = Distribution.get_option_dict(self, command_name)
+                if command_name == 'easy_install':
+                    if find_links is not None:
+                        opts['find_links'] = ('setup script', find_links)
+                    if index_url is not None:
+                        opts['index_url'] = ('setup script', index_url)
+                    if allow_hosts is not None:
+                        opts['allow_hosts'] = ('setup script', allow_hosts)
+                return opts
+
+        if version:
+            req = '{0}=={1}'.format(DIST_NAME, version)
+        else:
+            req = DIST_NAME
+
+        attrs = {'setup_requires': [req]}
+
+        try:
+            if DEBUG:
+                _Distribution(attrs=attrs)
+            else:
+                with _silence():
+                    _Distribution(attrs=attrs)
+
+            # If the setup_requires succeeded it will have added the new dist to
+            # the main working_set
+            return pkg_resources.working_set.by_key.get(DIST_NAME)
+        except Exception as e:
+            if DEBUG:
+                raise
+
+            msg = 'Error retrieving {0} from {1}:\n{2}'
+            if find_links:
+                source = find_links[0]
+            elif index_url != INDEX_URL:
+                source = index_url
+            else:
+                source = 'PyPI'
+
+            raise Exception(msg.format(DIST_NAME, source, repr(e)))
+
+    def _do_upgrade(self, dist):
+        # Build up a requirement for a higher bugfix release but a lower minor
+        # release (so API compatibility is guaranteed)
+        # sketchy version parsing--maybe come up with something a bit more
+        # robust for this
+        major, minor = (int(part) for part in dist.parsed_version[:2])
+        next_minor = '.'.join([str(major), str(minor + 1), '0'])
+        req = pkg_resources.Requirement.parse(
+            '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_minor))
+
+        package_index = PackageIndex(index_url=self.index_url)
+
+        upgrade = package_index.obtain(req)
+
+        if upgrade is not None:
+            return self._do_download(version=upgrade.version)
+
+    def _check_submodule(self):
+        """
+        Check if the given path is a git submodule.
+
+        See the docstrings for ``_check_submodule_using_git`` and
+        ``_check_submodule_no_git`` for further details.
+        """
+
+        if (self.path is None or
+                (os.path.exists(self.path) and not os.path.isdir(self.path))):
+            return False
+
+        if self.use_git:
+            return self._check_submodule_using_git()
+        else:
+            return self._check_submodule_no_git()
+
+    def _check_submodule_using_git(self):
+        """
+        Check if the given path is a git submodule.  If so, attempt to initialize
+        and/or update the submodule if needed.
+
+        This function makes calls to the ``git`` command in subprocesses.  The
+        ``_check_submodule_no_git`` option uses pure Python to check if the given
+        path looks like a git submodule, but it cannot perform updates.
+        """
+
+        cmd = ['git', 'submodule', 'status', '--', self.path]
+
+        try:
+            log.info('Running `{0}`; use the --no-git option to disable git '
+                     'commands'.format(' '.join(cmd)))
+            returncode, stdout, stderr = run_cmd(cmd)
+        except _CommandNotFound:
+            # The git command simply wasn't found; this is most likely the
+            # case on user systems that don't have git and are simply
+            # trying to install the package from PyPI or a source
+            # distribution.  Silently ignore this case and simply don't try
+            # to use submodules
+            return False
+
+        stderr = stderr.strip()
+
+        if returncode != 0 and stderr:
+            # Unfortunately the return code alone cannot be relied on, as
+            # earlier versions of git returned 0 even if the requested submodule
+            # does not exist
+
+            # This is a warning that occurs in perl (from running git submodule)
+            # which only occurs with a malformatted locale setting which can
+            # happen sometimes on OSX.  See again
+            # https://github.com/astropy/astropy/issues/2749
+            perl_warning = ('perl: warning: Falling back to the standard locale '
+                            '("C").')
+            if not stderr.strip().endswith(perl_warning):
+                # Some other uknown error condition occurred
+                log.warn('git submodule command failed '
+                         'unexpectedly:\n{0}'.format(stderr))
+                return False
+
+        # Output of `git submodule status` is as follows:
+        #
+        # 1: Status indicator: '-' for submodule is uninitialized, '+' if
+        # submodule is initialized but is not at the commit currently indicated
+        # in .gitmodules (and thus needs to be updated), or 'U' if the
+        # submodule is in an unstable state (i.e. has merge conflicts)
+        #
+        # 2. SHA-1 hash of the current commit of the submodule (we don't really
+        # need this information but it's useful for checking that the output is
+        # correct)
+        #
+        # 3. The output of `git describe` for the submodule's current commit
+        # hash (this includes for example what branches the commit is on) but
+        # only if the submodule is initialized.  We ignore this information for
+        # now
+        _git_submodule_status_re = re.compile(
+            '^(?P<status>[+-U ])(?P<commit>[0-9a-f]{40}) '
+            '(?P<submodule>\S+)( .*)?$')
+
+        # The stdout should only contain one line--the status of the
+        # requested submodule
+        m = _git_submodule_status_re.match(stdout)
+        if m:
+            # Yes, the path *is* a git submodule
+            self._update_submodule(m.group('submodule'), m.group('status'))
+            return True
+        else:
+            log.warn(
+                'Unexpected output from `git submodule status`:\n{0}\n'
+                'Will attempt import from {1!r} regardless.'.format(
+                    stdout, self.path))
+            return False
+
+    def _check_submodule_no_git(self):
+        """
+        Like ``_check_submodule_using_git``, but simply parses the .gitmodules file
+        to determine if the supplied path is a git submodule, and does not exec any
+        subprocesses.
+
+        This can only determine if a path is a submodule--it does not perform
+        updates, etc.  This function may need to be updated if the format of the
+        .gitmodules file is changed between git versions.
+        """
+
+        gitmodules_path = os.path.abspath('.gitmodules')
+
+        if not os.path.isfile(gitmodules_path):
+            return False
+
+        # This is a minimal reader for gitconfig-style files.  It handles a few of
+        # the quirks that make gitconfig files incompatible with ConfigParser-style
+        # files, but does not support the full gitconfig syntax (just enough
+        # needed to read a .gitmodules file).
+        gitmodules_fileobj = io.StringIO()
+
+        # Must use io.open for cross-Python-compatible behavior wrt unicode
+        with io.open(gitmodules_path) as f:
+            for line in f:
+                # gitconfig files are more flexible with leading whitespace; just
+                # go ahead and remove it
+                line = line.lstrip()
+
+                # comments can start with either # or ;
+                if line and line[0] in (':', ';'):
+                    continue
+
+                gitmodules_fileobj.write(line)
+
+        gitmodules_fileobj.seek(0)
+
+        cfg = RawConfigParser()
+
+        try:
+            cfg.readfp(gitmodules_fileobj)
+        except Exception as exc:
+            log.warn('Malformatted .gitmodules file: {0}\n'
+                     '{1} cannot be assumed to be a git submodule.'.format(
+                         exc, self.path))
+            return False
+
+        for section in cfg.sections():
+            if not cfg.has_option(section, 'path'):
+                continue
+
+            submodule_path = cfg.get(section, 'path').rstrip(os.sep)
+
+            if submodule_path == self.path.rstrip(os.sep):
+                return True
+
+        return False
+
+    def _update_submodule(self, submodule, status):
+        if status == ' ':
+            # The submodule is up to date; no action necessary
+            return
+        elif status == '-':
+            if self.offline:
+                raise _AHBootstrapSystemExit(
+                    "Cannot initialize the {0} submodule in --offline mode; "
+                    "this requires being able to clone the submodule from an "
+                    "online repository.".format(submodule))
+            cmd = ['update', '--init']
+            action = 'Initializing'
+        elif status == '+':
+            cmd = ['update']
+            action = 'Updating'
+            if self.offline:
+                cmd.append('--no-fetch')
+        elif status == 'U':
+            raise _AHBoostrapSystemExit(
+                'Error: Submodule {0} contains unresolved merge conflicts.  '
+                'Please complete or abandon any changes in the submodule so that '
+                'it is in a usable state, then try again.'.format(submodule))
+        else:
+            log.warn('Unknown status {0!r} for git submodule {1!r}.  Will '
+                     'attempt to use the submodule as-is, but try to ensure '
+                     'that the submodule is in a clean state and contains no '
+                     'conflicts or errors.\n{2}'.format(status, submodule,
+                                                        _err_help_msg))
+            return
+
+        err_msg = None
+        cmd = ['git', 'submodule'] + cmd + ['--', submodule]
+        log.warn('{0} {1} submodule with: `{2}`'.format(
+            action, submodule, ' '.join(cmd)))
+
+        try:
+            log.info('Running `{0}`; use the --no-git option to disable git '
+                     'commands'.format(' '.join(cmd)))
+            returncode, stdout, stderr = run_cmd(cmd)
+        except OSError as e:
+            err_msg = str(e)
+        else:
+            if returncode != 0:
+                err_msg = stderr
+
+        if err_msg is not None:
+            log.warn('An unexpected error occurred updating the git submodule '
+                     '{0!r}:\n{1}\n{2}'.format(submodule, err_msg,
+                                               _err_help_msg))
+
+class _CommandNotFound(OSError):
+    """
+    An exception raised when a command run with run_cmd is not found on the
+    system.
+    """
+
+
+def run_cmd(cmd):
+    """
+    Run a command in a subprocess, given as a list of command-line
+    arguments.
+
+    Returns a ``(returncode, stdout, stderr)`` tuple.
+    """
+
+    try:
+        p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
+        # XXX: May block if either stdout or stderr fill their buffers;
+        # however for the commands this is currently used for that is
+        # unlikely (they should have very brief output)
+        stdout, stderr = p.communicate()
+    except OSError as e:
+        if DEBUG:
+            raise
+
+        if e.errno == errno.ENOENT:
+            msg = 'Command not found: `{0}`'.format(' '.join(cmd))
+            raise _CommandNotFound(msg, cmd)
+        else:
+            raise _AHBoostrapSystemExit(
+                'An unexpected error occurred when running the '
+                '`{0}` command:\n{1}'.format(' '.join(cmd), str(e)))
+
+
+    # Can fail of the default locale is not configured properly.  See
+    # https://github.com/astropy/astropy/issues/2749.  For the purposes under
+    # consideration 'latin1' is an acceptable fallback.
+    try:
+        stdio_encoding = locale.getdefaultlocale()[1] or 'latin1'
+    except ValueError:
+        # Due to an OSX oddity locale.getdefaultlocale() can also crash
+        # depending on the user's locale/language settings.  See:
+        # http://bugs.python.org/issue18378
+        stdio_encoding = 'latin1'
+
+    # Unlikely to fail at this point but even then let's be flexible
+    if not isinstance(stdout, _text_type):
+        stdout = stdout.decode(stdio_encoding, 'replace')
+    if not isinstance(stderr, _text_type):
+        stderr = stderr.decode(stdio_encoding, 'replace')
+
+    return (p.returncode, stdout, stderr)
+
+
+class _DummyFile(object):
+    """A noop writeable object."""
+
+    errors = ''  # Required for Python 3.x
+    encoding = 'utf-8'
+
+    def write(self, s):
+        pass
+
+    def flush(self):
+        pass
+
+
+ at contextlib.contextmanager
+def _silence():
+    """A context manager that silences sys.stdout and sys.stderr."""
+
+    old_stdout = sys.stdout
+    old_stderr = sys.stderr
+    sys.stdout = _DummyFile()
+    sys.stderr = _DummyFile()
+    exception_occurred = False
+    try:
+        yield
+    except:
+        exception_occurred = True
+        # Go ahead and clean up so that exception handling can work normally
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+        raise
+
+    if not exception_occurred:
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+
+
+_err_help_msg = """
+If the problem persists consider installing astropy_helpers manually using pip
+(`pip install astropy_helpers`) or by manually downloading the source archive,
+extracting it, and installing by running `python setup.py install` from the
+root of the extracted source code.
+"""
+
+
+class _AHBootstrapSystemExit(SystemExit):
+    def __init__(self, *args):
+        if not args:
+            msg = 'An unknown problem occurred bootstrapping astropy_helpers.'
+        else:
+            msg = args[0]
+
+        msg += '\n' + _err_help_msg
+
+        super(_AHBootstrapSystemExit, self).__init__(msg, *args[1:])
+
+
+if sys.version_info[:2] < (2, 7):
+    # In Python 2.6 the distutils log does not log warnings, errors, etc. to
+    # stderr so we have to wrap it to ensure consistency at least in this
+    # module
+    import distutils
+
+    class log(object):
+        def __getattr__(self, attr):
+            return getattr(distutils.log, attr)
+
+        def warn(self, msg, *args):
+            self._log_to_stderr(distutils.log.WARN, msg, *args)
+
+        def error(self, msg):
+            self._log_to_stderr(distutils.log.ERROR, msg, *args)
+
+        def fatal(self, msg):
+            self._log_to_stderr(distutils.log.FATAL, msg, *args)
+
+        def log(self, level, msg, *args):
+            if level in (distutils.log.WARN, distutils.log.ERROR,
+                         distutils.log.FATAL):
+                self._log_to_stderr(level, msg, *args)
+            else:
+                distutils.log.log(level, msg, *args)
+
+        def _log_to_stderr(self, level, msg, *args):
+            # This is the only truly 'public' way to get the current threshold
+            # of the log
+            current_threshold = distutils.log.set_threshold(distutils.log.WARN)
+            distutils.log.set_threshold(current_threshold)
+            if level >= current_threshold:
+                if args:
+                    msg = msg % args
+                sys.stderr.write('%s\n' % msg)
+                sys.stderr.flush()
+
+    log = log()
+
+
+BOOTSTRAPPER = _Bootstrapper.main()
+
+
+def use_astropy_helpers(**kwargs):
+    """
+    Ensure that the `astropy_helpers` module is available and is importable.
+    This supports automatic submodule initialization if astropy_helpers is
+    included in a project as a git submodule, or will download it from PyPI if
+    necessary.
+
+    Parameters
+    ----------
+
+    path : str or None, optional
+        A filesystem path relative to the root of the project's source code
+        that should be added to `sys.path` so that `astropy_helpers` can be
+        imported from that path.
+
+        If the path is a git submodule it will automatically be initialzed
+        and/or updated.
+
+        The path may also be to a ``.tar.gz`` archive of the astropy_helpers
+        source distribution.  In this case the archive is automatically
+        unpacked and made temporarily available on `sys.path` as a ``.egg``
+        archive.
+
+        If `None` skip straight to downloading.
+
+    download_if_needed : bool, optional
+        If the provided filesystem path is not found an attempt will be made to
+        download astropy_helpers from PyPI.  It will then be made temporarily
+        available on `sys.path` as a ``.egg`` archive (using the
+        ``setup_requires`` feature of setuptools.  If the ``--offline`` option
+        is given at the command line the value of this argument is overridden
+        to `False`.
+
+    index_url : str, optional
+        If provided, use a different URL for the Python package index than the
+        main PyPI server.
+
+    use_git : bool, optional
+        If `False` no git commands will be used--this effectively disables
+        support for git submodules. If the ``--no-git`` option is given at the
+        command line the value of this argument is overridden to `False`.
+
+    auto_upgrade : bool, optional
+        By default, when installing a package from a non-development source
+        distribution ah_boostrap will try to automatically check for patch
+        releases to astropy-helpers on PyPI and use the patched version over
+        any bundled versions.  Setting this to `False` will disable that
+        functionality. If the ``--offline`` option is given at the command line
+        the value of this argument is overridden to `False`.
+
+    offline : bool, optional
+        If `False` disable all actions that require an internet connection,
+        including downloading packages from the package index and fetching
+        updates to any git submodule.  Defaults to `True`.
+    """
+
+    global BOOTSTRAPPER
+
+    config = BOOTSTRAPPER.config
+    config.update(**kwargs)
+
+    # Create a new bootstrapper with the updated configuration and run it
+    BOOTSTRAPPER = _Bootstrapper(**config)
+    BOOTSTRAPPER.run()
diff --git a/astropy_helpers/appveyor.yml b/astropy_helpers/appveyor.yml
new file mode 100644
index 0000000..181434e
--- /dev/null
+++ b/astropy_helpers/appveyor.yml
@@ -0,0 +1,52 @@
+# AppVeyor.com is a Continuous Integration service to build and run tests under
+# Windows
+
+environment:
+
+  global:
+      PYTHON: "C:\\conda"
+      MINICONDA_VERSION: "3.5.5"
+      CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\continuous-integration\\appveyor\\windows_sdk.cmd"
+      PYTHON_ARCH: "64" # needs to be set for CMD_IN_ENV to succeed. If a mix
+                        # of 32 bit and 64 bit builds are needed, move this
+                        # to the matrix section.
+
+  matrix:
+      - PYTHON_VERSION: "2.6"
+      - PYTHON_VERSION: "2.7"
+      - PYTHON_VERSION: "3.4"
+
+platform:
+    -x64
+
+install:
+    # Install miniconda using a powershell script.
+    - "powershell continuous-integration/appveyor/install-miniconda.ps1"
+    - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+
+    # Install the build and runtime dependencies of the project.
+    - "conda update --yes conda"
+
+    # Create a conda environment
+    - "conda create -q --yes -n test python=%PYTHON_VERSION%"
+    - "activate test"
+
+    # Check that we have the expected version of Python
+    - "python --version"
+
+    # Install specified version of numpy and dependencies
+    - "conda install -q --yes numpy Cython sphinx pytest"
+
+    # Some of the tests use git commands that require a user to be configured
+    - git config --global user.name "A U Thor"
+    - git config --global user.email "author at example.com"
+
+    # Install graphviz
+    - cinst graphviz.portable
+
+# Not a .NET project, we build SunPy in the install step instead
+build: false
+
+test_script:
+  - "%CMD_IN_ENV% py.test"
+
diff --git a/astropy_helpers/astropy_helpers.egg-info/PKG-INFO b/astropy_helpers/astropy_helpers.egg-info/PKG-INFO
new file mode 100644
index 0000000..bd6bbb0
--- /dev/null
+++ b/astropy_helpers/astropy_helpers.egg-info/PKG-INFO
@@ -0,0 +1,52 @@
+Metadata-Version: 1.1
+Name: astropy-helpers
+Version: 0.5.dev358
+Summary: Utilities for building and installing Astropy, Astropy affiliated packages, and their respective documentation.
+Home-page: http://astropy.org
+Author: The Astropy Developers
+Author-email: astropy.team at gmail.com
+License: BSD
+Download-URL: http://pypi.python.org/packages/source/a/astropy-helpers/astropy-helpers-0.5.dev358.tar.gz
+Description: astropy-helpers
+        ===============
+        
+        This project provides a Python package, ``astropy_helpers``, which includes
+        many build, installation, and documentation-related tools used by the Astropy
+        project, but packaged separately for use by other projects that wish to
+        leverage this work.  The motivation behind this package and details of its
+        implementation are in the accepted 
+        `Astropy Proposal for Enhancement (APE) 4 <https://github.com/astropy/astropy-APEs/blob/master/APE4.rst>`_.
+        
+        ``astropy_helpers`` includes a special "bootstrap" module called
+        ``ah_bootstrap.py`` which is intended to be used by a project's setup.py in
+        order to ensure that the ``astropy_helpers`` package is available for
+        build/installation.  This is similar to the ``ez_setup.py`` module that is
+        shipped with some projects to bootstrap `setuptools
+        <https://bitbucket.org/pypa/setuptools>`_.
+        
+        As described in APE4, the version numbers for ``astropy_helpers`` follow the
+        corresponding major/minor version of the `astropy core package
+        <http://www.astropy.org/>`_, but with an independent sequence of micro (bugfix)
+        version numbers. Hence, the initial release is 0.4, in parallel with Astropy
+        v0.4, which will be the first version  of Astropy to use ``astropy-helpers``.
+        
+        For examples of how to implement ``astropy-helpers`` in a project,
+        see the ``setup.py`` and ``setup.cfg`` files of the 
+        `Affiliated package template <https://github.com/astropy/package-template>`_.
+        
+        .. image:: https://travis-ci.org/astropy/astropy-helpers.png
+            :target: https://travis-ci.org/astropy/astropy-helpers
+        
+        .. image:: https://coveralls.io/repos/astropy/astropy-helpers/badge.png
+            :target: https://coveralls.io/r/astropy/astropy-helpers
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Topic :: Software Development :: Build Tools
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Archiving :: Packaging
diff --git a/astropy_helpers/astropy_helpers.egg-info/SOURCES.txt b/astropy_helpers/astropy_helpers.egg-info/SOURCES.txt
new file mode 100644
index 0000000..7e8dfab
--- /dev/null
+++ b/astropy_helpers/astropy_helpers.egg-info/SOURCES.txt
@@ -0,0 +1,77 @@
+CHANGES.rst
+LICENSE.rst
+MANIFEST.in
+README.rst
+ah_bootstrap.py
+ez_setup.py
+setup.cfg
+setup.py
+astropy_helpers/__init__.py
+astropy_helpers/distutils_helpers.py
+astropy_helpers/git_helpers.py
+astropy_helpers/setup_helpers.py
+astropy_helpers/test_helpers.py
+astropy_helpers/utils.py
+astropy_helpers/version.py
+astropy_helpers/version_helpers.py
+astropy_helpers.egg-info/PKG-INFO
+astropy_helpers.egg-info/SOURCES.txt
+astropy_helpers.egg-info/dependency_links.txt
+astropy_helpers.egg-info/not-zip-safe
+astropy_helpers.egg-info/top_level.txt
+astropy_helpers/commands/__init__.py
+astropy_helpers/commands/build_ext.py
+astropy_helpers/commands/build_py.py
+astropy_helpers/commands/build_sphinx.py
+astropy_helpers/commands/install.py
+astropy_helpers/commands/install_lib.py
+astropy_helpers/commands/register.py
+astropy_helpers/compat/__init__.py
+astropy_helpers/compat/subprocess.py
+astropy_helpers/compat/_subprocess_py2/__init__.py
+astropy_helpers/sphinx/__init__.py
+astropy_helpers/sphinx/conf.py
+astropy_helpers/sphinx/setup_package.py
+astropy_helpers/sphinx/ext/__init__.py
+astropy_helpers/sphinx/ext/astropyautosummary.py
+astropy_helpers/sphinx/ext/autodoc_enhancements.py
+astropy_helpers/sphinx/ext/automodapi.py
+astropy_helpers/sphinx/ext/automodsumm.py
+astropy_helpers/sphinx/ext/changelog_links.py
+astropy_helpers/sphinx/ext/comment_eater.py
+astropy_helpers/sphinx/ext/compiler_unparse.py
+astropy_helpers/sphinx/ext/docscrape.py
+astropy_helpers/sphinx/ext/docscrape_sphinx.py
+astropy_helpers/sphinx/ext/doctest.py
+astropy_helpers/sphinx/ext/edit_on_github.py
+astropy_helpers/sphinx/ext/numpydoc.py
+astropy_helpers/sphinx/ext/phantom_import.py
+astropy_helpers/sphinx/ext/smart_resolver.py
+astropy_helpers/sphinx/ext/tocdepthfix.py
+astropy_helpers/sphinx/ext/traitsdoc.py
+astropy_helpers/sphinx/ext/utils.py
+astropy_helpers/sphinx/ext/viewcode.py
+astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst
+astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst
+astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst
+astropy_helpers/sphinx/ext/tests/__init__.py
+astropy_helpers/sphinx/ext/tests/test_autodoc_enhancements.py
+astropy_helpers/sphinx/ext/tests/test_automodapi.py
+astropy_helpers/sphinx/ext/tests/test_automodsumm.py
+astropy_helpers/sphinx/ext/tests/test_docscrape.py
+astropy_helpers/sphinx/ext/tests/test_utils.py
+astropy_helpers/sphinx/local/python3links.inv
+astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html
+astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html
+astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html
+astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html
+astropy_helpers/sphinx/themes/bootstrap-astropy/theme.conf
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js
+astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.js
+astropy_helpers/src/__init__.py
+astropy_helpers/src/compiler.c
+astropy_helpers/src/setup_package.py
\ No newline at end of file
diff --git a/astropy_helpers/astropy_helpers.egg-info/dependency_links.txt b/astropy_helpers/astropy_helpers.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/astropy_helpers/astropy_helpers.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/astropy_helpers/astropy_helpers.egg-info/not-zip-safe b/astropy_helpers/astropy_helpers.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/astropy_helpers/astropy_helpers.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/astropy_helpers/astropy_helpers.egg-info/top_level.txt b/astropy_helpers/astropy_helpers.egg-info/top_level.txt
new file mode 100644
index 0000000..1b83b19
--- /dev/null
+++ b/astropy_helpers/astropy_helpers.egg-info/top_level.txt
@@ -0,0 +1 @@
+astropy_helpers
diff --git a/astropy_helpers/astropy_helpers/__init__.py b/astropy_helpers/astropy_helpers/__init__.py
new file mode 100644
index 0000000..ebfc30a
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/__init__.py
@@ -0,0 +1,6 @@
+try:
+    from .version import version as __version__
+    from .version import githash as __githash__
+except ImportError:
+    __version__ = ''
+    __githash__ = ''
diff --git a/astropy_helpers/astropy_helpers/commands/__init__.py b/astropy_helpers/astropy_helpers/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy_helpers/astropy_helpers/commands/build_ext.py b/astropy_helpers/astropy_helpers/commands/build_ext.py
new file mode 100644
index 0000000..a1a4a04
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/build_ext.py
@@ -0,0 +1,179 @@
+import errno
+import os
+import shutil
+
+from distutils.core import Extension
+from setuptools.command.build_ext import build_ext as SetuptoolsBuildExt
+
+from ..utils import get_numpy_include_path, invalidate_caches
+from ..version_helpers import get_pkg_version_module
+
+
+def should_build_with_cython(package, release=None):
+    """Returns the previously used Cython version (or 'unknown' if not
+    previously built) if Cython should be used to build extension modules from
+    pyx files.  If the ``release`` parameter is not specified an attempt is
+    made to determine the release flag from `astropy.version`.
+    """
+
+    from ..setup_helpers import _module_state
+
+    try:
+        version_module = __import__(package + '.cython_version',
+                                    fromlist=['release', 'cython_version'])
+    except ImportError:
+        version_module = None
+
+    if release is None and version_module is not None:
+        try:
+            release = version_module.release
+        except AttributeError:
+            pass
+
+    try:
+        cython_version = version_module.cython_version
+    except AttributeError:
+        cython_version = 'unknown'
+
+    # Only build with Cython if, of course, Cython is installed, we're in a
+    # development version (i.e. not release) or the Cython-generated source
+    # files haven't been created yet (cython_version == 'unknown'). The latter
+    # case can happen even when release is True if checking out a release tag
+    # from the repository
+    if (_module_state['have_cython'] and
+            (not release or cython_version == 'unknown')):
+        return cython_version
+    else:
+        return False
+
+
+# TODO: I think this can be reworked without having to create the class
+# programmatically.
+def generate_build_ext_command(packagename, release):
+    """
+    Creates a custom 'build_ext' command that allows for manipulating some of
+    the C extension options at build time.  We use a function to build the
+    class since the base class for build_ext may be different depending on
+    certain build-time parameters (for example, we may use Cython's build_ext
+    instead of the default version in distutils).
+
+    Uses the default distutils.command.build_ext by default.
+    """
+
+    uses_cython = should_build_with_cython(packagename, release)
+
+    if uses_cython:
+        from Cython.Distutils import build_ext as basecls
+    else:
+        basecls = SetuptoolsBuildExt
+
+    attrs = dict(basecls.__dict__)
+    orig_run = getattr(basecls, 'run', None)
+    orig_finalize = getattr(basecls, 'finalize_options', None)
+
+    def finalize_options(self):
+        # Add a copy of the _compiler.so module as well, but only if there are
+        # in fact C modules to compile (otherwise there's no reason to include
+        # a record of the compiler used)
+        if self.extensions:
+            src_path = os.path.relpath(
+                os.path.join(os.path.dirname(__file__), 'src'))
+            shutil.copy2(os.path.join(src_path, 'compiler.c'),
+                         os.path.join(self.package_name, '_compiler.c'))
+            ext = Extension(self.package_name + '._compiler',
+                            [os.path.join(self.package_name, '_compiler.c')])
+            self.extensions.insert(0, ext)
+
+        if orig_finalize is not None:
+            orig_finalize(self)
+
+        # Generate
+        if self.uses_cython:
+            try:
+                from Cython import __version__ as cython_version
+            except ImportError:
+                # This shouldn't happen if we made it this far
+                cython_version = None
+
+            if (cython_version is not None and
+                    cython_version != self.uses_cython):
+                self.force_rebuild = True
+                # Update the used cython version
+                self.uses_cython = cython_version
+
+        # Regardless of the value of the '--force' option, force a rebuild if
+        # the debug flag changed from the last build
+        if self.force_rebuild:
+            self.force = True
+
+    def run(self):
+        # For extensions that require 'numpy' in their include dirs, replace
+        # 'numpy' with the actual paths
+        np_include = get_numpy_include_path()
+        for extension in self.extensions:
+            if 'numpy' in extension.include_dirs:
+                idx = extension.include_dirs.index('numpy')
+                extension.include_dirs.insert(idx, np_include)
+                extension.include_dirs.remove('numpy')
+
+            # Replace .pyx with C-equivalents, unless c files are missing
+            for jdx, src in enumerate(extension.sources):
+                if src.endswith('.pyx'):
+                    pyxfn = src
+                    cfn = src[:-4] + '.c'
+                elif src.endswith('.c'):
+                    pyxfn = src[:-2] + '.pyx'
+                    cfn = src
+
+                if not os.path.isfile(pyxfn):
+                    continue
+
+                if self.uses_cython:
+                    extension.sources[jdx] = pyxfn
+                else:
+                    if os.path.isfile(cfn):
+                        extension.sources[jdx] = cfn
+                    else:
+                        msg = (
+                            'Could not find C file {0} for Cython file {1} '
+                            'when building extension {2}. Cython must be '
+                            'installed to build from a git checkout.'.format(
+                                cfn, pyxfn, extension.name))
+                        raise IOError(errno.ENOENT, msg, cfn)
+
+        if orig_run is not None:
+            # This should always be the case for a correctly implemented
+            # distutils command.
+            orig_run(self)
+
+        # Update cython_version.py if building with Cython
+        try:
+            cython_version = get_pkg_version_module(
+                    packagename, fromlist=['cython_version'])[0]
+        except (AttributeError, ImportError):
+            cython_version = 'unknown'
+        if self.uses_cython and self.uses_cython != cython_version:
+            package_dir = os.path.relpath(packagename)
+            cython_py = os.path.join(package_dir, 'cython_version.py')
+            with open(cython_py, 'w') as f:
+                f.write('# Generated file; do not modify\n')
+                f.write('cython_version = {0!r}\n'.format(self.uses_cython))
+
+            if os.path.isdir(self.build_lib):
+                # The build/lib directory may not exist if the build_py command
+                # was not previously run, which may sometimes be the case
+                self.copy_file(cython_py,
+                               os.path.join(self.build_lib, cython_py),
+                               preserve_mode=False)
+
+            invalidate_caches()
+
+    attrs['run'] = run
+    attrs['finalize_options'] = finalize_options
+    attrs['force_rebuild'] = False
+    attrs['uses_cython'] = uses_cython
+    attrs['package_name'] = packagename
+    attrs['user_options'] = basecls.user_options[:]
+    attrs['boolean_options'] = basecls.boolean_options[:]
+
+    return type('build_ext', (basecls, object), attrs)
diff --git a/astropy_helpers/astropy_helpers/commands/build_py.py b/astropy_helpers/astropy_helpers/commands/build_py.py
new file mode 100644
index 0000000..7ec9351
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/build_py.py
@@ -0,0 +1,39 @@
+from setuptools.command.build_py import build_py as SetuptoolsBuildPy
+
+from ..utils import _get_platlib_dir
+
+
+class AstropyBuildPy(SetuptoolsBuildPy):
+    user_options = SetuptoolsBuildPy.user_options[:]
+    boolean_options = SetuptoolsBuildPy.boolean_options[:]
+
+    def finalize_options(self):
+        # Update build_lib settings from the build command to always put
+        # build files in platform-specific subdirectories of build/, even
+        # for projects with only pure-Python source (this is desirable
+        # specifically for support of multiple Python version).
+        build_cmd = self.get_finalized_command('build')
+        platlib_dir = _get_platlib_dir(build_cmd)
+
+        build_cmd.build_purelib = platlib_dir
+        build_cmd.build_lib = platlib_dir
+        self.build_lib = platlib_dir
+
+        SetuptoolsBuildPy.finalize_options(self)
+
+    def run_2to3(self, files, doctests=False):
+        # Filter the files to exclude things that shouldn't be 2to3'd
+        skip_2to3 = self.distribution.skip_2to3
+        filtered_files = []
+        for filename in files:
+            for package in skip_2to3:
+                if filename[len(self.build_lib) + 1:].startswith(package):
+                    break
+            else:
+                filtered_files.append(filename)
+
+        SetuptoolsBuildPy.run_2to3(self, filtered_files, doctests)
+
+    def run(self):
+        # first run the normal build_py
+        SetuptoolsBuildPy.run(self)
diff --git a/astropy_helpers/astropy_helpers/commands/build_sphinx.py b/astropy_helpers/astropy_helpers/commands/build_sphinx.py
new file mode 100644
index 0000000..fbb408a
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/build_sphinx.py
@@ -0,0 +1,215 @@
+import inspect
+import os
+import pkgutil
+import re
+import shutil
+import subprocess
+import sys
+import textwrap
+
+from distutils import log
+from distutils.cmd import DistutilsOptionError
+
+from sphinx.setup_command import BuildDoc as SphinxBuildDoc
+
+
+PY3 = sys.version_info[0] >= 3
+
+
+class AstropyBuildSphinx(SphinxBuildDoc):
+    """
+    A version of the ``build_sphinx`` command that uses the version of Astropy
+    that is built by the setup ``build`` command, rather than whatever is
+    installed on the system.  To build docs against the installed version, run
+    ``make html`` in the ``astropy/docs`` directory.
+
+    This also automatically creates the docs/_static directories--this is
+    needed because GitHub won't create the _static dir because it has no
+    tracked files.
+    """
+
+    description = 'Build Sphinx documentation for Astropy environment'
+    user_options = SphinxBuildDoc.user_options[:]
+    user_options.append(('warnings-returncode', 'w',
+            'Parses the sphinx output and sets the return code to 1 if there '
+            'are any warnings. Note that this will cause the sphinx log to '
+            'only update when it completes, rather than continuously as is '
+            'normally the case.'))
+    user_options.append(('clean-docs', 'l',
+            'Completely clean previous builds, including '
+            'automodapi-generated files before building new ones'))
+    user_options.append(('no-intersphinx', 'n',
+            'Skip intersphinx, even if conf.py says to use it'))
+    user_options.append(('open-docs-in-browser', 'o',
+            'Open the docs in a browser (using the webbrowser module) if the '
+            'build finishes successfully.'))
+
+    boolean_options = SphinxBuildDoc.boolean_options[:]
+    boolean_options.append('warnings-returncode')
+    boolean_options.append('clean-docs')
+    boolean_options.append('no-intersphinx')
+    boolean_options.append('open-docs-in-browser')
+
+    _self_iden_rex = re.compile(r"self\.([^\d\W][\w]+)", re.UNICODE)
+
+    def initialize_options(self):
+        SphinxBuildDoc.initialize_options(self)
+        self.clean_docs = False
+        self.no_intersphinx = False
+        self.open_docs_in_browser = False
+        self.warnings_returncode = False
+
+    def finalize_options(self):
+        #Clear out previous sphinx builds, if requested
+        if self.clean_docs:
+            dirstorm = [os.path.join(self.source_dir, 'api')]
+            if self.build_dir is None:
+                dirstorm.append('docs/_build')
+            else:
+                dirstorm.append(self.build_dir)
+
+            for d in dirstorm:
+                if os.path.isdir(d):
+                    log.info('Cleaning directory ' + d)
+                    shutil.rmtree(d)
+                else:
+                    log.info('Not cleaning directory ' + d + ' because '
+                             'not present or not a directory')
+
+        SphinxBuildDoc.finalize_options(self)
+
+    def run(self):
+        # TODO: Break this method up into a few more subroutines and
+        # document them better
+        import webbrowser
+
+        if PY3:
+            from urllib.request import pathname2url
+        else:
+            from urllib import pathname2url
+
+        # This is used at the very end of `run` to decide if sys.exit should
+        # be called. If it's None, it won't be.
+        retcode = None
+
+        # If possible, create the _static dir
+        if self.build_dir is not None:
+            # the _static dir should be in the same place as the _build dir
+            # for Astropy
+            basedir, subdir = os.path.split(self.build_dir)
+            if subdir == '':  # the path has a trailing /...
+                basedir, subdir = os.path.split(basedir)
+            staticdir = os.path.join(basedir, '_static')
+            if os.path.isfile(staticdir):
+                raise DistutilsOptionError(
+                    'Attempted to build_sphinx in a location where' +
+                    staticdir + 'is a file.  Must be a directory.')
+            self.mkpath(staticdir)
+
+        # Now make sure Astropy is built and determine where it was built
+        build_cmd = self.reinitialize_command('build')
+        build_cmd.inplace = 0
+        self.run_command('build')
+        build_cmd = self.get_finalized_command('build')
+        build_cmd_path = os.path.abspath(build_cmd.build_lib)
+
+        ah_importer = pkgutil.get_importer('astropy_helpers')
+        ah_path = os.path.abspath(ah_importer.path)
+
+        # Now generate the source for and spawn a new process that runs the
+        # command.  This is needed to get the correct imports for the built
+        # version
+        runlines, runlineno = inspect.getsourcelines(SphinxBuildDoc.run)
+        subproccode = textwrap.dedent("""
+            from sphinx.setup_command import *
+
+            os.chdir({srcdir!r})
+            sys.path.insert(0, {build_cmd_path!r})
+            sys.path.insert(0, {ah_path!r})
+
+        """).format(build_cmd_path=build_cmd_path, ah_path=ah_path,
+                    srcdir=self.source_dir)
+        # runlines[1:] removes 'def run(self)' on the first line
+        subproccode += textwrap.dedent(''.join(runlines[1:]))
+
+        # All "self.foo" in the subprocess code needs to be replaced by the
+        # values taken from the current self in *this* process
+        subproccode = self._self_iden_rex.split(subproccode)
+        for i in range(1, len(subproccode), 2):
+            iden = subproccode[i]
+            val = getattr(self, iden)
+            if iden.endswith('_dir'):
+                # Directories should be absolute, because the `chdir` call
+                # in the new process moves to a different directory
+                subproccode[i] = repr(os.path.abspath(val))
+            else:
+                subproccode[i] = repr(val)
+        subproccode = ''.join(subproccode)
+
+        if self.no_intersphinx:
+            # the confoverrides variable in sphinx.setup_command.BuildDoc can
+            # be used to override the conf.py ... but this could well break
+            # if future versions of sphinx change the internals of BuildDoc,
+            # so remain vigilant!
+            subproccode = subproccode.replace('confoverrides = {}',
+                'confoverrides = {\'intersphinx_mapping\':{}}')
+
+        log.debug('Starting subprocess of {0} with python code:\n{1}\n'
+                  '[CODE END])'.format(sys.executable, subproccode))
+
+        # To return the number of warnings, we need to capture stdout. This
+        # prevents a continuous updating at the terminal, but there's no
+        # apparent way around this.
+        if self.warnings_returncode:
+            proc = subprocess.Popen([sys.executable],
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT)
+            stdo, stde = proc.communicate(subproccode.encode('utf-8'))
+
+            print(stdo)
+
+            stdolines = stdo.splitlines()
+
+            if b'build succeeded.' in stdolines:
+                retcode = 0
+            else:
+                retcode = 1
+
+            if retcode != 0:
+                if os.environ.get('TRAVIS', None) == 'true':
+                    #this means we are in the travis build, so customize
+                    #the message appropriately.
+                    msg = ('The build_sphinx travis build FAILED '
+                           'because sphinx issued documentation '
+                           'warnings (scroll up to see the warnings).')
+                else:  # standard failure message
+                    msg = ('build_sphinx returning a non-zero exit '
+                           'code because sphinx issued documentation '
+                           'warnings.')
+                log.warn(msg)
+
+        else:
+            proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE)
+            proc.communicate(subproccode.encode('utf-8'))
+
+        if proc.returncode == 0:
+            if self.open_docs_in_browser:
+                if self.builder == 'html':
+                    absdir = os.path.abspath(self.builder_target_dir)
+                    index_path = os.path.join(absdir, 'index.html')
+                    fileurl = 'file://' + pathname2url(index_path)
+                    webbrowser.open(fileurl)
+                else:
+                    log.warn('open-docs-in-browser option was given, but '
+                             'the builder is not html! Ignogring.')
+        else:
+            log.warn('Sphinx Documentation subprocess failed with return '
+                     'code ' + str(proc.returncode))
+
+        if retcode is not None:
+            # this is potentially dangerous in that there might be something
+            # after the call to `setup` in `setup.py`, and exiting here will
+            # prevent that from running.  But there's no other apparent way
+            # to signal what the return code should be.
+            sys.exit(retcode)
diff --git a/astropy_helpers/astropy_helpers/commands/install.py b/astropy_helpers/astropy_helpers/commands/install.py
new file mode 100644
index 0000000..c3d5727
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/install.py
@@ -0,0 +1,14 @@
+from setuptools.command.install import install as SetuptoolsInstall
+
+from ..utils import _get_platlib_dir
+
+
+class AstropyInstall(SetuptoolsInstall):
+    user_options = SetuptoolsInstall.user_options[:]
+    boolean_options = SetuptoolsInstall.boolean_options[:]
+
+    def finalize_options(self):
+        build_cmd = self.get_finalized_command('build')
+        platlib_dir = _get_platlib_dir(build_cmd)
+        self.build_lib = platlib_dir
+        SetuptoolsInstall.finalize_options(self)
diff --git a/astropy_helpers/astropy_helpers/commands/install_lib.py b/astropy_helpers/astropy_helpers/commands/install_lib.py
new file mode 100644
index 0000000..2081566
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/install_lib.py
@@ -0,0 +1,14 @@
+from setuptools.command.install_lib import install_lib as SetuptoolsInstallLib
+
+from ..utils import _get_platlib_dir
+
+
+class AstropyInstallLib(SetuptoolsInstallLib):
+    user_options = SetuptoolsInstallLib.user_options[:]
+    boolean_options = SetuptoolsInstallLib.boolean_options[:]
+
+    def finalize_options(self):
+        build_cmd = self.get_finalized_command('build')
+        platlib_dir = _get_platlib_dir(build_cmd)
+        self.build_dir = platlib_dir
+        SetuptoolsInstallLib.finalize_options(self)
diff --git a/astropy_helpers/astropy_helpers/commands/register.py b/astropy_helpers/astropy_helpers/commands/register.py
new file mode 100644
index 0000000..dce1817
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/commands/register.py
@@ -0,0 +1,53 @@
+from setuptools.command.register import register as SetuptoolsRegister
+
+
+class AstropyRegister(SetuptoolsRegister):
+    """Extends the built in 'register' command to support a ``--hidden`` option
+    to make the registered version hidden on PyPI by default.
+
+    The result of this is that when a version is registered as "hidden" it can
+    still be downloaded from PyPI, but it does not show up in the list of
+    actively supported versions under http://pypi.python.org/pypi/astropy, and
+    is not set as the most recent version.
+
+    Although this can always be set through the web interface it may be more
+    convenient to be able to specify via the 'register' command.  Hidden may
+    also be considered a safer default when running the 'register' command,
+    though this command uses distutils' normal behavior if the ``--hidden``
+    option is omitted.
+    """
+
+    user_options = SetuptoolsRegister.user_options + [
+        ('hidden', None, 'mark this release as hidden on PyPI by default')
+    ]
+    boolean_options = SetuptoolsRegister.boolean_options + ['hidden']
+
+    def initialize_options(self):
+        SetuptoolsRegister.initialize_options(self)
+        self.hidden = False
+
+    def build_post_data(self, action):
+        data = SetuptoolsRegister.build_post_data(self, action)
+        if action == 'submit' and self.hidden:
+            data['_pypi_hidden'] = '1'
+        return data
+
+    def _set_config(self):
+        # The original register command is buggy--if you use .pypirc with a
+        # server-login section *at all* the repository you specify with the -r
+        # option will be overwritten with either the repository in .pypirc or
+        # with the default,
+        # If you do not have a .pypirc using the -r option will just crash.
+        # Way to go distutils
+
+        # If we don't set self.repository back to a default value _set_config
+        # can crash if there was a user-supplied value for this option; don't
+        # worry, we'll get the real value back afterwards
+        self.repository = 'pypi'
+        SetuptoolsRegister._set_config(self)
+        options = self.distribution.get_option_dict('register')
+        if 'repository' in options:
+            source, value = options['repository']
+            # Really anything that came from setup.cfg or the command line
+            # should override whatever was in .pypirc
+            self.repository = value
diff --git a/astropy_helpers/astropy_helpers/compat/__init__.py b/astropy_helpers/astropy_helpers/compat/__init__.py
new file mode 100644
index 0000000..818e760
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/compat/__init__.py
@@ -0,0 +1,12 @@
+def _fix_user_options(options):
+    """
+    This is for Python 2.x and 3.x compatibility.  distutils expects Command
+    options to all be byte strings on Python 2 and Unicode strings on Python 3.
+    """
+
+    def to_str_or_none(x):
+        if x is None:
+            return None
+        return str(x)
+
+    return [tuple(to_str_or_none(x) for x in y) for y in options]
diff --git a/astropy_helpers/astropy_helpers/compat/_subprocess_py2/__init__.py b/astropy_helpers/astropy_helpers/compat/_subprocess_py2/__init__.py
new file mode 100644
index 0000000..a14df41
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/compat/_subprocess_py2/__init__.py
@@ -0,0 +1,38 @@
+from __future__ import absolute_import
+
+from subprocess import *
+
+
+def check_output(*popenargs, **kwargs):
+    r"""Run command with arguments and return its output as a byte
+    string.
+
+    If the exit code was non-zero it raises a CalledProcessError.  The
+    CalledProcessError object will have the return code in the
+    returncode
+    attribute and output in the output attribute.
+
+    The arguments are the same as for the Popen constructor.  Example::
+
+    >>> check_output(["ls", "-l", "/dev/null"])
+    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
+
+    The stdout argument is not allowed as it is used internally.
+    To capture standard error in the result, use stderr=STDOUT.::
+
+    >>> check_output(["/bin/sh", "-c",
+    ...               "ls -l non_existent_file ; exit 0"],
+    ...              stderr=STDOUT)
+    'ls: non_existent_file: No such file or directory\n'
+    """
+    if 'stdout' in kwargs:
+        raise ValueError('stdout argument not allowed, it will be overridden.')
+    process = Popen(stdout=PIPE, *popenargs, **kwargs)
+    output, unused_err = process.communicate()
+    retcode = process.poll()
+    if retcode:
+        cmd = kwargs.get("args")
+        if cmd is None:
+            cmd = popenargs[0]
+        raise CalledProcessError(retcode, cmd)
+    return output
diff --git a/astropy_helpers/astropy_helpers/compat/subprocess.py b/astropy_helpers/astropy_helpers/compat/subprocess.py
new file mode 100644
index 0000000..93a388b
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/compat/subprocess.py
@@ -0,0 +1,19 @@
+"""
+A replacement wrapper around the subprocess module that adds
+check_output (which was only added to Python in 2.7.
+
+Instead of importing subprocess, other modules should use this as follows::
+
+    from astropy.utils.compat import subprocess
+
+This module is safe to import from anywhere within astropy.
+"""
+from __future__ import absolute_import, print_function
+
+import subprocess
+
+# python2.7 and later provide a check_output method
+if not hasattr(subprocess, 'check_output'):
+    from ._subprocess_py2 import check_output
+
+from subprocess import *
diff --git a/astropy_helpers/astropy_helpers/distutils_helpers.py b/astropy_helpers/astropy_helpers/distutils_helpers.py
new file mode 100644
index 0000000..d1dbac6
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/distutils_helpers.py
@@ -0,0 +1,257 @@
+"""
+This module contains various utilities for introspecting the distutils
+module and the setup process.
+
+Some of these utilities require the
+`astropy_helpers.setup_helpers.register_commands` function to be called first,
+as it will affect introspection of setuptools command-line arguments.  Other
+utilities in this module do not have that restriction.
+"""
+
+import os
+import sys
+
+from distutils import ccompiler
+from distutils.dist import Distribution
+from distutils.errors import DistutilsError
+
+from .utils import silence
+
+
+# This function, and any functions that call it, require the setup in
+# `astropy_helpers.setup_helpers.register_commands` to be run first.
+def get_dummy_distribution():
+    """
+    Returns a distutils Distribution object used to instrument the setup
+    environment before calling the actual setup() function.
+    """
+
+    from .setup_helpers import _module_state
+
+    if _module_state['registered_commands'] is None:
+        raise RuntimeError(
+            'astropy_helpers.setup_helpers.register_commands() must be '
+            'called before using '
+            'astropy_helpers.setup_helpers.get_dummy_distribution()')
+
+    # Pre-parse the Distutils command-line options and config files to if
+    # the option is set.
+    dist = Distribution({'script_name': os.path.basename(sys.argv[0]),
+                         'script_args': sys.argv[1:]})
+    dist.cmdclass.update(_module_state['registered_commands'])
+
+    with silence():
+        try:
+            dist.parse_config_files()
+            dist.parse_command_line()
+        except (DistutilsError, AttributeError, SystemExit):
+            # Let distutils handle DistutilsErrors itself AttributeErrors can
+            # get raise for ./setup.py --help SystemExit can be raised if a
+            # display option was used, for example
+            pass
+
+    return dist
+
+
+def get_distutils_option(option, commands):
+    """ Returns the value of the given distutils option.
+
+    Parameters
+    ----------
+    option : str
+        The name of the option
+
+    commands : list of str
+        The list of commands on which this option is available
+
+    Returns
+    -------
+    val : str or None
+        the value of the given distutils option. If the option is not set,
+        returns None.
+    """
+
+    dist = get_dummy_distribution()
+
+    for cmd in commands:
+        cmd_opts = dist.command_options.get(cmd)
+        if cmd_opts is not None and option in cmd_opts:
+            return cmd_opts[option][1]
+    else:
+        return None
+
+
+def get_distutils_build_option(option):
+    """ Returns the value of the given distutils build option.
+
+    Parameters
+    ----------
+    option : str
+        The name of the option
+
+    Returns
+    -------
+    val : str or None
+        The value of the given distutils build option. If the option
+        is not set, returns None.
+    """
+    return get_distutils_option(option, ['build', 'build_ext', 'build_clib'])
+
+
+def get_distutils_install_option(option):
+    """ Returns the value of the given distutils install option.
+
+    Parameters
+    ----------
+    option : str
+        The name of the option
+
+    Returns
+    -------
+    val : str or None
+        The value of the given distutils build option. If the option
+        is not set, returns None.
+    """
+    return get_distutils_option(option, ['install'])
+
+
+def get_distutils_build_or_install_option(option):
+    """ Returns the value of the given distutils build or install option.
+
+    Parameters
+    ----------
+    option : str
+        The name of the option
+
+    Returns
+    -------
+    val : str or None
+        The value of the given distutils build or install option. If the
+        option is not set, returns None.
+    """
+    return get_distutils_option(option, ['build', 'build_ext', 'build_clib',
+                                         'install'])
+
+
+def get_compiler_option():
+    """ Determines the compiler that will be used to build extension modules.
+
+    Returns
+    -------
+    compiler : str
+        The compiler option specificied for the build, build_ext, or build_clib
+        command; or the default compiler for the platform if none was
+        specified.
+
+    """
+
+    compiler = get_distutils_build_option('compiler')
+    if compiler is None:
+        return ccompiler.get_default_compiler()
+
+    return compiler
+
+
+def add_command_option(command, name, doc, is_bool=False):
+    """
+    Add a custom option to a setup command.
+
+    Issues a warning if the option already exists on that command.
+
+    Parameters
+    ----------
+    command : str
+        The name of the command as given on the command line
+
+    name : str
+        The name of the build option
+
+    doc : str
+        A short description of the option, for the `--help` message
+
+    is_bool : bool, optional
+        When `True`, the option is a boolean option and doesn't
+        require an associated value.
+    """
+
+    dist = get_dummy_distribution()
+    cmdcls = dist.get_command_class(command)
+
+    if (hasattr(cmdcls, '_astropy_helpers_options') and
+            name in cmdcls._astropy_helpers_options):
+        return
+
+    attr = name.replace('-', '_')
+
+    if hasattr(cmdcls, attr):
+        raise RuntimeError(
+            '{0!r} already has a {1!r} class attribute, barring {2!r} from '
+            'being usable as a custom option name.'.format(cmdcls, attr, name))
+
+    for idx, cmd in enumerate(cmdcls.user_options):
+        if cmd[0] == name:
+            log.warn('Overriding existing {0!r} option '
+                     '{1!r}'.format(command, name))
+            del cmdcls.user_options[idx]
+            if name in cmdcls.boolean_options:
+                cmdcls.boolean_options.remove(name)
+            break
+
+    cmdcls.user_options.append((name, None, doc))
+
+    if is_bool:
+        cmdcls.boolean_options.append(name)
+
+    # Distutils' command parsing requires that a command object have an
+    # attribute with the same name as the option (with '-' replaced with '_')
+    # in order for that option to be recognized as valid
+    setattr(cmdcls, attr, None)
+
+    # This caches the options added through add_command_option so that if it is
+    # run multiple times in the same interpreter repeated adds are ignored
+    # (this way we can still raise a RuntimeError if a custom option overrides
+    # a built-in option)
+    if not hasattr(cmdcls, '_astropy_helpers_options'):
+        cmdcls._astropy_helpers_options = set([name])
+    else:
+        cmdcls._astropy_helpers_options.add(name)
+
+
+def get_distutils_display_options():
+    """ Returns a set of all the distutils display options in their long and
+    short forms.  These are the setup.py arguments such as --name or --version
+    which print the project's metadata and then exit.
+
+    Returns
+    -------
+    opts : set
+        The long and short form display option arguments, including the - or --
+    """
+
+    short_display_opts = set('-' + o[1] for o in Distribution.display_options
+                             if o[1])
+    long_display_opts = set('--' + o[0] for o in Distribution.display_options)
+
+    # Include -h and --help which are not explicitly listed in
+    # Distribution.display_options (as they are handled by optparse)
+    short_display_opts.add('-h')
+    long_display_opts.add('--help')
+
+    # This isn't the greatest approach to hardcode these commands.
+    # However, there doesn't seem to be a good way to determine
+    # whether build *will be* run as part of the command at this
+    # phase.
+    display_commands = set([
+        'clean', 'register', 'setopt', 'saveopts', 'egg_info',
+        'alias'])
+
+    return short_display_opts.union(long_display_opts.union(display_commands))
+
+
+def is_distutils_display_option():
+    """ Returns True if sys.argv contains any of the distutils display options
+    such as --version or --name.
+    """
+
+    display_options = get_distutils_display_options()
+    return bool(set(sys.argv[1:]).intersection(display_options))
diff --git a/astropy_helpers/astropy_helpers/git_helpers.py b/astropy_helpers/astropy_helpers/git_helpers.py
new file mode 100644
index 0000000..9c98fe4
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/git_helpers.py
@@ -0,0 +1,155 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Utilities for retrieving revision information from a project's git repository.
+"""
+
+# Do not remove the following comment; it is used by
+# astropy_helpers.version_helpers to determine the beginning of the code in
+# this module
+
+# BEGIN
+
+import locale
+import os
+import subprocess
+import warnings
+
+
+def _decode_stdio(stream):
+    try:
+        stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8'
+    except ValueError:
+        stdio_encoding = 'utf-8'
+
+    try:
+        text = stream.decode(stdio_encoding)
+    except UnicodeDecodeError:
+        # Final fallback
+        text = stream.decode('latin1')
+
+    return text
+
+
+def update_git_devstr(version, path=None):
+    """
+    Updates the git revision string if and only if the path is being imported
+    directly from a git working copy.  This ensures that the revision number in
+    the version string is accurate.
+    """
+
+    try:
+        # Quick way to determine if we're in git or not - returns '' if not
+        devstr = get_git_devstr(sha=True, show_warning=False, path=path)
+    except OSError:
+        return version
+
+    if not devstr:
+        # Probably not in git so just pass silently
+        return version
+
+    if 'dev' in version:  # update to the current git revision
+        version_base = version.split('.dev', 1)[0]
+        devstr = get_git_devstr(sha=False, show_warning=False, path=path)
+
+        return version_base + '.dev' + devstr
+    else:
+        #otherwise it's already the true/release version
+        return version
+
+
+def get_git_devstr(sha=False, show_warning=True, path=None):
+    """
+    Determines the number of revisions in this repository.
+
+    Parameters
+    ----------
+    sha : bool
+        If True, the full SHA1 hash will be returned. Otherwise, the total
+        count of commits in the repository will be used as a "revision
+        number".
+
+    show_warning : bool
+        If True, issue a warning if git returns an error code, otherwise errors
+        pass silently.
+
+    path : str or None
+        If a string, specifies the directory to look in to find the git
+        repository.  If `None`, the current working directory is used.
+        If given a filename it uses the directory containing that file.
+
+    Returns
+    -------
+    devversion : str
+        Either a string with the revision number (if `sha` is False), the
+        SHA1 hash of the current commit (if `sha` is True), or an empty string
+        if git version info could not be identified.
+
+    """
+
+    if path is None:
+        path = os.getcwd()
+
+    if not os.path.isdir(path):
+        path = os.path.abspath(os.path.dirname(path))
+
+    if not os.path.exists(os.path.join(path, '.git')):
+        return ''
+
+    if sha:
+        # Faster for getting just the hash of HEAD
+        cmd = ['rev-parse', 'HEAD']
+    else:
+        cmd = ['rev-list', '--count', 'HEAD']
+
+    def run_git(cmd):
+        try:
+            p = subprocess.Popen(['git'] + cmd, cwd=path,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 stdin=subprocess.PIPE)
+            stdout, stderr = p.communicate()
+        except OSError as e:
+            if show_warning:
+                warnings.warn('Error running git: ' + str(e))
+            return (None, '', '')
+
+        if p.returncode == 128:
+            if show_warning:
+                warnings.warn('No git repository present at {0!r}! Using '
+                              'default dev version.'.format(path))
+            return (p.returncode, '', '')
+        if p.returncode == 129:
+            if show_warning:
+                warnings.warn('Your git looks old (does it support {0}?); ' 
+                              'consider upgrading to v1.7.2 or '
+                              'later.'.format(cmd[0]))
+            return (p.returncode, stdout, stderr)
+        elif p.returncode != 0:
+            if show_warning:
+                warnings.warn('Git failed while determining revision '
+                              'count: {0}'.format(_decode_stdio(stderr)))
+            return (p.returncode, stdout, stderr)
+
+        return p.returncode, stdout, stderr
+
+    returncode, stdout, stderr = run_git(cmd)
+
+    if not sha and returncode == 129:
+        # git returns 129 if a command option failed to parse; in
+        # particular this could happen in git versions older than 1.7.2
+        # where the --count option is not supported
+        # Also use --abbrev-commit and --abbrev=0 to display the minimum
+        # number of characters needed per-commit (rather than the full hash)
+        cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD']
+        returncode, stdout, stderr = run_git(cmd)
+        # Fall back on the old method of getting all revisions and counting
+        # the lines
+        if returncode == 0:
+            return str(stdout.count(b'\n'))
+        else:
+            return ''
+    elif sha:
+        return _decode_stdio(stdout)[:40]
+    else:
+        return _decode_stdio(stdout).strip()
diff --git a/astropy_helpers/astropy_helpers/setup_helpers.py b/astropy_helpers/astropy_helpers/setup_helpers.py
new file mode 100644
index 0000000..3f109a0
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/setup_helpers.py
@@ -0,0 +1,843 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This module contains a number of utilities for use during
+setup/build/packaging that are useful to astropy as a whole.
+"""
+
+from __future__ import absolute_import, print_function
+
+import collections
+import os
+import re
+import shlex
+import shutil
+import subprocess
+import sys
+import textwrap
+import traceback
+
+from distutils import log, ccompiler, sysconfig
+from distutils.dist import Distribution
+from distutils.errors import DistutilsOptionError, DistutilsModuleError
+from distutils.core import Extension
+from distutils.core import Command
+from distutils.command.sdist import sdist as DistutilsSdist
+
+from setuptools import find_packages as _find_packages
+
+from .distutils_helpers import *
+from .version_helpers import get_pkg_version_module
+from .test_helpers import AstropyTest
+from .utils import (silence, walk_skip_hidden, import_file, extends_doc,
+                    resolve_name)
+
+
+from .commands.build_ext import generate_build_ext_command
+from .commands.build_py import AstropyBuildPy
+from .commands.install import AstropyInstall
+from .commands.install_lib import AstropyInstallLib
+from .commands.register import AstropyRegister
+
+# This import is not used in this module, but it is included for backwards
+# compat with version 0.4, which included this function in the public API
+# for this module
+from .utils import get_numpy_include_path, write_if_different
+from .commands.build_ext import should_build_with_cython
+
+_module_state = {
+    'adjusted_compiler': False,
+    'registered_commands': None,
+    'have_cython': False,
+    'have_sphinx': False,
+    'package_cache': None
+}
+
+try:
+    import Cython
+    _module_state['have_cython'] = True
+except ImportError:
+    pass
+
+try:
+    import sphinx
+    _module_state['have_sphinx'] = True
+except ValueError as e:
+    # This can occur deep in the bowels of Sphinx's imports by way of docutils
+    # and an occurence of this bug: http://bugs.python.org/issue18378
+    # In this case sphinx is effectively unusable
+    if 'unknown locale' in e.args[0]:
+        log.warn(
+            "Possible misconfiguration of one of the environment variables "
+            "LC_ALL, LC_CTYPES, LANG, or LANGUAGE.  For an example of how to "
+            "configure your system's language environment on OSX see "
+            "http://blog.remibergsma.com/2012/07/10/"
+            "setting-locales-correctly-on-mac-osx-terminal-application/")
+except ImportError:
+    pass
+except SyntaxError:
+    # occurs if markupsafe is recent version, which doesn't support Python 3.2
+    pass
+
+
+PY3 = sys.version_info[0] >= 3
+
+
+# This adds a new keyword to the setup() function
+Distribution.skip_2to3 = []
+
+
+def adjust_compiler(package):
+    """
+    This function detects broken compilers and switches to another.  If
+    the environment variable CC is explicitly set, or a compiler is
+    specified on the commandline, no override is performed -- the purpose
+    here is to only override a default compiler.
+
+    The specific compilers with problems are:
+
+        * The default compiler in XCode-4.2, llvm-gcc-4.2,
+          segfaults when compiling wcslib.
+
+    The set of broken compilers can be updated by changing the
+    compiler_mapping variable.  It is a list of 2-tuples where the
+    first in the pair is a regular expression matching the version
+    of the broken compiler, and the second is the compiler to change
+    to.
+    """
+
+    compiler_mapping = [
+        (b'i686-apple-darwin[0-9]*-llvm-gcc-4.2', 'clang')
+        ]
+
+    if _module_state['adjusted_compiler']:
+        return
+
+    # Whatever the result of this function is, it only needs to be run once
+    _module_state['adjusted_compiler'] = True
+
+    if 'CC' in os.environ:
+
+        # Check that CC is not set to llvm-gcc-4.2
+        c_compiler = os.environ['CC']
+
+        try:
+            version = get_compiler_version(c_compiler)
+        except OSError:
+            msg = textwrap.dedent(
+                    """
+                    The C compiler set by the CC environment variable:
+
+                        {compiler:s}
+
+                    cannot be found or executed.
+                    """.format(compiler=c_compiler))
+            log.warn(msg)
+            sys.exit(1)
+
+        for broken, fixed in compiler_mapping:
+            if re.match(broken, version):
+                msg = textwrap.dedent(
+                    """Compiler specified by CC environment variable
+                    ({compiler:s}:{version:s}) will fail to compile {pkg:s}.
+                    Please set CC={fixed:s} and try again.
+                    You can do this, for example, by running:
+
+                        CC={fixed:s} python setup.py <command>
+
+                    where <command> is the command you ran.
+                    """.format(compiler=c_compiler, version=version,
+                               pkg=package, fixed=fixed))
+                log.warn(msg)
+                sys.exit(1)
+
+        # If C compiler is set via CC, and isn't broken, we are good to go. We
+        # should definitely not try accessing the compiler specified by
+        # ``sysconfig.get_config_var('CC')`` lower down, because this may fail
+        # if the compiler used to compile Python is missing (and maybe this is
+        # why the user is setting CC). For example, the official Python 2.7.3
+        # MacOS X binary was compled with gcc-4.2, which is no longer available
+        # in XCode 4.
+        return
+
+    if get_distutils_build_option('compiler'):
+        return
+
+    compiler_type = ccompiler.get_default_compiler()
+
+    if compiler_type == 'unix':
+
+        # We have to get the compiler this way, as this is the one that is
+        # used if os.environ['CC'] is not set. It is actually read in from
+        # the Python Makefile. Note that this is not necessarily the same
+        # compiler as returned by ccompiler.new_compiler()
+        c_compiler = sysconfig.get_config_var('CC')
+
+        try:
+            version = get_compiler_version(c_compiler)
+        except OSError:
+            msg = textwrap.dedent(
+                    """
+                    The C compiler used to compile Python {compiler:s}, and
+                    which is normally used to compile C extensions, is not
+                    available. You can explicitly specify which compiler to
+                    use by setting the CC environment variable, for example:
+
+                        CC=gcc python setup.py <command>
+
+                    or if you are using MacOS X, you can try:
+
+                        CC=clang python setup.py <command>
+                    """.format(compiler=c_compiler))
+            log.warn(msg)
+            sys.exit(1)
+
+
+        for broken, fixed in compiler_mapping:
+            if re.match(broken, version):
+                os.environ['CC'] = fixed
+                break
+
+
+def get_compiler_version(compiler):
+
+    process = subprocess.Popen(
+        shlex.split(compiler) + ['--version'], stdout=subprocess.PIPE)
+
+    output = process.communicate()[0].strip()
+    try:
+        version = output.split()[0]
+    except IndexError:
+        return 'unknown'
+
+    return version
+
+
+def get_debug_option(packagename):
+    """ Determines if the build is in debug mode.
+
+    Returns
+    -------
+    debug : bool
+        True if the current build was started with the debug option, False
+        otherwise.
+
+    """
+
+    try:
+        current_debug = get_pkg_version_module(packagename,
+                                               fromlist=['debug'])[0]
+    except (ImportError, AttributeError):
+        current_debug = None
+
+    # Only modify the debug flag if one of the build commands was explicitly
+    # run (i.e. not as a sub-command of something else)
+    dist = get_dummy_distribution()
+    if any(cmd in dist.commands for cmd in ['build', 'build_ext']):
+        debug = bool(get_distutils_build_option('debug'))
+    else:
+        debug = bool(current_debug)
+
+    if current_debug is not None and current_debug != debug:
+        build_ext_cmd = dist.get_command_class('build_ext')
+        build_ext_cmd.force_rebuild = True
+
+    return debug
+
+
+def register_commands(package, version, release, srcdir='.'):
+    if _module_state['registered_commands'] is not None:
+        return _module_state['registered_commands']
+
+    if _module_state['have_sphinx']:
+        from .commands.build_sphinx import AstropyBuildSphinx
+    else:
+        AstropyBuildSphinx = FakeBuildSphinx
+
+    _module_state['registered_commands'] = registered_commands = {
+        'test': generate_test_command(package),
+
+        # Use distutils' sdist because it respects package_data.
+        # setuptools/distributes sdist requires duplication of information in
+        # MANIFEST.in
+        'sdist': DistutilsSdist,
+
+        # The exact form of the build_ext command depends on whether or not
+        # we're building a release version
+        'build_ext': generate_build_ext_command(package, release),
+
+        # We have a custom build_py to generate the default configuration file
+        'build_py': AstropyBuildPy,
+
+        # Since install can (in some circumstances) be run without
+        # first building, we also need to override install and
+        # install_lib.  See #2223
+        'install': AstropyInstall,
+        'install_lib': AstropyInstallLib,
+
+        'register': AstropyRegister,
+        'build_sphinx': AstropyBuildSphinx
+    }
+
+    # Need to override the __name__ here so that the commandline options are
+    # presented as being related to the "build" command, for example; normally
+    # this wouldn't be necessary since commands also have a command_name
+    # attribute, but there is a bug in distutils' help display code that it
+    # uses __name__ instead of command_name. Yay distutils!
+    for name, cls in registered_commands.items():
+        cls.__name__ = name
+
+    # Add a few custom options; more of these can be added by specific packages
+    # later
+    for option in [
+            ('use-system-libraries',
+             "Use system libraries whenever possible", True)]:
+        add_command_option('build', *option)
+        add_command_option('install', *option)
+
+    add_command_hooks(registered_commands, srcdir=srcdir)
+
+    return registered_commands
+
+
+def add_command_hooks(commands, srcdir='.'):
+    """
+    Look through setup_package.py modules for functions with names like
+    ``pre_<command_name>_hook`` and ``post_<command_name>_hook`` where
+    ``<command_name>`` is the name of a ``setup.py`` command (e.g. build_ext).
+
+    If either hook is present this adds a wrapped version of that command to
+    the passed in ``commands`` `dict`.  ``commands`` may be pre-populated with
+    other custom distutils command classes that should be wrapped if there are
+    hooks for them (e.g. `AstropyBuildPy`).
+    """
+
+    hook_re = re.compile(r'^(pre|post)_(.+)_hook$')
+
+    # Distutils commands have a method of the same name, but it is not a
+    # *classmethod* (which probably didn't exist when distutils was first
+    # written)
+    def get_command_name(cmdcls):
+        if hasattr(cmdcls, 'command_name'):
+            return cmdcls.command_name
+        else:
+            return cmdcls.__name__
+
+    packages = filter_packages(find_packages(srcdir))
+    dist = get_dummy_distribution()
+
+    hooks = collections.defaultdict(dict)
+
+    for setuppkg in iter_setup_packages(srcdir, packages):
+        for name, obj in vars(setuppkg).items():
+            match = hook_re.match(name)
+            if not match:
+                continue
+
+            hook_type = match.group(1)
+            cmd_name = match.group(2)
+
+            cmd_cls = dist.get_command_class(cmd_name)
+
+            if hook_type not in hooks[cmd_name]:
+                hooks[cmd_name][hook_type] = []
+
+            hooks[cmd_name][hook_type].append((setuppkg.__name__, obj))
+
+    for cmd_name, cmd_hooks in hooks.items():
+        commands[cmd_name] = generate_hooked_command(
+                cmd_name, dist.get_command_class(cmd_name), cmd_hooks)
+
+
+def generate_hooked_command(cmd_name, cmd_cls, hooks):
+    """
+    Returns a generated subclass of ``cmd_cls`` that runs the pre- and
+    post-command hooks for that command before and after the ``cmd_cls.run``
+    method.
+    """
+
+    def run(self, orig_run=cmd_cls.run):
+        self.run_command_hooks('pre_hooks')
+        orig_run(self)
+        self.run_command_hooks('post_hooks')
+
+    return type(cmd_name, (cmd_cls, object),
+                {'run': run, 'run_command_hooks': run_command_hooks,
+                 'pre_hooks': hooks.get('pre', []),
+                 'post_hooks': hooks.get('post', [])})
+
+
+def run_command_hooks(cmd_obj, hook_kind):
+    """Run hooks registered for that command and phase.
+
+    *cmd_obj* is a finalized command object; *hook_kind* is either
+    'pre_hook' or 'post_hook'.
+    """
+
+    hooks = getattr(cmd_obj, hook_kind, None)
+
+    if not hooks:
+        return
+
+    for modname, hook in hooks:
+        if isinstance(hook, str):
+            try:
+                hook_obj = resolve_name(hook)
+            except ImportError as exc:
+                raise DistutilsModuleError(
+                        'cannot find hook {0}: {1}'.format(hook, err))
+        else:
+            hook_obj = hook
+
+        if not callable(hook_obj):
+            raise DistutilsOptionError('hook {0!r} is not callable' % hook)
+
+        log.info('running {0} from {1} for {2} command'.format(
+                 hook_kind.rstrip('s'), modname, cmd_obj.get_command_name()))
+
+        try :
+            hook_obj(cmd_obj)
+        except Exception as exc:
+            log.error('{0} command hook {1} raised an exception: %s\n'.format(
+                hook_obj.__name__, cmd_obj.get_command_name()))
+            log.error(traceback.format_exc())
+            sys.exit(1)
+
+
+def generate_test_command(package_name):
+    """
+    Creates a custom 'test' command for the given package which sets the
+    command's ``package_name`` class attribute to the name of the package being
+    tested.
+    """
+
+    return type(package_name.title() + 'Test', (AstropyTest,),
+                {'package_name': package_name})
+
+
+def update_package_files(srcdir, extensions, package_data, packagenames,
+                         package_dirs):
+    """
+    This function is deprecated and maintained for backward compatibility
+    with affiliated packages.  Affiliated packages should update their
+    setup.py to use `get_package_info` instead.
+    """
+
+    info = get_package_info(srcdir)
+    extensions.extend(info['ext_modules'])
+    package_data.update(info['package_data'])
+    packagenames = list(set(packagenames + info['packages']))
+    package_dirs.update(info['package_dir'])
+
+
+def get_package_info(srcdir='.', exclude=()):
+    """
+    Collates all of the information for building all subpackages
+    subpackages and returns a dictionary of keyword arguments that can
+    be passed directly to `distutils.setup`.
+
+    The purpose of this function is to allow subpackages to update the
+    arguments to the package's ``setup()`` function in its setup.py
+    script, rather than having to specify all extensions/package data
+    directly in the ``setup.py``.  See Astropy's own
+    ``setup.py`` for example usage and the Astropy development docs
+    for more details.
+
+    This function obtains that information by iterating through all
+    packages in ``srcdir`` and locating a ``setup_package.py`` module.
+    This module can contain the following functions:
+    ``get_extensions()``, ``get_package_data()``,
+    ``get_build_options()``, ``get_external_libraries()``,
+    and ``requires_2to3()``.
+
+    Each of those functions take no arguments.
+
+    - ``get_extensions`` returns a list of
+      `distutils.extension.Extension` objects.
+
+    - ``get_package_data()`` returns a dict formatted as required by
+      the ``package_data`` argument to ``setup()``.
+
+    - ``get_build_options()`` returns a list of tuples describing the
+      extra build options to add.
+
+    - ``get_external_libraries()`` returns
+      a list of libraries that can optionally be built using external
+      dependencies.
+
+    - ``get_entry_points()`` returns a dict formatted as required by
+      the ``entry_points`` argument to ``setup()``.
+
+    - ``requires_2to3()`` should return `True` when the source code
+      requires `2to3` processing to run on Python 3.x.  If
+      ``requires_2to3()`` is missing, it is assumed to return `True`.
+
+    """
+    ext_modules = []
+    packages = []
+    package_data = {}
+    package_dir = {}
+    skip_2to3 = []
+
+    # Use the find_packages tool to locate all packages and modules
+    packages = filter_packages(find_packages(srcdir, exclude=exclude))
+
+    # For each of the setup_package.py modules, extract any
+    # information that is needed to install them.  The build options
+    # are extracted first, so that their values will be available in
+    # subsequent calls to `get_extensions`, etc.
+    for setuppkg in iter_setup_packages(srcdir, packages):
+        if hasattr(setuppkg, 'get_build_options'):
+            options = setuppkg.get_build_options()
+            for option in options:
+                add_command_option('build', *option)
+        if hasattr(setuppkg, 'get_external_libraries'):
+            libraries = setuppkg.get_external_libraries()
+            for library in libraries:
+                add_external_library(library)
+        if hasattr(setuppkg, 'requires_2to3'):
+            requires_2to3 = setuppkg.requires_2to3()
+        else:
+            requires_2to3 = True
+        if not requires_2to3:
+            skip_2to3.append(
+                os.path.dirname(setuppkg.__file__))
+
+    for setuppkg in iter_setup_packages(srcdir, packages):
+        # get_extensions must include any Cython extensions by their .pyx
+        # filename.
+        if hasattr(setuppkg, 'get_extensions'):
+            ext_modules.extend(setuppkg.get_extensions())
+        if hasattr(setuppkg, 'get_package_data'):
+            package_data.update(setuppkg.get_package_data())
+
+    # Locate any .pyx files not already specified, and add their extensions in.
+    # The default include dirs include numpy to facilitate numerical work.
+    ext_modules.extend(get_cython_extensions(srcdir, packages, ext_modules,
+                                             ['numpy']))
+
+    # Now remove extensions that have the special name 'skip_cython', as they
+    # exist Only to indicate that the cython extensions shouldn't be built
+    for i, ext in reversed(list(enumerate(ext_modules))):
+        if ext.name == 'skip_cython':
+            del ext_modules[i]
+
+    # On Microsoft compilers, we need to pass the '/MANIFEST'
+    # commandline argument.  This was the default on MSVC 9.0, but is
+    # now required on MSVC 10.0, but it doesn't seeem to hurt to add
+    # it unconditionally.
+    if get_compiler_option() == 'msvc':
+        for ext in ext_modules:
+            ext.extra_link_args.append('/MANIFEST')
+
+    return {
+        'ext_modules': ext_modules,
+        'packages': packages,
+        'package_dir': package_dir,
+        'package_data': package_data,
+        'skip_2to3': skip_2to3
+        }
+
+
+def iter_setup_packages(srcdir, packages):
+    """ A generator that finds and imports all of the ``setup_package.py``
+    modules in the source packages.
+
+    Returns
+    -------
+    modgen : generator
+        A generator that yields (modname, mod), where `mod` is the module and
+        `modname` is the module name for the ``setup_package.py`` modules.
+
+    """
+
+    for packagename in packages:
+        package_parts = packagename.split('.')
+        package_path = os.path.join(srcdir, *package_parts)
+        setup_package = os.path.relpath(
+            os.path.join(package_path, 'setup_package.py'))
+
+        if os.path.isfile(setup_package):
+            module = import_file(setup_package,
+                                 name=packagename + '.setup_package')
+            yield module
+
+
+def iter_pyx_files(package_dir, package_name):
+    """
+    A generator that yields Cython source files (ending in '.pyx') in the
+    source packages.
+
+    Returns
+    -------
+    pyxgen : generator
+        A generator that yields (extmod, fullfn) where `extmod` is the
+        full name of the module that the .pyx file would live in based
+        on the source directory structure, and `fullfn` is the path to
+        the .pyx file.
+    """
+    for dirpath, dirnames, filenames in walk_skip_hidden(package_dir):
+        for fn in filenames:
+            if fn.endswith('.pyx'):
+                fullfn = os.path.relpath(os.path.join(dirpath, fn))
+                # Package must match file name
+                extmod = '.'.join([package_name, fn[:-4]])
+                yield (extmod, fullfn)
+
+        break  # Don't recurse into subdirectories
+
+
+def get_cython_extensions(srcdir, packages, prevextensions=tuple(),
+                          extincludedirs=None):
+    """
+    Looks for Cython files and generates Extensions if needed.
+
+    Parameters
+    ----------
+    srcdir : str
+        Path to the root of the source directory to search.
+    prevextensions : list of `~distutils.core.Extension` objects
+        The extensions that are already defined.  Any .pyx files already here
+        will be ignored.
+    extincludedirs : list of str or None
+        Directories to include as the `include_dirs` argument to the generated
+        `~distutils.core.Extension` objects.
+
+    Returns
+    -------
+    exts : list of `~distutils.core.Extension` objects
+        The new extensions that are needed to compile all .pyx files (does not
+        include any already in `prevextensions`).
+    """
+
+    # Vanilla setuptools and old versions of distribute include Cython files
+    # as .c files in the sources, not .pyx, so we cannot simply look for
+    # existing .pyx sources in the previous sources, but we should also check
+    # for .c files with the same remaining filename. So we look for .pyx and
+    # .c files, and we strip the extension.
+    prevsourcepaths = []
+    ext_modules = []
+
+    for ext in prevextensions:
+        for s in ext.sources:
+            if s.endswith(('.pyx', '.c')):
+                sourcepath = os.path.realpath(os.path.splitext(s)[0])
+                prevsourcepaths.append(sourcepath)
+
+    for package_name in packages:
+        package_parts = package_name.split('.')
+        package_path = os.path.join(srcdir, *package_parts)
+
+        for extmod, pyxfn in iter_pyx_files(package_path, package_name):
+            sourcepath = os.path.realpath(os.path.splitext(pyxfn)[0])
+            if sourcepath not in prevsourcepaths:
+                ext_modules.append(Extension(extmod, [pyxfn],
+                                             include_dirs=extincludedirs))
+
+    return ext_modules
+
+
+class DistutilsExtensionArgs(collections.defaultdict):
+    """
+    A special dictionary whose default values are the empty list.
+
+    This is useful for building up a set of arguments for
+    `distutils.Extension` without worrying whether the entry is
+    already present.
+    """
+    def __init__(self, *args, **kwargs):
+        def default_factory():
+            return []
+
+        super(DistutilsExtensionArgs, self).__init__(
+            default_factory, *args, **kwargs)
+
+    def update(self, other):
+        for key, val in other.items():
+            self[key].extend(val)
+
+
+def pkg_config(packages, default_libraries, executable='pkg-config'):
+    """
+    Uses pkg-config to update a set of distutils Extension arguments
+    to include the flags necessary to link against the given packages.
+
+    If the pkg-config lookup fails, default_libraries is applied to
+    libraries.
+
+    Parameters
+    ----------
+    packages : list of str
+        A list of pkg-config packages to look up.
+
+    default_libraries : list of str
+        A list of library names to use if the pkg-config lookup fails.
+
+    Returns
+    -------
+    config : dict
+        A dictionary containing keyword arguments to
+        `distutils.Extension`.  These entries include:
+
+        - ``include_dirs``: A list of include directories
+        - ``library_dirs``: A list of library directories
+        - ``libraries``: A list of libraries
+        - ``define_macros``: A list of macro defines
+        - ``undef_macros``: A list of macros to undefine
+        - ``extra_compile_args``: A list of extra arguments to pass to
+          the compiler
+    """
+
+    flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries',
+                '-D': 'define_macros', '-U': 'undef_macros'}
+    command = "{0} --libs --cflags {1}".format(executable, ' '.join(packages)),
+
+    result = DistutilsExtensionArgs()
+
+    try:
+        pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+        output = pipe.communicate()[0].strip()
+    except subprocess.CalledProcessError as e:
+        lines = [
+            "{0} failed.  This may cause the build to fail below.".format(executable),
+            "  command: {0}".format(e.cmd),
+            "  returncode: {0}".format(e.returncode),
+            "  output: {0}".format(e.output)
+            ]
+        log.warn('\n'.join(lines))
+        result['libraries'].extend(default_libraries)
+    else:
+        if pipe.returncode != 0:
+            lines = [
+                "pkg-config could not lookup up package(s) {0}.".format(
+                    ", ".join(packages)),
+                "This may cause the build to fail below."
+                ]
+            log.warn('\n'.join(lines))
+            result['libraries'].extend(default_libraries)
+        else:
+            for token in output.split():
+                # It's not clear what encoding the output of
+                # pkg-config will come to us in.  It will probably be
+                # some combination of pure ASCII (for the compiler
+                # flags) and the filesystem encoding (for any argument
+                # that includes directories or filenames), but this is
+                # just conjecture, as the pkg-config documentation
+                # doesn't seem to address it.
+                arg = token[:2].decode('ascii')
+                value = token[2:].decode(sys.getfilesystemencoding())
+                if arg in flag_map:
+                    if arg == '-D':
+                        value = tuple(value.split('=', 1))
+                    result[flag_map[arg]].append(value)
+                else:
+                    result['extra_compile_args'].append(value)
+
+    return result
+
+
+def add_external_library(library):
+    """
+    Add a build option for selecting the internal or system copy of a library.
+
+    Parameters
+    ----------
+    library : str
+        The name of the library.  If the library is `foo`, the build
+        option will be called `--use-system-foo`.
+    """
+
+    for command in ['build', 'build_ext', 'install']:
+        add_command_option(command, str('use-system-' + library),
+                           'Use the system {0} library'.format(library),
+                           is_bool=True)
+
+
+def use_system_library(library):
+    """
+    Returns `True` if the build configuration indicates that the given
+    library should use the system copy of the library rather than the
+    internal one.
+
+    For the given library `foo`, this will be `True` if
+    `--use-system-foo` or `--use-system-libraries` was provided at the
+    commandline or in `setup.cfg`.
+
+    Parameters
+    ----------
+    library : str
+        The name of the library
+
+    Returns
+    -------
+    use_system : bool
+        `True` if the build should use the system copy of the library.
+    """
+    return (
+        get_distutils_build_or_install_option('use_system_{0}'.format(library))
+        or get_distutils_build_or_install_option('use_system_libraries'))
+
+
+ at extends_doc(_find_packages)
+def find_packages(where='.', exclude=(), invalidate_cache=False):
+    """
+    This version of ``find_packages`` caches previous results to speed up
+    subsequent calls.  Use ``invalide_cache=True`` to ignore cached results
+    from previous ``find_packages`` calls, and repeat the package search.
+    """
+
+    if not invalidate_cache and _module_state['package_cache'] is not None:
+        return _module_state['package_cache']
+
+    packages = _find_packages(where=where, exclude=exclude)
+    _module_state['package_cache'] = packages
+
+    return packages
+
+
+def filter_packages(packagenames):
+    """
+    Removes some packages from the package list that shouldn't be
+    installed on the current version of Python.
+    """
+
+    if PY3:
+        exclude = '_py2'
+    else:
+        exclude = '_py3'
+
+    return [x for x in packagenames if not x.endswith(exclude)]
+
+
+class FakeBuildSphinx(Command):
+    """
+    A dummy build_sphinx command that is called if Sphinx is not
+    installed and displays a relevant error message
+    """
+
+    #user options inherited from sphinx.setup_command.BuildDoc
+    user_options = [
+         ('fresh-env', 'E', '' ),
+         ('all-files', 'a', ''),
+         ('source-dir=', 's', ''),
+         ('build-dir=', None, ''),
+         ('config-dir=', 'c', ''),
+         ('builder=', 'b', ''),
+         ('project=', None, ''),
+         ('version=', None, ''),
+         ('release=', None, ''),
+         ('today=', None, ''),
+         ('link-index', 'i', ''),
+     ]
+
+    #user options appended in astropy.setup_helpers.AstropyBuildSphinx
+    user_options.append(('warnings-returncode', 'w',''))
+    user_options.append(('clean-docs', 'l', ''))
+    user_options.append(('no-intersphinx', 'n', ''))
+    user_options.append(('open-docs-in-browser', 'o',''))
+
+    def initialize_options(self):
+        try:
+            raise RuntimeError("Sphinx must be installed for build_sphinx")
+        except:
+            log.error('error : Sphinx must be installed for build_sphinx')
+            sys.exit(1)
diff --git a/astropy_helpers/astropy_helpers/sphinx/__init__.py b/astropy_helpers/astropy_helpers/sphinx/__init__.py
new file mode 100644
index 0000000..e446ac0
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/__init__.py
@@ -0,0 +1,6 @@
+"""
+This package contains utilities and extensions for the Astropy sphinx
+documentation.  In particular, the `astropy.sphinx.conf` should be imported by
+the sphinx ``conf.py`` file for affiliated packages that wish to make use of
+the Astropy documentation format.
+"""
diff --git a/astropy_helpers/astropy_helpers/sphinx/conf.py b/astropy_helpers/astropy_helpers/sphinx/conf.py
new file mode 100644
index 0000000..d6809b5
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/conf.py
@@ -0,0 +1,311 @@
+# -*- coding: utf-8 -*-
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+#
+# Astropy shared Sphinx settings.  These settings are shared between
+# astropy itself and affiliated packages.
+#
+# Note that not all possible configuration values are present in this file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import warnings
+
+from os import path
+
+
+# -- General configuration ----------------------------------------------------
+
+# The version check in Sphinx itself can only compare the major and
+# minor parts of the version number, not the micro.  To do a more
+# specific version check, call check_sphinx_version("x.y.z.") from
+# your project's conf.py
+needs_sphinx = '1.2'
+
+
+def check_sphinx_version(expected_version):
+    import sphinx
+    from distutils import version
+
+    sphinx_version = version.LooseVersion(sphinx.__version__)
+    expected_version = version.LooseVersion(expected_version)
+    if sphinx_version < expected_version:
+        raise RuntimeError(
+            "At least Sphinx version {0} is required to build this "
+            "documentation.  Found {1}.".format(
+                expected_version, sphinx_version))
+
+
+# Configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {
+    'python': ('http://docs.python.org/', None),
+    'python3': ('http://docs.python.org/3/', path.abspath(path.join(path.dirname(__file__), 'local/python3links.inv'))),
+    'numpy': ('http://docs.scipy.org/doc/numpy/', None),
+    'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None),
+    'matplotlib': ('http://matplotlib.org/', None),
+    'astropy': ('http://docs.astropy.org/en/stable/', None),
+    'h5py': ('http://docs.h5py.org/en/latest/', None)
+    }
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# Add any paths that contain templates here, relative to this directory.
+# templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents. Set to the "smart" one.
+default_role = 'obj'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# This is added to the end of RST files - a good place to put substitutions to
+# be used globally.
+rst_epilog = """
+.. _Astropy: http://astropy.org
+"""
+
+
+# -- Project information ------------------------------------------------------
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+#pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Settings for extensions and extension options ----------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.todo',
+    'sphinx.ext.coverage',
+    'sphinx.ext.pngmath',
+    'sphinx.ext.inheritance_diagram',
+    'astropy_helpers.sphinx.ext.numpydoc',
+    'astropy_helpers.sphinx.ext.astropyautosummary',
+    'astropy_helpers.sphinx.ext.autodoc_enhancements',
+    'astropy_helpers.sphinx.ext.automodsumm',
+    'astropy_helpers.sphinx.ext.automodapi',
+    'astropy_helpers.sphinx.ext.tocdepthfix',
+    'astropy_helpers.sphinx.ext.doctest',
+    'astropy_helpers.sphinx.ext.changelog_links',
+    'astropy_helpers.sphinx.ext.viewcode',  # Use patched version of viewcode
+    'astropy_helpers.sphinx.ext.smart_resolver'
+    ]
+
+# Above, we use a patched version of viewcode rather than 'sphinx.ext.viewcode'
+# This can be changed to the sphinx version once the following issue is fixed
+# in sphinx:
+# https://bitbucket.org/birkenfeld/sphinx/issue/623/
+# extension-viewcode-fails-with-function
+
+try:
+    import matplotlib.sphinxext.plot_directive
+    extensions += [matplotlib.sphinxext.plot_directive.__name__]
+# AttributeError is checked here in case matplotlib is installed but
+# Sphinx isn't.  Note that this module is imported by the config file
+# generator, even if we're not building the docs.
+except (ImportError, AttributeError):
+    warnings.warn(
+        "matplotlib's plot_directive could not be imported. " +
+        "Inline plots will not be included in the output")
+
+# Don't show summaries of the members in each class along with the
+# class' docstring
+numpydoc_show_class_members = False
+
+autosummary_generate = True
+
+automodapi_toctreedirnm = 'api'
+
+# Class documentation should contain *both* the class docstring and
+# the __init__ docstring
+autoclass_content = "both"
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = [path.abspath(path.join(path.dirname(__file__), 'themes'))]
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'bootstrap-astropy'
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+    '**': ['localtoc.html'],
+    'search': [],
+    'genindex': [],
+    'py-modindex': [],
+}
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+
+# included in the bootstrap-astropy theme
+html_favicon = path.join(html_theme_path[0], html_theme, 'static',
+                         'astropy_logo.ico')
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%d %b %Y'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# -- Options for LaTeX output ------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+latex_use_parts = True
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+latex_preamble = r"""
+% Use a more modern-looking monospace font
+\usepackage{inconsolata}
+
+% The enumitem package provides unlimited nesting of lists and enums.
+% Sphinx may use this in the future, in which case this can be removed.
+% See https://bitbucket.org/birkenfeld/sphinx/issue/777/latex-output-too-deeply-nested
+\usepackage{enumitem}
+\setlistdepth{15}
+
+% In the parameters section, place a newline after the Parameters
+% header.  (This is stolen directly from Numpy's conf.py, since it
+% affects Numpy-style docstrings).
+\usepackage{expdlist}
+\let\latexdescription=\description
+\def\description{\latexdescription{}{} \breaklabel}
+
+% Support the superscript Unicode numbers used by the "unicode" units
+% formatter
+\DeclareUnicodeCharacter{2070}{\ensuremath{^0}}
+\DeclareUnicodeCharacter{00B9}{\ensuremath{^1}}
+\DeclareUnicodeCharacter{00B2}{\ensuremath{^2}}
+\DeclareUnicodeCharacter{00B3}{\ensuremath{^3}}
+\DeclareUnicodeCharacter{2074}{\ensuremath{^4}}
+\DeclareUnicodeCharacter{2075}{\ensuremath{^5}}
+\DeclareUnicodeCharacter{2076}{\ensuremath{^6}}
+\DeclareUnicodeCharacter{2077}{\ensuremath{^7}}
+\DeclareUnicodeCharacter{2078}{\ensuremath{^8}}
+\DeclareUnicodeCharacter{2079}{\ensuremath{^9}}
+\DeclareUnicodeCharacter{207B}{\ensuremath{^-}}
+\DeclareUnicodeCharacter{00B0}{\ensuremath{^{\circ}}}
+\DeclareUnicodeCharacter{2032}{\ensuremath{^{\prime}}}
+\DeclareUnicodeCharacter{2033}{\ensuremath{^{\prime\prime}}}
+
+% Make the "warning" and "notes" sections use a sans-serif font to
+% make them stand out more.
+\renewenvironment{notice}[2]{
+  \def\py at noticetype{#1}
+  \csname py at noticestart@#1\endcsname
+  \textsf{\textbf{#2}}
+}{\csname py at noticeend@\py at noticetype\endcsname}
+"""
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# -- Options for the linkcheck builder ----------------------------------------
+
+# A timeout value, in seconds, for the linkcheck builder
+linkcheck_timeout = 60
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/__init__.py b/astropy_helpers/astropy_helpers/sphinx/ext/__init__.py
new file mode 100644
index 0000000..0fce2cf
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/__init__.py
@@ -0,0 +1,3 @@
+from __future__ import division, absolute_import, print_function
+
+from .numpydoc import setup
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/astropyautosummary.py b/astropy_helpers/astropy_helpers/sphinx/ext/astropyautosummary.py
new file mode 100644
index 0000000..c513256
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/astropyautosummary.py
@@ -0,0 +1,113 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This sphinx extension builds off of `sphinx.ext.autosummary` to
+clean up some issues it presents in the Astropy docs.
+
+The main issue this fixes is the summary tables getting cut off before the
+end of the sentence in some cases.
+
+Note: Sphinx 1.2 appears to have fixed the the main issues in the stock
+autosummary extension that are addressed by this extension.  So use of this
+extension with newer versions of Sphinx is deprecated.
+"""
+
+import re
+
+from distutils.version import LooseVersion
+
+import sphinx
+
+from sphinx.ext.autosummary import Autosummary
+
+from ...utils import deprecated
+
+# used in AstropyAutosummary.get_items
+_itemsummrex = re.compile(r'^([A-Z].*?\.(?:\s|$))')
+
+
+ at deprecated('1.0', message='AstropyAutosummary is only needed when used '
+                           'with Sphinx versions less than 1.2')
+class AstropyAutosummary(Autosummary):
+    def get_items(self, names):
+        """Try to import the given names, and return a list of
+        ``[(name, signature, summary_string, real_name), ...]``.
+        """
+        from sphinx.ext.autosummary import (get_import_prefixes_from_env,
+            import_by_name, get_documenter, mangle_signature)
+
+        env = self.state.document.settings.env
+
+        prefixes = get_import_prefixes_from_env(env)
+
+        items = []
+
+        max_item_chars = 50
+
+        for name in names:
+            display_name = name
+            if name.startswith('~'):
+                name = name[1:]
+                display_name = name.split('.')[-1]
+
+            try:
+                import_by_name_values = import_by_name(name, prefixes=prefixes)
+            except ImportError:
+                self.warn('[astropyautosummary] failed to import %s' % name)
+                items.append((name, '', '', name))
+                continue
+
+            # to accommodate Sphinx v1.2.2 and v1.2.3
+            if len(import_by_name_values) == 3:
+                real_name, obj, parent = import_by_name_values
+            elif len(import_by_name_values) == 4:
+                real_name, obj, parent, module_name = import_by_name_values
+
+            # NB. using real_name here is important, since Documenters
+            #     handle module prefixes slightly differently
+            documenter = get_documenter(obj, parent)(self, real_name)
+            if not documenter.parse_name():
+                self.warn('[astropyautosummary] failed to parse name %s' % real_name)
+                items.append((display_name, '', '', real_name))
+                continue
+            if not documenter.import_object():
+                self.warn('[astropyautosummary] failed to import object %s' % real_name)
+                items.append((display_name, '', '', real_name))
+                continue
+
+            # -- Grab the signature
+
+            sig = documenter.format_signature()
+            if not sig:
+                sig = ''
+            else:
+                max_chars = max(10, max_item_chars - len(display_name))
+                sig = mangle_signature(sig, max_chars=max_chars)
+                sig = sig.replace('*', r'\*')
+
+            # -- Grab the summary
+
+            doc = list(documenter.process_doc(documenter.get_doc()))
+
+            while doc and not doc[0].strip():
+                doc.pop(0)
+            m = _itemsummrex.search(" ".join(doc).strip())
+            if m:
+                summary = m.group(1).strip()
+            elif doc:
+                summary = doc[0].strip()
+            else:
+                summary = ''
+
+            items.append((display_name, sig, summary, real_name))
+
+        return items
+
+
+def setup(app):
+    # need autosummary, of course
+    app.setup_extension('sphinx.ext.autosummary')
+
+    # Don't make the replacement if Sphinx is at least 1.2
+    if LooseVersion(sphinx.__version__) < LooseVersion('1.2.0'):
+        # this replaces the default autosummary with the astropy one
+        app.add_directive('autosummary', AstropyAutosummary)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/autodoc_enhancements.py b/astropy_helpers/astropy_helpers/sphinx/ext/autodoc_enhancements.py
new file mode 100644
index 0000000..ee63814
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/autodoc_enhancements.py
@@ -0,0 +1,56 @@
+"""
+Miscellaneous enhancements to help autodoc along.
+"""
+
+
+# See
+# https://github.com/astropy/astropy-helpers/issues/116#issuecomment-71254836
+# for further background on this.
+def type_object_attrgetter(obj, attr, *defargs):
+    """
+    This implements an improved attrgetter for type objects (i.e. classes)
+    that can handle class attributes that are implemented as properties on
+    a metaclass.
+
+    Normally `getattr` on a class with a `property` (say, "foo"), would return
+    the `property` object itself.  However, if the class has a metaclass which
+    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
+    the "foo" property on the metaclass and resolve it.  For the purposes of
+    autodoc we just want to document the "foo" property defined on the class,
+    not on the metaclass.
+
+    For example::
+
+        >>> class Meta(type):
+        ...     @property
+        ...     def foo(cls):
+        ...         return 'foo'
+        ...
+        >>> class MyClass(metaclass=Meta):
+        ...     @property
+        ...     def foo(self):
+        ...         \"\"\"Docstring for MyClass.foo property.\"\"\"
+        ...         return 'myfoo'
+        ...
+        >>> getattr(MyClass, 'foo')
+        'foo'
+        >>> type_object_attrgetter(MyClass, 'foo')
+        <property at 0x...>
+        >>> type_object_attrgetter(MyClass, 'foo').__doc__
+        'Docstring for MyClass.foo property.'
+
+    The last line of the example shows the desired behavior for the purposes
+    of autodoc.
+    """
+
+    if attr in obj.__dict__ and isinstance(obj.__dict__[attr], property):
+        # Note, this should only be used for properties--for any other type of
+        # descriptor (classmethod, for example) this can mess up existing
+        # expectcations of what getattr(cls, ...) returns
+        return obj.__dict__[attr]
+    else:
+        return getattr(obj, attr, *defargs)
+
+
+def setup(app):
+    app.add_autodoc_attrgetter(type, type_object_attrgetter)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/automodapi.py b/astropy_helpers/astropy_helpers/sphinx/ext/automodapi.py
new file mode 100644
index 0000000..db7c4c0
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/automodapi.py
@@ -0,0 +1,350 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This sphinx extension adds a tools to simplify generating the API
+documentation for Astropy packages and affiliated packages.
+
+.. _automodapi:
+
+========================
+automodapi directive
+========================
+This directive takes a single argument that must be a module or package. It
+will produce a block of documentation that includes the docstring for the
+package, an :ref:`automodsumm` directive, and an :ref:`automod-diagram` if
+there are any classes in the module. If only the main docstring of the
+module/package is desired in the documentation, use `automodule`_ instead of
+`automodapi`_.
+
+It accepts the following options:
+
+    * ``:no-inheritance-diagram:``
+        If present, the inheritance diagram will not be shown even if
+        the module/package has classes.
+
+    * ``:skip: str``
+        This option results in the
+        specified object being skipped, that is the object will *not* be
+        included in the generated documentation. This option may appear
+        any number of times to skip multiple objects.
+
+    * ``:no-main-docstr:``
+        If present, the docstring for the module/package will not be generated.
+        The function and class tables will still be used, however.
+
+    * ``:headings: str``
+        Specifies the characters (in one string) used as the heading
+        levels used for the generated section. This must have at least 2
+        characters (any after 2 will be ignored). This also *must* match
+        the rest of the documentation on this page for sphinx to be
+        happy. Defaults to "-^", which matches the convention used for
+        Python's documentation, assuming the automodapi call is inside a
+        top-level section (which usually uses '=').
+
+    * ``:no-heading:``
+        If specified do not create a top level heading for the section.
+        That is, do not create a title heading with text like "packagename
+        Package".  The actual docstring for the package/module will still be
+        shown, though, unless ``:no-main-docstr:`` is given.
+
+    * ``:allowed-package-names: str``
+        Specifies the packages that functions/classes documented here are
+        allowed to be from, as comma-separated list of package names. If not
+        given, only objects that are actually in a subpackage of the package
+        currently being documented are included.
+
+This extension also adds two sphinx configuration options:
+
+* ``automodapi_toctreedirnm``
+    This must be a string that specifies the name of the directory the
+    automodsumm generated documentation ends up in. This directory path should
+    be relative to the documentation root (e.g., same place as ``index.rst``).
+    Defaults to ``'api'``.
+
+* ``automodapi_writereprocessed``
+    Should be a bool, and if `True`, will cause `automodapi`_ to write files
+    with any `automodapi`_ sections replaced with the content Sphinx
+    processes after `automodapi`_ has run.  The output files are not
+    actually used by sphinx, so this option is only for figuring out the
+    cause of sphinx warnings or other debugging.  Defaults to `False`.
+
+.. _automodule: http://sphinx-doc.org/latest/ext/autodoc.html?highlight=automodule#directive-automodule
+"""
+
+# Implementation note:
+# The 'automodapi' directive is not actually implemented as a docutils
+# directive. Instead, this extension searches for the 'automodapi' text in
+# all sphinx documents, and replaces it where necessary from a template built
+# into this extension. This is necessary because automodsumm (and autosummary)
+# use the "builder-inited" event, which comes before the directives are
+# actually built.
+
+import inspect
+import os
+import re
+import sys
+
+from .utils import find_mod_objs
+
+
+automod_templ_modheader = """
+{modname} {pkgormod}
+{modhds}{pkgormodhds}
+
+{automoduleline}
+"""
+
+automod_templ_classes = """
+Classes
+{clshds}
+
+.. automodsumm:: {modname}
+    :classes-only:
+    {clsfuncoptions}
+"""
+
+automod_templ_funcs = """
+Functions
+{funchds}
+
+.. automodsumm:: {modname}
+    :functions-only:
+    {clsfuncoptions}
+"""
+
+automod_templ_inh = """
+Class Inheritance Diagram
+{clsinhsechds}
+
+.. automod-diagram:: {modname}
+    :private-bases:
+    :parts: 1
+    {allowedpkgnms}
+"""
+
+_automodapirex = re.compile(r'^(?:\s*\.\.\s+automodapi::\s*)([A-Za-z0-9_.]+)'
+                            r'\s*$((?:\n\s+:[a-zA-Z_\-]+:.*$)*)',
+                            flags=re.MULTILINE)
+# the last group of the above regex is intended to go into finall with the below
+_automodapiargsrex = re.compile(r':([a-zA-Z_\-]+):(.*)$', flags=re.MULTILINE)
+
+
+def automodapi_replace(sourcestr, app, dotoctree=True, docname=None,
+                       warnings=True):
+    """
+    Replaces `sourcestr`'s entries of ".. automdapi::" with the
+    automodapi template form based on provided options.
+
+    This is used with the sphinx event 'source-read' to replace
+    `automodapi`_ entries before sphinx actually processes them, as
+    automodsumm needs the code to be present to generate stub
+    documentation.
+
+    Parameters
+    ----------
+    sourcestr : str
+        The string with sphinx source to be checked for automodapi
+        replacement.
+    app : `sphinx.application.Application`
+        The sphinx application.
+    dotoctree : bool
+        If `True`, a ":toctree:" option will be added in the "..
+        automodsumm::" sections of the template, pointing to the
+        appropriate "generated" directory based on the Astropy convention
+        (e.g. in ``docs/api``)
+    docname : str
+        The name of the file for this `sourcestr` (if known - if not, it
+        can be `None`). If not provided and `dotoctree` is `True`, the
+        generated files may end up in the wrong place.
+    warnings : bool
+        If `False`, all warnings that would normally be issued are
+        silenced.
+
+    Returns
+    -------
+    newstr :str
+        The string with automodapi entries replaced with the correct
+        sphinx markup.
+    """
+
+    spl = _automodapirex.split(sourcestr)
+    if len(spl) > 1:  # automodsumm is in this document
+
+        if dotoctree:
+            toctreestr = ':toctree: '
+            dirnm = app.config.automodapi_toctreedirnm
+            if not dirnm.endswith("/"):
+                dirnm += "/"
+            if docname is not None:
+                toctreestr += '../' * docname.count('/') + dirnm
+            else:
+                toctreestr += dirnm
+        else:
+            toctreestr = ''
+
+        newstrs = [spl[0]]
+        for grp in range(len(spl) // 3):
+            modnm = spl[grp * 3 + 1]
+
+            # find where this is in the document for warnings
+            if docname is None:
+                location = None
+            else:
+                location = (docname, spl[0].count('\n'))
+
+            # initialize default options
+            toskip = []
+            inhdiag = maindocstr = top_head = True
+            hds = '-^'
+            allowedpkgnms = []
+
+            # look for actual options
+            unknownops = []
+            for opname, args in _automodapiargsrex.findall(spl[grp * 3 + 2]):
+                if opname == 'skip':
+                    toskip.append(args.strip())
+                elif opname == 'no-inheritance-diagram':
+                    inhdiag = False
+                elif opname == 'no-main-docstr':
+                    maindocstr = False
+                elif opname == 'headings':
+                    hds = args
+                elif opname == 'no-heading':
+                    top_head = False
+                elif opname == 'allowed-package-names':
+                    allowedpkgnms.append(args.strip())
+                else:
+                    unknownops.append(opname)
+
+            #join all the allowedpkgnms
+            if len(allowedpkgnms) == 0:
+                allowedpkgnms = ''
+                onlylocals = True
+            else:
+                allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms)
+                onlylocals = allowedpkgnms
+
+            # get the two heading chars
+            if len(hds) < 2:
+                msg = 'Not enough headings (got {0}, need 2), using default -^'
+                if warnings:
+                    app.warn(msg.format(len(hds)), location)
+                hds = '-^'
+            h1, h2 = hds.lstrip()[:2]
+
+            # tell sphinx that the remaining args are invalid.
+            if len(unknownops) > 0 and app is not None:
+                opsstrs = ','.join(unknownops)
+                msg = 'Found additional options ' + opsstrs + ' in automodapi.'
+                if warnings:
+                    app.warn(msg, location)
+
+            ispkg, hascls, hasfuncs = _mod_info(modnm, toskip, onlylocals=onlylocals)
+
+            # add automodule directive only if no-main-docstr isn't present
+            if maindocstr:
+                automodline = '.. automodule:: {modname}'.format(modname=modnm)
+            else:
+                automodline = ''
+            if top_head:
+                newstrs.append(automod_templ_modheader.format(modname=modnm,
+                    modhds=h1 * len(modnm),
+                    pkgormod='Package' if ispkg else 'Module',
+                    pkgormodhds=h1 * (8 if ispkg else 7),
+                    automoduleline=automodline))
+            else:
+                newstrs.append(automod_templ_modheader.format(
+                    modname='',
+                    modhds='',
+                    pkgormod='',
+                    pkgormodhds='',
+                    automoduleline=automodline))
+
+            #construct the options for the class/function sections
+            #start out indented at 4 spaces, but need to keep the indentation.
+            clsfuncoptions = []
+            if toctreestr:
+                clsfuncoptions.append(toctreestr)
+            if toskip:
+                clsfuncoptions.append(':skip: ' + ','.join(toskip))
+            if allowedpkgnms:
+                clsfuncoptions.append(allowedpkgnms)
+            clsfuncoptionstr = '\n    '.join(clsfuncoptions)
+
+            if hasfuncs:
+                newstrs.append(automod_templ_funcs.format(
+                    modname=modnm,
+                    funchds=h2 * 9,
+                    clsfuncoptions=clsfuncoptionstr))
+
+            if hascls:
+                newstrs.append(automod_templ_classes.format(
+                    modname=modnm,
+                    clshds=h2 * 7,
+                    clsfuncoptions=clsfuncoptionstr))
+
+            if inhdiag and hascls:
+                # add inheritance diagram if any classes are in the module
+                newstrs.append(automod_templ_inh.format(
+                    modname=modnm,
+                    clsinhsechds=h2 * 25,
+                    allowedpkgnms=allowedpkgnms))
+
+            newstrs.append(spl[grp * 3 + 3])
+
+        newsourcestr = ''.join(newstrs)
+
+        if app.config.automodapi_writereprocessed:
+            # sometimes they are unicode, sometimes not, depending on how
+            # sphinx has processed things
+            if isinstance(newsourcestr, unicode):
+                ustr = newsourcestr
+            else:
+                ustr = newsourcestr.decode(app.config.source_encoding)
+
+            if docname is None:
+                with open(os.path.join(app.srcdir, 'unknown.automodapi'), 'a') as f:
+                    f.write('\n**NEW DOC**\n\n')
+                    f.write(ustr.encode('utf8'))
+            else:
+                with open(os.path.join(app.srcdir, docname + '.automodapi'), 'w') as f:
+                    f.write(ustr.encode('utf8'))
+
+        return newsourcestr
+    else:
+        return sourcestr
+
+
+def _mod_info(modname, toskip=[], onlylocals=True):
+    """
+    Determines if a module is a module or a package and whether or not
+    it has classes or functions.
+    """
+
+    hascls = hasfunc = False
+
+    for localnm, fqnm, obj in zip(*find_mod_objs(modname, onlylocals=onlylocals)):
+        if localnm not in toskip:
+            hascls = hascls or inspect.isclass(obj)
+            hasfunc = hasfunc or inspect.isroutine(obj)
+            if hascls and hasfunc:
+                break
+
+    # find_mod_objs has already imported modname
+    pkg = sys.modules[modname]
+    ispkg = '__init__.' in os.path.split(pkg.__name__)[1]
+
+    return ispkg, hascls, hasfunc
+
+
+def process_automodapi(app, docname, source):
+    source[0] = automodapi_replace(source[0], app, True, docname)
+
+
+def setup(app):
+    # need automodsumm for automodapi
+    app.setup_extension('astropy_helpers.sphinx.ext.automodsumm')
+
+    app.connect('source-read', process_automodapi)
+
+    app.add_config_value('automodapi_toctreedirnm', 'api', True)
+    app.add_config_value('automodapi_writereprocessed', False, True)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/automodsumm.py b/astropy_helpers/astropy_helpers/sphinx/ext/automodsumm.py
new file mode 100644
index 0000000..67db268
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/automodsumm.py
@@ -0,0 +1,592 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This sphinx extension adds two directives for summarizing the public
+members of a module or package.
+
+These directives are primarily for use with the `automodapi`_ extension,
+but can be used independently.
+
+.. _automodsumm:
+
+=======================
+automodsumm directive
+=======================
+
+This directive will produce an "autosummary"-style table for public
+attributes of a specified module. See the `sphinx.ext.autosummary`_ extension
+for details on this process. The main difference from the `autosummary`_
+directive is that `autosummary`_ requires manually inputting all attributes
+that appear in the table, while this captures the entries automatically.
+
+This directive requires a single argument that must be a module or
+package.
+
+It also accepts any options supported by the `autosummary`_ directive-
+see `sphinx.ext.autosummary`_ for details. It also accepts two additional
+options:
+
+    * ``:classes-only:``
+        If present, the autosummary table will only contain entries for
+        classes. This cannot be used at the same time with
+        ``:functions-only:`` .
+
+    * ``:functions-only:``
+        If present, the autosummary table will only contain entries for
+        functions. This cannot be used at the same time with
+        ``:classes-only:`` .
+
+    * ``:skip: obj1, [obj2, obj3, ...]``
+        If present, specifies that the listed objects should be skipped
+        and not have their documentation generated, nor be includded in
+        the summary table.
+
+    * ``:allowed-package-names: pkgormod1, [pkgormod2, pkgormod3, ...]``
+        Specifies the packages that functions/classes documented here are
+        allowed to be from, as comma-separated list of package names. If not
+        given, only objects that are actually in a subpackage of the package
+        currently being documented are included.
+
+This extension also adds one sphinx configuration option:
+
+* ``automodsumm_writereprocessed``
+    Should be a bool, and if True, will cause `automodsumm`_ to write files
+    with any ``automodsumm`` sections replaced with the content Sphinx
+    processes after ``automodsumm`` has run.  The output files are not
+    actually used by sphinx, so this option is only for figuring out the
+    cause of sphinx warnings or other debugging.  Defaults to `False`.
+
+.. _sphinx.ext.autosummary: http://sphinx-doc.org/latest/ext/autosummary.html
+.. _autosummary: http://sphinx-doc.org/latest/ext/autosummary.html#directive-autosummary
+
+.. _automod-diagram:
+
+===========================
+automod-diagram directive
+===========================
+
+This directive will produce an inheritance diagram like that of the
+`sphinx.ext.inheritance_diagram`_ extension.
+
+This directive requires a single argument that must be a module or
+package. It accepts no options.
+
+.. note::
+    Like 'inheritance-diagram', 'automod-diagram' requires
+    `graphviz <http://www.graphviz.org/>`_ to generate the inheritance diagram.
+
+.. _sphinx.ext.inheritance_diagram: http://sphinx-doc.org/latest/ext/inheritance.html
+"""
+
+import inspect
+import os
+import re
+
+from distutils.version import LooseVersion
+
+import sphinx
+from sphinx.ext.autosummary import Autosummary
+from sphinx.ext.inheritance_diagram import InheritanceDiagram
+from docutils.parsers.rst.directives import flag
+
+from .utils import find_mod_objs
+from .astropyautosummary import AstropyAutosummary
+
+
+# Don't use AstropyAutosummary with newer versions of Sphinx
+# See https://github.com/astropy/astropy-helpers/pull/129
+if LooseVersion(sphinx.__version__) < LooseVersion('1.2.0'):
+    BaseAutosummary = AstropyAutosummary
+else:
+    BaseAutosummary = Autosummary
+
+
+def _str_list_converter(argument):
+    """
+    A directive option conversion function that converts the option into a list
+    of strings. Used for 'skip' option.
+    """
+    if argument is None:
+        return []
+    else:
+        return [s.strip() for s in argument.split(',')]
+
+
+class Automodsumm(BaseAutosummary):
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    has_content = False
+    option_spec = dict(Autosummary.option_spec)
+    option_spec['functions-only'] = flag
+    option_spec['classes-only'] = flag
+    option_spec['skip'] = _str_list_converter
+    option_spec['allowed-package-names'] = _str_list_converter
+
+    def run(self):
+        env = self.state.document.settings.env
+        modname = self.arguments[0]
+
+        self.warnings = []
+        nodelist = []
+
+        try:
+            localnames, fqns, objs = find_mod_objs(modname)
+        except ImportError:
+            self.warnings = []
+            self.warn("Couldn't import module " + modname)
+            return self.warnings
+
+        try:
+            # set self.content to trick the Autosummary internals.
+            # Be sure to respect functions-only and classes-only.
+            funconly = 'functions-only' in self.options
+            clsonly = 'classes-only' in self.options
+
+            skipnames = []
+            if 'skip' in self.options:
+                option_skipnames = set(self.options['skip'])
+                for lnm in localnames:
+                    if lnm in option_skipnames:
+                        option_skipnames.remove(lnm)
+                        skipnames.append(lnm)
+                if len(option_skipnames) > 0:
+                    self.warn('Tried to skip objects {objs} in module {mod}, '
+                              'but they were not present.  Ignoring.'.format(
+                              objs=option_skipnames, mod=modname))
+
+            if funconly and not clsonly:
+                cont = []
+                for nm, obj in zip(localnames, objs):
+                    if nm not in skipnames and inspect.isroutine(obj):
+                        cont.append(nm)
+            elif clsonly:
+                cont = []
+                for nm, obj in zip(localnames, objs):
+                    if nm not in skipnames and inspect.isclass(obj):
+                        cont.append(nm)
+            else:
+                if clsonly and funconly:
+                    self.warning('functions-only and classes-only both '
+                                 'defined. Skipping.')
+                cont = [nm for nm in localnames if nm not in skipnames]
+
+            self.content = cont
+
+            #for some reason, even though ``currentmodule`` is substituted in, sphinx
+            #doesn't necessarily recognize this fact.  So we just force it
+            #internally, and that seems to fix things
+            env.temp_data['py:module'] = modname
+
+            #can't use super because Sphinx/docutils has trouble
+            #return super(Autosummary,self).run()
+            nodelist.extend(Autosummary.run(self))
+            return self.warnings + nodelist
+        finally:  # has_content = False for the Automodsumm
+            self.content = []
+
+
+#<-------------------automod-diagram stuff------------------------------------>
+class Automoddiagram(InheritanceDiagram):
+
+    option_spec = dict(InheritanceDiagram.option_spec)
+    option_spec['allowed-package-names'] = _str_list_converter
+
+    def run(self):
+        try:
+            ols = self.options.get('allowed-package-names', [])
+            ols = True if len(ols) == 0 else ols  # if none are given, assume only local
+
+            nms, objs = find_mod_objs(self.arguments[0], onlylocals=ols)[1:]
+        except ImportError:
+            self.warnings = []
+            self.warn("Couldn't import module " + self.arguments[0])
+            return self.warnings
+
+        clsnms = []
+        for n, o in zip(nms, objs):
+
+            if inspect.isclass(o):
+                clsnms.append(n)
+
+        oldargs = self.arguments
+        try:
+            if len(clsnms) > 0:
+                self.arguments = [' '.join(clsnms)]
+            return InheritanceDiagram.run(self)
+        finally:
+            self.arguments = oldargs
+
+
+#<---------------------automodsumm generation stuff--------------------------->
+def process_automodsumm_generation(app):
+    env = app.builder.env
+    ext = app.config.source_suffix
+
+    filestosearch = [x + ext for x in env.found_docs
+                     if os.path.isfile(env.doc2path(x))]\
+
+    liness = []
+    for sfn in filestosearch:
+        lines = automodsumm_to_autosummary_lines(sfn, app)
+        liness.append(lines)
+        if app.config.automodsumm_writereprocessed:
+            if lines:  # empty list means no automodsumm entry is in the file
+                outfn = os.path.join(app.srcdir, sfn) + '.automodsumm'
+                with open(outfn, 'w') as f:
+                    for l in lines:
+                        f.write(l)
+                        f.write('\n')
+
+    for sfn, lines in zip(filestosearch, liness):
+        if len(lines) > 0:
+            generate_automodsumm_docs(lines, sfn, builder=app.builder,
+                                      warn=app.warn, info=app.info,
+                                      suffix=app.config.source_suffix,
+                                      base_path=app.srcdir)
+
+#_automodsummrex = re.compile(r'^(\s*)\.\. automodsumm::\s*([A-Za-z0-9_.]+)\s*'
+#                             r'\n\1(\s*)(\S|$)', re.MULTILINE)
+_lineendrex = r'(?:\n|$)'
+_hdrex = r'^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*' + _lineendrex
+_oprex1 = r'(?:\1(\s+)\S.*' + _lineendrex + ')'
+_oprex2 = r'(?:\1\4\S.*' + _lineendrex + ')'
+_automodsummrex = re.compile(_hdrex + '(' + _oprex1 + '?' + _oprex2 + '*)',
+                             re.MULTILINE)
+
+
+def automodsumm_to_autosummary_lines(fn, app):
+    """
+    Generates lines from a file with an "automodsumm" entry suitable for
+    feeding into "autosummary".
+
+    Searches the provided file for `automodsumm` directives and returns
+    a list of lines specifying the `autosummary` commands for the modules
+    requested. This does *not* return the whole file contents - just an
+    autosummary section in place of any :automodsumm: entries. Note that
+    any options given for `automodsumm` are also included in the
+    generated `autosummary` section.
+
+    Parameters
+    ----------
+    fn : str
+        The name of the file to search for `automodsumm` entries.
+    app : sphinx.application.Application
+        The sphinx Application object
+
+    Return
+    ------
+    lines : list of str
+        Lines for all `automodsumm` entries with the entries replaced by
+        `autosummary` and the module's members added.
+
+
+    """
+    fullfn = os.path.join(app.builder.env.srcdir, fn)
+
+    with open(fullfn) as fr:
+        if 'astropy_helpers.sphinx.ext.automodapi' in app._extensions:
+            from astropy_helpers.sphinx.ext.automodapi import automodapi_replace
+            # Must do the automodapi on the source to get the automodsumm
+            # that might be in there
+            filestr = automodapi_replace(fr.read(), app, True, fn, False)
+        else:
+            filestr = fr.read()
+
+    spl = _automodsummrex.split(filestr)
+    #0th entry is the stuff before the first automodsumm line
+    indent1s = spl[1::5]
+    mods = spl[2::5]
+    opssecs = spl[3::5]
+    indent2s = spl[4::5]
+    remainders = spl[5::5]
+
+    # only grab automodsumm sections and convert them to autosummary with the
+    # entries for all the public objects
+    newlines = []
+
+    #loop over all automodsumms in this document
+    for i, (i1, i2, modnm, ops, rem) in enumerate(zip(indent1s, indent2s, mods,
+                                                    opssecs, remainders)):
+        allindent = i1 + ('' if i2 is None else i2)
+
+        #filter out functions-only and classes-only options if present
+        oplines = ops.split('\n')
+        toskip = []
+        allowedpkgnms = []
+        funcsonly = clssonly = False
+        for i, ln in reversed(list(enumerate(oplines))):
+            if ':functions-only:' in ln:
+                funcsonly = True
+                del oplines[i]
+            if ':classes-only:' in ln:
+                clssonly = True
+                del oplines[i]
+            if ':skip:' in ln:
+                toskip.extend(_str_list_converter(ln.replace(':skip:', '')))
+                del oplines[i]
+            if ':allowed-package-names:' in ln:
+                allowedpkgnms.extend(_str_list_converter(ln.replace(':allowed-package-names:', '')))
+                del oplines[i]
+        if funcsonly and clssonly:
+            msg = ('Defined both functions-only and classes-only options. '
+                   'Skipping this directive.')
+            lnnum = sum([spl[j].count('\n') for j in range(i * 5 + 1)])
+            app.warn('[automodsumm]' + msg, (fn, lnnum))
+            continue
+
+        # Use the currentmodule directive so we can just put the local names
+        # in the autosummary table.  Note that this doesn't always seem to
+        # actually "take" in Sphinx's eyes, so in `Automodsumm.run`, we have to
+        # force it internally, as well.
+        newlines.extend([i1 + '.. currentmodule:: ' + modnm,
+                         '',
+                         '.. autosummary::'])
+        newlines.extend(oplines)
+
+        ols = True if len(allowedpkgnms) == 0 else allowedpkgnms
+        for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols)):
+            if nm in toskip:
+                continue
+            if funcsonly and not inspect.isroutine(obj):
+                continue
+            if clssonly and not inspect.isclass(obj):
+                continue
+            newlines.append(allindent + nm)
+
+    return newlines
+
+
+def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None,
+                              info=None, base_path=None, builder=None,
+                              template_dir=None):
+    """
+    This function is adapted from
+    `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
+    generate source for the automodsumm directives that should be
+    autosummarized. Unlike generate_autosummary_docs, this function is
+    called one file at a time.
+    """
+
+    from sphinx.jinja2glue import BuiltinTemplateLoader
+    from sphinx.ext.autosummary import import_by_name, get_documenter
+    from sphinx.ext.autosummary.generate import (find_autosummary_in_lines,
+                                                 _simple_info, _simple_warn)
+    from sphinx.util.osutil import ensuredir
+    from sphinx.util.inspect import safe_getattr
+    from jinja2 import FileSystemLoader, TemplateNotFound
+    from jinja2.sandbox import SandboxedEnvironment
+
+    if info is None:
+        info = _simple_info
+    if warn is None:
+        warn = _simple_warn
+
+    #info('[automodsumm] generating automodsumm for: ' + srcfn)
+
+    # Create our own templating environment - here we use Astropy's
+    # templates rather than the default autosummary templates, in order to
+    # allow docstrings to be shown for methods.
+    template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'),
+                     os.path.join(base_path, '_templates')]
+    if builder is not None:
+        # allow the user to override the templates
+        template_loader = BuiltinTemplateLoader()
+        template_loader.init(builder, dirs=template_dirs)
+    else:
+        if template_dir:
+            template_dirs.insert(0, template_dir)
+        template_loader = FileSystemLoader(template_dirs)
+    template_env = SandboxedEnvironment(loader=template_loader)
+
+    # read
+    #items = find_autosummary_in_files(sources)
+    items = find_autosummary_in_lines(lines, filename=srcfn)
+    if len(items) > 0:
+        msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
+        info(msg.format(len(items), srcfn))
+
+#    gennms = [item[0] for item in items]
+#    if len(gennms) > 20:
+#        gennms = gennms[:10] + ['...'] + gennms[-10:]
+#    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))
+
+    # remove possible duplicates
+    items = dict([(item, True) for item in items]).keys()
+
+    # keep track of new files
+    new_files = []
+
+    # write
+    for name, path, template_name in sorted(items):
+        if path is None:
+            # The corresponding autosummary:: directive did not have
+            # a :toctree: option
+            continue
+
+        path = os.path.abspath(path)
+        ensuredir(path)
+
+        try:
+            import_by_name_values = import_by_name(name)
+        except ImportError as e:
+            warn('[automodsumm] failed to import %r: %s' % (name, e))
+            continue
+
+        # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively
+        if len(import_by_name_values) == 3:
+            name, obj, parent = import_by_name_values
+        elif len(import_by_name_values) == 4:
+            name, obj, parent, module_name = import_by_name_values
+
+        fn = os.path.join(path, name + suffix)
+
+        # skip it if it exists
+        if os.path.isfile(fn):
+            continue
+
+        new_files.append(fn)
+
+        f = open(fn, 'w')
+
+        try:
+            doc = get_documenter(obj, parent)
+
+            if template_name is not None:
+                template = template_env.get_template(template_name)
+            else:
+                tmplstr = 'autosummary/%s.rst'
+                try:
+                    template = template_env.get_template(tmplstr % doc.objtype)
+                except TemplateNotFound:
+                    template = template_env.get_template(tmplstr % 'base')
+
+            def get_members_mod(obj, typ, include_public=[]):
+                """
+                typ = None -> all
+                """
+                items = []
+                for name in dir(obj):
+                    try:
+                        documenter = get_documenter(safe_getattr(obj, name),
+                                                    obj)
+                    except AttributeError:
+                        continue
+                    if typ is None or documenter.objtype == typ:
+                        items.append(name)
+                public = [x for x in items
+                          if x in include_public or not x.startswith('_')]
+                return public, items
+
+            def get_members_class(obj, typ, include_public=[],
+                                  include_base=False):
+                """
+                typ = None -> all
+                include_base -> include attrs that are from a base class
+                """
+                items = []
+
+                # using dir gets all of the attributes, including the elements
+                # from the base class, otherwise use __slots__ or __dict__
+                if include_base:
+                    names = dir(obj)
+                else:
+                    if hasattr(obj, '__slots__'):
+                        names = tuple(getattr(obj, '__slots__'))
+                    else:
+                        names = getattr(obj, '__dict__').keys()
+
+                for name in names:
+                    try:
+                        documenter = get_documenter(safe_getattr(obj, name),
+                                                    obj)
+                    except AttributeError:
+                        continue
+                    if typ is None or documenter.objtype == typ:
+                        items.append(name)
+                public = [x for x in items
+                          if x in include_public or not x.startswith('_')]
+                return public, items
+
+            ns = {}
+
+            if doc.objtype == 'module':
+                ns['members'] = get_members_mod(obj, None)
+                ns['functions'], ns['all_functions'] = \
+                                   get_members_mod(obj, 'function')
+                ns['classes'], ns['all_classes'] = \
+                                 get_members_mod(obj, 'class')
+                ns['exceptions'], ns['all_exceptions'] = \
+                                   get_members_mod(obj, 'exception')
+            elif doc.objtype == 'class':
+                api_class_methods = ['__init__', '__call__']
+                ns['members'] = get_members_class(obj, None)
+                ns['methods'], ns['all_methods'] = \
+                                 get_members_class(obj, 'method', api_class_methods)
+                ns['attributes'], ns['all_attributes'] = \
+                                 get_members_class(obj, 'attribute')
+                ns['methods'].sort()
+                ns['attributes'].sort()
+
+            parts = name.split('.')
+            if doc.objtype in ('method', 'attribute'):
+                mod_name = '.'.join(parts[:-2])
+                cls_name = parts[-2]
+                obj_name = '.'.join(parts[-2:])
+                ns['class'] = cls_name
+            else:
+                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]
+
+            ns['fullname'] = name
+            ns['module'] = mod_name
+            ns['objname'] = obj_name
+            ns['name'] = parts[-1]
+
+            ns['objtype'] = doc.objtype
+            ns['underline'] = len(name) * '='
+
+            # We now check whether a file for reference footnotes exists for
+            # the module being documented. We first check if the
+            # current module is a file or a directory, as this will give a
+            # different path for the reference file. For example, if
+            # documenting astropy.wcs then the reference file is at
+            # ../wcs/references.txt, while if we are documenting
+            # astropy.config.logging_helper (which is at
+            # astropy/config/logging_helper.py) then the reference file is set
+            # to ../config/references.txt
+            if '.' in mod_name:
+                mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1]
+            else:
+                mod_name_dir = mod_name
+            if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \
+               and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])):
+                mod_name_dir = mod_name_dir.rsplit('/', 1)[0]
+
+            # We then have to check whether it exists, and if so, we pass it
+            # to the template.
+            if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')):
+                # An important subtlety here is that the path we pass in has
+                # to be relative to the file being generated, so we have to
+                # figure out the right number of '..'s
+                ndirsback = path.replace(base_path, '').count('/')
+                ref_file_rel_segments = ['..'] * ndirsback
+                ref_file_rel_segments.append(mod_name_dir)
+                ref_file_rel_segments.append('references.txt')
+                ns['referencefile'] = os.path.join(*ref_file_rel_segments)
+
+            rendered = template.render(**ns)
+            f.write(rendered)
+        finally:
+            f.close()
+
+
+def setup(app):
+    # need our autosummary
+    app.setup_extension('astropy_helpers.sphinx.ext.astropyautosummary')
+    # need inheritance-diagram for automod-diagram
+    app.setup_extension('sphinx.ext.inheritance_diagram')
+
+    app.add_directive('automod-diagram', Automoddiagram)
+    app.add_directive('automodsumm', Automodsumm)
+    app.connect('builder-inited', process_automodsumm_generation)
+
+    app.add_config_value('automodsumm_writereprocessed', False, True)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/changelog_links.py b/astropy_helpers/astropy_helpers/sphinx/ext/changelog_links.py
new file mode 100644
index 0000000..f77a31d
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/changelog_links.py
@@ -0,0 +1,78 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This sphinx extension makes the issue numbers in the changelog into links to
+GitHub issues.
+"""
+
+from __future__ import print_function
+
+import re
+
+from docutils.nodes import Text, reference
+
+BLOCK_PATTERN = re.compile('\[#.+\]', flags=re.DOTALL)
+ISSUE_PATTERN = re.compile('#[0-9]+')
+
+
+def process_changelog_links(app, doctree, docname):
+    for rex in app.changelog_links_rexes:
+        if rex.match(docname):
+            break
+    else:
+        # if the doc doesn't match any of the changelog regexes, don't process
+        return
+
+    app.info('[changelog_links] Adding changelog links to "{0}"'.format(docname))
+
+    for item in doctree.traverse():
+
+        if not isinstance(item, Text):
+            continue
+
+        # We build a new list of items to replace the current item. If
+        # a link is found, we need to use a 'reference' item.
+        children = []
+
+        # First cycle through blocks of issues (delimited by []) then
+        # iterate inside each one to find the individual issues.
+        prev_block_end = 0
+        for block in BLOCK_PATTERN.finditer(item):
+            block_start, block_end = block.start(), block.end()
+            children.append(Text(item[prev_block_end:block_start]))
+            block = item[block_start:block_end]
+            prev_end = 0
+            for m in ISSUE_PATTERN.finditer(block):
+                start, end = m.start(), m.end()
+                children.append(Text(block[prev_end:start]))
+                issue_number = block[start:end]
+                refuri = app.config.github_issues_url + issue_number[1:]
+                children.append(reference(text=issue_number,
+                                          name=issue_number,
+                                          refuri=refuri))
+                prev_end = end
+
+            prev_block_end = block_end
+
+            # If no issues were found, this adds the whole item,
+            # otherwise it adds the remaining text.
+            children.append(Text(block[prev_end:block_end]))
+
+        # If no blocks were found, this adds the whole item, otherwise
+        # it adds the remaining text.
+        children.append(Text(item[prev_block_end:]))
+
+        # Replace item by the new list of items we have generated,
+        # which may contain links.
+        item.parent.replace(item, children)
+
+
+def setup_patterns_rexes(app):
+    app.changelog_links_rexes = [re.compile(pat) for pat in
+                                 app.config.changelog_links_docpattern]
+
+
+def setup(app):
+    app.connect('doctree-resolved', process_changelog_links)
+    app.connect('builder-inited', setup_patterns_rexes)
+    app.add_config_value('github_issues_url', None, True)
+    app.add_config_value('changelog_links_docpattern', ['.*changelog.*', 'whatsnew/.*'], True)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/comment_eater.py b/astropy_helpers/astropy_helpers/sphinx/ext/comment_eater.py
new file mode 100644
index 0000000..8cddd33
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/comment_eater.py
@@ -0,0 +1,169 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from io import StringIO
+
+import compiler
+import inspect
+import textwrap
+import tokenize
+
+from .compiler_unparse import unparse
+
+
+class Comment(object):
+    """ A comment block.
+    """
+    is_comment = True
+    def __init__(self, start_lineno, end_lineno, text):
+        # int : The first line number in the block. 1-indexed.
+        self.start_lineno = start_lineno
+        # int : The last line number. Inclusive!
+        self.end_lineno = end_lineno
+        # str : The text block including '#' character but not any leading spaces.
+        self.text = text
+
+    def add(self, string, start, end, line):
+        """ Add a new comment line.
+        """
+        self.start_lineno = min(self.start_lineno, start[0])
+        self.end_lineno = max(self.end_lineno, end[0])
+        self.text += string
+
+    def __repr__(self):
+        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.start_lineno,
+            self.end_lineno, self.text)
+
+
+class NonComment(object):
+    """ A non-comment block of code.
+    """
+    is_comment = False
+    def __init__(self, start_lineno, end_lineno):
+        self.start_lineno = start_lineno
+        self.end_lineno = end_lineno
+
+    def add(self, string, start, end, line):
+        """ Add lines to the block.
+        """
+        if string.strip():
+            # Only add if not entirely whitespace.
+            self.start_lineno = min(self.start_lineno, start[0])
+            self.end_lineno = max(self.end_lineno, end[0])
+
+    def __repr__(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.start_lineno,
+            self.end_lineno)
+
+
+class CommentBlocker(object):
+    """ Pull out contiguous comment blocks.
+    """
+    def __init__(self):
+        # Start with a dummy.
+        self.current_block = NonComment(0, 0)
+
+        # All of the blocks seen so far.
+        self.blocks = []
+
+        # The index mapping lines of code to their associated comment blocks.
+        self.index = {}
+
+    def process_file(self, file):
+        """ Process a file object.
+        """
+        if sys.version_info[0] >= 3:
+            nxt = file.__next__
+        else:
+            nxt = file.next
+        for token in tokenize.generate_tokens(nxt):
+            self.process_token(*token)
+        self.make_index()
+
+    def process_token(self, kind, string, start, end, line):
+        """ Process a single token.
+        """
+        if self.current_block.is_comment:
+            if kind == tokenize.COMMENT:
+                self.current_block.add(string, start, end, line)
+            else:
+                self.new_noncomment(start[0], end[0])
+        else:
+            if kind == tokenize.COMMENT:
+                self.new_comment(string, start, end, line)
+            else:
+                self.current_block.add(string, start, end, line)
+
+    def new_noncomment(self, start_lineno, end_lineno):
+        """ We are transitioning from a noncomment to a comment.
+        """
+        block = NonComment(start_lineno, end_lineno)
+        self.blocks.append(block)
+        self.current_block = block
+
+    def new_comment(self, string, start, end, line):
+        """ Possibly add a new comment.
+
+        Only adds a new comment if this comment is the only thing on the line.
+        Otherwise, it extends the noncomment block.
+        """
+        prefix = line[:start[1]]
+        if prefix.strip():
+            # Oops! Trailing comment, not a comment block.
+            self.current_block.add(string, start, end, line)
+        else:
+            # A comment block.
+            block = Comment(start[0], end[0], string)
+            self.blocks.append(block)
+            self.current_block = block
+
+    def make_index(self):
+        """ Make the index mapping lines of actual code to their associated
+        prefix comments.
+        """
+        for prev, block in zip(self.blocks[:-1], self.blocks[1:]):
+            if not block.is_comment:
+                self.index[block.start_lineno] = prev
+
+    def search_for_comment(self, lineno, default=None):
+        """ Find the comment block just before the given line number.
+
+        Returns None (or the specified default) if there is no such block.
+        """
+        if not self.index:
+            self.make_index()
+        block = self.index.get(lineno, None)
+        text = getattr(block, 'text', default)
+        return text
+
+
+def strip_comment_marker(text):
+    """ Strip # markers at the front of a block of comment text.
+    """
+    lines = []
+    for line in text.splitlines():
+        lines.append(line.lstrip('#'))
+    text = textwrap.dedent('\n'.join(lines))
+    return text
+
+
+def get_class_traits(klass):
+    """ Yield all of the documentation for trait definitions on a class object.
+    """
+    # FIXME: gracefully handle errors here or in the caller?
+    source = inspect.getsource(klass)
+    cb = CommentBlocker()
+    cb.process_file(StringIO(source))
+    mod_ast = compiler.parse(source)
+    class_ast = mod_ast.node.nodes[0]
+    for node in class_ast.code.nodes:
+        # FIXME: handle other kinds of assignments?
+        if isinstance(node, compiler.ast.Assign):
+            name = node.nodes[0].name
+            rhs = unparse(node.expr).strip()
+            doc = strip_comment_marker(cb.search_for_comment(node.lineno, default=''))
+            yield name, rhs, doc
+
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/compiler_unparse.py b/astropy_helpers/astropy_helpers/sphinx/ext/compiler_unparse.py
new file mode 100644
index 0000000..8933a83
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/compiler_unparse.py
@@ -0,0 +1,865 @@
+""" Turn compiler.ast structures back into executable python code.
+
+    The unparse method takes a compiler.ast tree and transforms it back into
+    valid python code.  It is incomplete and currently only works for
+    import statements, function calls, function definitions, assignments, and
+    basic expressions.
+
+    Inspired by python-2.5-svn/Demo/parser/unparse.py
+
+    fixme: We may want to move to using _ast trees because the compiler for
+           them is about 6 times faster than compiler.compile.
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+def unparse(ast, single_line_functions=False):
+    s = StringIO()
+    UnparseCompilerAst(ast, s, single_line_functions)
+    return s.getvalue().lstrip()
+
+op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2,
+                  'compiler.ast.Add':1, 'compiler.ast.Sub':1 }
+
+class UnparseCompilerAst:
+    """ Methods in this class recursively traverse an AST and
+        output source code for the abstract syntax; original formatting
+        is disregarged.
+    """
+
+    #########################################################################
+    # object interface.
+    #########################################################################
+
+    def __init__(self, tree, file = sys.stdout, single_line_functions=False):
+        """ Unparser(tree, file=sys.stdout) -> None.
+
+            Print the source for tree to file.
+        """
+        self.f = file
+        self._single_func = single_line_functions
+        self._do_indent = True
+        self._indent = 0
+        self._dispatch(tree)
+        self._write("\n")
+        self.f.flush()
+
+    #########################################################################
+    # Unparser private interface.
+    #########################################################################
+
+    ### format, output, and dispatch methods ################################
+
+    def _fill(self, text = ""):
+        "Indent a piece of text, according to the current indentation level"
+        if self._do_indent:
+            self._write("\n"+"    "*self._indent + text)
+        else:
+            self._write(text)
+
+    def _write(self, text):
+        "Append a piece of text to the current line."
+        self.f.write(text)
+
+    def _enter(self):
+        "Print ':', and increase the indentation."
+        self._write(": ")
+        self._indent += 1
+
+    def _leave(self):
+        "Decrease the indentation level."
+        self._indent -= 1
+
+    def _dispatch(self, tree):
+        "_dispatcher function, _dispatching tree type T to method _T."
+        if isinstance(tree, list):
+            for t in tree:
+                self._dispatch(t)
+            return
+        meth = getattr(self, "_"+tree.__class__.__name__)
+        if tree.__class__.__name__ == 'NoneType' and not self._do_indent:
+            return
+        meth(tree)
+
+
+    #########################################################################
+    # compiler.ast unparsing methods.
+    #
+    # There should be one method per concrete grammar type. They are
+    # organized in alphabetical order.
+    #########################################################################
+
+    def _Add(self, t):
+        self.__binary_op(t, '+')
+
+    def _And(self, t):
+        self._write(" (")
+        for i, node in enumerate(t.nodes):
+            self._dispatch(node)
+            if i != len(t.nodes)-1:
+                self._write(") and (")
+        self._write(")")
+
+    def _AssAttr(self, t):
+        """ Handle assigning an attribute of an object
+        """
+        self._dispatch(t.expr)
+        self._write('.'+t.attrname)
+
+    def _Assign(self, t):
+        """ Expression Assignment such as "a = 1".
+
+            This only handles assignment in expressions.  Keyword assignment
+            is handled separately.
+        """
+        self._fill()
+        for target in t.nodes:
+            self._dispatch(target)
+            self._write(" = ")
+        self._dispatch(t.expr)
+        if not self._do_indent:
+            self._write('; ')
+
+    def _AssName(self, t):
+        """ Name on left hand side of expression.
+
+            Treat just like a name on the right side of an expression.
+        """
+        self._Name(t)
+
+    def _AssTuple(self, t):
+        """ Tuple on left hand side of an expression.
+        """
+
+        # _write each elements, separated by a comma.
+        for element in t.nodes[:-1]:
+            self._dispatch(element)
+            self._write(", ")
+
+        # Handle the last one without writing comma
+        last_element = t.nodes[-1]
+        self._dispatch(last_element)
+
+    def _AugAssign(self, t):
+        """ +=,-=,*=,/=,**=, etc. operations
+        """
+
+        self._fill()
+        self._dispatch(t.node)
+        self._write(' '+t.op+' ')
+        self._dispatch(t.expr)
+        if not self._do_indent:
+            self._write(';')
+
+    def _Bitand(self, t):
+        """ Bit and operation.
+        """
+
+        for i, node in enumerate(t.nodes):
+            self._write("(")
+            self._dispatch(node)
+            self._write(")")
+            if i != len(t.nodes)-1:
+                self._write(" & ")
+
+    def _Bitor(self, t):
+        """ Bit or operation
+        """
+
+        for i, node in enumerate(t.nodes):
+            self._write("(")
+            self._dispatch(node)
+            self._write(")")
+            if i != len(t.nodes)-1:
+                self._write(" | ")
+
+    def _CallFunc(self, t):
+        """ Function call.
+        """
+        self._dispatch(t.node)
+        self._write("(")
+        comma = False
+        for e in t.args:
+            if comma: self._write(", ")
+            else: comma = True
+            self._dispatch(e)
+        if t.star_args:
+            if comma: self._write(", ")
+            else: comma = True
+            self._write("*")
+            self._dispatch(t.star_args)
+        if t.dstar_args:
+            if comma: self._write(", ")
+            else: comma = True
+            self._write("**")
+            self._dispatch(t.dstar_args)
+        self._write(")")
+
+    def _Compare(self, t):
+        self._dispatch(t.expr)
+        for op, expr in t.ops:
+            self._write(" " + op + " ")
+            self._dispatch(expr)
+
+    def _Const(self, t):
+        """ A constant value such as an integer value, 3, or a string, "hello".
+        """
+        self._dispatch(t.value)
+
+    def _Decorators(self, t):
+        """ Handle function decorators (eg. @has_units)
+        """
+        for node in t.nodes:
+            self._dispatch(node)
+
+    def _Dict(self, t):
+        self._write("{")
+        for  i, (k, v) in enumerate(t.items):
+            self._dispatch(k)
+            self._write(": ")
+            self._dispatch(v)
+            if i < len(t.items)-1:
+                self._write(", ")
+        self._write("}")
+
+    def _Discard(self, t):
+        """ Node for when return value is ignored such as in "foo(a)".
+        """
+        self._fill()
+        self._dispatch(t.expr)
+
+    def _Div(self, t):
+        self.__binary_op(t, '/')
+
+    def _Ellipsis(self, t):
+        self._write("...")
+
+    def _From(self, t):
+        """ Handle "from xyz import foo, bar as baz".
+        """
+        # fixme: Are From and ImportFrom handled differently?
+        self._fill("from ")
+        self._write(t.modname)
+        self._write(" import ")
+        for i, (name,asname) in enumerate(t.names):
+            if i != 0:
+                self._write(", ")
+            self._write(name)
+            if asname is not None:
+                self._write(" as "+asname)
+
+    def _Function(self, t):
+        """ Handle function definitions
+        """
+        if t.decorators is not None:
+            self._fill("@")
+            self._dispatch(t.decorators)
+        self._fill("def "+t.name + "(")
+        defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults)
+        for i, arg in enumerate(zip(t.argnames, defaults)):
+            self._write(arg[0])
+            if arg[1] is not None:
+                self._write('=')
+                self._dispatch(arg[1])
+            if i < len(t.argnames)-1:
+                self._write(', ')
+        self._write(")")
+        if self._single_func:
+            self._do_indent = False
+        self._enter()
+        self._dispatch(t.code)
+        self._leave()
+        self._do_indent = True
+
+    def _Getattr(self, t):
+        """ Handle getting an attribute of an object
+        """
+        if isinstance(t.expr, (Div, Mul, Sub, Add)):
+            self._write('(')
+            self._dispatch(t.expr)
+            self._write(')')
+        else:
+            self._dispatch(t.expr)
+            
+        self._write('.'+t.attrname)
+        
+    def _If(self, t):
+        self._fill()
+        
+        for i, (compare,code) in enumerate(t.tests):
+            if i == 0:
+                self._write("if ")
+            else:
+                self._write("elif ")
+            self._dispatch(compare)
+            self._enter()
+            self._fill()
+            self._dispatch(code)
+            self._leave()
+            self._write("\n")
+
+        if t.else_ is not None:
+            self._write("else")
+            self._enter()
+            self._fill()
+            self._dispatch(t.else_)
+            self._leave()
+            self._write("\n")
+            
+    def _IfExp(self, t):
+        self._dispatch(t.then)
+        self._write(" if ")
+        self._dispatch(t.test)
+
+        if t.else_ is not None:
+            self._write(" else (")
+            self._dispatch(t.else_)
+            self._write(")")
+
+    def _Import(self, t):
+        """ Handle "import xyz.foo".
+        """
+        self._fill("import ")
+        
+        for i, (name,asname) in enumerate(t.names):
+            if i != 0:
+                self._write(", ")
+            self._write(name)
+            if asname is not None:
+                self._write(" as "+asname)
+
+    def _Keyword(self, t):
+        """ Keyword value assignment within function calls and definitions.
+        """
+        self._write(t.name)
+        self._write("=")
+        self._dispatch(t.expr)
+        
+    def _List(self, t):
+        self._write("[")
+        for  i,node in enumerate(t.nodes):
+            self._dispatch(node)
+            if i < len(t.nodes)-1:
+                self._write(", ")
+        self._write("]")
+
+    def _Module(self, t):
+        if t.doc is not None:
+            self._dispatch(t.doc)
+        self._dispatch(t.node)
+
+    def _Mul(self, t):
+        self.__binary_op(t, '*')
+
+    def _Name(self, t):
+        self._write(t.name)
+
+    def _NoneType(self, t):
+        self._write("None")
+        
+    def _Not(self, t):
+        self._write('not (')
+        self._dispatch(t.expr)
+        self._write(')')
+        
+    def _Or(self, t):
+        self._write(" (")
+        for i, node in enumerate(t.nodes):
+            self._dispatch(node)
+            if i != len(t.nodes)-1:
+                self._write(") or (")
+        self._write(")")
+                
+    def _Pass(self, t):
+        self._write("pass\n")
+
+    def _Printnl(self, t):
+        self._fill("print ")
+        if t.dest:
+            self._write(">> ")
+            self._dispatch(t.dest)
+            self._write(", ")
+        comma = False
+        for node in t.nodes:
+            if comma: self._write(', ')
+            else: comma = True
+            self._dispatch(node)
+
+    def _Power(self, t):
+        self.__binary_op(t, '**')
+
+    def _Return(self, t):
+        self._fill("return ")
+        if t.value:
+            if isinstance(t.value, Tuple):
+                text = ', '.join([ name.name for name in t.value.asList() ])
+                self._write(text)
+            else:
+                self._dispatch(t.value)
+            if not self._do_indent:
+                self._write('; ')
+
+    def _Slice(self, t):
+        self._dispatch(t.expr)
+        self._write("[")
+        if t.lower:
+            self._dispatch(t.lower)
+        self._write(":")
+        if t.upper:
+            self._dispatch(t.upper)
+        #if t.step:
+        #    self._write(":")
+        #    self._dispatch(t.step)
+        self._write("]")
+
+    def _Sliceobj(self, t):
+        for i, node in enumerate(t.nodes):
+            if i != 0:
+                self._write(":")
+            if not (isinstance(node, Const) and node.value is None):
+                self._dispatch(node)
+
+    def _Stmt(self, tree):
+        for node in tree.nodes:
+            self._dispatch(node)
+
+    def _Sub(self, t):
+        self.__binary_op(t, '-')
+
+    def _Subscript(self, t):
+        self._dispatch(t.expr)
+        self._write("[")
+        for i, value in enumerate(t.subs):
+            if i != 0:
+                self._write(",")
+            self._dispatch(value)
+        self._write("]")
+
+    def _TryExcept(self, t):
+        self._fill("try")
+        self._enter()
+        self._dispatch(t.body)
+        self._leave()
+
+        for handler in t.handlers:
+            self._fill('except ')
+            self._dispatch(handler[0])
+            if handler[1] is not None:
+                self._write(', ')
+                self._dispatch(handler[1])
+            self._enter()
+            self._dispatch(handler[2])
+            self._leave()
+            
+        if t.else_:
+            self._fill("else")
+            self._enter()
+            self._dispatch(t.else_)
+            self._leave()
+
+    def _Tuple(self, t):
+
+        if not t.nodes:
+            # Empty tuple.
+            self._write("()")
+        else:
+            self._write("(")
+
+            # _write each elements, separated by a comma.
+            for element in t.nodes[:-1]:
+                self._dispatch(element)
+                self._write(", ")
+
+            # Handle the last one without writing comma
+            last_element = t.nodes[-1]
+            self._dispatch(last_element)
+
+            self._write(")")
+            
+    def _UnaryAdd(self, t):
+        self._write("+")
+        self._dispatch(t.expr)
+        
+    def _UnarySub(self, t):
+        self._write("-")
+        self._dispatch(t.expr)        
+
+    def _With(self, t):
+        self._fill('with ')
+        self._dispatch(t.expr)
+        if t.vars:
+            self._write(' as ')
+            self._dispatch(t.vars.name)
+        self._enter()
+        self._dispatch(t.body)
+        self._leave()
+        self._write('\n')
+        
+    def _int(self, t):
+        self._write(repr(t))
+
+    def __binary_op(self, t, symbol):
+        # Check if parenthesis are needed on left side and then dispatch
+        has_paren = False
+        left_class = str(t.left.__class__)
+        if (left_class in op_precedence.keys() and
+            op_precedence[left_class] < op_precedence[str(t.__class__)]):
+            has_paren = True
+        if has_paren:
+            self._write('(')
+        self._dispatch(t.left)
+        if has_paren:
+            self._write(')')
+        # Write the appropriate symbol for operator
+        self._write(symbol)
+        # Check if parenthesis are needed on the right side and then dispatch
+        has_paren = False
+        right_class = str(t.right.__class__)
+        if (right_class in op_precedence.keys() and
+            op_precedence[right_class] < op_precedence[str(t.__class__)]):
+            has_paren = True
+        if has_paren:
+            self._write('(')
+        self._dispatch(t.right)
+        if has_paren:
+            self._write(')')
+
+    def _float(self, t):
+        # if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001'
+        # We prefer str here.
+        self._write(str(t))
+
+    def _str(self, t):
+        self._write(repr(t))
+        
+    def _tuple(self, t):
+        self._write(str(t))
+
+    #########################################################################
+    # These are the methods from the _ast modules unparse.
+    #
+    # As our needs to handle more advanced code increase, we may want to
+    # modify some of the methods below so that they work for compiler.ast.
+    #########################################################################
+
+#    # stmt
+#    def _Expr(self, tree):
+#        self._fill()
+#        self._dispatch(tree.value)
+#
+#    def _Import(self, t):
+#        self._fill("import ")
+#        first = True
+#        for a in t.names:
+#            if first:
+#                first = False
+#            else:
+#                self._write(", ")
+#            self._write(a.name)
+#            if a.asname:
+#                self._write(" as "+a.asname)
+#
+##    def _ImportFrom(self, t):
+##        self._fill("from ")
+##        self._write(t.module)
+##        self._write(" import ")
+##        for i, a in enumerate(t.names):
+##            if i == 0:
+##                self._write(", ")
+##            self._write(a.name)
+##            if a.asname:
+##                self._write(" as "+a.asname)
+##        # XXX(jpe) what is level for?
+##
+#
+#    def _Break(self, t):
+#        self._fill("break")
+#
+#    def _Continue(self, t):
+#        self._fill("continue")
+#
+#    def _Delete(self, t):
+#        self._fill("del ")
+#        self._dispatch(t.targets)
+#
+#    def _Assert(self, t):
+#        self._fill("assert ")
+#        self._dispatch(t.test)
+#        if t.msg:
+#            self._write(", ")
+#            self._dispatch(t.msg)
+#
+#    def _Exec(self, t):
+#        self._fill("exec ")
+#        self._dispatch(t.body)
+#        if t.globals:
+#            self._write(" in ")
+#            self._dispatch(t.globals)
+#        if t.locals:
+#            self._write(", ")
+#            self._dispatch(t.locals)
+#
+#    def _Print(self, t):
+#        self._fill("print ")
+#        do_comma = False
+#        if t.dest:
+#            self._write(">>")
+#            self._dispatch(t.dest)
+#            do_comma = True
+#        for e in t.values:
+#            if do_comma:self._write(", ")
+#            else:do_comma=True
+#            self._dispatch(e)
+#        if not t.nl:
+#            self._write(",")
+#
+#    def _Global(self, t):
+#        self._fill("global")
+#        for i, n in enumerate(t.names):
+#            if i != 0:
+#                self._write(",")
+#            self._write(" " + n)
+#
+#    def _Yield(self, t):
+#        self._fill("yield")
+#        if t.value:
+#            self._write(" (")
+#            self._dispatch(t.value)
+#            self._write(")")
+#
+#    def _Raise(self, t):
+#        self._fill('raise ')
+#        if t.type:
+#            self._dispatch(t.type)
+#        if t.inst:
+#            self._write(", ")
+#            self._dispatch(t.inst)
+#        if t.tback:
+#            self._write(", ")
+#            self._dispatch(t.tback)
+#
+#
+#    def _TryFinally(self, t):
+#        self._fill("try")
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#
+#        self._fill("finally")
+#        self._enter()
+#        self._dispatch(t.finalbody)
+#        self._leave()
+#
+#    def _excepthandler(self, t):
+#        self._fill("except ")
+#        if t.type:
+#            self._dispatch(t.type)
+#        if t.name:
+#            self._write(", ")
+#            self._dispatch(t.name)
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#
+#    def _ClassDef(self, t):
+#        self._write("\n")
+#        self._fill("class "+t.name)
+#        if t.bases:
+#            self._write("(")
+#            for a in t.bases:
+#                self._dispatch(a)
+#                self._write(", ")
+#            self._write(")")
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#
+#    def _FunctionDef(self, t):
+#        self._write("\n")
+#        for deco in t.decorators:
+#            self._fill("@")
+#            self._dispatch(deco)
+#        self._fill("def "+t.name + "(")
+#        self._dispatch(t.args)
+#        self._write(")")
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#
+#    def _For(self, t):
+#        self._fill("for ")
+#        self._dispatch(t.target)
+#        self._write(" in ")
+#        self._dispatch(t.iter)
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#        if t.orelse:
+#            self._fill("else")
+#            self._enter()
+#            self._dispatch(t.orelse)
+#            self._leave
+#
+#    def _While(self, t):
+#        self._fill("while ")
+#        self._dispatch(t.test)
+#        self._enter()
+#        self._dispatch(t.body)
+#        self._leave()
+#        if t.orelse:
+#            self._fill("else")
+#            self._enter()
+#            self._dispatch(t.orelse)
+#            self._leave
+#
+#    # expr
+#    def _Str(self, tree):
+#        self._write(repr(tree.s))
+##
+#    def _Repr(self, t):
+#        self._write("`")
+#        self._dispatch(t.value)
+#        self._write("`")
+#
+#    def _Num(self, t):
+#        self._write(repr(t.n))
+#
+#    def _ListComp(self, t):
+#        self._write("[")
+#        self._dispatch(t.elt)
+#        for gen in t.generators:
+#            self._dispatch(gen)
+#        self._write("]")
+#
+#    def _GeneratorExp(self, t):
+#        self._write("(")
+#        self._dispatch(t.elt)
+#        for gen in t.generators:
+#            self._dispatch(gen)
+#        self._write(")")
+#
+#    def _comprehension(self, t):
+#        self._write(" for ")
+#        self._dispatch(t.target)
+#        self._write(" in ")
+#        self._dispatch(t.iter)
+#        for if_clause in t.ifs:
+#            self._write(" if ")
+#            self._dispatch(if_clause)
+#
+#    def _IfExp(self, t):
+#        self._dispatch(t.body)
+#        self._write(" if ")
+#        self._dispatch(t.test)
+#        if t.orelse:
+#            self._write(" else ")
+#            self._dispatch(t.orelse)
+#
+#    unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
+#    def _UnaryOp(self, t):
+#        self._write(self.unop[t.op.__class__.__name__])
+#        self._write("(")
+#        self._dispatch(t.operand)
+#        self._write(")")
+#
+#    binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
+#                    "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
+#                    "FloorDiv":"//", "Pow": "**"}
+#    def _BinOp(self, t):
+#        self._write("(")
+#        self._dispatch(t.left)
+#        self._write(")" + self.binop[t.op.__class__.__name__] + "(")
+#        self._dispatch(t.right)
+#        self._write(")")
+#
+#    boolops = {_ast.And: 'and', _ast.Or: 'or'}
+#    def _BoolOp(self, t):
+#        self._write("(")
+#        self._dispatch(t.values[0])
+#        for v in t.values[1:]:
+#            self._write(" %s " % self.boolops[t.op.__class__])
+#            self._dispatch(v)
+#        self._write(")")
+#
+#    def _Attribute(self,t):
+#        self._dispatch(t.value)
+#        self._write(".")
+#        self._write(t.attr)
+#
+##    def _Call(self, t):
+##        self._dispatch(t.func)
+##        self._write("(")
+##        comma = False
+##        for e in t.args:
+##            if comma: self._write(", ")
+##            else: comma = True
+##            self._dispatch(e)
+##        for e in t.keywords:
+##            if comma: self._write(", ")
+##            else: comma = True
+##            self._dispatch(e)
+##        if t.starargs:
+##            if comma: self._write(", ")
+##            else: comma = True
+##            self._write("*")
+##            self._dispatch(t.starargs)
+##        if t.kwargs:
+##            if comma: self._write(", ")
+##            else: comma = True
+##            self._write("**")
+##            self._dispatch(t.kwargs)
+##        self._write(")")
+#
+#    # slice
+#    def _Index(self, t):
+#        self._dispatch(t.value)
+#
+#    def _ExtSlice(self, t):
+#        for i, d in enumerate(t.dims):
+#            if i != 0:
+#                self._write(': ')
+#            self._dispatch(d)
+#
+#    # others
+#    def _arguments(self, t):
+#        first = True
+#        nonDef = len(t.args)-len(t.defaults)
+#        for a in t.args[0:nonDef]:
+#            if first:first = False
+#            else: self._write(", ")
+#            self._dispatch(a)
+#        for a,d in zip(t.args[nonDef:], t.defaults):
+#            if first:first = False
+#            else: self._write(", ")
+#            self._dispatch(a),
+#            self._write("=")
+#            self._dispatch(d)
+#        if t.vararg:
+#            if first:first = False
+#            else: self._write(", ")
+#            self._write("*"+t.vararg)
+#        if t.kwarg:
+#            if first:first = False
+#            else: self._write(", ")
+#            self._write("**"+t.kwarg)
+#
+##    def _keyword(self, t):
+##        self._write(t.arg)
+##        self._write("=")
+##        self._dispatch(t.value)
+#
+#    def _Lambda(self, t):
+#        self._write("lambda ")
+#        self._dispatch(t.args)
+#        self._write(": ")
+#        self._dispatch(t.body)
+
+
+
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/docscrape.py b/astropy_helpers/astropy_helpers/sphinx/ext/docscrape.py
new file mode 100644
index 0000000..2b1719d
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/docscrape.py
@@ -0,0 +1,531 @@
+"""Extract reference documentation from the NumPy source tree.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import inspect
+import textwrap
+import re
+import pydoc
+from warnings import warn
+import collections
+import sys
+
+
+class Reader(object):
+    """A line-based string reader.
+
+    """
+    def __init__(self, data):
+        """
+        Parameters
+        ----------
+        data : str
+           String with lines separated by '\n'.
+
+        """
+        if isinstance(data,list):
+            self._str = data
+        else:
+            self._str = data.split('\n') # store string as list of lines
+
+        self.reset()
+
+    def __getitem__(self, n):
+        return self._str[n]
+
+    def reset(self):
+        self._l = 0 # current line nr
+
+    def read(self):
+        if not self.eof():
+            out = self[self._l]
+            self._l += 1
+            return out
+        else:
+            return ''
+
+    def seek_next_non_empty_line(self):
+        for l in self[self._l:]:
+            if l.strip():
+                break
+            else:
+                self._l += 1
+
+    def eof(self):
+        return self._l >= len(self._str)
+
+    def read_to_condition(self, condition_func):
+        start = self._l
+        for line in self[start:]:
+            if condition_func(line):
+                return self[start:self._l]
+            self._l += 1
+            if self.eof():
+                return self[start:self._l+1]
+        return []
+
+    def read_to_next_empty_line(self):
+        self.seek_next_non_empty_line()
+        def is_empty(line):
+            return not line.strip()
+        return self.read_to_condition(is_empty)
+
+    def read_to_next_unindented_line(self):
+        def is_unindented(line):
+            return (line.strip() and (len(line.lstrip()) == len(line)))
+        return self.read_to_condition(is_unindented)
+
+    def peek(self,n=0):
+        if self._l + n < len(self._str):
+            return self[self._l + n]
+        else:
+            return ''
+
+    def is_empty(self):
+        return not ''.join(self._str).strip()
+
+
+class NumpyDocString(object):
+    def __init__(self, docstring, config={}):
+        docstring = textwrap.dedent(docstring).split('\n')
+
+        self._doc = Reader(docstring)
+        self._parsed_data = {
+            'Signature': '',
+            'Summary': [''],
+            'Extended Summary': [],
+            'Parameters': [],
+            'Returns': [],
+            'Raises': [],
+            'Warns': [],
+            'Other Parameters': [],
+            'Attributes': [],
+            'Methods': [],
+            'See Also': [],
+            'Notes': [],
+            'Warnings': [],
+            'References': '',
+            'Examples': '',
+            'index': {}
+            }
+
+        self._parse()
+
+    def __getitem__(self,key):
+        return self._parsed_data[key]
+
+    def __setitem__(self,key,val):
+        if key not in self._parsed_data:
+            warn("Unknown section %s" % key)
+        else:
+            self._parsed_data[key] = val
+
+    def _is_at_section(self):
+        self._doc.seek_next_non_empty_line()
+
+        if self._doc.eof():
+            return False
+
+        l1 = self._doc.peek().strip()  # e.g. Parameters
+
+        if l1.startswith('.. index::'):
+            return True
+
+        l2 = self._doc.peek(1).strip() #    ---------- or ==========
+        return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1))
+
+    def _strip(self,doc):
+        i = 0
+        j = 0
+        for i,line in enumerate(doc):
+            if line.strip(): break
+
+        for j,line in enumerate(doc[::-1]):
+            if line.strip(): break
+
+        return doc[i:len(doc)-j]
+
+    def _read_to_next_section(self):
+        section = self._doc.read_to_next_empty_line()
+
+        while not self._is_at_section() and not self._doc.eof():
+            if not self._doc.peek(-1).strip(): # previous line was empty
+                section += ['']
+
+            section += self._doc.read_to_next_empty_line()
+
+        return section
+
+    def _read_sections(self):
+        while not self._doc.eof():
+            data = self._read_to_next_section()
+            name = data[0].strip()
+
+            if name.startswith('..'): # index section
+                yield name, data[1:]
+            elif len(data) < 2:
+                yield StopIteration
+            else:
+                yield name, self._strip(data[2:])
+
+    def _parse_param_list(self,content):
+        r = Reader(content)
+        params = []
+        while not r.eof():
+            header = r.read().strip()
+            if ' : ' in header:
+                arg_name, arg_type = header.split(' : ')[:2]
+            else:
+                arg_name, arg_type = header, ''
+
+            desc = r.read_to_next_unindented_line()
+            desc = dedent_lines(desc)
+
+            params.append((arg_name,arg_type,desc))
+
+        return params
+
+
+    _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
+                           r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
+    def _parse_see_also(self, content):
+        """
+        func_name : Descriptive text
+            continued text
+        another_func_name : Descriptive text
+        func_name1, func_name2, :meth:`func_name`, func_name3
+
+        """
+        items = []
+
+        def parse_item_name(text):
+            """Match ':role:`name`' or 'name'"""
+            m = self._name_rgx.match(text)
+            if m:
+                g = m.groups()
+                if g[1] is None:
+                    return g[3], None
+                else:
+                    return g[2], g[1]
+            raise ValueError("%s is not a item name" % text)
+
+        def push_item(name, rest):
+            if not name:
+                return
+            name, role = parse_item_name(name)
+            items.append((name, list(rest), role))
+            del rest[:]
+
+        current_func = None
+        rest = []
+
+        for line in content:
+            if not line.strip(): continue
+
+            m = self._name_rgx.match(line)
+            if m and line[m.end():].strip().startswith(':'):
+                push_item(current_func, rest)
+                current_func, line = line[:m.end()], line[m.end():]
+                rest = [line.split(':', 1)[1].strip()]
+                if not rest[0]:
+                    rest = []
+            elif not line.startswith(' '):
+                push_item(current_func, rest)
+                current_func = None
+                if ',' in line:
+                    for func in line.split(','):
+                        if func.strip():
+                            push_item(func, [])
+                elif line.strip():
+                    current_func = line
+            elif current_func is not None:
+                rest.append(line.strip())
+        push_item(current_func, rest)
+        return items
+
+    def _parse_index(self, section, content):
+        """
+        .. index: default
+           :refguide: something, else, and more
+
+        """
+        def strip_each_in(lst):
+            return [s.strip() for s in lst]
+
+        out = {}
+        section = section.split('::')
+        if len(section) > 1:
+            out['default'] = strip_each_in(section[1].split(','))[0]
+        for line in content:
+            line = line.split(':')
+            if len(line) > 2:
+                out[line[1]] = strip_each_in(line[2].split(','))
+        return out
+
+    def _parse_summary(self):
+        """Grab signature (if given) and summary"""
+        if self._is_at_section():
+            return
+
+        # If several signatures present, take the last one
+        while True:
+            summary = self._doc.read_to_next_empty_line()
+            summary_str = " ".join([s.strip() for s in summary]).strip()
+            if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
+                self['Signature'] = summary_str
+                if not self._is_at_section():
+                    continue
+            break
+
+        if summary is not None:
+            self['Summary'] = summary
+
+        if not self._is_at_section():
+            self['Extended Summary'] = self._read_to_next_section()
+
+    def _parse(self):
+        self._doc.reset()
+        self._parse_summary()
+
+        for (section,content) in self._read_sections():
+            if not section.startswith('..'):
+                section = ' '.join([s.capitalize() for s in section.split(' ')])
+            if section in ('Parameters', 'Returns', 'Raises', 'Warns',
+                           'Other Parameters', 'Attributes', 'Methods'):
+                self[section] = self._parse_param_list(content)
+            elif section.startswith('.. index::'):
+                self['index'] = self._parse_index(section, content)
+            elif section == 'See Also':
+                self['See Also'] = self._parse_see_also(content)
+            else:
+                self[section] = content
+
+    # string conversion routines
+
+    def _str_header(self, name, symbol='-'):
+        return [name, len(name)*symbol]
+
+    def _str_indent(self, doc, indent=4):
+        out = []
+        for line in doc:
+            out += [' '*indent + line]
+        return out
+
+    def _str_signature(self):
+        if self['Signature']:
+            return [self['Signature'].replace('*','\*')] + ['']
+        else:
+            return ['']
+
+    def _str_summary(self):
+        if self['Summary']:
+            return self['Summary'] + ['']
+        else:
+            return []
+
+    def _str_extended_summary(self):
+        if self['Extended Summary']:
+            return self['Extended Summary'] + ['']
+        else:
+            return []
+
+    def _str_param_list(self, name):
+        out = []
+        if self[name]:
+            out += self._str_header(name)
+            for param,param_type,desc in self[name]:
+                if param_type:
+                    out += ['%s : %s' % (param, param_type)]
+                else:
+                    out += [param]
+                out += self._str_indent(desc)
+            out += ['']
+        return out
+
+    def _str_section(self, name):
+        out = []
+        if self[name]:
+            out += self._str_header(name)
+            out += self[name]
+            out += ['']
+        return out
+
+    def _str_see_also(self, func_role):
+        if not self['See Also']: return []
+        out = []
+        out += self._str_header("See Also")
+        last_had_desc = True
+        for func, desc, role in self['See Also']:
+            if role:
+                link = ':%s:`%s`' % (role, func)
+            elif func_role:
+                link = ':%s:`%s`' % (func_role, func)
+            else:
+                link = "`%s`_" % func
+            if desc or last_had_desc:
+                out += ['']
+                out += [link]
+            else:
+                out[-1] += ", %s" % link
+            if desc:
+                out += self._str_indent([' '.join(desc)])
+                last_had_desc = True
+            else:
+                last_had_desc = False
+        out += ['']
+        return out
+
+    def _str_index(self):
+        idx = self['index']
+        out = []
+        out += ['.. index:: %s' % idx.get('default','')]
+        for section, references in idx.items():
+            if section == 'default':
+                continue
+            out += ['   :%s: %s' % (section, ', '.join(references))]
+        return out
+
+    def __str__(self, func_role=''):
+        out = []
+        out += self._str_signature()
+        out += self._str_summary()
+        out += self._str_extended_summary()
+        for param_list in ('Parameters', 'Returns', 'Other Parameters',
+                           'Raises', 'Warns'):
+            out += self._str_param_list(param_list)
+        out += self._str_section('Warnings')
+        out += self._str_see_also(func_role)
+        for s in ('Notes','References','Examples'):
+            out += self._str_section(s)
+        for param_list in ('Attributes', 'Methods'):
+            out += self._str_param_list(param_list)
+        out += self._str_index()
+        return '\n'.join(out)
+
+
+def indent(str,indent=4):
+    indent_str = ' '*indent
+    if str is None:
+        return indent_str
+    lines = str.split('\n')
+    return '\n'.join(indent_str + l for l in lines)
+
+def dedent_lines(lines):
+    """Deindent a list of lines maximally"""
+    return textwrap.dedent("\n".join(lines)).split("\n")
+
+def header(text, style='-'):
+    return text + '\n' + style*len(text) + '\n'
+
+
+class FunctionDoc(NumpyDocString):
+    def __init__(self, func, role='func', doc=None, config={}):
+        self._f = func
+        self._role = role # e.g. "func" or "meth"
+
+        if doc is None:
+            if func is None:
+                raise ValueError("No function or docstring given")
+            doc = inspect.getdoc(func) or ''
+        NumpyDocString.__init__(self, doc)
+
+        if not self['Signature'] and func is not None:
+            func, func_name = self.get_func()
+            try:
+                # try to read signature
+                if sys.version_info[0] >= 3:
+                    argspec = inspect.getfullargspec(func)
+                else:
+                    argspec = inspect.getargspec(func)
+                argspec = inspect.formatargspec(*argspec)
+                argspec = argspec.replace('*','\*')
+                signature = '%s%s' % (func_name, argspec)
+            except TypeError as e:
+                signature = '%s()' % func_name
+            self['Signature'] = signature
+
+    def get_func(self):
+        func_name = getattr(self._f, '__name__', self.__class__.__name__)
+        if inspect.isclass(self._f):
+            func = getattr(self._f, '__call__', self._f.__init__)
+        else:
+            func = self._f
+        return func, func_name
+
+    def __str__(self):
+        out = ''
+
+        func, func_name = self.get_func()
+        signature = self['Signature'].replace('*', '\*')
+
+        roles = {'func': 'function',
+                 'meth': 'method'}
+
+        if self._role:
+            if self._role not in roles:
+                print("Warning: invalid role %s" % self._role)
+            out += '.. %s:: %s\n    \n\n' % (roles.get(self._role,''),
+                                             func_name)
+
+        out += super(FunctionDoc, self).__str__(func_role=self._role)
+        return out
+
+
+class ClassDoc(NumpyDocString):
+
+    extra_public_methods = ['__call__']
+
+    def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc,
+                 config={}):
+        if not inspect.isclass(cls) and cls is not None:
+            raise ValueError("Expected a class or None, but got %r" % cls)
+        self._cls = cls
+
+        if modulename and not modulename.endswith('.'):
+            modulename += '.'
+        self._mod = modulename
+
+        if doc is None:
+            if cls is None:
+                raise ValueError("No class or documentation string given")
+            doc = pydoc.getdoc(cls)
+
+        NumpyDocString.__init__(self, doc)
+
+        if config.get('show_class_members', True):
+            def splitlines_x(s):
+                if not s:
+                    return []
+                else:
+                    return s.splitlines()
+
+            for field, items in [('Methods', self.methods),
+                                 ('Attributes', self.properties)]:
+                if not self[field]:
+                    doc_list = []
+                    for name in sorted(items):
+                         try:
+                            doc_item = pydoc.getdoc(getattr(self._cls, name))
+                            doc_list.append((name, '', splitlines_x(doc_item)))
+                         except AttributeError:
+                            pass # method doesn't exist
+                    self[field] = doc_list
+
+    @property
+    def methods(self):
+        if self._cls is None:
+            return []
+        return [name for name,func in inspect.getmembers(self._cls)
+                if ((not name.startswith('_')
+                     or name in self.extra_public_methods)
+                    and isinstance(func, collections.Callable))]
+
+    @property
+    def properties(self):
+        if self._cls is None:
+            return []
+        return [name for name,func in inspect.getmembers(self._cls)
+                if not name.startswith('_') and
+                (func is None or isinstance(func, property) or
+                 inspect.isgetsetdescriptor(func))]
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/docscrape_sphinx.py b/astropy_helpers/astropy_helpers/sphinx/ext/docscrape_sphinx.py
new file mode 100644
index 0000000..cdc2a37
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/docscrape_sphinx.py
@@ -0,0 +1,274 @@
+from __future__ import division, absolute_import, print_function
+
+import sys, re, inspect, textwrap, pydoc
+import sphinx
+import collections
+from .docscrape import NumpyDocString, FunctionDoc, ClassDoc
+
+if sys.version_info[0] >= 3:
+    sixu = lambda s: s
+else:
+    sixu = lambda s: unicode(s, 'unicode_escape')
+
+
+class SphinxDocString(NumpyDocString):
+    def __init__(self, docstring, config={}):
+        NumpyDocString.__init__(self, docstring, config=config)
+        self.load_config(config)
+
+    def load_config(self, config):
+        self.use_plots = config.get('use_plots', False)
+        self.class_members_toctree = config.get('class_members_toctree', True)
+
+    # string conversion routines
+    def _str_header(self, name, symbol='`'):
+        return ['.. rubric:: ' + name, '']
+
+    def _str_field_list(self, name):
+        return [':' + name + ':']
+
+    def _str_indent(self, doc, indent=4):
+        out = []
+        for line in doc:
+            out += [' '*indent + line]
+        return out
+
+    def _str_signature(self):
+        return ['']
+        if self['Signature']:
+            return ['``%s``' % self['Signature']] + ['']
+        else:
+            return ['']
+
+    def _str_summary(self):
+        return self['Summary'] + ['']
+
+    def _str_extended_summary(self):
+        return self['Extended Summary'] + ['']
+
+    def _str_returns(self):
+        out = []
+        if self['Returns']:
+            out += self._str_field_list('Returns')
+            out += ['']
+            for param, param_type, desc in self['Returns']:
+                if param_type:
+                    out += self._str_indent(['**%s** : %s' % (param.strip(),
+                                                              param_type)])
+                else:
+                    out += self._str_indent([param.strip()])
+                if desc:
+                    out += ['']
+                    out += self._str_indent(desc, 8)
+                out += ['']
+        return out
+
+    def _str_param_list(self, name):
+        out = []
+        if self[name]:
+            out += self._str_field_list(name)
+            out += ['']
+            for param, param_type, desc in self[name]:
+                if param_type:
+                    out += self._str_indent(['**%s** : %s' % (param.strip(),
+                                                              param_type)])
+                else:
+                    out += self._str_indent(['**%s**' % param.strip()])
+                if desc:
+                    out += ['']
+                    out += self._str_indent(desc, 8)
+                out += ['']
+        return out
+
+    @property
+    def _obj(self):
+        if hasattr(self, '_cls'):
+            return self._cls
+        elif hasattr(self, '_f'):
+            return self._f
+        return None
+
+    def _str_member_list(self, name):
+        """
+        Generate a member listing, autosummary:: table where possible,
+        and a table where not.
+
+        """
+        out = []
+        if self[name]:
+            out += ['.. rubric:: %s' % name, '']
+            prefix = getattr(self, '_name', '')
+
+            if prefix:
+                prefix = '~%s.' % prefix
+
+            autosum = []
+            others = []
+            for param, param_type, desc in self[name]:
+                param = param.strip()
+
+                # Check if the referenced member can have a docstring or not
+                param_obj = getattr(self._obj, param, None)
+                if not (callable(param_obj)
+                        or isinstance(param_obj, property)
+                        or inspect.isgetsetdescriptor(param_obj)):
+                    param_obj = None
+
+                if param_obj and (pydoc.getdoc(param_obj) or not desc):
+                    # Referenced object has a docstring
+                    autosum += ["   %s%s" % (prefix, param)]
+                else:
+                    others.append((param, param_type, desc))
+
+            if autosum:
+                out += ['.. autosummary::']
+                if self.class_members_toctree:
+                    out += ['   :toctree:']
+                out += [''] + autosum
+
+            if others:
+                maxlen_0 = max(3, max([len(x[0]) for x in others]))
+                hdr = sixu("=")*maxlen_0 + sixu("  ") + sixu("=")*10
+                fmt = sixu('%%%ds  %%s  ') % (maxlen_0,)
+                out += ['', hdr]
+                for param, param_type, desc in others:
+                    desc = sixu(" ").join(x.strip() for x in desc).strip()
+                    if param_type:
+                        desc = "(%s) %s" % (param_type, desc)
+                    out += [fmt % (param.strip(), desc)]
+                out += [hdr]
+            out += ['']
+        return out
+
+    def _str_section(self, name):
+        out = []
+        if self[name]:
+            out += self._str_header(name)
+            out += ['']
+            content = textwrap.dedent("\n".join(self[name])).split("\n")
+            out += content
+            out += ['']
+        return out
+
+    def _str_see_also(self, func_role):
+        out = []
+        if self['See Also']:
+            see_also = super(SphinxDocString, self)._str_see_also(func_role)
+            out = ['.. seealso::', '']
+            out += self._str_indent(see_also[2:])
+        return out
+
+    def _str_warnings(self):
+        out = []
+        if self['Warnings']:
+            out = ['.. warning::', '']
+            out += self._str_indent(self['Warnings'])
+        return out
+
+    def _str_index(self):
+        idx = self['index']
+        out = []
+        if len(idx) == 0:
+            return out
+
+        out += ['.. index:: %s' % idx.get('default','')]
+        for section, references in idx.items():
+            if section == 'default':
+                continue
+            elif section == 'refguide':
+                out += ['   single: %s' % (', '.join(references))]
+            else:
+                out += ['   %s: %s' % (section, ','.join(references))]
+        return out
+
+    def _str_references(self):
+        out = []
+        if self['References']:
+            out += self._str_header('References')
+            if isinstance(self['References'], str):
+                self['References'] = [self['References']]
+            out.extend(self['References'])
+            out += ['']
+            # Latex collects all references to a separate bibliography,
+            # so we need to insert links to it
+            if sphinx.__version__ >= "0.6":
+                out += ['.. only:: latex','']
+            else:
+                out += ['.. latexonly::','']
+            items = []
+            for line in self['References']:
+                m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I)
+                if m:
+                    items.append(m.group(1))
+            out += ['   ' + ", ".join(["[%s]_" % item for item in items]), '']
+        return out
+
+    def _str_examples(self):
+        examples_str = "\n".join(self['Examples'])
+
+        if (self.use_plots and 'import matplotlib' in examples_str
+                and 'plot::' not in examples_str):
+            out = []
+            out += self._str_header('Examples')
+            out += ['.. plot::', '']
+            out += self._str_indent(self['Examples'])
+            out += ['']
+            return out
+        else:
+            return self._str_section('Examples')
+
+    def __str__(self, indent=0, func_role="obj"):
+        out = []
+        out += self._str_signature()
+        out += self._str_index() + ['']
+        out += self._str_summary()
+        out += self._str_extended_summary()
+        out += self._str_param_list('Parameters')
+        out += self._str_returns()
+        for param_list in ('Other Parameters', 'Raises', 'Warns'):
+            out += self._str_param_list(param_list)
+        out += self._str_warnings()
+        out += self._str_see_also(func_role)
+        out += self._str_section('Notes')
+        out += self._str_references()
+        out += self._str_examples()
+        for param_list in ('Attributes', 'Methods'):
+            out += self._str_member_list(param_list)
+        out = self._str_indent(out,indent)
+        return '\n'.join(out)
+
+class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
+    def __init__(self, obj, doc=None, config={}):
+        self.load_config(config)
+        FunctionDoc.__init__(self, obj, doc=doc, config=config)
+
+class SphinxClassDoc(SphinxDocString, ClassDoc):
+    def __init__(self, obj, doc=None, func_doc=None, config={}):
+        self.load_config(config)
+        ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config)
+
+class SphinxObjDoc(SphinxDocString):
+    def __init__(self, obj, doc=None, config={}):
+        self._f = obj
+        self.load_config(config)
+        SphinxDocString.__init__(self, doc, config=config)
+
+def get_doc_object(obj, what=None, doc=None, config={}):
+    if what is None:
+        if inspect.isclass(obj):
+            what = 'class'
+        elif inspect.ismodule(obj):
+            what = 'module'
+        elif isinstance(obj, collections.Callable):
+            what = 'function'
+        else:
+            what = 'object'
+    if what == 'class':
+        return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc,
+                              config=config)
+    elif what in ('function', 'method'):
+        return SphinxFunctionDoc(obj, doc=doc, config=config)
+    else:
+        if doc is None:
+            doc = pydoc.getdoc(obj)
+        return SphinxObjDoc(obj, doc, config=config)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/doctest.py b/astropy_helpers/astropy_helpers/sphinx/ext/doctest.py
new file mode 100644
index 0000000..d652f23
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/doctest.py
@@ -0,0 +1,38 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This is a set of three directives that allow us to insert metadata
+about doctests into the .rst files so the testing framework knows
+which tests to skip.
+
+This is quite different from the doctest extension in Sphinx itself,
+which actually does something.  For astropy, all of the testing is
+centrally managed from py.test and Sphinx is not used for running
+tests.
+"""
+import re
+from docutils.nodes import literal_block
+from sphinx.util.compat import Directive
+
+
+class DoctestSkipDirective(Directive):
+    has_content = True
+
+    def run(self):
+        # Check if there is any valid argument, and skip it. Currently only
+        # 'win32' is supported in astropy.tests.pytest_plugins.
+        if re.match('win32', self.content[0]):
+            self.content = self.content[2:]
+        code = '\n'.join(self.content)
+        return [literal_block(code, code)]
+
+
+class DoctestRequiresDirective(DoctestSkipDirective):
+    # This is silly, but we really support an unbounded number of
+    # optional arguments
+    optional_arguments = 64
+
+
+def setup(app):
+    app.add_directive('doctest-requires', DoctestRequiresDirective)
+    app.add_directive('doctest-skip', DoctestSkipDirective)
+    app.add_directive('doctest-skip-all', DoctestSkipDirective)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/edit_on_github.py b/astropy_helpers/astropy_helpers/sphinx/ext/edit_on_github.py
new file mode 100644
index 0000000..793bf8c
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/edit_on_github.py
@@ -0,0 +1,165 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+This extension makes it easy to edit documentation on github.
+
+It adds links associated with each docstring that go to the
+corresponding view source page on Github.  From there, the user can
+push the "Edit" button, edit the docstring, and submit a pull request.
+
+It has the following configuration options (to be set in the project's
+``conf.py``):
+
+* ``edit_on_github_project``
+    The name of the github project, in the form
+    "username/projectname".
+
+* ``edit_on_github_branch``
+    The name of the branch to edit.  If this is a released version,
+    this should be a git tag referring to that version.  For a
+    dev version, it often makes sense for it to be "master".  It
+    may also be a git hash.
+
+* ``edit_on_github_source_root``
+    The location within the source tree of the root of the
+    Python package.  Defaults to "lib".
+
+* ``edit_on_github_doc_root``
+    The location within the source tree of the root of the
+    documentation source.  Defaults to "doc", but it may make sense to
+    set it to "doc/source" if the project uses a separate source
+    directory.
+
+* ``edit_on_github_docstring_message``
+    The phrase displayed in the links to edit a docstring.  Defaults
+    to "[edit on github]".
+
+* ``edit_on_github_page_message``
+    The phrase displayed in the links to edit a RST page.  Defaults
+    to "[edit this page on github]".
+
+* ``edit_on_github_help_message``
+    The phrase displayed as a tooltip on the edit links.  Defaults to
+    "Push the Edit button on the next page"
+
+* ``edit_on_github_skip_regex``
+    When the path to the .rst file matches this regular expression,
+    no "edit this page on github" link will be added.  Defaults to
+    ``"_.*"``.
+"""
+import inspect
+import os
+import re
+import sys
+
+from docutils import nodes
+
+from sphinx import addnodes
+
+
+def import_object(modname, name):
+    """
+    Import the object given by *modname* and *name* and return it.
+    If not found, or the import fails, returns None.
+    """
+    try:
+        __import__(modname)
+        mod = sys.modules[modname]
+        obj = mod
+        for part in name.split('.'):
+            obj = getattr(obj, part)
+        return obj
+    except:
+        return None
+
+
+def get_url_base(app):
+    return  'http://github.com/%s/tree/%s/' % (
+        app.config.edit_on_github_project,
+        app.config.edit_on_github_branch)
+
+
+def doctree_read(app, doctree):
+    # Get the configuration parameters
+    if app.config.edit_on_github_project == 'REQUIRED':
+        raise ValueError(
+            "The edit_on_github_project configuration variable must be "
+            "provided in the conf.py")
+
+    source_root = app.config.edit_on_github_source_root
+    url = get_url_base(app)
+
+    docstring_message = app.config.edit_on_github_docstring_message
+
+    # Handle the docstring-editing links
+    for objnode in doctree.traverse(addnodes.desc):
+        if objnode.get('domain') != 'py':
+            continue
+        names = set()
+        for signode in objnode:
+            if not isinstance(signode, addnodes.desc_signature):
+                continue
+            modname = signode.get('module')
+            if not modname:
+                continue
+            fullname = signode.get('fullname')
+            if fullname in names:
+                # only one link per name, please
+                continue
+            names.add(fullname)
+            obj = import_object(modname, fullname)
+            anchor = None
+            if obj is not None:
+                try:
+                    lines, lineno = inspect.getsourcelines(obj)
+                except:
+                    pass
+                else:
+                    anchor = '#L%d' % lineno
+            if anchor:
+                real_modname = inspect.getmodule(obj).__name__
+                path = '%s%s%s.py%s' % (
+                    url, source_root, real_modname.replace('.', '/'), anchor)
+                onlynode = addnodes.only(expr='html')
+                onlynode += nodes.reference(
+                    reftitle=app.config.edit_on_github_help_message,
+                    refuri=path)
+                onlynode[0] += nodes.inline(
+                    '', '', nodes.raw('', ' ', format='html'),
+                    nodes.Text(docstring_message),
+                    classes=['edit-on-github', 'viewcode-link'])
+                signode += onlynode
+
+
+def html_page_context(app, pagename, templatename, context, doctree):
+    if (templatename == 'page.html' and
+        not re.match(app.config.edit_on_github_skip_regex, pagename)):
+
+        doc_root = app.config.edit_on_github_doc_root
+        if doc_root != '' and not doc_root.endswith('/'):
+            doc_root += '/'
+        doc_path = os.path.relpath(doctree.get('source'), app.builder.srcdir)
+        url = get_url_base(app)
+
+        page_message = app.config.edit_on_github_page_message
+
+        context['edit_on_github'] = url + doc_root + doc_path
+        context['edit_on_github_page_message'] = (
+            app.config.edit_on_github_page_message)
+
+
+def setup(app):
+    app.add_config_value('edit_on_github_project', 'REQUIRED', True)
+    app.add_config_value('edit_on_github_branch', 'master', True)
+    app.add_config_value('edit_on_github_source_root', 'lib', True)
+    app.add_config_value('edit_on_github_doc_root', 'doc', True)
+    app.add_config_value('edit_on_github_docstring_message',
+                         '[edit on github]', True)
+    app.add_config_value('edit_on_github_page_message',
+                         'Edit This Page on Github', True)
+    app.add_config_value('edit_on_github_help_message',
+                         'Push the Edit button on the next page', True)
+    app.add_config_value('edit_on_github_skip_regex',
+                         '_.*', True)
+
+    app.connect('doctree-read', doctree_read)
+    app.connect('html-page-context', html_page_context)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/numpydoc.py b/astropy_helpers/astropy_helpers/sphinx/ext/numpydoc.py
new file mode 100644
index 0000000..2bc2d1e
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/numpydoc.py
@@ -0,0 +1,187 @@
+"""
+========
+numpydoc
+========
+
+Sphinx extension that handles docstrings in the Numpy standard format. [1]
+
+It will:
+
+- Convert Parameters etc. sections to field lists.
+- Convert See Also section to a See also entry.
+- Renumber references.
+- Extract the signature from the docstring, if it can't be determined otherwise.
+
+.. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os, sys, re, pydoc
+import sphinx
+import inspect
+import collections
+
+if sphinx.__version__ < '1.0.1':
+    raise RuntimeError("Sphinx 1.0.1 or newer is required")
+
+from .docscrape_sphinx import get_doc_object, SphinxDocString
+from sphinx.util.compat import Directive
+
+if sys.version_info[0] >= 3:
+    sixu = lambda s: s
+else:
+    sixu = lambda s: unicode(s, 'unicode_escape')
+
+
+def mangle_docstrings(app, what, name, obj, options, lines,
+                      reference_offset=[0]):
+
+    cfg = dict(use_plots=app.config.numpydoc_use_plots,
+               show_class_members=app.config.numpydoc_show_class_members,
+               class_members_toctree=app.config.numpydoc_class_members_toctree,
+              )
+
+    if what == 'module':
+        # Strip top title
+        title_re = re.compile(sixu('^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*'),
+                              re.I|re.S)
+        lines[:] = title_re.sub(sixu(''), sixu("\n").join(lines)).split(sixu("\n"))
+    else:
+        doc = get_doc_object(obj, what, sixu("\n").join(lines), config=cfg)
+        if sys.version_info[0] >= 3:
+            doc = str(doc)
+        else:
+            doc = unicode(doc)
+        lines[:] = doc.split(sixu("\n"))
+
+    if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
+           obj.__name__:
+        if hasattr(obj, '__module__'):
+            v = dict(full_name=sixu("%s.%s") % (obj.__module__, obj.__name__))
+        else:
+            v = dict(full_name=obj.__name__)
+        lines += [sixu(''), sixu('.. htmlonly::'), sixu('')]
+        lines += [sixu('    %s') % x for x in
+                  (app.config.numpydoc_edit_link % v).split("\n")]
+
+    # replace reference numbers so that there are no duplicates
+    references = []
+    for line in lines:
+        line = line.strip()
+        m = re.match(sixu('^.. \\[([a-z0-9_.-])\\]'), line, re.I)
+        if m:
+            references.append(m.group(1))
+
+    # start renaming from the longest string, to avoid overwriting parts
+    references.sort(key=lambda x: -len(x))
+    if references:
+        for i, line in enumerate(lines):
+            for r in references:
+                if re.match(sixu('^\\d+$'), r):
+                    new_r = sixu("R%d") % (reference_offset[0] + int(r))
+                else:
+                    new_r = sixu("%s%d") % (r, reference_offset[0])
+                lines[i] = lines[i].replace(sixu('[%s]_') % r,
+                                            sixu('[%s]_') % new_r)
+                lines[i] = lines[i].replace(sixu('.. [%s]') % r,
+                                            sixu('.. [%s]') % new_r)
+
+    reference_offset[0] += len(references)
+
+def mangle_signature(app, what, name, obj, options, sig, retann):
+    # Do not try to inspect classes that don't define `__init__`
+    if (inspect.isclass(obj) and
+        (not hasattr(obj, '__init__') or
+        'initializes x; see ' in pydoc.getdoc(obj.__init__))):
+        return '', ''
+
+    if not (isinstance(obj, collections.Callable) or hasattr(obj, '__argspec_is_invalid_')): return
+    if not hasattr(obj, '__doc__'): return
+
+    doc = SphinxDocString(pydoc.getdoc(obj))
+    if doc['Signature']:
+        sig = re.sub(sixu("^[^(]*"), sixu(""), doc['Signature'])
+        return sig, sixu('')
+
+def setup(app, get_doc_object_=get_doc_object):
+    if not hasattr(app, 'add_config_value'):
+        return # probably called by nose, better bail out
+
+    global get_doc_object
+    get_doc_object = get_doc_object_
+
+    app.connect('autodoc-process-docstring', mangle_docstrings)
+    app.connect('autodoc-process-signature', mangle_signature)
+    app.add_config_value('numpydoc_edit_link', None, False)
+    app.add_config_value('numpydoc_use_plots', None, False)
+    app.add_config_value('numpydoc_show_class_members', True, True)
+    app.add_config_value('numpydoc_class_members_toctree', True, True)
+
+    # Extra mangling domains
+    app.add_domain(NumpyPythonDomain)
+    app.add_domain(NumpyCDomain)
+
+#------------------------------------------------------------------------------
+# Docstring-mangling domains
+#------------------------------------------------------------------------------
+
+from docutils.statemachine import ViewList
+from sphinx.domains.c import CDomain
+from sphinx.domains.python import PythonDomain
+
+class ManglingDomainBase(object):
+    directive_mangling_map = {}
+
+    def __init__(self, *a, **kw):
+        super(ManglingDomainBase, self).__init__(*a, **kw)
+        self.wrap_mangling_directives()
+
+    def wrap_mangling_directives(self):
+        for name, objtype in list(self.directive_mangling_map.items()):
+            self.directives[name] = wrap_mangling_directive(
+                self.directives[name], objtype)
+
+class NumpyPythonDomain(ManglingDomainBase, PythonDomain):
+    name = 'np'
+    directive_mangling_map = {
+        'function': 'function',
+        'class': 'class',
+        'exception': 'class',
+        'method': 'function',
+        'classmethod': 'function',
+        'staticmethod': 'function',
+        'attribute': 'attribute',
+    }
+    indices = []
+
+class NumpyCDomain(ManglingDomainBase, CDomain):
+    name = 'np-c'
+    directive_mangling_map = {
+        'function': 'function',
+        'member': 'attribute',
+        'macro': 'function',
+        'type': 'class',
+        'var': 'object',
+    }
+
+def wrap_mangling_directive(base_directive, objtype):
+    class directive(base_directive):
+        def run(self):
+            env = self.state.document.settings.env
+
+            name = None
+            if self.arguments:
+                m = re.match(r'^(.*\s+)?(.*?)(\(.*)?', self.arguments[0])
+                name = m.group(2).strip()
+
+            if not name:
+                name = self.arguments[0]
+
+            lines = list(self.content)
+            mangle_docstrings(env.app, objtype, name, None, None, lines)
+            self.content = ViewList(lines, self.content.parent)
+
+            return base_directive.run(self)
+
+    return directive
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/phantom_import.py b/astropy_helpers/astropy_helpers/sphinx/ext/phantom_import.py
new file mode 100644
index 0000000..9a60b4a
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/phantom_import.py
@@ -0,0 +1,167 @@
+"""
+==============
+phantom_import
+==============
+
+Sphinx extension to make directives from ``sphinx.ext.autodoc`` and similar
+extensions to use docstrings loaded from an XML file.
+
+This extension loads an XML file in the Pydocweb format [1] and
+creates a dummy module that contains the specified docstrings. This
+can be used to get the current docstrings from a Pydocweb instance
+without needing to rebuild the documented module.
+
+.. [1] http://code.google.com/p/pydocweb
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import imp, sys, compiler, types, os, inspect, re
+
+def setup(app):
+    app.connect('builder-inited', initialize)
+    app.add_config_value('phantom_import_file', None, True)
+
+def initialize(app):
+    fn = app.config.phantom_import_file
+    if (fn and os.path.isfile(fn)):
+        print("[numpydoc] Phantom importing modules from", fn, "...")
+        import_phantom_module(fn)
+
+#------------------------------------------------------------------------------
+# Creating 'phantom' modules from an XML description
+#------------------------------------------------------------------------------
+def import_phantom_module(xml_file):
+    """
+    Insert a fake Python module to sys.modules, based on a XML file.
+
+    The XML file is expected to conform to Pydocweb DTD. The fake
+    module will contain dummy objects, which guarantee the following:
+
+    - Docstrings are correct.
+    - Class inheritance relationships are correct (if present in XML).
+    - Function argspec is *NOT* correct (even if present in XML).
+      Instead, the function signature is prepended to the function docstring.
+    - Class attributes are *NOT* correct; instead, they are dummy objects.
+
+    Parameters
+    ----------
+    xml_file : str
+        Name of an XML file to read
+    
+    """
+    import lxml.etree as etree
+
+    object_cache = {}
+
+    tree = etree.parse(xml_file)
+    root = tree.getroot()
+
+    # Sort items so that
+    # - Base classes come before classes inherited from them
+    # - Modules come before their contents
+    all_nodes = dict([(n.attrib['id'], n) for n in root])
+    
+    def _get_bases(node, recurse=False):
+        bases = [x.attrib['ref'] for x in node.findall('base')]
+        if recurse:
+            j = 0
+            while True:
+                try:
+                    b = bases[j]
+                except IndexError: break
+                if b in all_nodes:
+                    bases.extend(_get_bases(all_nodes[b]))
+                j += 1
+        return bases
+
+    type_index = ['module', 'class', 'callable', 'object']
+    
+    def base_cmp(a, b):
+        x = cmp(type_index.index(a.tag), type_index.index(b.tag))
+        if x != 0: return x
+
+        if a.tag == 'class' and b.tag == 'class':
+            a_bases = _get_bases(a, recurse=True)
+            b_bases = _get_bases(b, recurse=True)
+            x = cmp(len(a_bases), len(b_bases))
+            if x != 0: return x
+            if a.attrib['id'] in b_bases: return -1
+            if b.attrib['id'] in a_bases: return 1
+        
+        return cmp(a.attrib['id'].count('.'), b.attrib['id'].count('.'))
+
+    nodes = root.getchildren()
+    nodes.sort(base_cmp)
+
+    # Create phantom items
+    for node in nodes:
+        name = node.attrib['id']
+        doc = (node.text or '').decode('string-escape') + "\n"
+        if doc == "\n": doc = ""
+
+        # create parent, if missing
+        parent = name
+        while True:
+            parent = '.'.join(parent.split('.')[:-1])
+            if not parent: break
+            if parent in object_cache: break
+            obj = imp.new_module(parent)
+            object_cache[parent] = obj
+            sys.modules[parent] = obj
+
+        # create object
+        if node.tag == 'module':
+            obj = imp.new_module(name)
+            obj.__doc__ = doc
+            sys.modules[name] = obj
+        elif node.tag == 'class':
+            bases = [object_cache[b] for b in _get_bases(node)
+                     if b in object_cache]
+            bases.append(object)
+            init = lambda self: None
+            init.__doc__ = doc
+            obj = type(name, tuple(bases), {'__doc__': doc, '__init__': init})
+            obj.__name__ = name.split('.')[-1]
+        elif node.tag == 'callable':
+            funcname = node.attrib['id'].split('.')[-1]
+            argspec = node.attrib.get('argspec')
+            if argspec:
+                argspec = re.sub('^[^(]*', '', argspec)
+                doc = "%s%s\n\n%s" % (funcname, argspec, doc)
+            obj = lambda: 0
+            obj.__argspec_is_invalid_ = True
+            if sys.version_info[0] >= 3:
+                obj.__name__ = funcname
+            else:
+                obj.func_name = funcname
+            obj.__name__ = name
+            obj.__doc__ = doc
+            if inspect.isclass(object_cache[parent]):
+                obj.__objclass__ = object_cache[parent]
+        else:
+            class Dummy(object): pass
+            obj = Dummy()
+            obj.__name__ = name
+            obj.__doc__ = doc
+            if inspect.isclass(object_cache[parent]):
+                obj.__get__ = lambda: None
+        object_cache[name] = obj
+
+        if parent:
+            if inspect.ismodule(object_cache[parent]):
+                obj.__module__ = parent
+                setattr(object_cache[parent], name.split('.')[-1], obj)
+
+    # Populate items
+    for node in root:
+        obj = object_cache.get(node.attrib['id'])
+        if obj is None: continue
+        for ref in node.findall('ref'):
+            if node.tag == 'class':
+                if ref.attrib['ref'].startswith(node.attrib['id'] + '.'):
+                    setattr(obj, ref.attrib['name'],
+                            object_cache.get(ref.attrib['ref']))
+            else:
+                setattr(obj, ref.attrib['name'],
+                        object_cache.get(ref.attrib['ref']))
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/smart_resolver.py b/astropy_helpers/astropy_helpers/sphinx/ext/smart_resolver.py
new file mode 100644
index 0000000..f01ca2f
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/smart_resolver.py
@@ -0,0 +1,92 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+"""
+The classes in the astropy docs are documented by their API location,
+which is not necessarily where they are defined in the source.  This
+causes a problem when certain automated features of the doc build,
+such as the inheritance diagrams or the `Bases` list of a class
+reference a class by its canonical location rather than its "user"
+location.
+
+In the `autodoc-process-docstring` event, a mapping from the actual
+name to the API name is maintained.  Later, in the `missing-reference`
+event, unresolved references are looked up in this dictionary and
+corrected if possible.
+"""
+
+from docutils.nodes import literal, reference
+
+
+def process_docstring(app, what, name, obj, options, lines):
+    if isinstance(obj, type):
+        env = app.env
+        if not hasattr(env, 'class_name_mapping'):
+            env.class_name_mapping = {}
+        mapping = env.class_name_mapping
+        mapping[obj.__module__ + '.' + obj.__name__] = name
+
+
+def missing_reference_handler(app, env, node, contnode):
+    if not hasattr(env, 'class_name_mapping'):
+        env.class_name_mapping = {}
+    mapping = env.class_name_mapping
+    reftype = node['reftype']
+    reftarget = node['reftarget']
+    if reftype in ('obj', 'class', 'exc', 'meth'):
+        reftarget = node['reftarget']
+        suffix = ''
+        if reftarget not in mapping:
+            if '.' in reftarget:
+                front, suffix = reftarget.rsplit('.', 1)
+            else:
+                suffix = reftarget
+
+            if suffix.startswith('_') and not suffix.startswith('__'):
+                # If this is a reference to a hidden class or method,
+                # we can't link to it, but we don't want to have a
+                # nitpick warning.
+                return node[0].deepcopy()
+
+            if reftype in ('obj', 'meth') and '.' in reftarget:
+                if front in mapping:
+                    reftarget = front
+                    suffix = '.' + suffix
+
+            if (reftype in ('class', ) and '.' in reftarget
+                and reftarget not in mapping):
+
+                if '.' in front:
+                    reftarget, _ = front.rsplit('.', 1)
+                    suffix = '.' + suffix
+                reftarget = reftarget + suffix
+                prefix = reftarget.rsplit('.')[0]
+                if (reftarget not in mapping and
+                    prefix in env.intersphinx_named_inventory):
+
+                    if reftarget in env.intersphinx_named_inventory[prefix]['py:class']:
+                        newtarget = env.intersphinx_named_inventory[prefix]['py:class'][reftarget][2]
+                        if not node['refexplicit'] and \
+                                '~' not in node.rawsource:
+                            contnode = literal(text=reftarget)
+                        newnode = reference('', '', internal=True)
+                        newnode['reftitle'] = reftarget
+                        newnode['refuri'] = newtarget
+                        newnode.append(contnode)
+
+                        return newnode
+
+        if reftarget in mapping:
+            newtarget = mapping[reftarget] + suffix
+            if not node['refexplicit'] and not '~' in node.rawsource:
+                contnode = literal(text=newtarget)
+            newnode = env.domains['py'].resolve_xref(
+                env, node['refdoc'], app.builder, 'class', newtarget,
+                node, contnode)
+            if newnode is not None:
+                newnode['reftitle'] = reftarget
+            return newnode
+
+
+def setup(app):
+    app.connect('autodoc-process-docstring', process_docstring)
+
+    app.connect('missing-reference', missing_reference_handler)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst
new file mode 100644
index 0000000..a58aa35
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst
@@ -0,0 +1,10 @@
+{% if referencefile %}
+.. include:: {{ referencefile }}
+{% endif %}
+
+{{ objname }}
+{{ underline }}
+
+.. currentmodule:: {{ module }}
+
+.. auto{{ objtype }}:: {{ objname }}
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst
new file mode 100644
index 0000000..85105fa
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst
@@ -0,0 +1,65 @@
+{% if referencefile %}
+.. include:: {{ referencefile }}
+{% endif %}
+
+{{ objname }}
+{{ underline }}
+
+.. currentmodule:: {{ module }}
+
+.. autoclass:: {{ objname }}
+   :show-inheritance:
+
+   {% if '__init__' in methods %}
+     {% set caught_result = methods.remove('__init__') %}
+   {% endif %}
+
+   {% block attributes_summary %}
+   {% if attributes %}
+
+   .. rubric:: Attributes Summary
+
+   .. autosummary::
+   {% for item in attributes %}
+      ~{{ name }}.{{ item }}
+   {%- endfor %}
+
+   {% endif %}
+   {% endblock %}
+
+   {% block methods_summary %}
+   {% if methods %}
+
+   .. rubric:: Methods Summary
+
+   .. autosummary::
+   {% for item in methods %}
+      ~{{ name }}.{{ item }}
+   {%- endfor %}
+
+   {% endif %}
+   {% endblock %}
+
+   {% block attributes_documentation %}
+   {% if attributes %}
+
+   .. rubric:: Attributes Documentation
+
+   {% for item in attributes %}
+   .. autoattribute:: {{ item }}
+   {%- endfor %}
+
+   {% endif %}
+   {% endblock %}
+
+   {% block methods_documentation %}
+   {% if methods %}
+
+   .. rubric:: Methods Documentation
+
+   {% for item in methods %}
+   .. automethod:: {{ item }}
+   {%- endfor %}
+
+   {% endif %}
+   {% endblock %}
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst
new file mode 100644
index 0000000..11208a2
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst
@@ -0,0 +1,41 @@
+{% if referencefile %}
+.. include:: {{ referencefile }}
+{% endif %}
+
+{{ objname }}
+{{ underline }}
+
+.. automodule:: {{ fullname }}
+
+   {% block functions %}
+   {% if functions %}
+   .. rubric:: Functions
+
+   .. autosummary::
+   {% for item in functions %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block classes %}
+   {% if classes %}
+   .. rubric:: Classes
+
+   .. autosummary::
+   {% for item in classes %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block exceptions %}
+   {% if exceptions %}
+   .. rubric:: Exceptions
+
+   .. autosummary::
+   {% for item in exceptions %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/__init__.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/__init__.py
new file mode 100644
index 0000000..6476492
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/__init__.py
@@ -0,0 +1,70 @@
+import os
+import subprocess as sp
+import sys
+
+from textwrap import dedent
+
+import pytest
+
+
+ at pytest.fixture
+def cython_testpackage(tmpdir, request):
+    """
+    Creates a trivial Cython package for use with tests.
+    """
+
+    test_pkg = tmpdir.mkdir('test_pkg')
+    test_pkg.mkdir('_eva_').ensure('__init__.py')
+    test_pkg.join('_eva_').join('unit02.pyx').write(dedent("""\
+        def pilot():
+            \"\"\"Returns the pilot of Eva Unit-02.\"\"\"
+
+            return True
+    """))
+
+    import astropy_helpers
+
+    test_pkg.join('setup.py').write(dedent("""\
+        import sys
+
+        sys.path.insert(0, {0!r})
+
+        from os.path import join
+        from setuptools import setup, Extension
+        from astropy_helpers.setup_helpers import register_commands
+
+        NAME = '_eva_'
+        VERSION = 0.1
+        RELEASE = True
+
+        cmdclassd = register_commands(NAME, VERSION, RELEASE)
+
+        setup(
+            name=NAME,
+            version=VERSION,
+            cmdclass=cmdclassd,
+            ext_modules=[Extension('_eva_.unit02',
+                                   [join('_eva_', 'unit02.pyx')])]
+        )
+    """.format(os.path.dirname(astropy_helpers.__path__[0]))))
+
+    test_pkg.chdir()
+    # Build the Cython module in a subprocess; otherwise strange things can
+    # happen with Cython's global module state
+    sp.call([sys.executable, 'setup.py', 'build_ext', '--inplace'])
+
+    sys.path.insert(0, str(test_pkg))
+    import _eva_.unit02
+
+    def cleanup(test_pkg=test_pkg):
+        for modname in ['_eva_', '_eva_.unit02']:
+            try:
+                del sys.modules[modname]
+            except KeyError:
+                pass
+
+        sys.path.remove(str(test_pkg))
+
+    request.addfinalizer(cleanup)
+
+    return test_pkg
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_autodoc_enhancements.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_autodoc_enhancements.py
new file mode 100644
index 0000000..9b7d83e
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_autodoc_enhancements.py
@@ -0,0 +1,56 @@
+import sys
+
+from textwrap import dedent
+
+import pytest
+
+from ..autodoc_enhancements import type_object_attrgetter
+
+
+# Define test classes outside the class; otherwise there is flakiness with the
+# details of how exec works on different Python versions
+class Meta(type):
+    @property
+    def foo(cls):
+        return 'foo'
+
+if sys.version_info[0] < 3:
+    exec(dedent("""
+        class MyClass(object):
+            __metaclass__ = Meta
+            @property
+            def foo(self):
+                \"\"\"Docstring for MyClass.foo property.\"\"\"
+                return 'myfoo'
+    """))
+else:
+    exec(dedent("""
+        class MyClass(metaclass=Meta):
+            @property
+            def foo(self):
+                \"\"\"Docstring for MyClass.foo property.\"\"\"
+                return 'myfoo'
+    """))
+
+
+def test_type_attrgetter():
+    """
+    This test essentially reproduces the docstring for
+    `type_object_attrgetter`.
+
+    Sphinx itself tests the custom attrgetter feature; see:
+    https://bitbucket.org/birkenfeld/sphinx/src/40bd03003ac6fe274ccf3c80d7727509e00a69ea/tests/test_autodoc.py?at=default#cl-502
+    so rather than a full end-to-end functional test it's simple enough to just
+    test that this function does what it needs to do.
+    """
+
+    assert getattr(MyClass, 'foo') == 'foo'
+    obj = type_object_attrgetter(MyClass, 'foo')
+    assert isinstance(obj, property)
+    assert obj.__doc__ == 'Docstring for MyClass.foo property.'
+
+    with pytest.raises(AttributeError):
+        type_object_attrgetter(MyClass, 'susy')
+
+    assert type_object_attrgetter(MyClass, 'susy', 'default') == 'default'
+    assert type_object_attrgetter(MyClass, '__dict__') == MyClass.__dict__
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodapi.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodapi.py
new file mode 100644
index 0000000..5e2dfc7
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodapi.py
@@ -0,0 +1,343 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import os
+import sys
+
+import pytest
+
+from . import *
+from ....utils import iteritems
+
+pytest.importorskip('sphinx')  # skips these tests if sphinx not present
+
+
+class FakeConfig(object):
+    """
+    Mocks up a sphinx configuration setting construct for automodapi tests
+    """
+    def __init__(self, **kwargs):
+        for k, v in iteritems(kwargs):
+            setattr(self, k, v)
+
+
+class FakeApp(object):
+    """
+    Mocks up a `sphinx.application.Application` object for automodapi tests
+    """
+
+    # Some default config values
+    _defaults = {
+        'automodapi_toctreedirnm': 'api',
+        'automodapi_writereprocessed': False
+    }
+
+    def __init__(self, **configs):
+        config = self._defaults.copy()
+        config.update(configs)
+        self.config = FakeConfig(**config)
+        self.info = []
+        self.warnings = []
+
+    def info(self, msg, loc):
+        self.info.append((msg, loc))
+
+    def warn(self, msg, loc):
+        self.warnings.append((msg, loc))
+
+
+am_replacer_str = """
+This comes before
+
+.. automodapi:: astropy_helpers.sphinx.ext.tests.test_automodapi
+{options}
+
+This comes after
+"""
+
+am_replacer_basic_expected = """
+This comes before
+
+astropy_helpers.sphinx.ext.tests.test_automodapi Module
+-------------------------------------------------------
+
+.. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi
+
+Functions
+^^^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :functions-only:
+    :toctree: api/
+
+Classes
+^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :classes-only:
+    :toctree: api/
+
+Class Inheritance Diagram
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :private-bases:
+    :parts: 1
+    {empty}
+
+This comes after
+""".format(empty='')
+# the .format is necessary for editors that remove empty-line whitespace
+
+
+def test_am_replacer_basic():
+    """
+    Tests replacing an ".. automodapi::" with the automodapi no-option
+    template
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    result = automodapi_replace(am_replacer_str.format(options=''), fakeapp)
+
+    assert result == am_replacer_basic_expected
+
+am_replacer_noinh_expected = """
+This comes before
+
+astropy_helpers.sphinx.ext.tests.test_automodapi Module
+-------------------------------------------------------
+
+.. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi
+
+Functions
+^^^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :functions-only:
+    :toctree: api/
+
+Classes
+^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :classes-only:
+    :toctree: api/
+
+
+This comes after
+""".format(empty='')
+
+
+def test_am_replacer_noinh():
+    """
+    Tests replacing an ".. automodapi::" with no-inheritance-diagram
+    option
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    ops = ['', ':no-inheritance-diagram:']
+    ostr = '\n    '.join(ops)
+    result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp)
+
+    assert result == am_replacer_noinh_expected
+
+am_replacer_titleandhdrs_expected = """
+This comes before
+
+astropy_helpers.sphinx.ext.tests.test_automodapi Module
+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+
+.. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi
+
+Functions
+*********
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :functions-only:
+    :toctree: api/
+
+Classes
+*******
+
+.. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :classes-only:
+    :toctree: api/
+
+Class Inheritance Diagram
+*************************
+
+.. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi
+    :private-bases:
+    :parts: 1
+    {empty}
+
+
+This comes after
+""".format(empty='')
+
+
+def test_am_replacer_titleandhdrs():
+    """
+    Tests replacing an ".. automodapi::" entry with title-setting and header
+    character options.
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    ops = ['', ':title: A new title', ':headings: &*']
+    ostr = '\n    '.join(ops)
+    result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp)
+
+    assert result == am_replacer_titleandhdrs_expected
+
+
+am_replacer_nomain_str = """
+This comes before
+
+.. automodapi:: astropy_helpers.sphinx.ext.automodapi
+    :no-main-docstr:
+
+This comes after
+"""
+
+am_replacer_nomain_expected = """
+This comes before
+
+astropy_helpers.sphinx.ext.automodapi Module
+--------------------------------------------
+
+
+
+Functions
+^^^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.automodapi
+    :functions-only:
+    :toctree: api/
+
+
+This comes after
+""".format(empty='')
+
+
+def test_am_replacer_nomain():
+    """
+    Tests replacing an ".. automodapi::" with "no-main-docstring" .
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    result = automodapi_replace(am_replacer_nomain_str, fakeapp)
+
+    assert result == am_replacer_nomain_expected
+
+
+am_replacer_skip_str = """
+This comes before
+
+.. automodapi:: astropy_helpers.sphinx.ext.automodapi
+    :skip: something1
+    :skip: something2
+
+This comes after
+"""
+
+am_replacer_skip_expected = """
+This comes before
+
+astropy_helpers.sphinx.ext.automodapi Module
+--------------------------------------------
+
+.. automodule:: astropy_helpers.sphinx.ext.automodapi
+
+Functions
+^^^^^^^^^
+
+.. automodsumm:: astropy_helpers.sphinx.ext.automodapi
+    :functions-only:
+    :toctree: api/
+    :skip: something1,something2
+
+
+This comes after
+""".format(empty='')
+
+
+def test_am_replacer_skip():
+    """
+    Tests using the ":skip: option in an ".. automodapi::" .
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    result = automodapi_replace(am_replacer_skip_str, fakeapp)
+
+    assert result == am_replacer_skip_expected
+
+
+am_replacer_invalidop_str = """
+This comes before
+
+.. automodapi:: astropy_helpers.sphinx.ext.automodapi
+    :invalid-option:
+
+This comes after
+"""
+
+
+def test_am_replacer_invalidop():
+    """
+    Tests that a sphinx warning is produced with an invalid option.
+    """
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    automodapi_replace(am_replacer_invalidop_str, fakeapp)
+
+    expected_warnings = [('Found additional options invalid-option in '
+                          'automodapi.', None)]
+
+    assert fakeapp.warnings == expected_warnings
+
+
+am_replacer_cython_str = """
+This comes before
+
+.. automodapi:: _eva_.unit02
+{options}
+
+This comes after
+"""
+
+am_replacer_cython_expected = """
+This comes before
+
+_eva_.unit02 Module
+-------------------
+
+.. automodule:: _eva_.unit02
+
+Functions
+^^^^^^^^^
+
+.. automodsumm:: _eva_.unit02
+    :functions-only:
+    :toctree: api/
+
+This comes after
+""".format(empty='')
+
+
+def test_am_replacer_cython(cython_testpackage):
+    """
+    Tests replacing an ".. automodapi::" for a Cython module.
+    """
+
+    from ..automodapi import automodapi_replace
+
+    fakeapp = FakeApp()
+    result = automodapi_replace(am_replacer_cython_str.format(options=''),
+                                fakeapp)
+
+    assert result == am_replacer_cython_expected
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodsumm.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodsumm.py
new file mode 100644
index 0000000..cd8afa3
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodsumm.py
@@ -0,0 +1,112 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import sys
+
+import pytest
+
+from . import *
+from ....utils import iteritems
+
+pytest.importorskip('sphinx')  # skips these tests if sphinx not present
+
+
+class FakeEnv(object):
+    """
+    Mocks up a sphinx env setting construct for automodapi tests
+    """
+    def __init__(self, **kwargs):
+        for k, v in iteritems(kwargs):
+            setattr(self, k, v)
+
+
+class FakeBuilder(object):
+    """
+    Mocks up a sphinx builder setting construct for automodapi tests
+    """
+    def __init__(self, **kwargs):
+        self.env = FakeEnv(**kwargs)
+
+
+class FakeApp(object):
+    """
+    Mocks up a `sphinx.application.Application` object for automodapi tests
+    """
+    def __init__(self, srcdir, automodapipresent=True):
+        self.builder = FakeBuilder(srcdir=srcdir)
+        self.info = []
+        self.warnings = []
+        self._extensions = []
+        if automodapipresent:
+            self._extensions.append('astropy_helpers.sphinx.ext.automodapi')
+
+    def info(self, msg, loc):
+        self.info.append((msg, loc))
+
+    def warn(self, msg, loc):
+        self.warnings.append((msg, loc))
+
+
+ams_to_asmry_str = """
+Before
+
+.. automodsumm:: astropy_helpers.sphinx.ext.automodsumm
+    :p:
+
+And After
+"""
+
+ams_to_asmry_expected = """\
+.. currentmodule:: astropy_helpers.sphinx.ext.automodsumm
+
+.. autosummary::
+    :p:
+
+    Automoddiagram
+    Automodsumm
+    automodsumm_to_autosummary_lines
+    generate_automodsumm_docs
+    process_automodsumm_generation
+    setup"""
+
+
+def test_ams_to_asmry(tmpdir):
+    from ..automodsumm import automodsumm_to_autosummary_lines
+
+    fi = tmpdir.join('automodsumm.rst')
+    fi.write(ams_to_asmry_str)
+
+    fakeapp = FakeApp(srcdir='')
+    resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp)
+
+    assert '\n'.join(resultlines) == ams_to_asmry_expected
+
+
+ams_cython_str = """
+Before
+
+.. automodsumm:: _eva_.unit02
+    :functions-only:
+    :p:
+
+And After
+"""
+
+ams_cython_expected = """\
+.. currentmodule:: _eva_.unit02
+
+.. autosummary::
+    :p:
+
+    pilot"""
+
+
+def test_ams_cython(tmpdir, cython_testpackage):
+    from ..automodsumm import automodsumm_to_autosummary_lines
+
+    fi = tmpdir.join('automodsumm.rst')
+    fi.write(ams_cython_str)
+
+    fakeapp = FakeApp(srcdir='')
+    resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp)
+
+    assert '\n'.join(resultlines) == ams_cython_expected
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_docscrape.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_docscrape.py
new file mode 100644
index 0000000..1cefd43
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_docscrape.py
@@ -0,0 +1,762 @@
+# -*- encoding:utf-8 -*-
+from __future__ import division, absolute_import, print_function
+
+import sys, textwrap
+
+from ..docscrape import NumpyDocString, FunctionDoc, ClassDoc
+from ..docscrape_sphinx import SphinxDocString, SphinxClassDoc
+
+if sys.version_info[0] >= 3:
+    sixu = lambda s: s
+else:
+    sixu = lambda s: unicode(s, 'unicode_escape')
+
+
+doc_txt = '''\
+  numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+  Draw values from a multivariate normal distribution with specified
+  mean and covariance.
+
+  The multivariate normal or Gaussian distribution is a generalisation
+  of the one-dimensional normal distribution to higher dimensions.
+
+  Parameters
+  ----------
+  mean : (N,) ndarray
+      Mean of the N-dimensional distribution.
+
+      .. math::
+
+         (1+2+3)/3
+
+  cov : (N, N) ndarray
+      Covariance matrix of the distribution.
+  shape : tuple of ints
+      Given a shape of, for example, (m,n,k), m*n*k samples are
+      generated, and packed in an m-by-n-by-k arrangement.  Because
+      each sample is N-dimensional, the output shape is (m,n,k,N).
+
+  Returns
+  -------
+  out : ndarray
+      The drawn samples, arranged according to `shape`.  If the
+      shape given is (m,n,...), then the shape of `out` is is
+      (m,n,...,N).
+
+      In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
+      value drawn from the distribution.
+  list of str
+      This is not a real return value.  It exists to test
+      anonymous return values.
+
+  Other Parameters
+  ----------------
+  spam : parrot
+      A parrot off its mortal coil.
+
+  Raises
+  ------
+  RuntimeError
+      Some error
+
+  Warns
+  -----
+  RuntimeWarning
+      Some warning
+
+  Warnings
+  --------
+  Certain warnings apply.
+
+  Notes
+  -----
+  Instead of specifying the full covariance matrix, popular
+  approximations include:
+
+    - Spherical covariance (`cov` is a multiple of the identity matrix)
+    - Diagonal covariance (`cov` has non-negative elements only on the diagonal)
+
+  This geometrical property can be seen in two dimensions by plotting
+  generated data-points:
+
+  >>> mean = [0,0]
+  >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
+
+  >>> x,y = multivariate_normal(mean,cov,5000).T
+  >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
+
+  Note that the covariance matrix must be symmetric and non-negative
+  definite.
+
+  References
+  ----------
+  .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
+         Processes," 3rd ed., McGraw-Hill Companies, 1991
+  .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
+         2nd ed., Wiley, 2001.
+
+  See Also
+  --------
+  some, other, funcs
+  otherfunc : relationship
+
+  Examples
+  --------
+  >>> mean = (1,2)
+  >>> cov = [[1,0],[1,0]]
+  >>> x = multivariate_normal(mean,cov,(3,3))
+  >>> print x.shape
+  (3, 3, 2)
+
+  The following is probably true, given that 0.6 is roughly twice the
+  standard deviation:
+
+  >>> print list( (x[0,0,:] - mean) < 0.6 )
+  [True, True]
+
+  .. index:: random
+     :refguide: random;distributions, random;gauss
+
+  '''
+doc = NumpyDocString(doc_txt)
+
+
+def test_signature():
+    assert doc['Signature'].startswith('numpy.multivariate_normal(')
+    assert doc['Signature'].endswith('spam=None)')
+
+def test_summary():
+    assert doc['Summary'][0].startswith('Draw values')
+    assert doc['Summary'][-1].endswith('covariance.')
+
+def test_extended_summary():
+    assert doc['Extended Summary'][0].startswith('The multivariate normal')
+
+def test_parameters():
+    assert len(doc['Parameters']) == 3
+    assert [n for n,_,_ in doc['Parameters']] == ['mean','cov','shape']
+
+    arg, arg_type, desc = doc['Parameters'][1]
+    assert arg_type == '(N, N) ndarray'
+    assert desc[0].startswith('Covariance matrix')
+    assert doc['Parameters'][0][-1][-2] == '   (1+2+3)/3'
+
+def test_other_parameters():
+    assert len(doc['Other Parameters']) == 1
+    assert [n for n,_,_ in doc['Other Parameters']] == ['spam']
+    arg, arg_type, desc = doc['Other Parameters'][0]
+    assert arg_type == 'parrot'
+    assert desc[0].startswith('A parrot off its mortal coil')
+
+def test_returns():
+    assert len(doc['Returns']) == 2
+    arg, arg_type, desc = doc['Returns'][0]
+    assert arg == 'out'
+    assert arg_type == 'ndarray'
+    assert desc[0].startswith('The drawn samples')
+    assert desc[-1].endswith('distribution.')
+
+    arg, arg_type, desc = doc['Returns'][1]
+    assert arg == 'list of str'
+    assert arg_type == ''
+    assert desc[0].startswith('This is not a real')
+    assert desc[-1].endswith('anonymous return values.')
+
+def test_notes():
+    assert doc['Notes'][0].startswith('Instead')
+    assert doc['Notes'][-1].endswith('definite.')
+    assert len(doc['Notes']) == 17
+
+def test_references():
+    assert doc['References'][0].startswith('..')
+    assert doc['References'][-1].endswith('2001.')
+
+def test_examples():
+    assert doc['Examples'][0].startswith('>>>')
+    assert doc['Examples'][-1].endswith('True]')
+
+def test_index():
+    assert doc['index']['default'] == 'random'
+    assert len(doc['index']) == 2
+    assert len(doc['index']['refguide']) == 2
+
+def non_blank_line_by_line_compare(a,b):
+    a = textwrap.dedent(a)
+    b = textwrap.dedent(b)
+    a = [l.rstrip() for l in a.split('\n') if l.strip()]
+    b = [l.rstrip() for l in b.split('\n') if l.strip()]
+    for n,line in enumerate(a):
+        if not line == b[n]:
+            raise AssertionError("Lines %s of a and b differ: "
+                                 "\n>>> %s\n<<< %s\n" %
+                                 (n,line,b[n]))
+def test_str():
+    non_blank_line_by_line_compare(str(doc),
+"""numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+Draw values from a multivariate normal distribution with specified
+mean and covariance.
+
+The multivariate normal or Gaussian distribution is a generalisation
+of the one-dimensional normal distribution to higher dimensions.
+
+Parameters
+----------
+mean : (N,) ndarray
+    Mean of the N-dimensional distribution.
+
+    .. math::
+
+       (1+2+3)/3
+
+cov : (N, N) ndarray
+    Covariance matrix of the distribution.
+shape : tuple of ints
+    Given a shape of, for example, (m,n,k), m*n*k samples are
+    generated, and packed in an m-by-n-by-k arrangement.  Because
+    each sample is N-dimensional, the output shape is (m,n,k,N).
+
+Returns
+-------
+out : ndarray
+    The drawn samples, arranged according to `shape`.  If the
+    shape given is (m,n,...), then the shape of `out` is is
+    (m,n,...,N).
+
+    In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
+    value drawn from the distribution.
+list of str
+    This is not a real return value.  It exists to test
+    anonymous return values.
+
+Other Parameters
+----------------
+spam : parrot
+    A parrot off its mortal coil.
+
+Raises
+------
+RuntimeError
+    Some error
+
+Warns
+-----
+RuntimeWarning
+    Some warning
+
+Warnings
+--------
+Certain warnings apply.
+
+See Also
+--------
+`some`_, `other`_, `funcs`_
+
+`otherfunc`_
+    relationship
+
+Notes
+-----
+Instead of specifying the full covariance matrix, popular
+approximations include:
+
+  - Spherical covariance (`cov` is a multiple of the identity matrix)
+  - Diagonal covariance (`cov` has non-negative elements only on the diagonal)
+
+This geometrical property can be seen in two dimensions by plotting
+generated data-points:
+
+>>> mean = [0,0]
+>>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
+
+>>> x,y = multivariate_normal(mean,cov,5000).T
+>>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
+
+Note that the covariance matrix must be symmetric and non-negative
+definite.
+
+References
+----------
+.. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
+       Processes," 3rd ed., McGraw-Hill Companies, 1991
+.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
+       2nd ed., Wiley, 2001.
+
+Examples
+--------
+>>> mean = (1,2)
+>>> cov = [[1,0],[1,0]]
+>>> x = multivariate_normal(mean,cov,(3,3))
+>>> print x.shape
+(3, 3, 2)
+
+The following is probably true, given that 0.6 is roughly twice the
+standard deviation:
+
+>>> print list( (x[0,0,:] - mean) < 0.6 )
+[True, True]
+
+.. index:: random
+   :refguide: random;distributions, random;gauss""")
+
+
+def test_sphinx_str():
+    sphinx_doc = SphinxDocString(doc_txt)
+    non_blank_line_by_line_compare(str(sphinx_doc),
+"""
+.. index:: random
+   single: random;distributions, random;gauss
+
+Draw values from a multivariate normal distribution with specified
+mean and covariance.
+
+The multivariate normal or Gaussian distribution is a generalisation
+of the one-dimensional normal distribution to higher dimensions.
+
+:Parameters:
+
+    **mean** : (N,) ndarray
+
+        Mean of the N-dimensional distribution.
+
+        .. math::
+
+           (1+2+3)/3
+
+    **cov** : (N, N) ndarray
+
+        Covariance matrix of the distribution.
+
+    **shape** : tuple of ints
+
+        Given a shape of, for example, (m,n,k), m*n*k samples are
+        generated, and packed in an m-by-n-by-k arrangement.  Because
+        each sample is N-dimensional, the output shape is (m,n,k,N).
+
+:Returns:
+
+    **out** : ndarray
+
+        The drawn samples, arranged according to `shape`.  If the
+        shape given is (m,n,...), then the shape of `out` is is
+        (m,n,...,N).
+
+        In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
+        value drawn from the distribution.
+
+    list of str
+
+        This is not a real return value.  It exists to test
+        anonymous return values.
+
+:Other Parameters:
+
+    **spam** : parrot
+
+        A parrot off its mortal coil.
+
+:Raises:
+
+    **RuntimeError**
+
+        Some error
+
+:Warns:
+
+    **RuntimeWarning**
+
+        Some warning
+
+.. warning::
+
+    Certain warnings apply.
+
+.. seealso::
+
+    :obj:`some`, :obj:`other`, :obj:`funcs`
+
+    :obj:`otherfunc`
+        relationship
+
+.. rubric:: Notes
+
+Instead of specifying the full covariance matrix, popular
+approximations include:
+
+  - Spherical covariance (`cov` is a multiple of the identity matrix)
+  - Diagonal covariance (`cov` has non-negative elements only on the diagonal)
+
+This geometrical property can be seen in two dimensions by plotting
+generated data-points:
+
+>>> mean = [0,0]
+>>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
+
+>>> x,y = multivariate_normal(mean,cov,5000).T
+>>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
+
+Note that the covariance matrix must be symmetric and non-negative
+definite.
+
+.. rubric:: References
+
+.. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
+       Processes," 3rd ed., McGraw-Hill Companies, 1991
+.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
+       2nd ed., Wiley, 2001.
+
+.. only:: latex
+
+   [1]_, [2]_
+
+.. rubric:: Examples
+
+>>> mean = (1,2)
+>>> cov = [[1,0],[1,0]]
+>>> x = multivariate_normal(mean,cov,(3,3))
+>>> print x.shape
+(3, 3, 2)
+
+The following is probably true, given that 0.6 is roughly twice the
+standard deviation:
+
+>>> print list( (x[0,0,:] - mean) < 0.6 )
+[True, True]
+""")
+
+
+doc2 = NumpyDocString("""
+    Returns array of indices of the maximum values of along the given axis.
+
+    Parameters
+    ----------
+    a : {array_like}
+        Array to look in.
+    axis : {None, integer}
+        If None, the index is into the flattened array, otherwise along
+        the specified axis""")
+
+def test_parameters_without_extended_description():
+    assert len(doc2['Parameters']) == 2
+
+doc3 = NumpyDocString("""
+    my_signature(*params, **kwds)
+
+    Return this and that.
+    """)
+
+def test_escape_stars():
+    signature = str(doc3).split('\n')[0]
+    signature == 'my_signature(\*params, \*\*kwds)'
+
+doc4 = NumpyDocString(
+    """a.conj()
+
+    Return an array with all complex-valued elements conjugated.""")
+
+def test_empty_extended_summary():
+    assert doc4['Extended Summary'] == []
+
+doc5 = NumpyDocString(
+    """
+    a.something()
+
+    Raises
+    ------
+    LinAlgException
+        If array is singular.
+
+    Warns
+    -----
+    SomeWarning
+        If needed
+    """)
+
+def test_raises():
+    assert len(doc5['Raises']) == 1
+    name,_,desc = doc5['Raises'][0]
+    assert name == 'LinAlgException'
+    assert desc == ['If array is singular.']
+
+def test_warns():
+    assert len(doc5['Warns']) == 1
+    name,_,desc = doc5['Warns'][0]
+    assert name == 'SomeWarning'
+    assert desc == ['If needed']
+
+def test_see_also():
+    doc6 = NumpyDocString(
+    """
+    z(x,theta)
+
+    See Also
+    --------
+    func_a, func_b, func_c
+    func_d : some equivalent func
+    foo.func_e : some other func over
+             multiple lines
+    func_f, func_g, :meth:`func_h`, func_j,
+    func_k
+    :obj:`baz.obj_q`
+    :class:`class_j`: fubar
+        foobar
+    """)
+
+    assert len(doc6['See Also']) == 12
+    for func, desc, role in doc6['See Also']:
+        if func in ('func_a', 'func_b', 'func_c', 'func_f',
+                    'func_g', 'func_h', 'func_j', 'func_k', 'baz.obj_q'):
+            assert(not desc)
+        else:
+            assert(desc)
+
+        if func == 'func_h':
+            assert role == 'meth'
+        elif func == 'baz.obj_q':
+            assert role == 'obj'
+        elif func == 'class_j':
+            assert role == 'class'
+        else:
+            assert role is None
+
+        if func == 'func_d':
+            assert desc == ['some equivalent func']
+        elif func == 'foo.func_e':
+            assert desc == ['some other func over', 'multiple lines']
+        elif func == 'class_j':
+            assert desc == ['fubar', 'foobar']
+
+def test_see_also_print():
+    class Dummy(object):
+        """
+        See Also
+        --------
+        func_a, func_b
+        func_c : some relationship
+                 goes here
+        func_d
+        """
+        pass
+
+    obj = Dummy()
+    s = str(FunctionDoc(obj, role='func'))
+    assert(':func:`func_a`, :func:`func_b`' in s)
+    assert('    some relationship' in s)
+    assert(':func:`func_d`' in s)
+
+doc7 = NumpyDocString("""
+
+        Doc starts on second line.
+
+        """)
+
+def test_empty_first_line():
+    assert doc7['Summary'][0].startswith('Doc starts')
+
+
+def test_no_summary():
+    str(SphinxDocString("""
+    Parameters
+    ----------"""))
+
+
+def test_unicode():
+    doc = SphinxDocString("""
+    öäöäöäöäöåååå
+
+    öäöäöäööäååå
+
+    Parameters
+    ----------
+    ååå : äää
+        ööö
+
+    Returns
+    -------
+    ååå : ööö
+        äää
+
+    """)
+    assert isinstance(doc['Summary'][0], str)
+    assert doc['Summary'][0] == 'öäöäöäöäöåååå'
+
+def test_plot_examples():
+    cfg = dict(use_plots=True)
+
+    doc = SphinxDocString("""
+    Examples
+    --------
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot([1,2,3],[4,5,6])
+    >>> plt.show()
+    """, config=cfg)
+    assert 'plot::' in str(doc), str(doc)
+
+    doc = SphinxDocString("""
+    Examples
+    --------
+    .. plot::
+
+       import matplotlib.pyplot as plt
+       plt.plot([1,2,3],[4,5,6])
+       plt.show()
+    """, config=cfg)
+    assert str(doc).count('plot::') == 1, str(doc)
+
+def test_class_members():
+
+    class Dummy(object):
+        """
+        Dummy class.
+
+        """
+        def spam(self, a, b):
+            """Spam\n\nSpam spam."""
+            pass
+        def ham(self, c, d):
+            """Cheese\n\nNo cheese."""
+            pass
+        @property
+        def spammity(self):
+            """Spammity index"""
+            return 0.95
+
+        class Ignorable(object):
+            """local class, to be ignored"""
+            pass
+
+    for cls in (ClassDoc, SphinxClassDoc):
+        doc = cls(Dummy, config=dict(show_class_members=False))
+        assert 'Methods' not in str(doc), (cls, str(doc))
+        assert 'spam' not in str(doc), (cls, str(doc))
+        assert 'ham' not in str(doc), (cls, str(doc))
+        assert 'spammity' not in str(doc), (cls, str(doc))
+        assert 'Spammity index' not in str(doc), (cls, str(doc))
+
+        doc = cls(Dummy, config=dict(show_class_members=True))
+        assert 'Methods' in str(doc), (cls, str(doc))
+        assert 'spam' in str(doc), (cls, str(doc))
+        assert 'ham' in str(doc), (cls, str(doc))
+        assert 'spammity' in str(doc), (cls, str(doc))
+
+        if cls is SphinxClassDoc:
+            assert '.. autosummary::' in str(doc), str(doc)
+        else:
+            assert 'Spammity index' in str(doc), str(doc)
+
+def test_duplicate_signature():
+    # Duplicate function signatures occur e.g. in ufuncs, when the
+    # automatic mechanism adds one, and a more detailed comes from the
+    # docstring itself.
+
+    doc = NumpyDocString(
+    """
+    z(x1, x2)
+
+    z(a, theta)
+    """)
+
+    assert doc['Signature'].strip() == 'z(a, theta)'
+
+
+class_doc_txt = """
+    Foo
+
+    Parameters
+    ----------
+    f : callable ``f(t, y, *f_args)``
+        Aaa.
+    jac : callable ``jac(t, y, *jac_args)``
+        Bbb.
+
+    Attributes
+    ----------
+    t : float
+        Current time.
+    y : ndarray
+        Current variable values.
+
+    Methods
+    -------
+    a
+    b
+    c
+
+    Examples
+    --------
+    For usage examples, see `ode`.
+"""
+
+def test_class_members_doc():
+    doc = ClassDoc(None, class_doc_txt)
+    non_blank_line_by_line_compare(str(doc),
+    """
+    Foo
+
+    Parameters
+    ----------
+    f : callable ``f(t, y, *f_args)``
+        Aaa.
+    jac : callable ``jac(t, y, *jac_args)``
+        Bbb.
+
+    Examples
+    --------
+    For usage examples, see `ode`.
+
+    Attributes
+    ----------
+    t : float
+        Current time.
+    y : ndarray
+        Current variable values.
+
+    Methods
+    -------
+    a
+
+    b
+
+    c
+
+    .. index::
+
+    """)
+
+def test_class_members_doc_sphinx():
+    doc = SphinxClassDoc(None, class_doc_txt)
+    non_blank_line_by_line_compare(str(doc),
+    """
+    Foo
+
+    :Parameters:
+
+        **f** : callable ``f(t, y, *f_args)``
+
+            Aaa.
+
+        **jac** : callable ``jac(t, y, *jac_args)``
+
+            Bbb.
+
+    .. rubric:: Examples
+
+    For usage examples, see `ode`.
+
+    .. rubric:: Attributes
+
+    ===  ==========
+      t  (float) Current time.
+      y  (ndarray) Current variable values.
+    ===  ==========
+
+    .. rubric:: Methods
+
+    ===  ==========
+      a
+      b
+      c
+    ===  ==========
+
+    """)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_utils.py b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_utils.py
new file mode 100644
index 0000000..8f1a9dd
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_utils.py
@@ -0,0 +1,34 @@
+#namedtuple is needed for find_mod_objs so it can have a non-local module
+
+import sys
+from collections import namedtuple
+
+import pytest
+
+from ..utils import find_mod_objs
+
+PY3 = sys.version_info[0] >= 3
+pytestmark = pytest.mark.skipif("PY3")
+
+
+def test_find_mod_objs():
+    lnms, fqns, objs = find_mod_objs('astropy_helpers')
+
+    # this import  is after the above call intentionally to make sure
+    # find_mod_objs properly imports astropy on its own
+    import astropy_helpers
+
+    # just check for astropy.test ... other things might be added, so we
+    # shouldn't check that it's the only thing
+    assert lnms == []
+
+    lnms, fqns, objs = find_mod_objs(
+        'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=False)
+
+    assert namedtuple in objs
+
+    lnms, fqns, objs = find_mod_objs(
+        'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=True)
+    assert 'namedtuple' not in lnms
+    assert 'collections.namedtuple' not in fqns
+    assert namedtuple not in objs
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/tocdepthfix.py b/astropy_helpers/astropy_helpers/sphinx/ext/tocdepthfix.py
new file mode 100644
index 0000000..be29478
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/tocdepthfix.py
@@ -0,0 +1,18 @@
+from sphinx import addnodes
+
+
+def fix_toc_entries(app, doctree):
+    # Get the docname; I don't know why this isn't just passed in to the
+    # callback
+    # This seems a bit unreliable as it's undocumented, but it's not "private"
+    # either:
+    docname = app.builder.env.temp_data['docname']
+    if app.builder.env.metadata[docname].get('tocdepth', 0) != 0:
+        # We need to reprocess any TOC nodes in the doctree and make sure all
+        # the files listed in any TOCs are noted
+        for treenode in doctree.traverse(addnodes.toctree):
+            app.builder.env.note_toctree(docname, treenode)
+
+
+def setup(app):
+    app.connect('doctree-read', fix_toc_entries)
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/traitsdoc.py b/astropy_helpers/astropy_helpers/sphinx/ext/traitsdoc.py
new file mode 100644
index 0000000..596c54e
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/traitsdoc.py
@@ -0,0 +1,142 @@
+"""
+=========
+traitsdoc
+=========
+
+Sphinx extension that handles docstrings in the Numpy standard format, [1]
+and support Traits [2].
+
+This extension can be used as a replacement for ``numpydoc`` when support
+for Traits is required.
+
+.. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
+.. [2] http://code.enthought.com/projects/traits/
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import inspect
+import os
+import pydoc
+import collections
+
+from . import docscrape
+from . import docscrape_sphinx
+from .docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString
+
+from . import numpydoc
+
+from . import comment_eater
+
+class SphinxTraitsDoc(SphinxClassDoc):
+    def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc):
+        if not inspect.isclass(cls):
+            raise ValueError("Initialise using a class. Got %r" % cls)
+        self._cls = cls
+
+        if modulename and not modulename.endswith('.'):
+            modulename += '.'
+        self._mod = modulename
+        self._name = cls.__name__
+        self._func_doc = func_doc
+
+        docstring = pydoc.getdoc(cls)
+        docstring = docstring.split('\n')
+
+        # De-indent paragraph
+        try:
+            indent = min(len(s) - len(s.lstrip()) for s in docstring
+                         if s.strip())
+        except ValueError:
+            indent = 0
+
+        for n,line in enumerate(docstring):
+            docstring[n] = docstring[n][indent:]
+
+        self._doc = docscrape.Reader(docstring)
+        self._parsed_data = {
+            'Signature': '',
+            'Summary': '',
+            'Description': [],
+            'Extended Summary': [],
+            'Parameters': [],
+            'Returns': [],
+            'Raises': [],
+            'Warns': [],
+            'Other Parameters': [],
+            'Traits': [],
+            'Methods': [],
+            'See Also': [],
+            'Notes': [],
+            'References': '',
+            'Example': '',
+            'Examples': '',
+            'index': {}
+            }
+
+        self._parse()
+
+    def _str_summary(self):
+        return self['Summary'] + ['']
+
+    def _str_extended_summary(self):
+        return self['Description'] + self['Extended Summary'] + ['']
+
+    def __str__(self, indent=0, func_role="func"):
+        out = []
+        out += self._str_signature()
+        out += self._str_index() + ['']
+        out += self._str_summary()
+        out += self._str_extended_summary()
+        for param_list in ('Parameters', 'Traits', 'Methods',
+                           'Returns','Raises'):
+            out += self._str_param_list(param_list)
+        out += self._str_see_also("obj")
+        out += self._str_section('Notes')
+        out += self._str_references()
+        out += self._str_section('Example')
+        out += self._str_section('Examples')
+        out = self._str_indent(out,indent)
+        return '\n'.join(out)
+
+def looks_like_issubclass(obj, classname):
+    """ Return True if the object has a class or superclass with the given class
+    name.
+
+    Ignores old-style classes.
+    """
+    t = obj
+    if t.__name__ == classname:
+        return True
+    for klass in t.__mro__:
+        if klass.__name__ == classname:
+            return True
+    return False
+
+def get_doc_object(obj, what=None, config=None):
+    if what is None:
+        if inspect.isclass(obj):
+            what = 'class'
+        elif inspect.ismodule(obj):
+            what = 'module'
+        elif isinstance(obj, collections.Callable):
+            what = 'function'
+        else:
+            what = 'object'
+    if what == 'class':
+        doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc, config=config)
+        if looks_like_issubclass(obj, 'HasTraits'):
+            for name, trait, comment in comment_eater.get_class_traits(obj):
+                # Exclude private traits.
+                if not name.startswith('_'):
+                    doc['Traits'].append((name, trait, comment.splitlines()))
+        return doc
+    elif what in ('function', 'method'):
+        return SphinxFunctionDoc(obj, '', config=config)
+    else:
+        return SphinxDocString(pydoc.getdoc(obj), config=config)
+
+def setup(app):
+    # init numpydoc
+    numpydoc.setup(app, get_doc_object)
+
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/utils.py b/astropy_helpers/astropy_helpers/sphinx/ext/utils.py
new file mode 100644
index 0000000..2a06c83
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/utils.py
@@ -0,0 +1,65 @@
+import inspect
+import sys
+
+
+def find_mod_objs(modname, onlylocals=False):
+    """ Returns all the public attributes of a module referenced by name.
+
+    .. note::
+        The returned list *not* include subpackages or modules of
+        `modname`,nor does it include private attributes (those that
+        beginwith '_' or are not in `__all__`).
+
+    Parameters
+    ----------
+    modname : str
+        The name of the module to search.
+    onlylocals : bool
+        If True, only attributes that are either members of `modname` OR one of
+        its modules or subpackages will be included.
+
+    Returns
+    -------
+    localnames : list of str
+        A list of the names of the attributes as they are named in the
+        module `modname` .
+    fqnames : list of str
+        A list of the full qualified names of the attributes (e.g.,
+        ``astropy.utils.misc.find_mod_objs``). For attributes that are
+        simple variables, this is based on the local name, but for
+        functions or classes it can be different if they are actually
+        defined elsewhere and just referenced in `modname`.
+    objs : list of objects
+        A list of the actual attributes themselves (in the same order as
+        the other arguments)
+
+    """
+
+    __import__(modname)
+    mod = sys.modules[modname]
+
+    if hasattr(mod, '__all__'):
+        pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__]
+    else:
+        pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_']
+
+    # filter out modules and pull the names and objs out
+    ismodule = inspect.ismodule
+    localnames = [k for k, v in pkgitems if not ismodule(v)]
+    objs = [v for k, v in pkgitems if not ismodule(v)]
+
+    # fully qualified names can be determined from the object's module
+    fqnames = []
+    for obj, lnm in zip(objs, localnames):
+        if hasattr(obj, '__module__') and hasattr(obj, '__name__'):
+            fqnames.append(obj.__module__ + '.' + obj.__name__)
+        else:
+            fqnames.append(modname + '.' + lnm)
+
+    if onlylocals:
+        valids = [fqn.startswith(modname) for fqn in fqnames]
+        localnames = [e for i, e in enumerate(localnames) if valids[i]]
+        fqnames = [e for i, e in enumerate(fqnames) if valids[i]]
+        objs = [e for i, e in enumerate(objs) if valids[i]]
+
+    return localnames, fqnames, objs
diff --git a/astropy_helpers/astropy_helpers/sphinx/ext/viewcode.py b/astropy_helpers/astropy_helpers/sphinx/ext/viewcode.py
new file mode 100644
index 0000000..d27e973
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/ext/viewcode.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.viewcode
+    ~~~~~~~~~~~~~~~~~~~
+
+    Add links to module code in Python object descriptions.
+
+    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+
+    Patched using patch in https://bitbucket.org/birkenfeld/sphinx/issue/623/extension-viewcode-fails-with-function on 21 Aug 2013 by Kyle H Barbary
+"""
+
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.locale import _
+from sphinx.pycode import ModuleAnalyzer
+from sphinx.util.nodes import make_refnode
+
+import sys
+import traceback
+
+if sys.version < '3':
+    text_type = unicode
+else:
+    text_type = str
+
+from ...utils import iteritems
+
+
+def doctree_read(app, doctree):
+    env = app.builder.env
+    if not hasattr(env, '_viewcode_modules'):
+        env._viewcode_modules = {}
+
+    def get_full_modname(modname, attribute):
+        try:
+            __import__(modname)
+        except Exception as error:
+            if not app.quiet:
+                app.info(traceback.format_exc().rstrip())
+            app.warn('viewcode can\'t import %s, failed with error "%s"' %
+                (modname, error))
+            return None
+        module = sys.modules[modname]
+        try:
+            # Allow an attribute to have multiple parts and incidentially allow
+            # repeated .s in the attribute.
+            attr = attribute.split('.')
+            value = module
+            for attr in attribute.split('.'):
+                if attr:
+                    value = getattr(value, attr)
+        except AttributeError:
+            app.warn('Didn\'t find %s in %s' % (attribute, module.__name__))
+            return None
+        else:
+            return getattr(value, '__module__', None)
+
+
+    def has_tag(modname, fullname, docname, refname):
+        entry = env._viewcode_modules.get(modname, None)
+        if entry is None:
+            try:
+                analyzer = ModuleAnalyzer.for_module(modname)
+            except Exception:
+                env._viewcode_modules[modname] = False
+                return
+            analyzer.find_tags()
+            if not isinstance(analyzer.code, text_type):
+                code = analyzer.code.decode(analyzer.encoding)
+            else:
+                code = analyzer.code
+            entry = code, analyzer.tags, {}, refname
+            env._viewcode_modules[modname] = entry
+        elif entry is False:
+            return
+        _, tags, used, _ = entry
+        if fullname in tags:
+            used[fullname] = docname
+            return True
+
+
+    for objnode in doctree.traverse(addnodes.desc):
+        if objnode.get('domain') != 'py':
+            continue
+        names = set()
+        for signode in objnode:
+            if not isinstance(signode, addnodes.desc_signature):
+                continue
+            modname = signode.get('module')
+            fullname = signode.get('fullname')
+            refname = modname
+            if env.config.viewcode_import:
+                modname = get_full_modname(modname, fullname)
+            if not modname:
+                continue
+            if not has_tag(modname, fullname, env.docname, refname):
+                continue
+            if fullname in names:
+                # only one link per name, please
+                continue
+            names.add(fullname)
+            pagename = '_modules/' + modname.replace('.', '/')
+            onlynode = addnodes.only(expr='html')
+            onlynode += addnodes.pending_xref(
+                '', reftype='viewcode', refdomain='std', refexplicit=False,
+                reftarget=pagename, refid=fullname,
+                refdoc=env.docname)
+            onlynode[0] += nodes.inline('', _('[source]'),
+                                        classes=['viewcode-link'])
+            signode += onlynode
+
+
+def missing_reference(app, env, node, contnode):
+    # resolve our "viewcode" reference nodes -- they need special treatment
+    if node['reftype'] == 'viewcode':
+        return make_refnode(app.builder, node['refdoc'], node['reftarget'],
+                            node['refid'], contnode)
+
+
+def collect_pages(app):
+    env = app.builder.env
+    if not hasattr(env, '_viewcode_modules'):
+        return
+    highlighter = app.builder.highlighter
+    urito = app.builder.get_relative_uri
+
+    modnames = set(env._viewcode_modules)
+
+    app.builder.info(' (%d module code pages)' %
+                     len(env._viewcode_modules), nonl=1)
+
+    for modname, entry in iteritems(env._viewcode_modules):
+        if not entry:
+            continue
+        code, tags, used, refname = entry
+        # construct a page name for the highlighted source
+        pagename = '_modules/' + modname.replace('.', '/')
+        # highlight the source using the builder's highlighter
+        highlighted = highlighter.highlight_block(code, 'python', linenos=False)
+        # split the code into lines
+        lines = highlighted.splitlines()
+        # split off wrap markup from the first line of the actual code
+        before, after = lines[0].split('<pre>')
+        lines[0:1] = [before + '<pre>', after]
+        # nothing to do for the last line; it always starts with </pre> anyway
+        # now that we have code lines (starting at index 1), insert anchors for
+        # the collected tags (HACK: this only works if the tag boundaries are
+        # properly nested!)
+        maxindex = len(lines) - 1
+        for name, docname in iteritems(used):
+            type, start, end = tags[name]
+            backlink = urito(pagename, docname) + '#' + refname + '.' + name
+            lines[start] = (
+                '<div class="viewcode-block" id="%s"><a class="viewcode-back" '
+                'href="%s">%s</a>' % (name, backlink, _('[docs]'))
+                + lines[start])
+            lines[min(end - 1, maxindex)] += '</div>'
+        # try to find parents (for submodules)
+        parents = []
+        parent = modname
+        while '.' in parent:
+            parent = parent.rsplit('.', 1)[0]
+            if parent in modnames:
+                parents.append({
+                    'link': urito(pagename, '_modules/' +
+                                  parent.replace('.', '/')),
+                    'title': parent})
+        parents.append({'link': urito(pagename, '_modules/index'),
+                        'title': _('Module code')})
+        parents.reverse()
+        # putting it all together
+        context = {
+            'parents': parents,
+            'title': modname,
+            'body': _('<h1>Source code for %s</h1>') % modname + \
+                    '\n'.join(lines)
+        }
+        yield (pagename, context, 'page.html')
+
+    if not modnames:
+        return
+
+    app.builder.info(' _modules/index')
+    html = ['\n']
+    # the stack logic is needed for using nested lists for submodules
+    stack = ['']
+    for modname in sorted(modnames):
+        if modname.startswith(stack[-1]):
+            stack.append(modname + '.')
+            html.append('<ul>')
+        else:
+            stack.pop()
+            while not modname.startswith(stack[-1]):
+                stack.pop()
+                html.append('</ul>')
+            stack.append(modname + '.')
+        html.append('<li><a href="%s">%s</a></li>\n' % (
+            urito('_modules/index', '_modules/' + modname.replace('.', '/')),
+            modname))
+    html.append('</ul>' * (len(stack) - 1))
+    context = {
+        'title': _('Overview: module code'),
+        'body': _('<h1>All modules for which code is available</h1>') + \
+            ''.join(html),
+    }
+
+    yield ('_modules/index', context, 'page.html')
+
+
+def setup(app):
+    app.add_config_value('viewcode_import', True, False)
+    app.connect('doctree-read', doctree_read)
+    app.connect('html-collect-pages', collect_pages)
+    app.connect('missing-reference', missing_reference)
+    #app.add_config_value('viewcode_include_modules', [], 'env')
+    #app.add_config_value('viewcode_exclude_modules', [], 'env')
diff --git a/astropy_helpers/astropy_helpers/sphinx/local/python3links.inv b/astropy_helpers/astropy_helpers/sphinx/local/python3links.inv
new file mode 100644
index 0000000..bedc7f8
Binary files /dev/null and b/astropy_helpers/astropy_helpers/sphinx/local/python3links.inv differ
diff --git a/astropy_helpers/astropy_helpers/sphinx/local/python3links.txt b/astropy_helpers/astropy_helpers/sphinx/local/python3links.txt
new file mode 100644
index 0000000..0b14628
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/local/python3links.txt
@@ -0,0 +1,20 @@
+# Sphinx inventory version 2
+# Project: Python
+# Version: 3.4
+# The remainder of this file should be compressed using zlib.
+bytes py:function -1 library/functions.html#bytes -
+TimeoutError py:exception -1 library/exceptions.html#TimeoutError -
+builtins.object py:class -1 library/functions.html#object -
+builtins.list py:class -1 library/functions.html#list -
+builtins.type py:class -1 library/functions.html#type -
+builtins.classmethod py:class -1 library/functions.html#classmethod -
+builtins.SyntaxWarning py:exception -1 library/exceptions.html#SyntaxWarning -
+builtins.RuntimeWarning py:exception -1 library/exceptions.html#RuntimeWarning -
+builtins.ValueError py:exception -1 library/exceptions.html#ValueError -
+object py:function -1 library/functions.html#object -
+object py:class -1 library/functions.html#object -
+urllib.request.urlopen py:function -1 library/urllib.request.html#urllib.request.urlopen -
+concurrent.futures.Future py:class -1 library/concurrent.futures.html#concurrent.futures.Future -
+concurrent.futures.ThreadPoolExecutor py:class -1 library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor -
+queue.Queue py:class -1 library/queue.html#queue.Queue -
+print() py:function -1 library/functions.html#print -
diff --git a/astropy_helpers/astropy_helpers/sphinx/setup_package.py b/astropy_helpers/astropy_helpers/sphinx/setup_package.py
new file mode 100644
index 0000000..f9d0579
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/setup_package.py
@@ -0,0 +1,10 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+def get_package_data():
+    # Install the theme files
+    return {
+        'astropy_helpers.sphinx': [
+            'ext/templates/*/*',
+            'local/*.inv',
+            'themes/bootstrap-astropy/*.*',
+            'themes/bootstrap-astropy/static/*.*']}
diff --git a/astropy/sphinx/themes/bootstrap-astropy/globaltoc.html b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/globaltoc.html
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html
diff --git a/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html
new file mode 100644
index 0000000..40b0da4
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html
@@ -0,0 +1,96 @@
+{% extends "basic/layout.html" %}
+
+{# Collapsible sidebar script from default/layout.html in Sphinx #}
+{% set script_files = script_files + ['_static/sidebar.js'] %}
+
+{# Add the google webfonts needed for the logo #}
+{% block extrahead %}
+<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,600' rel='stylesheet' type='text/css'>
+{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
+
+{% endblock %}
+
+
+{% block header %}
+<div class="topbar">
+  <a class="brand" title="{{ _('Documentation Home') }}" href="{{ pathto(master_doc) }}"><span id="logotext1">{{ theme_logotext1 }}</span><span id="logotext2">{{ theme_logotext2 }}</span><span id="logotext3">{{ theme_logotext3 }}</span></a>
+  <ul>
+    <li><a class="homelink" title="Astropy Homepage" href="http://www.astropy.org"></a></li>
+    <li><a title="{{ _('General Index') }}" href="{{ pathto('genindex') }}">Index</a></li>
+    <li><a title="{{ _('Module Index') }}" href="{{ pathto('py-modindex') }}">Modules</a></li>
+    <li>
+      {% block sidebarsearch %}
+      {% include "searchbox.html" %}
+      {% endblock %}
+    </li>
+  </ul>
+</div>
+{% endblock %}
+
+{% block relbar1 %}
+<div class="related">
+    <h3>{{ _('Navigation') }}</h3>
+    <ul>
+      {%- if next %}
+      <li class="right">
+	<a href="{{ next.link|e }}" title="{{ next.title|striptags|e }}">
+	  next {{ "»"|safe }}
+	</a>
+      </li>
+      {%- endif %}
+      {%- if prev %}
+      <li class="right">
+	<a href="{{ prev.link|e }}" title="{{ prev.title|striptags|e }}">
+	  {{ "«"|safe }} previous
+	</a>
+	{% if next %}{{ reldelim2 }}{% endif %}
+      </li>
+      {%- endif %}
+      {%- block rootrellink %}
+      <li>
+	<a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>
+	{{ reldelim1 }}
+      </li>
+      {%- endblock %}
+      {%- for parent in parents %}
+      <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
+      {%- endfor %}
+      {# Don't put the title in the relbar for the first (index) page. #}
+      {% if prev %}<li>{{ title }}</li>{% endif %}
+      {%- block relbaritems %} {% endblock %}
+    </ul>
+</div>
+{% endblock %}
+
+{# Silence the bottom relbar. #}
+{% block relbar2 %}{% endblock %}
+
+
+{%- block footer %}
+<footer class="footer">
+  <p class="pull-right">
+    {%- if edit_on_github %}
+    <a href="{{ edit_on_github }}">{{ edit_on_github_page_message }}</a>  
+    {%- endif %}
+    {%- if show_source and has_source and sourcename %}
+    <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+       rel="nofollow">{{ _('Page Source') }}</a>
+    {%- endif %}  
+    <a href="#">Back to Top</a></p>
+  <p>
+    {%- if show_copyright %}
+    {%- if hasdoc('copyright') %}
+    {% trans path=pathto('copyright'), copyright=copyright|e %}© <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}<br/>
+    {%- else %}
+    {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}<br/>
+    {%- endif %}
+    {%- endif %}
+    {%- if show_sphinx %}
+    {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}  
+    {%- endif %}
+    {%- if last_updated %}
+    {% trans last_updated=last_updated|e %}Last built {{ last_updated }}.{% endtrans %} <br/>
+    {%- endif %}
+  </p>
+</footer>
+{%- endblock %}
diff --git a/astropy/sphinx/themes/bootstrap-astropy/localtoc.html b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/localtoc.html
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html
diff --git a/astropy/sphinx/themes/bootstrap-astropy/searchbox.html b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/searchbox.html
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html
diff --git a/astropy/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png
diff --git a/astropy/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico
diff --git a/astropy/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png
diff --git a/astropy/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css
diff --git a/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js
new file mode 100644
index 0000000..5d82c67
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js
@@ -0,0 +1,57 @@
+$(document).ready(function() {
+    /* Add a [>>>] button on the top-right corner of code samples to hide
+     * the >>> and ... prompts and the output and thus make the code
+     * copyable. */
+    var div = $('.highlight-python .highlight,' +
+                '.highlight-python3 .highlight')
+    var pre = div.find('pre');
+
+    // get the styles from the current theme
+    pre.parent().parent().css('position', 'relative');
+    var hide_text = 'Hide the prompts and output';
+    var show_text = 'Show the prompts and output';
+    var border_width = pre.css('border-top-width');
+    var border_style = pre.css('border-top-style');
+    var border_color = pre.css('border-top-color');
+    var button_styles = {
+        'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
+        'border-color': border_color, 'border-style': border_style,
+        'border-width': border_width, 'color': border_color, 'text-size': '75%',
+        'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
+        'border-radius': '0 3px 0 0'
+    }
+
+    // create and add the button to all the code blocks that contain >>>
+    div.each(function(index) {
+        var jthis = $(this);
+        if (jthis.find('.gp').length > 0) {
+            var button = $('<span class="copybutton">>>></span>');
+            button.css(button_styles)
+            button.attr('title', hide_text);
+            jthis.prepend(button);
+        }
+        // tracebacks (.gt) contain bare text elements that need to be
+        // wrapped in a span to work with .nextUntil() (see later)
+        jthis.find('pre:has(.gt)').contents().filter(function() {
+            return ((this.nodeType == 3) && (this.data.trim().length > 0));
+        }).wrap('<span>');
+    });
+
+    // define the behavior of the button when it's clicked
+    $('.copybutton').toggle(
+        function() {
+            var button = $(this);
+            button.parent().find('.go, .gp, .gt').hide();
+            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
+            button.css('text-decoration', 'line-through');
+            button.attr('title', show_text);
+        },
+        function() {
+            var button = $(this);
+            button.parent().find('.go, .gp, .gt').show();
+            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
+            button.css('text-decoration', 'none');
+            button.attr('title', hide_text);
+        });
+});
+
diff --git a/astropy/sphinx/themes/bootstrap-astropy/static/sidebar.js b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.js
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/static/sidebar.js
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.js
diff --git a/astropy/sphinx/themes/bootstrap-astropy/theme.conf b/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/theme.conf
similarity index 100%
rename from astropy/sphinx/themes/bootstrap-astropy/theme.conf
rename to astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/theme.conf
diff --git a/astropy_helpers/astropy_helpers/src/__init__.py b/astropy_helpers/astropy_helpers/src/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/astropy_helpers/astropy_helpers/src/compiler.c b/astropy_helpers/astropy_helpers/src/compiler.c
new file mode 100644
index 0000000..75500ca
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/src/compiler.c
@@ -0,0 +1,129 @@
+#include <Python.h>
+
+/***************************************************************************
+ * Macros for determining the compiler version.
+ *
+ * These are borrowed from boost, and majorly abridged to include only
+ * the compilers we care about.
+ ***************************************************************************/
+
+#ifndef PY3K
+#if PY_MAJOR_VERSION >= 3
+#define PY3K 1
+#else
+#define PY3K 0
+#endif
+#endif
+
+
+#define STRINGIZE(X) DO_STRINGIZE(X)
+#define DO_STRINGIZE(X) #X
+
+#if defined __clang__
+/*  Clang C++ emulates GCC, so it has to appear early. */
+#    define COMPILER "Clang version " __clang_version__
+
+#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
+/* Intel */
+#    if defined(__INTEL_COMPILER)
+#        define INTEL_VERSION __INTEL_COMPILER
+#    elif defined(__ICL)
+#        define INTEL_VERSION __ICL
+#    elif defined(__ICC)
+#        define INTEL_VERSION __ICC
+#    elif defined(__ECC)
+#        define INTEL_VERSION __ECC
+#    endif
+#    define COMPILER "Intel C compiler version " STRINGIZE(INTEL_VERSION)
+
+#elif defined(__GNUC__)
+/* gcc */
+#    define COMPILER "GCC version " __VERSION__
+
+#elif defined(__SUNPRO_CC)
+/* Sun Workshop Compiler */
+#    define COMPILER "Sun compiler version " STRINGIZE(__SUNPRO_CC)
+
+#elif defined(_MSC_VER)
+/* Microsoft Visual C/C++
+   Must be last since other compilers define _MSC_VER for compatibility as well */
+#    if _MSC_VER < 1200
+#        define COMPILER_VERSION 5.0
+#    elif _MSC_VER < 1300
+#        define COMPILER_VERSION 6.0
+#    elif _MSC_VER == 1300
+#        define COMPILER_VERSION 7.0
+#    elif _MSC_VER == 1310
+#        define COMPILER_VERSION 7.1
+#    elif _MSC_VER == 1400
+#        define COMPILER_VERSION 8.0
+#    elif _MSC_VER == 1500
+#        define COMPILER_VERSION 9.0
+#    elif _MSC_VER == 1600
+#        define COMPILER_VERSION 10.0
+#    else
+#        define COMPILER_VERSION _MSC_VER
+#    endif
+#    define COMPILER "Microsoft Visual C++ version " STRINGIZE(COMPILER_VERSION)
+
+#else
+/* Fallback */
+#    define COMPILER "Unknown compiler"
+
+#endif
+
+
+/***************************************************************************
+ * Module-level
+ ***************************************************************************/
+
+struct module_state {
+/* The Sun compiler can't handle empty structs */
+#if defined(__SUNPRO_C) || defined(_MSC_VER)
+    int _dummy;
+#endif
+};
+
+#if PY3K
+    static struct PyModuleDef moduledef = {
+        PyModuleDef_HEAD_INIT,
+        "_compiler",
+        NULL,
+        sizeof(struct module_state),
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+    };
+
+    #define INITERROR return NULL
+
+    PyMODINIT_FUNC
+    PyInit__compiler(void)
+
+#else
+    #define INITERROR return
+
+    PyMODINIT_FUNC
+    init_compiler(void)
+#endif
+
+{
+  PyObject* m;
+
+#if PY3K
+  m = PyModule_Create(&moduledef);
+#else
+  m = Py_InitModule3("_compiler", NULL, NULL);
+#endif
+
+  if (m == NULL)
+    INITERROR;
+
+  PyModule_AddStringConstant(m, "compiler", COMPILER);
+
+#if PY3K
+  return m;
+#endif
+}
diff --git a/astropy_helpers/astropy_helpers/src/setup_package.py b/astropy_helpers/astropy_helpers/src/setup_package.py
new file mode 100644
index 0000000..f750125
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/src/setup_package.py
@@ -0,0 +1,2 @@
+def get_package_data():
+    return {'astropy_helpers.src': ['compiler.c']}
diff --git a/astropy_helpers/astropy_helpers/test_helpers.py b/astropy_helpers/astropy_helpers/test_helpers.py
new file mode 100644
index 0000000..c78a9ae
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/test_helpers.py
@@ -0,0 +1,250 @@
+from __future__ import (absolute_import, division, print_function,
+                        unicode_literals)
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+from setuptools import Command
+
+from .compat import _fix_user_options
+
+
+PY3 = sys.version_info[0] == 3
+
+
+class AstropyTest(Command, object):
+    description = 'Run the tests for this package'
+
+    user_options = [
+        ('package=', 'P',
+         "The name of a specific package to test, e.g. 'io.fits' or 'utils'.  "
+         "If nothing is specified, all default tests are run."),
+        ('test-path=', 't',
+         'Specify a test location by path.  If a relative path to a  .py file, '
+         'it is relative to the built package, so e.g., a  leading "astropy/" '
+         'is necessary.  If a relative  path to a .rst file, it is relative to '
+         'the directory *below* the --docs-path directory, so a leading '
+         '"docs/" is usually necessary.  May also be an absolute path.'),
+        ('verbose-results', 'V',
+         'Turn on verbose output from pytest.'),
+        ('plugins=', 'p',
+         'Plugins to enable when running pytest.'),
+        ('pastebin=', 'b',
+         "Enable pytest pastebin output. Either 'all' or 'failed'."),
+        ('args=', 'a',
+         'Additional arguments to be passed to pytest.'),
+        ('remote-data', 'R', 'Run tests that download remote data.'),
+        ('pep8', '8',
+         'Enable PEP8 checking and disable regular tests. '
+         'Requires the pytest-pep8 plugin.'),
+        ('pdb', 'd',
+         'Start the interactive Python debugger on errors.'),
+        ('coverage', 'c',
+         'Create a coverage report. Requires the coverage package.'),
+        ('open-files', 'o', 'Fail if any tests leave files open.  Requires the '
+         'psutil package.'),
+        ('parallel=', 'j',
+         'Run the tests in parallel on the specified number of '
+         'CPUs.  If negative, all the cores on the machine will be '
+         'used.  Requires the pytest-xdist plugin.'),
+        ('docs-path=', None,
+         'The path to the documentation .rst files.  If not provided, and '
+         'the current directory contains a directory called "docs", that '
+         'will be used.'),
+        ('skip-docs', None,
+         "Don't test the documentation .rst files."),
+        ('repeat=', None,
+         'How many times to repeat each test (can be used to check for '
+         'sporadic failures).')
+    ]
+
+    user_options = _fix_user_options(user_options)
+
+    package_name = ''
+
+    def initialize_options(self):
+        self.package = None
+        self.test_path = None
+        self.verbose_results = False
+        self.plugins = None
+        self.pastebin = None
+        self.args = None
+        self.remote_data = False
+        self.pep8 = False
+        self.pdb = False
+        self.coverage = False
+        self.open_files = False
+        self.parallel = 0
+        self.docs_path = None
+        self.skip_docs = False
+        self.repeat = None
+
+    def finalize_options(self):
+        # Normally we would validate the options here, but that's handled in
+        # run_tests
+        pass
+
+    def generate_testing_command(self):
+        """
+        Build a Python script to run the tests.
+        """
+
+        cmd_pre = ''  # Commands to run before the test function
+        cmd_post = ''  # Commands to run after the test function
+
+        if self.coverage:
+           pre, post = self._generate_coverage_commands()
+           cmd_pre += pre
+           cmd_post += post
+
+        if PY3:
+            set_flag = "import builtins; builtins._ASTROPY_TEST_ = True"
+        else:
+            set_flag = "import __builtin__; __builtin__._ASTROPY_TEST_ = True"
+
+        cmd = ('{cmd_pre}{0}; import {1.package_name}, sys; result = ('
+               '{1.package_name}.test('
+               'package={1.package!r}, '
+               'test_path={1.test_path!r}, '
+               'args={1.args!r}, '
+               'plugins={1.plugins!r}, '
+               'verbose={1.verbose_results!r}, '
+               'pastebin={1.pastebin!r}, '
+               'remote_data={1.remote_data!r}, '
+               'pep8={1.pep8!r}, '
+               'pdb={1.pdb!r}, '
+               'open_files={1.open_files!r}, '
+               'parallel={1.parallel!r}, '
+               'docs_path={1.docs_path!r}, '
+               'skip_docs={1.skip_docs!r}, '
+               'repeat={1.repeat!r})); '
+               '{cmd_post}'
+               'sys.exit(result)')
+        return cmd.format(set_flag, self, cmd_pre=cmd_pre, cmd_post=cmd_post)
+
+    def _validate_required_deps(self):
+        """
+        This method checks that any required modules are installed before
+        running the tests.
+        """
+        try:
+            import astropy
+        except ImportError:
+            raise ImportError(
+                "The 'test' command requires the astropy package to be "
+                "installed and importable.")
+
+    def run(self):
+        """
+        Run the tests!
+        """
+        # Build a testing install of the package
+        self._build_temp_install()
+
+        # Ensure all required packages are installed
+        self._validate_required_deps()
+
+        # Ensure there is a doc path
+        if self.docs_path is None:
+            if os.path.exists('docs'):
+                self.docs_path = os.path.abspath('docs')
+
+        # Run everything in a try: finally: so that the tmp dir gets deleted.
+        try:
+            # Construct this modules testing command
+            cmd = self.generate_testing_command()
+
+            # Run the tests in a subprocess--this is necessary since
+            # new extension modules may have appeared, and this is the
+            # easiest way to set up a new environment
+
+            # On Python 3.x prior to 3.3, the creation of .pyc files
+            # is not atomic.  py.test jumps through some hoops to make
+            # this work by parsing import statements and carefully
+            # importing files atomically.  However, it can't detect
+            # when __import__ is used, so its carefulness still fails.
+            # The solution here (admittedly a bit of a hack), is to
+            # turn off the generation of .pyc files altogether by
+            # passing the `-B` switch to `python`.  This does mean
+            # that each core will have to compile .py file to bytecode
+            # itself, rather than getting lucky and borrowing the work
+            # already done by another core.  Compilation is an
+            # insignificant fraction of total testing time, though, so
+            # it's probably not worth worrying about.
+            retcode = subprocess.call([sys.executable, '-B', '-c', cmd],
+                                      cwd=self.testing_path, close_fds=False)
+
+        finally:
+            # Remove temporary directory
+            shutil.rmtree(self.tmp_dir)
+
+        raise SystemExit(retcode)
+
+    def _build_temp_install(self):
+        """
+        Build the package and copy the build to a temporary directory for
+        the purposes of testing this avoids creating pyc and __pycache__
+        directories inside the build directory
+        """
+        self.reinitialize_command('build', inplace=True)
+        self.run_command('build')
+        build_cmd = self.get_finalized_command('build')
+        new_path = os.path.abspath(build_cmd.build_lib)
+
+        self.tmp_dir = tempfile.mkdtemp(prefix=self.package_name + '-test-')
+        self.testing_path = os.path.join(self.tmp_dir, os.path.basename(new_path))
+        shutil.copytree(new_path, self.testing_path)
+        shutil.copy('setup.cfg', self.testing_path)
+
+    def _generate_coverage_commands(self):
+        """
+        This method creates the post and pre commands if coverage is to be
+        generated
+        """
+        if self.parallel != 0:
+            raise ValueError(
+                "--coverage can not be used with --parallel")
+
+        try:
+            import coverage
+        except ImportError:
+            raise ImportError(
+                "--coverage requires that the coverage package is "
+                "installed.")
+
+        # Don't use get_pkg_data_filename here, because it
+        # requires importing astropy.config and thus screwing
+        # up coverage results for those packages.
+        coveragerc = os.path.join(
+            self.testing_path, self.package_name, 'tests', 'coveragerc')
+
+        # We create a coveragerc that is specific to the version
+        # of Python we're running, so that we can mark branches
+        # as being specifically for Python 2 or Python 3
+        with open(coveragerc, 'r') as fd:
+            coveragerc_content = fd.read()
+        if PY3:
+            ignore_python_version = '2'
+        else:
+            ignore_python_version = '3'
+        coveragerc_content = coveragerc_content.replace(
+            "{ignore_python_version}", ignore_python_version).replace(
+                "{packagename}", self.package_name)
+        tmp_coveragerc = os.path.join(self.tmp_dir, 'coveragerc')
+        with open(tmp_coveragerc, 'wb') as tmp:
+            tmp.write(coveragerc_content.encode('utf-8'))
+
+        cmd_pre = (
+            'import coverage; '
+            'cov = coverage.coverage(data_file="{0}", config_file="{1}"); '
+            'cov.start();'.format(
+                os.path.abspath(".coverage"), tmp_coveragerc))
+        cmd_post = (
+            'cov.stop(); '
+            'from astropy.tests.helper import _save_coverage; '
+            '_save_coverage(cov, result, "{0}", "{1}");'.format(
+                os.path.abspath('.'), self.testing_path))
+
+        return cmd_pre, cmd_post
diff --git a/astropy_helpers/astropy_helpers/tests/__init__.py b/astropy_helpers/astropy_helpers/tests/__init__.py
new file mode 100644
index 0000000..0558b01
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/tests/__init__.py
@@ -0,0 +1,157 @@
+import os
+import subprocess as sp
+import sys
+
+from setuptools import sandbox
+
+import pytest
+
+from ..utils import extends_doc
+
+PACKAGE_DIR = os.path.dirname(__file__)
+
+
+def run_cmd(cmd, args, path=None, raise_error=True):
+    """
+    Runs a shell command with the given argument list.  Changes directory to
+    ``path`` if given, otherwise runs the command in the current directory.
+
+    Returns a 3-tuple of (stdout, stderr, exit code)
+
+    If ``raise_error=True`` raise an exception on non-zero exit codes.
+    """
+
+    if path is not None:
+        # Transparently support py.path objects
+        path = str(path)
+
+    p = sp.Popen([cmd] + list(args), stdout=sp.PIPE, stderr=sp.PIPE,
+                 cwd=path)
+    streams = tuple(s.decode('latin1').strip() for s in p.communicate())
+    return_code = p.returncode
+
+    if raise_error and return_code != 0:
+        raise RuntimeError(
+            "The command `{0}` with args {1!r} exited with code {2}.\n"
+            "Stdout:\n\n{3}\n\nStderr:\n\n{4}".format(
+                cmd, list(args), return_code, streams[0], streams[1]))
+
+    return streams + (return_code,)
+
+
+ at extends_doc(sandbox.run_setup)
+def run_setup(*args, **kwargs):
+    """
+    In Python 3, on MacOS X, the import cache has to be invalidated otherwise
+    new extensions built with ``run_setup`` do not always get picked up.
+    """
+
+    try:
+        return sandbox.run_setup(*args, **kwargs)
+    finally:
+        if sys.version_info[:2] >= (3, 1):
+            import importlib
+            importlib.invalidate_caches()
+
+
+ at pytest.fixture(scope='function', autouse=True)
+def reset_setup_helpers(request):
+    """
+    Saves and restores the global state of the astropy_helpers.setup_helpers
+    module between tests.
+    """
+
+    mod = __import__('astropy_helpers.setup_helpers', fromlist=[''])
+
+    old_state = mod._module_state.copy()
+
+    def finalizer(old_state=old_state):
+        mod = sys.modules.get('astropy_helpers.setup_helpers')
+        if mod is not None:
+            mod._module_state.update(old_state)
+
+    request.addfinalizer(finalizer)
+
+
+ at pytest.fixture(scope='function', autouse=True)
+def reset_distutils_log():
+    """
+    This is a setup/teardown fixture that ensures the log-level of the
+    distutils log is always set to a default of WARN, since different
+    settings could affect tests that check the contents of stdout.
+    """
+
+    from distutils import log
+    log.set_threshold(log.WARN)
+
+
+ at pytest.fixture(scope='module', autouse=True)
+def fix_hide_setuptools():
+    """
+    Workaround for https://github.com/astropy/astropy-helpers/issues/124
+
+    In setuptools 10.0 run_setup was changed in such a way that it sweeps
+    away the existing setuptools import before running the setup script.  In
+    principle this is nice, but in the practice of testing astropy_helpers
+    this is problematic since we're trying to test code that has already been
+    imported during the testing process, and which relies on the setuptools
+    module that was already in use.
+    """
+
+    if hasattr(sandbox, 'hide_setuptools'):
+        sandbox.hide_setuptools = lambda: None
+
+
+TEST_PACKAGE_SETUP_PY = """\
+#!/usr/bin/env python
+
+from setuptools import setup
+
+NAME = 'astropy-helpers-test'
+VERSION = {version!r}
+
+setup(name=NAME, version=VERSION,
+      packages=['_astropy_helpers_test_'],
+      zip_safe=False)
+"""
+
+
+ at pytest.fixture
+def testpackage(tmpdir, version='0.1'):
+    """
+    This fixture creates a simplified package called _astropy_helpers_test_
+    used primarily for testing ah_boostrap, but without using the
+    astropy_helpers package directly and getting it confused with the
+    astropy_helpers package already under test.
+    """
+
+    source = tmpdir.mkdir('testpkg')
+
+    with source.as_cwd():
+        source.mkdir('_astropy_helpers_test_')
+        init = source.join('_astropy_helpers_test_', '__init__.py')
+        init.write('__version__ = {0!r}'.format(version))
+        setup_py = TEST_PACKAGE_SETUP_PY.format(version=version)
+        source.join('setup.py').write(setup_py)
+
+        # Make the new test package into a git repo
+        run_cmd('git', ['init'])
+        run_cmd('git', ['add', '--all'])
+        run_cmd('git', ['commit', '-m', 'test package'])
+
+    return source
+
+
+def cleanup_import(package_name):
+    """Remove all references to package_name from sys.modules"""
+
+    for k in list(sys.modules):
+        if not isinstance(k, str):
+            # Some things will actually do this =_=
+            continue
+        elif k.startswith('astropy_helpers.tests'):
+            # Don't delete imported test modules or else the tests will break,
+            # badly
+            continue
+        if k == package_name or k.startswith(package_name + '.'):
+            del sys.modules[k]
diff --git a/astropy_helpers/astropy_helpers/tests/test_ah_bootstrap.py b/astropy_helpers/astropy_helpers/tests/test_ah_bootstrap.py
new file mode 100644
index 0000000..389b2f9
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/tests/test_ah_bootstrap.py
@@ -0,0 +1,419 @@
+# -*- coding: utf-8 -*-
+
+import glob
+import os
+import textwrap
+import sys
+
+from distutils.version import StrictVersion
+
+import setuptools
+from setuptools.package_index import PackageIndex
+
+import pytest
+
+from . import *
+from ..utils import silence
+
+
+TEST_SETUP_PY = """\
+#!/usr/bin/env python
+from __future__ import print_function
+
+import os
+import sys
+
+import ah_bootstrap
+# reset the name of the package installed by ah_boostrap to
+# _astropy_helpers_test_--this will prevent any confusion by pkg_resources with
+# any already installed packages named astropy_helpers
+# We also disable auto-upgrade by default
+ah_bootstrap.DIST_NAME = 'astropy-helpers-test'
+ah_bootstrap.PACKAGE_NAME = '_astropy_helpers_test_'
+ah_bootstrap.AUTO_UPGRADE = False
+ah_bootstrap.DOWNLOAD_IF_NEEDED = False
+try:
+    ah_bootstrap.BOOTSTRAPPER = ah_bootstrap._Bootstrapper.main()
+    ah_bootstrap.use_astropy_helpers({args})
+finally:
+    ah_bootstrap.DIST_NAME = 'astropy-helpers'
+    ah_bootstrap.PACKAGE_NAME = 'astropy_helpers'
+    ah_bootstrap.AUTO_UPGRADE = True
+    ah_bootstrap.DOWNLOAD_IF_NEEDED = True
+
+# Kind of a hacky way to do this, but this assertion is specifically
+# for test_check_submodule_no_git
+# TODO: Rework the tests in this module so that it's easier to test specific
+# behaviors of ah_bootstrap for each test
+assert '--no-git' not in sys.argv
+
+import _astropy_helpers_test_
+filename = os.path.abspath(_astropy_helpers_test_.__file__)
+filename = filename.replace('.pyc', '.py')  # More consistent this way
+print(filename)
+"""
+
+
+# The behavior checked in some of the tests depends on the version of
+# setuptools
+try:
+    SETUPTOOLS_VERSION = StrictVersion(setuptools.__version__).version
+except:
+    # Broken setuptools? ¯\_(ツ)_/¯
+    SETUPTOOLS_VERSION = (0, 0, 0)
+
+
+def test_bootstrap_from_submodule(tmpdir, testpackage, capsys):
+    """
+    Tests importing _astropy_helpers_test_ from a submodule in a git
+    repository.  This tests actually performing a fresh clone of the repository
+    without the submodule initialized, and that importing astropy_helpers in
+    that context works transparently after calling
+    `ah_boostrap.use_astropy_helpers`.
+    """
+
+    orig_repo = tmpdir.mkdir('orig')
+
+    # Ensure ah_bootstrap is imported from the local directory
+    import ah_bootstrap
+
+    with orig_repo.as_cwd():
+        run_cmd('git', ['init'])
+
+        # Write a test setup.py that uses ah_bootstrap; it also ensures that
+        # any previous reference to astropy_helpers is first wiped from
+        # sys.modules
+        orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args=''))
+        run_cmd('git', ['add', 'setup.py'])
+
+        # Add our own clone of the astropy_helpers repo as a submodule named
+        # astropy_helpers
+        run_cmd('git', ['submodule', 'add', str(testpackage),
+                        '_astropy_helpers_test_'])
+
+        run_cmd('git', ['commit', '-m', 'test repository'])
+
+        os.chdir(str(tmpdir))
+
+        # Creates a clone of our test repo in the directory 'clone'
+        run_cmd('git', ['clone', 'orig', 'clone'])
+
+        os.chdir('clone')
+
+        run_setup('setup.py', [])
+
+        stdout, stderr = capsys.readouterr()
+        path = stdout.strip()
+
+        # Ensure that the astropy_helpers used by the setup.py is the one that
+        # was imported from git submodule
+        a = os.path.normcase(path)
+        b = os.path.normcase(str(tmpdir.join('clone', '_astropy_helpers_test_',
+                                             '_astropy_helpers_test_',
+                                             '__init__.py')))
+        assert a == b
+
+
+def test_bootstrap_from_submodule_no_locale(tmpdir, testpackage, capsys,
+                                            monkeypatch):
+    """
+    Regression test for https://github.com/astropy/astropy/issues/2749
+
+    Runs test_bootstrap_from_submodule but with missing locale/langauge
+    settings.
+    """
+
+    for varname in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
+        monkeypatch.delenv(varname, raising=False)
+
+    test_bootstrap_from_submodule(tmpdir, testpackage, capsys)
+
+
+def test_bootstrap_from_submodule_bad_locale(tmpdir, testpackage, capsys,
+                                             monkeypatch):
+    """
+    Additional regression test for
+    https://github.com/astropy/astropy/issues/2749
+    """
+
+    for varname in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
+        monkeypatch.delenv(varname, raising=False)
+
+    # Test also with bad LC_CTYPE a la http://bugs.python.org/issue18378
+    monkeypatch.setenv('LC_CTYPE', 'UTF-8')
+
+    test_bootstrap_from_submodule(tmpdir, testpackage, capsys)
+
+
+def test_check_submodule_no_git(tmpdir, testpackage):
+    """
+    Tests that when importing astropy_helpers from a submodule, it is still
+    recognized as a submodule even when using the --no-git option.
+
+    In particular this ensures that the auto-upgrade feature is not activated.
+    """
+
+    orig_repo = tmpdir.mkdir('orig')
+
+    # Ensure ah_bootstrap is imported from the local directory
+    import ah_bootstrap
+
+    with orig_repo.as_cwd():
+        run_cmd('git', ['init'])
+
+        # Write a test setup.py that uses ah_bootstrap; it also ensures that
+        # any previous reference to astropy_helpers is first wiped from
+        # sys.modules
+        args = 'auto_upgrade=True'
+        orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args=args))
+        run_cmd('git', ['add', 'setup.py'])
+
+        # Add our own clone of the astropy_helpers repo as a submodule named
+        # astropy_helpers
+        run_cmd('git', ['submodule', 'add', str(testpackage),
+                        '_astropy_helpers_test_'])
+
+        run_cmd('git', ['commit', '-m', 'test repository'])
+
+        # Temporarily patch _do_upgrade to fail if called
+        class UpgradeError(Exception):
+            pass
+
+        def _do_upgrade(*args, **kwargs):
+            raise UpgradeError()
+
+        orig_do_upgrade = ah_bootstrap._Bootstrapper._do_upgrade
+        ah_bootstrap._Bootstrapper._do_upgrade = _do_upgrade
+        try:
+            run_setup('setup.py', ['--no-git'])
+        except UpgradeError:
+            pytest.fail('Attempted to run auto-upgrade despite importing '
+                        '_astropy_helpers_test_ from a git submodule')
+        finally:
+            ah_bootstrap._Bootstrapper._do_upgrade = orig_do_upgrade
+
+        # Ensure that the no-git option was in fact set
+        assert not ah_bootstrap.BOOTSTRAPPER.use_git
+
+
+def test_bootstrap_from_directory(tmpdir, testpackage, capsys):
+    """
+    Tests simply bundling a copy of the astropy_helpers source code in its
+    entirety bundled directly in the source package and not in an archive.
+    """
+
+    import ah_bootstrap
+
+    source = tmpdir.mkdir('source')
+    testpackage.copy(source.join('_astropy_helpers_test_'))
+
+    with source.as_cwd():
+        source.join('setup.py').write(TEST_SETUP_PY.format(args=''))
+        run_setup('setup.py', [])
+        stdout, stderr = capsys.readouterr()
+
+        stdout = stdout.splitlines()
+        if stdout:
+            path = stdout[-1].strip()
+        else:
+            path = ''
+
+        # Ensure that the astropy_helpers used by the setup.py is the one that
+        # was imported from git submodule
+        a = os.path.normcase(path)
+        b = os.path.normcase(str(source.join('_astropy_helpers_test_',
+                                             '_astropy_helpers_test_',
+                                             '__init__.py')))
+        assert a == b
+
+
+def test_bootstrap_from_archive(tmpdir, testpackage, capsys):
+    """
+    Tests importing _astropy_helpers_test_ from a .tar.gz source archive
+    shipped alongside the package that uses it.
+    """
+
+    orig_repo = tmpdir.mkdir('orig')
+
+    # Ensure ah_bootstrap is imported from the local directory
+    import ah_bootstrap
+
+    # Make a source distribution of the test package
+    with silence():
+        run_setup(str(testpackage.join('setup.py')),
+                  ['sdist', '--dist-dir=dist', '--formats=gztar'])
+
+    dist_dir = testpackage.join('dist')
+    for dist_file in dist_dir.visit('*.tar.gz'):
+        dist_file.copy(orig_repo)
+
+    with orig_repo.as_cwd():
+        # Write a test setup.py that uses ah_bootstrap; it also ensures that
+        # any previous reference to astropy_helpers is first wiped from
+        # sys.modules
+        args = 'path={0!r}'.format(os.path.basename(str(dist_file)))
+        orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args=args))
+
+        run_setup('setup.py', [])
+
+        stdout, stderr = capsys.readouterr()
+        path = stdout.splitlines()[-1].strip()
+
+        # Installation from the .tar.gz should have resulted in a .egg
+        # directory that the _astropy_helpers_test_ package was imported from
+        eggs = _get_local_eggs()
+        assert eggs
+        egg = orig_repo.join(eggs[0])
+        assert os.path.isdir(str(egg))
+
+        a = os.path.normcase(path)
+        b = os.path.normcase(str(egg.join('_astropy_helpers_test_',
+                                          '__init__.py')))
+
+        assert a == b
+
+
+def test_download_if_needed(tmpdir, testpackage, capsys):
+    """
+    Tests the case where astropy_helpers was not actually included in a
+    package, or is otherwise missing, and we need to "download" it.
+
+    This does not test actually downloading from the internet--this is normally
+    done through setuptools' easy_install command which can also install from a
+    source archive.  From the point of view of ah_boostrap the two actions are
+    equivalent, so we can just as easily simulate this by providing a setup.cfg
+    giving the path to a source archive to "download" (as though it were a
+    URL).
+    """
+
+    source = tmpdir.mkdir('source')
+
+    # Ensure ah_bootstrap is imported from the local directory
+    import ah_bootstrap
+
+    # Make a source distribution of the test package
+    with silence():
+        run_setup(str(testpackage.join('setup.py')),
+                  ['sdist', '--dist-dir=dist', '--formats=gztar'])
+
+    dist_dir = testpackage.join('dist')
+
+    with source.as_cwd():
+        source.join('setup.py').write(TEST_SETUP_PY.format(
+            args='download_if_needed=True'))
+        source.join('setup.cfg').write(textwrap.dedent("""\
+            [easy_install]
+            find_links = {find_links}
+        """.format(find_links=str(dist_dir))))
+
+        run_setup('setup.py', [])
+
+        stdout, stderr = capsys.readouterr()
+
+        # Just take the last line--on Python 2.6 distutils logs warning
+        # messages to stdout instead of stderr, causing them to be mixed up
+        # with our expected output
+        path = stdout.splitlines()[-1].strip()
+
+        # easy_install should have worked by 'installing' astropy_helpers as a
+        # .egg in the current directory
+        eggs = _get_local_eggs()
+        assert eggs
+        egg = source.join(eggs[0])
+        assert os.path.isdir(str(egg))
+
+        a = os.path.normcase(path)
+        b = os.path.normcase(str(egg.join('_astropy_helpers_test_',
+                                          '__init__.py')))
+        assert a == b
+
+
+def test_upgrade(tmpdir, capsys):
+    # Run the testpackage fixture manually, since we use it multiple times in
+    # this test to make different versions of _astropy_helpers_test_
+    orig_dir = testpackage(tmpdir.mkdir('orig'))
+
+    # Make a test package that uses _astropy_helpers_test_
+    source = tmpdir.mkdir('source')
+    dist_dir = source.mkdir('dists')
+    orig_dir.copy(source.join('_astropy_helpers_test_'))
+
+    with source.as_cwd():
+        setup_py = TEST_SETUP_PY.format(args='auto_upgrade=True')
+        source.join('setup.py').write(setup_py)
+
+        # This will be used to later to fake downloading the upgrade package
+        source.join('setup.cfg').write(textwrap.dedent("""\
+            [easy_install]
+            find_links = {find_links}
+        """.format(find_links=str(dist_dir))))
+
+    # Make additional "upgrade" versions of the _astropy_helpers_test_
+    # package--one of them is version 0.2 and the other is version 0.1.1.  The
+    # auto-upgrade should ignore version 0.2 but use version 0.1.1.
+    upgrade_dir_1 = testpackage(tmpdir.mkdir('upgrade_1'), version='0.2')
+    upgrade_dir_2 = testpackage(tmpdir.mkdir('upgrade_2'), version='0.1.1')
+
+    dists = []
+    # For each upgrade package go ahead and build a source distribution of it
+    # and copy that source distribution to a dist directory we'll use later to
+    # simulate a 'download'
+    for upgrade_dir in [upgrade_dir_1, upgrade_dir_2]:
+        with silence():
+            run_setup(str(upgrade_dir.join('setup.py')),
+                      ['sdist', '--dist-dir=dist', '--formats=gztar'])
+        dists.append(str(upgrade_dir.join('dist')))
+        for dist_file in upgrade_dir.visit('*.tar.gz'):
+            dist_file.copy(source.join('dists'))
+
+    # Monkey with the PackageIndex in ah_bootstrap so that it is initialized
+    # with the test upgrade packages, and so that it does not actually go out
+    # to the internet to look for anything
+    import ah_bootstrap
+
+    class FakePackageIndex(PackageIndex):
+        def __init__(self, *args, **kwargs):
+            PackageIndex.__init__(self, *args, **kwargs)
+            self.to_scan = dists
+
+        def find_packages(self, requirement):
+            # no-op
+            pass
+
+    ah_bootstrap.PackageIndex = FakePackageIndex
+
+    try:
+        with source.as_cwd():
+            # Now run the source setup.py; this test is similar to
+            # test_download_if_needed, but we explicitly check that the correct
+            # *version* of _astropy_helpers_test_ was used
+            run_setup('setup.py', [])
+
+            stdout, stderr = capsys.readouterr()
+            path = stdout.splitlines()[-1].strip()
+            eggs = _get_local_eggs()
+            assert eggs
+
+            egg = source.join(eggs[0])
+            assert os.path.isdir(str(egg))
+            a = os.path.normcase(path)
+            b = os.path.normcase(str(egg.join('_astropy_helpers_test_',
+                                              '__init__.py')))
+            assert a == b
+            assert 'astropy_helpers_test-0.1.1-' in str(egg)
+    finally:
+        ah_bootstrap.PackageIndex = PackageIndex
+
+
+def _get_local_eggs(path='.'):
+    """
+    Helper utility used by some tests to get the list of egg archive files
+    in a local directory.
+    """
+
+    if SETUPTOOLS_VERSION[0] >= 7:
+        eggs = glob.glob(os.path.join(path, '.eggs', '*.egg'))
+    else:
+        eggs = glob.glob('*.egg')
+
+    return eggs
diff --git a/astropy_helpers/astropy_helpers/tests/test_git_helpers.py b/astropy_helpers/astropy_helpers/tests/test_git_helpers.py
new file mode 100644
index 0000000..114f664
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/tests/test_git_helpers.py
@@ -0,0 +1,176 @@
+import glob
+import imp
+import os
+import pkgutil
+import re
+import sys
+import tarfile
+
+from . import *
+
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    _text_type = str
+else:
+    _text_type = unicode
+
+
+_DEV_VERSION_RE = re.compile(r'\d+\.\d+(?:\.\d+)?\.dev(\d+)')
+
+
+TEST_VERSION_SETUP_PY = """\
+#!/usr/bin/env python
+
+from setuptools import setup
+
+NAME = '_eva_'
+VERSION = {version!r}
+RELEASE = 'dev' not in VERSION
+
+from astropy_helpers.git_helpers import get_git_devstr
+from astropy_helpers.version_helpers import generate_version_py
+
+if not RELEASE:
+    VERSION += get_git_devstr(False)
+
+generate_version_py(NAME, VERSION, RELEASE, False)
+
+setup(name=NAME, version=VERSION, packages=['_eva_'])
+"""
+
+
+TEST_VERSION_INIT = """\
+try:
+    from .version import version as __version__
+    from .version import githash as __githash__
+except ImportError:
+    __version__ = __githash__ = ''
+"""
+
+
+ at pytest.fixture
+def version_test_package(tmpdir, request, version='42.42.dev'):
+    test_package = tmpdir.mkdir('test_package')
+    test_package.join('setup.py').write(
+        TEST_VERSION_SETUP_PY.format(version=version))
+    test_package.mkdir('_eva_').join('__init__.py').write(TEST_VERSION_INIT)
+    with test_package.as_cwd():
+        run_cmd('git', ['init'])
+        run_cmd('git', ['add', '--all'])
+        run_cmd('git', ['commit', '-m', 'test package'])
+
+    if '' in sys.path:
+        sys.path.remove('')
+
+    sys.path.insert(0, '')
+
+    def finalize():
+        cleanup_import('_eva_')
+
+    request.addfinalizer(finalize)
+
+    return test_package
+
+
+def test_update_git_devstr(version_test_package, capsys):
+    """Tests that the commit number in the package's version string updates
+    after git commits even without re-running setup.py.
+    """
+
+    with version_test_package.as_cwd():
+        run_setup('setup.py', ['--version'])
+
+        stdout, stderr = capsys.readouterr()
+        version = stdout.strip()
+
+        m = _DEV_VERSION_RE.match(version)
+        assert m, (
+            "Stdout did not match the version string pattern:"
+            "\n\n{0}\n\nStderr:\n\n{1}".format(stdout, stderr))
+        revcount = int(m.group(1))
+
+        import _eva_
+        assert _eva_.__version__ == version
+
+        # Make a silly git commit
+        with open('.test', 'w'):
+            pass
+
+        run_cmd('git', ['add', '.test'])
+        run_cmd('git', ['commit', '-m', 'test'])
+
+        import _eva_.version
+        imp.reload(_eva_.version)
+
+    # Previously this checked packagename.__version__, but in order for that to
+    # be updated we also have to re-import _astropy_init which could be tricky.
+    # Checking directly that the packagename.version module was updated is
+    # sufficient:
+    m = _DEV_VERSION_RE.match(_eva_.version.version)
+    assert m
+    assert int(m.group(1)) == revcount + 1
+
+    # This doesn't test astropy_helpers.get_helpers.update_git_devstr directly
+    # since a copy of that function is made in packagename.version (so that it
+    # can work without astropy_helpers installed).  In order to get test
+    # coverage on the actual astropy_helpers copy of that function just call it
+    # directly and compare to the value in packagename
+    from astropy_helpers.git_helpers import update_git_devstr
+
+    newversion = update_git_devstr(version, path=str(version_test_package))
+    assert newversion == _eva_.version.version
+
+
+def test_installed_git_version(version_test_package, tmpdir, capsys):
+    """
+    Test for https://github.com/astropy/astropy-helpers/issues/87
+
+    Ensures that packages installed with astropy_helpers have a correct copy
+    of the git hash of the installed commit.
+    """
+
+    # To test this, it should suffice to build a source dist, unpack it
+    # somewhere outside the git repository, and then do a build and import
+    # from the build directory--no need to "install" as such
+
+    with version_test_package.as_cwd():
+        run_setup('setup.py', ['build'])
+
+        try:
+            import _eva_
+            githash = _eva_.__githash__
+            assert githash and isinstance(githash, _text_type)
+        finally:
+            cleanup_import('_eva_')
+
+        run_setup('setup.py', ['sdist', '--dist-dir=dist', '--formats=gztar'])
+
+        tgzs = glob.glob(os.path.join('dist', '*.tar.gz'))
+        assert len(tgzs) == 1
+
+        tgz = version_test_package.join(tgzs[0])
+
+    build_dir = tmpdir.mkdir('build_dir')
+    tf = tarfile.open(str(tgz), mode='r:gz')
+    tf.extractall(str(build_dir))
+
+    with build_dir.as_cwd():
+        pkg_dir = glob.glob('_eva_-*')[0]
+        os.chdir(pkg_dir)
+        run_setup('setup.py', ['build'])
+
+        try:
+            import _eva_
+            loader = pkgutil.get_loader('_eva_')
+            # Ensure we are importing the 'packagename' that was just unpacked
+            # into the build_dir
+            if sys.version_info[:2] != (3, 3):
+                # Skip this test on Python 3.3 wherein the SourceFileLoader
+                # has a bug where get_filename() does not return an absolute
+                # path
+                assert loader.get_filename().startswith(str(build_dir))
+            assert _eva_.__githash__ == githash
+        finally:
+            cleanup_import('_eva_')
diff --git a/astropy_helpers/astropy_helpers/tests/test_setup_helpers.py b/astropy_helpers/astropy_helpers/tests/test_setup_helpers.py
new file mode 100644
index 0000000..7a9823d
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/tests/test_setup_helpers.py
@@ -0,0 +1,254 @@
+import shutil
+import sys
+
+from textwrap import dedent
+
+from .. import setup_helpers
+from ..setup_helpers import get_package_info, register_commands
+from . import *
+
+
+def test_cython_autoextensions(tmpdir):
+    """
+    Regression test for https://github.com/astropy/astropy-helpers/pull/19
+
+    Ensures that Cython extensions in sub-packages are discovered and built
+    only once.
+    """
+
+    # Make a simple test package
+    test_pkg = tmpdir.mkdir('test_pkg')
+    test_pkg.mkdir('yoda').mkdir('luke')
+    test_pkg.ensure('yoda', '__init__.py')
+    test_pkg.ensure('yoda', 'luke', '__init__.py')
+    test_pkg.join('yoda', 'luke', 'dagobah.pyx').write(
+        """def testfunc(): pass""")
+
+    # Required, currently, for get_package_info to work
+    register_commands('yoda', '0.0', False, srcdir=str(test_pkg))
+    package_info = get_package_info(str(test_pkg))
+
+    assert len(package_info['ext_modules']) == 1
+    assert package_info['ext_modules'][0].name == 'yoda.luke.dagobah'
+
+
+def test_no_cython_buildext(tmpdir):
+    """
+    Regression test for https://github.com/astropy/astropy-helpers/pull/35
+
+    This tests the custom build_ext command installed by astropy_helpers when
+    used with a project that has no Cython extensions (but does have one or
+    more normal C extensions).
+    """
+
+    # In order for this test to test the correct code path we need to fool
+    # setup_helpers into thinking we don't have Cython installed
+    setup_helpers._module_state['have_cython'] = False
+
+    test_pkg = tmpdir.mkdir('test_pkg')
+    test_pkg.mkdir('_eva_').ensure('__init__.py')
+
+    # TODO: It might be later worth making this particular test package into a
+    # reusable fixture for other build_ext tests
+
+    # A minimal C extension for testing
+    test_pkg.join('_eva_').join('unit01.c').write(dedent("""\
+        #include <Python.h>
+        #ifndef PY3K
+        #if PY_MAJOR_VERSION >= 3
+        #define PY3K 1
+        #else
+        #define PY3K 0
+        #endif
+        #endif
+
+        #if PY3K
+        static struct PyModuleDef moduledef = {
+            PyModuleDef_HEAD_INIT,
+            "unit01",
+            NULL,
+            -1,
+            NULL
+        };
+        PyMODINIT_FUNC
+        PyInit_unit01(void) {
+            return PyModule_Create(&moduledef);
+        }
+        #else
+        PyMODINIT_FUNC
+        initunit01(void) {
+            Py_InitModule3("unit01", NULL, NULL);
+        }
+        #endif
+    """))
+
+    test_pkg.join('setup.py').write(dedent("""\
+        from os.path import join
+        from setuptools import setup, Extension
+        from astropy_helpers.setup_helpers import register_commands
+
+        NAME = '_eva_'
+        VERSION = 0.1
+        RELEASE = True
+
+        cmdclassd = register_commands(NAME, VERSION, RELEASE)
+
+        setup(
+            name=NAME,
+            version=VERSION,
+            cmdclass=cmdclassd,
+            ext_modules=[Extension('_eva_.unit01',
+                                   [join('_eva_', 'unit01.c')])]
+        )
+    """))
+
+    with test_pkg.as_cwd():
+        run_setup('setup.py', ['build_ext', '--inplace'])
+
+    sys.path.insert(0, str(test_pkg))
+
+    try:
+        import _eva_.unit01
+        dirname = os.path.abspath(os.path.dirname(_eva_.unit01.__file__))
+        assert dirname == str(test_pkg.join('_eva_'))
+    finally:
+        cleanup_import('_eva_')
+        sys.path.remove(str(test_pkg))
+
+
+ at pytest.mark.parametrize('mode', ['cli', 'cli-w', 'direct'])
+def test_build_sphinx(tmpdir, mode):
+    """
+    Test for build_sphinx
+    """
+
+    import astropy_helpers
+    ah_path = os.path.dirname(astropy_helpers.__file__)
+
+    test_pkg = tmpdir.mkdir('test_pkg')
+
+    test_pkg.mkdir('mypackage')
+
+    test_pkg.join('mypackage').join('__init__.py').write(dedent("""\
+        def test_function():
+            pass
+
+        class A():
+            pass
+
+        class B(A):
+            pass
+    """))
+
+    docs = test_pkg.mkdir('docs')
+
+    autosummary = docs.mkdir('_templates').mkdir('autosummary')
+
+    autosummary.join('base.rst').write('{% extends "autosummary_core/base.rst" %}')
+    autosummary.join('class.rst').write('{% extends "autosummary_core/class.rst" %}')
+    autosummary.join('module.rst').write('{% extends "autosummary_core/module.rst" %}')
+
+    docs_dir = test_pkg.join('docs')
+
+    docs_dir.join('conf.py').write(dedent("""\
+        import sys
+        sys.path.append("../")
+        import warnings
+        with warnings.catch_warnings():  # ignore matplotlib warning
+            warnings.simplefilter("ignore")
+            from astropy_helpers.sphinx.conf import *
+        exclude_patterns.append('_templates')
+    """))
+
+    docs_dir.join('index.rst').write(dedent("""\
+        .. automodapi:: mypackage
+    """))
+
+    test_pkg.join('setup.py').write(dedent("""\
+        from os.path import join
+        from setuptools import setup, Extension
+        from astropy_helpers.setup_helpers import register_commands, get_package_info
+
+        NAME = 'mypackage'
+        VERSION = 0.1
+        RELEASE = True
+
+        cmdclassd = register_commands(NAME, VERSION, RELEASE)
+
+        setup(
+            name=NAME,
+            version=VERSION,
+            cmdclass=cmdclassd,
+            **get_package_info()
+        )
+    """))
+
+    with test_pkg.as_cwd():
+        shutil.copytree(ah_path, 'astropy_helpers')
+
+        if mode == 'cli':
+            run_setup('setup.py', ['build_sphinx'])
+        elif mode == 'cli-w':
+            run_setup('setup.py', ['build_sphinx', '-w'])
+        elif mode == 'direct':  # to check coverage
+            with docs_dir.as_cwd():
+                from sphinx import main
+                try:
+                    main(['-b html', '-d _build/doctrees', '.', '_build/html'])
+                except SystemExit as exc:
+                    assert exc.code == 0
+
+
+def test_command_hooks(tmpdir, capsys):
+    """A basic test for pre- and post-command hooks."""
+
+    test_pkg = tmpdir.mkdir('test_pkg')
+    test_pkg.mkdir('_welltall_')
+    test_pkg.join('_welltall_', '__init__.py').ensure()
+
+    # Create a setup_package module with a couple of command hooks in it
+    test_pkg.join('_welltall_', 'setup_package.py').write(dedent("""\
+        def pre_build_hook(cmd_obj):
+            print('Hello build!')
+
+        def post_build_hook(cmd_obj):
+            print('Goodbye build!')
+
+    """))
+
+    # A simple setup.py for the test package--running register_commands should
+    # discover and enable the command hooks
+    test_pkg.join('setup.py').write(dedent("""\
+        from os.path import join
+        from setuptools import setup, Extension
+        from astropy_helpers.setup_helpers import register_commands, get_package_info
+
+        NAME = '_welltall_'
+        VERSION = 0.1
+        RELEASE = True
+
+        cmdclassd = register_commands(NAME, VERSION, RELEASE)
+
+        setup(
+            name=NAME,
+            version=VERSION,
+            cmdclass=cmdclassd
+        )
+    """))
+
+    with test_pkg.as_cwd():
+        try:
+            run_setup('setup.py', ['build'])
+        finally:
+            cleanup_import('_welltall_')
+
+    stdout, stderr = capsys.readouterr()
+    want = dedent("""\
+        running build
+        running pre_hook from _welltall_.setup_package for build command
+        Hello build!
+        running post_hook from _welltall_.setup_package for build command
+        Goodbye build!
+    """).strip()
+
+    assert want in stdout
diff --git a/astropy_helpers/astropy_helpers/utils.py b/astropy_helpers/astropy_helpers/utils.py
new file mode 100644
index 0000000..9fd2ef3
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/utils.py
@@ -0,0 +1,591 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+from __future__ import absolute_import, unicode_literals
+
+import contextlib
+import functools
+import imp
+import inspect
+import os
+import sys
+import textwrap
+import types
+import warnings
+
+try:
+    from importlib import machinery as import_machinery
+except ImportError:
+    import_machinery = None
+
+
+# Python 3.3's importlib caches filesystem reads for faster imports in the
+# general case. But sometimes it's necessary to manually invalidate those
+# caches so that the import system can pick up new generated files.  See
+# https://github.com/astropy/astropy/issues/820
+if sys.version_info[:2] >= (3, 3):
+    from importlib import invalidate_caches
+else:
+    invalidate_caches = lambda: None
+
+
+# Note: The following Warning subclasses are simply copies of the Warnings in
+# Astropy of the same names.
+class AstropyWarning(Warning):
+    """
+    The base warning class from which all Astropy warnings should inherit.
+
+    Any warning inheriting from this class is handled by the Astropy logger.
+    """
+
+
+class AstropyDeprecationWarning(AstropyWarning):
+    """
+    A warning class to indicate a deprecated feature.
+    """
+
+
+class AstropyPendingDeprecationWarning(PendingDeprecationWarning,
+                                       AstropyWarning):
+    """
+    A warning class to indicate a soon-to-be deprecated feature.
+    """
+
+
+def _get_platlib_dir(cmd):
+    """
+    Given a build command, return the name of the appropriate platform-specific
+    build subdirectory directory (e.g. build/lib.linux-x86_64-2.7)
+    """
+
+    plat_specifier = '.{0}-{1}'.format(cmd.plat_name, sys.version[0:3])
+    return os.path.join(cmd.build_base, 'lib' + plat_specifier)
+
+
+def get_numpy_include_path():
+    """
+    Gets the path to the numpy headers.
+    """
+    # We need to go through this nonsense in case setuptools
+    # downloaded and installed Numpy for us as part of the build or
+    # install, since Numpy may still think it's in "setup mode", when
+    # in fact we're ready to use it to build astropy now.
+
+    if sys.version_info[0] >= 3:
+        import builtins
+        if hasattr(builtins, '__NUMPY_SETUP__'):
+            del builtins.__NUMPY_SETUP__
+        import imp
+        import numpy
+        imp.reload(numpy)
+    else:
+        import __builtin__
+        if hasattr(__builtin__, '__NUMPY_SETUP__'):
+            del __builtin__.__NUMPY_SETUP__
+        import numpy
+        reload(numpy)
+
+    try:
+        numpy_include = numpy.get_include()
+    except AttributeError:
+        numpy_include = numpy.get_numpy_include()
+    return numpy_include
+
+
+class _DummyFile(object):
+    """A noop writeable object."""
+
+    errors = ''  # Required for Python 3.x
+
+    def write(self, s):
+        pass
+
+    def flush(self):
+        pass
+
+
+ at contextlib.contextmanager
+def silence():
+    """A context manager that silences sys.stdout and sys.stderr."""
+
+    old_stdout = sys.stdout
+    old_stderr = sys.stderr
+    sys.stdout = _DummyFile()
+    sys.stderr = _DummyFile()
+    exception_occurred = False
+    try:
+        yield
+    except:
+        exception_occurred = True
+        # Go ahead and clean up so that exception handling can work normally
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+        raise
+
+    if not exception_occurred:
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+
+
+if sys.platform == 'win32':
+    import ctypes
+
+    def _has_hidden_attribute(filepath):
+        """
+        Returns True if the given filepath has the hidden attribute on
+        MS-Windows.  Based on a post here:
+        http://stackoverflow.com/questions/284115/cross-platform-hidden-file-detection
+        """
+        if isinstance(filepath, bytes):
+            filepath = filepath.decode(sys.getfilesystemencoding())
+        try:
+            attrs = ctypes.windll.kernel32.GetFileAttributesW(filepath)
+            assert attrs != -1
+            result = bool(attrs & 2)
+        except (AttributeError, AssertionError):
+            result = False
+        return result
+else:
+    def _has_hidden_attribute(filepath):
+        return False
+
+
+def is_path_hidden(filepath):
+    """
+    Determines if a given file or directory is hidden.
+
+    Parameters
+    ----------
+    filepath : str
+        The path to a file or directory
+
+    Returns
+    -------
+    hidden : bool
+        Returns `True` if the file is hidden
+    """
+
+    name = os.path.basename(os.path.abspath(filepath))
+    if isinstance(name, bytes):
+        is_dotted = name.startswith(b'.')
+    else:
+        is_dotted = name.startswith('.')
+    return is_dotted or _has_hidden_attribute(filepath)
+
+
+def walk_skip_hidden(top, onerror=None, followlinks=False):
+    """
+    A wrapper for `os.walk` that skips hidden files and directories.
+
+    This function does not have the parameter `topdown` from
+    `os.walk`: the directories must always be recursed top-down when
+    using this function.
+
+    See also
+    --------
+    os.walk : For a description of the parameters
+    """
+
+    for root, dirs, files in os.walk(
+            top, topdown=True, onerror=onerror,
+            followlinks=followlinks):
+        # These lists must be updated in-place so os.walk will skip
+        # hidden directories
+        dirs[:] = [d for d in dirs if not is_path_hidden(d)]
+        files[:] = [f for f in files if not is_path_hidden(f)]
+        yield root, dirs, files
+
+
+def write_if_different(filename, data):
+    """Write `data` to `filename`, if the content of the file is different.
+
+    Parameters
+    ----------
+    filename : str
+        The file name to be written to.
+    data : bytes
+        The data to be written to `filename`.
+    """
+
+    assert isinstance(data, bytes)
+
+    if os.path.exists(filename):
+        with open(filename, 'rb') as fd:
+            original_data = fd.read()
+    else:
+        original_data = None
+
+    if original_data != data:
+        with open(filename, 'wb') as fd:
+            fd.write(data)
+
+
+def import_file(filename, name=None):
+    """
+    Imports a module from a single file as if it doesn't belong to a
+    particular package.
+
+    The returned module will have the optional ``name`` if given, or else
+    a name generated from the filename.
+    """
+    # Specifying a traditional dot-separated fully qualified name here
+    # results in a number of "Parent module 'astropy' not found while
+    # handling absolute import" warnings.  Using the same name, the
+    # namespaces of the modules get merged together.  So, this
+    # generates an underscore-separated name which is more likely to
+    # be unique, and it doesn't really matter because the name isn't
+    # used directly here anyway.
+    mode = 'U' if sys.version_info[0] < 3 else 'r'
+
+    if name is None:
+        basename = os.path.splitext(filename)[0]
+        name = '_'.join(os.path.relpath(basename).split(os.sep)[1:])
+
+    if import_machinery:
+        loader = import_machinery.SourceFileLoader(name, filename)
+        mod = loader.load_module()
+    else:
+        with open(filename, mode) as fd:
+            mod = imp.load_module(name, fd, filename, ('.py', mode, 1))
+
+    return mod
+
+
+def resolve_name(name):
+    """Resolve a name like ``module.object`` to an object and return it.
+
+    Raise `ImportError` if the module or name is not found.
+    """
+
+    parts = name.split('.')
+    cursor = len(parts) - 1
+    module_name = parts[:cursor]
+    attr_name = parts[-1]
+
+    while cursor > 0:
+        try:
+            ret = __import__('.'.join(module_name), fromlist=[attr_name])
+            break
+        except ImportError:
+            if cursor == 0:
+                raise
+            cursor -= 1
+            module_name = parts[:cursor]
+            attr_name = parts[cursor]
+            ret = ''
+
+    for part in parts[cursor:]:
+        try:
+            ret = getattr(ret, part)
+        except AttributeError:
+            raise ImportError(name)
+
+    return ret
+
+
+if sys.version_info[0] >= 3:
+    def iteritems(dictionary):
+        return dictionary.items()
+else:
+    def iteritems(dictionary):
+        return dictionary.iteritems()
+
+
+def extends_doc(extended_func):
+    """
+    A function decorator for use when wrapping an existing function but adding
+    additional functionality.  This copies the docstring from the original
+    function, and appends to it (along with a newline) the docstring of the
+    wrapper function.
+
+    Example
+    -------
+
+        >>> def foo():
+        ...     '''Hello.'''
+        ...
+        >>> @extends_doc(foo)
+        ... def bar():
+        ...     '''Goodbye.'''
+        ...
+        >>> print(bar.__doc__)
+        Hello.
+
+        Goodbye.
+
+    """
+
+    def decorator(func):
+        func.__doc__ = '\n\n'.join([extended_func.__doc__.rstrip('\n'),
+                                    func.__doc__.lstrip('\n')])
+        return func
+
+    return decorator
+
+
+# Duplicated from astropy.utils.decorators.deprecated
+# When fixing issues in this function fix them in astropy first, then
+# port the fixes over to astropy-helpers
+def deprecated(since, message='', name='', alternative='', pending=False,
+               obj_type=None):
+    """
+    Used to mark a function or class as deprecated.
+
+    To mark an attribute as deprecated, use `deprecated_attribute`.
+
+    Parameters
+    ------------
+    since : str
+        The release at which this API became deprecated.  This is
+        required.
+
+    message : str, optional
+        Override the default deprecation message.  The format
+        specifier ``func`` may be used for the name of the function,
+        and ``alternative`` may be used in the deprecation message
+        to insert the name of an alternative to the deprecated
+        function. ``obj_type`` may be used to insert a friendly name
+        for the type of object being deprecated.
+
+    name : str, optional
+        The name of the deprecated function or class; if not provided
+        the name is automatically determined from the passed in
+        function or class, though this is useful in the case of
+        renamed functions, where the new function is just assigned to
+        the name of the deprecated function.  For example::
+
+            def new_function():
+                ...
+            oldFunction = new_function
+
+    alternative : str, optional
+        An alternative function or class name that the user may use in
+        place of the deprecated object.  The deprecation warning will
+        tell the user about this alternative if provided.
+
+    pending : bool, optional
+        If True, uses a AstropyPendingDeprecationWarning instead of a
+        AstropyDeprecationWarning.
+
+    obj_type : str, optional
+        The type of this object, if the automatically determined one
+        needs to be overridden.
+    """
+
+    method_types = (classmethod, staticmethod, types.MethodType)
+
+    def deprecate_doc(old_doc, message):
+        """
+        Returns a given docstring with a deprecation message prepended
+        to it.
+        """
+        if not old_doc:
+            old_doc = ''
+        old_doc = textwrap.dedent(old_doc).strip('\n')
+        new_doc = (('\n.. deprecated:: %(since)s'
+                    '\n    %(message)s\n\n' %
+                    {'since': since, 'message': message.strip()}) + old_doc)
+        if not old_doc:
+            # This is to prevent a spurious 'unexected unindent' warning from
+            # docutils when the original docstring was blank.
+            new_doc += r'\ '
+        return new_doc
+
+    def get_function(func):
+        """
+        Given a function or classmethod (or other function wrapper type), get
+        the function object.
+        """
+        if isinstance(func, method_types):
+            try:
+                func = func.__func__
+            except AttributeError:
+                # classmethods in Python2.6 and below lack the __func__
+                # attribute so we need to hack around to get it
+                method = func.__get__(None, object)
+                if isinstance(method, types.FunctionType):
+                    # For staticmethods anyways the wrapped object is just a
+                    # plain function (not a bound method or anything like that)
+                    func = method
+                elif hasattr(method, '__func__'):
+                    func = method.__func__
+                elif hasattr(method, 'im_func'):
+                    func = method.im_func
+                else:
+                    # Nothing we can do really...  just return the original
+                    # classmethod, etc.
+                    return func
+        return func
+
+    def deprecate_function(func, message):
+        """
+        Returns a wrapped function that displays an
+        ``AstropyDeprecationWarning`` when it is called.
+        """
+
+        if isinstance(func, method_types):
+            func_wrapper = type(func)
+        else:
+            func_wrapper = lambda f: f
+
+        func = get_function(func)
+
+        def deprecated_func(*args, **kwargs):
+            if pending:
+                category = AstropyPendingDeprecationWarning
+            else:
+                category = AstropyDeprecationWarning
+
+            warnings.warn(message, category, stacklevel=2)
+
+            return func(*args, **kwargs)
+
+        # If this is an extension function, we can't call
+        # functools.wraps on it, but we normally don't care.
+        # This crazy way to get the type of a wrapper descriptor is
+        # straight out of the Python 3.3 inspect module docs.
+        if type(func) != type(str.__dict__['__add__']):
+            deprecated_func = functools.wraps(func)(deprecated_func)
+
+        deprecated_func.__doc__ = deprecate_doc(
+            deprecated_func.__doc__, message)
+
+        return func_wrapper(deprecated_func)
+
+    def deprecate_class(cls, message):
+        """
+        Returns a wrapper class with the docstrings updated and an
+        __init__ function that will raise an
+        ``AstropyDeprectationWarning`` warning when called.
+        """
+        # Creates a new class with the same name and bases as the
+        # original class, but updates the dictionary with a new
+        # docstring and a wrapped __init__ method.  __module__ needs
+        # to be manually copied over, since otherwise it will be set
+        # to *this* module (astropy.utils.misc).
+
+        # This approach seems to make Sphinx happy (the new class
+        # looks enough like the original class), and works with
+        # extension classes (which functools.wraps does not, since
+        # it tries to modify the original class).
+
+        # We need to add a custom pickler or you'll get
+        #     Can't pickle <class ..>: it's not found as ...
+        # errors. Picklability is required for any class that is
+        # documented by Sphinx.
+
+        members = cls.__dict__.copy()
+
+        members.update({
+            '__doc__': deprecate_doc(cls.__doc__, message),
+            '__init__': deprecate_function(get_function(cls.__init__),
+                                           message),
+        })
+
+        return type(cls.__name__, cls.__bases__, members)
+
+    def deprecate(obj, message=message, name=name, alternative=alternative,
+                  pending=pending):
+        if obj_type is None:
+            if isinstance(obj, type):
+                obj_type_name = 'class'
+            elif inspect.isfunction(obj):
+                obj_type_name = 'function'
+            elif inspect.ismethod(obj) or isinstance(obj, method_types):
+                obj_type_name = 'method'
+            else:
+                obj_type_name = 'object'
+        else:
+            obj_type_name = obj_type
+
+        if not name:
+            name = get_function(obj).__name__
+
+        altmessage = ''
+        if not message or type(message) == type(deprecate):
+            if pending:
+                message = ('The %(func)s %(obj_type)s will be deprecated in a '
+                           'future version.')
+            else:
+                message = ('The %(func)s %(obj_type)s is deprecated and may '
+                           'be removed in a future version.')
+            if alternative:
+                altmessage = '\n        Use %s instead.' % alternative
+
+        message = ((message % {
+            'func': name,
+            'name': name,
+            'alternative': alternative,
+            'obj_type': obj_type_name}) +
+            altmessage)
+
+        if isinstance(obj, type):
+            return deprecate_class(obj, message)
+        else:
+            return deprecate_function(obj, message)
+
+    if type(message) == type(deprecate):
+        return deprecate(message)
+
+    return deprecate
+
+
+def deprecated_attribute(name, since, message=None, alternative=None,
+                         pending=False):
+    """
+    Used to mark a public attribute as deprecated.  This creates a
+    property that will warn when the given attribute name is accessed.
+    To prevent the warning (i.e. for internal code), use the private
+    name for the attribute by prepending an underscore
+    (i.e. ``self._name``).
+
+    Parameters
+    ----------
+    name : str
+        The name of the deprecated attribute.
+
+    since : str
+        The release at which this API became deprecated.  This is
+        required.
+
+    message : str, optional
+        Override the default deprecation message.  The format
+        specifier ``name`` may be used for the name of the attribute,
+        and ``alternative`` may be used in the deprecation message
+        to insert the name of an alternative to the deprecated
+        function.
+
+    alternative : str, optional
+        An alternative attribute that the user may use in place of the
+        deprecated attribute.  The deprecation warning will tell the
+        user about this alternative if provided.
+
+    pending : bool, optional
+        If True, uses a AstropyPendingDeprecationWarning instead of a
+        AstropyDeprecationWarning.
+
+    Examples
+    --------
+
+    ::
+
+        class MyClass:
+            # Mark the old_name as deprecated
+            old_name = misc.deprecated_attribute('old_name', '0.1')
+
+            def method(self):
+                self._old_name = 42
+    """
+    private_name = '_' + name
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def get(self):
+        return getattr(self, private_name)
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def set(self, val):
+        setattr(self, private_name, val)
+
+    @deprecated(since, name=name, obj_type='attribute')
+    def delete(self):
+        delattr(self, private_name)
+
+    return property(get, set, delete)
diff --git a/astropy_helpers/astropy_helpers/version.py b/astropy_helpers/astropy_helpers/version.py
new file mode 100644
index 0000000..d3513e3
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/version.py
@@ -0,0 +1,171 @@
+# Autogenerated by Astropy-affiliated package astropy_helpers's setup.py on 2015-01-27 18:05:50.140967
+
+
+import locale
+import os
+import subprocess
+import warnings
+
+
+def _decode_stdio(stream):
+    try:
+        stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8'
+    except ValueError:
+        stdio_encoding = 'utf-8'
+
+    try:
+        text = stream.decode(stdio_encoding)
+    except UnicodeDecodeError:
+        # Final fallback
+        text = stream.decode('latin1')
+
+    return text
+
+
+def update_git_devstr(version, path=None):
+    """
+    Updates the git revision string if and only if the path is being imported
+    directly from a git working copy.  This ensures that the revision number in
+    the version string is accurate.
+    """
+
+    try:
+        # Quick way to determine if we're in git or not - returns '' if not
+        devstr = get_git_devstr(sha=True, show_warning=False, path=path)
+    except OSError:
+        return version
+
+    if not devstr:
+        # Probably not in git so just pass silently
+        return version
+
+    if 'dev' in version:  # update to the current git revision
+        version_base = version.split('.dev', 1)[0]
+        devstr = get_git_devstr(sha=False, show_warning=False, path=path)
+
+        return version_base + '.dev' + devstr
+    else:
+        #otherwise it's already the true/release version
+        return version
+
+
+def get_git_devstr(sha=False, show_warning=True, path=None):
+    """
+    Determines the number of revisions in this repository.
+
+    Parameters
+    ----------
+    sha : bool
+        If True, the full SHA1 hash will be returned. Otherwise, the total
+        count of commits in the repository will be used as a "revision
+        number".
+
+    show_warning : bool
+        If True, issue a warning if git returns an error code, otherwise errors
+        pass silently.
+
+    path : str or None
+        If a string, specifies the directory to look in to find the git
+        repository.  If `None`, the current working directory is used.
+        If given a filename it uses the directory containing that file.
+
+    Returns
+    -------
+    devversion : str
+        Either a string with the revision number (if `sha` is False), the
+        SHA1 hash of the current commit (if `sha` is True), or an empty string
+        if git version info could not be identified.
+
+    """
+
+    if path is None:
+        path = os.getcwd()
+
+    if not os.path.isdir(path):
+        path = os.path.abspath(os.path.dirname(path))
+
+    if not os.path.exists(os.path.join(path, '.git')):
+        return ''
+
+    if sha:
+        # Faster for getting just the hash of HEAD
+        cmd = ['rev-parse', 'HEAD']
+    else:
+        cmd = ['rev-list', '--count', 'HEAD']
+
+    def run_git(cmd):
+        try:
+            p = subprocess.Popen(['git'] + cmd, cwd=path,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 stdin=subprocess.PIPE)
+            stdout, stderr = p.communicate()
+        except OSError as e:
+            if show_warning:
+                warnings.warn('Error running git: ' + str(e))
+            return (None, '', '')
+
+        if p.returncode == 128:
+            if show_warning:
+                warnings.warn('No git repository present at {0!r}! Using '
+                              'default dev version.'.format(path))
+            return (p.returncode, '', '')
+        if p.returncode == 129:
+            if show_warning:
+                warnings.warn('Your git looks old (does it support {0}?); ' 
+                              'consider upgrading to v1.7.2 or '
+                              'later.'.format(cmd[0]))
+            return (p.returncode, stdout, stderr)
+        elif p.returncode != 0:
+            if show_warning:
+                warnings.warn('Git failed while determining revision '
+                              'count: {0}'.format(_decode_stdio(stderr)))
+            return (p.returncode, stdout, stderr)
+
+        return p.returncode, stdout, stderr
+
+    returncode, stdout, stderr = run_git(cmd)
+
+    if not sha and returncode == 129:
+        # git returns 129 if a command option failed to parse; in
+        # particular this could happen in git versions older than 1.7.2
+        # where the --count option is not supported
+        # Also use --abbrev-commit and --abbrev=0 to display the minimum
+        # number of characters needed per-commit (rather than the full hash)
+        cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD']
+        returncode, stdout, stderr = run_git(cmd)
+        # Fall back on the old method of getting all revisions and counting
+        # the lines
+        if returncode == 0:
+            return str(stdout.count(b'\n'))
+        else:
+            return ''
+    elif sha:
+        return _decode_stdio(stdout)[:40]
+    else:
+        return _decode_stdio(stdout).strip()
+
+_last_generated_version = '0.5.dev'
+_last_githash = u'e49ffbe41f5528f8cbbe837e1b19651bbb44d8f7'
+
+version = update_git_devstr(_last_generated_version)
+githash = get_git_devstr(sha=True, show_warning=False,
+                         path=__file__) or _last_githash
+
+
+major = 0
+minor = 5
+bugfix = 0
+
+release = False
+debug = False
+
+try:
+    from ._compiler import compiler
+except ImportError:
+    compiler = "unknown"
+
+try:
+    from .cython_version import cython_version
+except ImportError:
+    cython_version = "unknown"
diff --git a/astropy_helpers/astropy_helpers/version_helpers.py b/astropy_helpers/astropy_helpers/version_helpers.py
new file mode 100644
index 0000000..1fae8e0
--- /dev/null
+++ b/astropy_helpers/astropy_helpers/version_helpers.py
@@ -0,0 +1,227 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+"""
+Utilities for generating the version string for Astropy (or an affiliated
+package) and the version.py module, which contains version info for the
+package.
+
+Within the generated astropy.version module, the `major`, `minor`, and `bugfix`
+variables hold the respective parts of the version number (bugfix is '0' if
+absent). The `release` variable is True if this is a release, and False if this
+is a development version of astropy. For the actual version string, use::
+
+    from astropy.version import version
+
+or::
+
+    from astropy import __version__
+
+"""
+
+from __future__ import division
+
+import datetime
+import imp
+import os
+import pkgutil
+import sys
+
+from distutils import log
+
+from . import git_helpers
+from .distutils_helpers import is_distutils_display_option
+from .utils import invalidate_caches
+
+PY3 = sys.version_info[0] == 3
+
+
+
+def _version_split(version):
+    """
+    Split a version string into major, minor, and bugfix numbers (with bugfix
+    optional, defaulting to 0).
+    """
+
+    for prerel in ('.dev', 'a', 'b', 'rc'):
+        if prerel in version:
+            version = version.split(prerel)[0]
+
+    versplit = version.split('.')
+    major = int(versplit[0])
+    minor = int(versplit[1])
+    bugfix = 0 if len(versplit) < 3 else int(versplit[2])
+    return major, minor, bugfix
+
+
+# This is used by setup.py to create a new version.py - see that file for
+# details. Note that the imports have to be absolute, since this is also used
+# by affiliated packages.
+_FROZEN_VERSION_PY_TEMPLATE = """
+# Autogenerated by {packagename}'s setup.py on {timestamp}
+
+{header}
+
+major = {major}
+minor = {minor}
+bugfix = {bugfix}
+
+release = {rel}
+debug = {debug}
+
+try:
+    from ._compiler import compiler
+except ImportError:
+    compiler = "unknown"
+
+try:
+    from .cython_version import cython_version
+except ImportError:
+    cython_version = "unknown"
+"""[1:]
+
+
+_FROZEN_VERSION_PY_WITH_GIT_HEADER = """
+{git_helpers}
+
+_last_generated_version = {verstr!r}
+_last_githash = {githash!r}
+
+version = update_git_devstr(_last_generated_version)
+githash = get_git_devstr(sha=True, show_warning=False,
+                         path=__file__) or _last_githash
+"""[1:]
+
+
+def _get_version_py_str(packagename, version, githash, release, debug,
+                        uses_git=True):
+    timestamp = str(datetime.datetime.now())
+    major, minor, bugfix = _version_split(version)
+
+    if packagename.lower() == 'astropy':
+        packagename = 'Astropy'
+    else:
+        packagename = 'Astropy-affiliated package ' + packagename
+
+    if uses_git:
+        loader = pkgutil.get_loader(git_helpers)
+        source = loader.get_source(git_helpers.__name__) or ''
+        source_lines = source.splitlines()
+        if not source_lines:
+            log.warn('Cannot get source code for astropy_helpers.git_helpers; '
+                     'git support disabled.')
+            return _get_version_py_str(packagename, version, release, debug,
+                                       uses_git=False)
+        idx = 0
+        for idx, line in enumerate(source_lines):
+            if line.startswith('# BEGIN'):
+                break
+        git_helpers_py = '\n'.join(source_lines[idx + 1:])
+
+        if PY3:
+            verstr = version
+        else:
+            # In Python 2 don't pass in a unicode string; otherwise verstr will
+            # be represented with u'' syntax which breaks on Python 3.x with x
+            # < 3.  This is only an issue when developing on multiple Python
+            # versions at once
+            verstr = version.encode('utf8')
+
+        new_githash = git_helpers.get_git_devstr(sha=True, show_warning=False)
+
+        if new_githash:
+            githash = new_githash
+
+        header = _FROZEN_VERSION_PY_WITH_GIT_HEADER.format(
+                git_helpers=git_helpers_py,
+                verstr=verstr, githash=githash)
+    else:
+        header = 'version = {0!r}'.format(version)
+
+    return _FROZEN_VERSION_PY_TEMPLATE.format(packagename=packagename,
+                                              timestamp=timestamp,
+                                              header=header,
+                                              major=major,
+                                              minor=minor,
+                                              bugfix=bugfix,
+                                              rel=release, debug=debug)
+
+
+def generate_version_py(packagename, version, release=None, debug=None,
+                        uses_git=True):
+    """Regenerate the version.py module if necessary."""
+
+    try:
+        version_module = get_pkg_version_module(packagename)
+
+        try:
+            last_generated_version = version_module._last_generated_version
+        except AttributeError:
+            last_generated_version = version_module.version
+
+        try:
+            last_githash = version_module._last_githash
+        except AttributeError:
+            last_githash = ''
+
+        current_release = version_module.release
+        current_debug = version_module.debug
+    except ImportError:
+        version_module = None
+        last_generated_version = None
+        last_githash = None
+        current_release = None
+        current_debug = None
+
+    if release is None:
+        # Keep whatever the current value is, if it exists
+        release = bool(current_release)
+
+    if debug is None:
+        # Likewise, keep whatever the current value is, if it exists
+        debug = bool(current_debug)
+
+    version_py = os.path.join(packagename, 'version.py')
+
+    if (last_generated_version != version or current_release != release or
+        current_debug != debug):
+        if '-q' not in sys.argv and '--quiet' not in sys.argv:
+            log.set_threshold(log.INFO)
+
+        if is_distutils_display_option():
+            # Always silence unnecessary log messages when display options are
+            # being used
+            log.set_threshold(log.WARN)
+
+        log.info('Freezing version number to {0}'.format(version_py))
+
+        with open(version_py, 'w') as f:
+            # This overwrites the actual version.py
+            f.write(_get_version_py_str(packagename, version, last_githash,
+                                        release, debug, uses_git=uses_git))
+
+        invalidate_caches()
+
+        if version_module:
+            imp.reload(version_module)
+
+
+def get_pkg_version_module(packagename, fromlist=None):
+    """Returns the package's .version module generated by
+    `astropy_helpers.version_helpers.generate_version_py`.  Raises an
+    ImportError if the version module is not found.
+
+    If ``fromlist`` is an iterable, return a tuple of the members of the
+    version module corresponding to the member names given in ``fromlist``.
+    Raises an `AttributeError` if any of these module members are not found.
+    """
+
+    if not fromlist:
+        # Due to a historical quirk of Python's import implementation,
+        # __import__ will not return submodules of a package if 'fromlist' is
+        # empty.
+        # TODO: For Python 3.1 and up it may be preferable to use importlib
+        # instead of the __import__ builtin
+        return __import__(packagename + '.version', fromlist=[''])
+    else:
+        mod = __import__(packagename + '.version', fromlist=fromlist)
+        return tuple(getattr(mod, member) for member in fromlist)
diff --git a/astropy_helpers/continuous-integration/appveyor/install-miniconda.ps1 b/astropy_helpers/continuous-integration/appveyor/install-miniconda.ps1
new file mode 100644
index 0000000..aeccc3b
--- /dev/null
+++ b/astropy_helpers/continuous-integration/appveyor/install-miniconda.ps1
@@ -0,0 +1,71 @@
+# Sample script to install anaconda under windows
+# Authors: Stuart Mumford
+# Borrwed from: Olivier Grisel and Kyle Kastner
+# License: BSD 3 clause
+
+$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
+
+function DownloadMiniconda ($version, $platform_suffix) {
+    $webclient = New-Object System.Net.WebClient
+    $filename = "Miniconda-" + $version + "-Windows-" + $platform_suffix + ".exe"
+
+    $url = $MINICONDA_URL + $filename
+
+    $basedir = $pwd.Path + "\"
+    $filepath = $basedir + $filename
+    if (Test-Path $filename) {
+        Write-Host "Reusing" $filepath
+        return $filepath
+    }
+
+    # Download and retry up to 3 times in case of network transient errors.
+    Write-Host "Downloading" $filename "from" $url
+    $retry_attempts = 2
+    for($i=0; $i -lt $retry_attempts; $i++){
+        try {
+            $webclient.DownloadFile($url, $filepath)
+            break
+        }
+        Catch [Exception]{
+            Start-Sleep 1
+        }
+   }
+   if (Test-Path $filepath) {
+       Write-Host "File saved at" $filepath
+   } else {
+       # Retry once to get the error message if any at the last try
+       $webclient.DownloadFile($url, $filepath)
+   }
+   return $filepath
+}
+
+function InstallMiniconda ($python_version, $architecture, $python_home) {
+    Write-Host "Installing miniconda" $python_version "for" $architecture "bit architecture to" $python_home
+    if (Test-Path $python_home) {
+        Write-Host $python_home "already exists, skipping."
+        return $false
+    }
+    if ($architecture -eq "x86") {
+        $platform_suffix = "x86"
+    } else {
+        $platform_suffix = "x86_64"
+    }
+    $filepath = DownloadMiniconda $python_version $platform_suffix
+    Write-Host "Installing" $filepath "to" $python_home
+    $args = "/InstallationType=AllUsers /S /AddToPath=1 /RegisterPython=1 /D=" + $python_home
+    Write-Host $filepath $args
+    Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
+    #Start-Sleep -s 15
+    if (Test-Path C:\conda) {
+        Write-Host "Miniconda $python_version ($architecture) installation complete"
+    } else {
+        Write-Host "Failed to install Python in $python_home"
+        Exit 1
+    }
+}
+
+function main () {
+    InstallMiniconda $env:MINICONDA_VERSION $env:PLATFORM $env:PYTHON
+}
+
+main
diff --git a/astropy_helpers/continuous-integration/appveyor/windows_sdk.cmd b/astropy_helpers/continuous-integration/appveyor/windows_sdk.cmd
new file mode 100644
index 0000000..3a472bc
--- /dev/null
+++ b/astropy_helpers/continuous-integration/appveyor/windows_sdk.cmd
@@ -0,0 +1,47 @@
+:: To build extensions for 64 bit Python 3, we need to configure environment
+:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
+::
+:: To build extensions for 64 bit Python 2, we need to configure environment
+:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
+::
+:: 32 bit builds do not require specific environment configurations.
+::
+:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
+:: cmd interpreter, at least for (SDK v7.0)
+::
+:: More details at:
+:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
+:: http://stackoverflow.com/a/13751649/163740
+::
+:: Author: Olivier Grisel
+:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
+ at ECHO OFF
+
+SET COMMAND_TO_RUN=%*
+SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
+
+SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%"
+IF %MAJOR_PYTHON_VERSION% == "2" (
+    SET WINDOWS_SDK_VERSION="v7.0"
+) ELSE IF %MAJOR_PYTHON_VERSION% == "3" (
+    SET WINDOWS_SDK_VERSION="v7.1"
+) ELSE (
+    ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
+    EXIT 1
+)
+
+IF "%PYTHON_ARCH%"=="64" (
+    ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
+    SET DISTUTILS_USE_SDK=1
+    SET MSSdk=1
+    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
+    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
+    ECHO Executing: %COMMAND_TO_RUN%
+    call %COMMAND_TO_RUN% || EXIT 1
+) ELSE (
+    ECHO Using default MSVC build environment for 32 bit architecture
+    ECHO Executing: %COMMAND_TO_RUN%
+    call %COMMAND_TO_RUN% || EXIT 1
+)
diff --git a/astropy_helpers/continuous-integration/travis/install_conda_linux.sh b/astropy_helpers/continuous-integration/travis/install_conda_linux.sh
new file mode 100755
index 0000000..902e00b
--- /dev/null
+++ b/astropy_helpers/continuous-integration/travis/install_conda_linux.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh
+chmod +x miniconda.sh
+./miniconda.sh -b
+export PATH=/home/travis/miniconda/bin:$PATH
+conda update --yes conda
diff --git a/astropy_helpers/continuous-integration/travis/install_conda_osx.sh b/astropy_helpers/continuous-integration/travis/install_conda_osx.sh
new file mode 100755
index 0000000..0d0ecc2
--- /dev/null
+++ b/astropy_helpers/continuous-integration/travis/install_conda_osx.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+wget http://repo.continuum.io/miniconda/Miniconda-3.7.3-MacOSX-x86_64.sh -O miniconda.sh
+chmod +x miniconda.sh
+./miniconda.sh -b
+export PATH=/Users/travis/miniconda/bin:$PATH
+conda update --yes conda
diff --git a/astropy_helpers/continuous-integration/travis/install_graphviz_linux.sh b/astropy_helpers/continuous-integration/travis/install_graphviz_linux.sh
new file mode 100755
index 0000000..b818bb9
--- /dev/null
+++ b/astropy_helpers/continuous-integration/travis/install_graphviz_linux.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+sudo apt-get update
+sudo apt-get install graphviz
diff --git a/astropy_helpers/continuous-integration/travis/install_graphviz_osx.sh b/astropy_helpers/continuous-integration/travis/install_graphviz_osx.sh
new file mode 100755
index 0000000..6144d14
--- /dev/null
+++ b/astropy_helpers/continuous-integration/travis/install_graphviz_osx.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+sudo brew update
+sudo brew install graphviz
\ No newline at end of file
diff --git a/astropy_helpers/ez_setup.py b/astropy_helpers/ez_setup.py
new file mode 100644
index 0000000..9dc2c87
--- /dev/null
+++ b/astropy_helpers/ez_setup.py
@@ -0,0 +1,382 @@
+#!python
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import shutil
+import sys
+import tempfile
+import tarfile
+import optparse
+import subprocess
+import platform
+
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+DEFAULT_VERSION = "1.4.2"
+DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
+
+def _python_cmd(*args):
+    args = (sys.executable,) + args
+    return subprocess.call(args) == 0
+
+def _check_call_py24(cmd, *args, **kwargs):
+    res = subprocess.call(cmd, *args, **kwargs)
+    class CalledProcessError(Exception):
+        pass
+    if not res == 0:
+        msg = "Command '%s' return non-zero exit status %d" % (cmd, res)
+        raise CalledProcessError(msg)
+vars(subprocess).setdefault('check_call', _check_call_py24)
+
+def _install(tarball, install_args=()):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Setuptools')
+        if not _python_cmd('setup.py', 'install', *install_args):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+            # exitcode will be 2
+            return 2
+    finally:
+        os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Setuptools egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+
+    # Remove previously-imported pkg_resources if present (see
+    # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
+    if 'pkg_resources' in sys.modules:
+        del sys.modules['pkg_resources']
+
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        import pkg_resources
+    except ImportError:
+        return _do_download(version, download_base, to_dir, download_delay)
+    try:
+        pkg_resources.require("setuptools>=" + version)
+        return
+    except pkg_resources.VersionConflict:
+        e = sys.exc_info()[1]
+        if was_imported:
+            sys.stderr.write(
+            "The required version of setuptools (>=%s) is not available,\n"
+            "and can't be installed while this script is running. Please\n"
+            "install a more recent version first, using\n"
+            "'easy_install -U setuptools'."
+            "\n\n(Currently using %r)\n" % (version, e.args[0]))
+            sys.exit(2)
+        else:
+            del pkg_resources, sys.modules['pkg_resources']    # reload ok
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    except pkg_resources.DistributionNotFound:
+        return _do_download(version, download_base, to_dir,
+                            download_delay)
+
+def _clean_check(cmd, target):
+    """
+    Run the command to download target. If the command fails, clean up before
+    re-raising the error.
+    """
+    try:
+        subprocess.check_call(cmd)
+    except subprocess.CalledProcessError:
+        if os.access(target, os.F_OK):
+            os.unlink(target)
+        raise
+
+def download_file_powershell(url, target):
+    """
+    Download the file at url to target using Powershell (which will validate
+    trust). Raise an exception if the command cannot complete.
+    """
+    target = os.path.abspath(target)
+    cmd = [
+        'powershell',
+        '-Command',
+        "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(),
+    ]
+    _clean_check(cmd, target)
+
+def has_powershell():
+    if platform.system() != 'Windows':
+        return False
+    cmd = ['powershell', '-Command', 'echo test']
+    devnull = open(os.path.devnull, 'wb')
+    try:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except:
+            return False
+    finally:
+        devnull.close()
+    return True
+
+download_file_powershell.viable = has_powershell
+
+def download_file_curl(url, target):
+    cmd = ['curl', url, '--silent', '--output', target]
+    _clean_check(cmd, target)
+
+def has_curl():
+    cmd = ['curl', '--version']
+    devnull = open(os.path.devnull, 'wb')
+    try:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except:
+            return False
+    finally:
+        devnull.close()
+    return True
+
+download_file_curl.viable = has_curl
+
+def download_file_wget(url, target):
+    cmd = ['wget', url, '--quiet', '--output-document', target]
+    _clean_check(cmd, target)
+
+def has_wget():
+    cmd = ['wget', '--version']
+    devnull = open(os.path.devnull, 'wb')
+    try:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except:
+            return False
+    finally:
+        devnull.close()
+    return True
+
+download_file_wget.viable = has_wget
+
+def download_file_insecure(url, target):
+    """
+    Use Python to download the file, even though it cannot authenticate the
+    connection.
+    """
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib2 import urlopen
+    src = dst = None
+    try:
+        src = urlopen(url)
+        # Read/write all in one block, so we don't create a corrupt file
+        # if the download is interrupted.
+        data = src.read()
+        dst = open(target, "wb")
+        dst.write(data)
+    finally:
+        if src:
+            src.close()
+        if dst:
+            dst.close()
+
+download_file_insecure.viable = lambda: True
+
+def get_best_downloader():
+    downloaders = [
+        download_file_powershell,
+        download_file_curl,
+        download_file_wget,
+        download_file_insecure,
+    ]
+
+    for dl in downloaders:
+        if dl.viable():
+            return dl
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15,
+                        downloader_factory=get_best_downloader):
+    """Download setuptools from a specified location and return its filename
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+
+    ``downloader_factory`` should be a function taking no arguments and
+    returning a function for downloading a URL to a target.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    tgz_name = "setuptools-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        log.warn("Downloading %s", url)
+        downloader = downloader_factory()
+        downloader(url, saveto)
+    return os.path.realpath(saveto)
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448  # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def _build_install_args(options):
+    """
+    Build the arguments to 'python setup.py install' on the setuptools package
+    """
+    install_args = []
+    if options.user_install:
+        if sys.version_info < (2, 6):
+            log.warn("--user requires Python 2.6 or later")
+            raise SystemExit(1)
+        install_args.append('--user')
+    return install_args
+
+def _parse_args():
+    """
+    Parse the command line for options
+    """
+    parser = optparse.OptionParser()
+    parser.add_option(
+        '--user', dest='user_install', action='store_true', default=False,
+        help='install in user site package (requires Python 2.6 or later)')
+    parser.add_option(
+        '--download-base', dest='download_base', metavar="URL",
+        default=DEFAULT_URL,
+        help='alternative URL from where to download the setuptools package')
+    parser.add_option(
+        '--insecure', dest='downloader_factory', action='store_const',
+        const=lambda: download_file_insecure, default=get_best_downloader,
+        help='Use internal, non-validating downloader'
+    )
+    options, args = parser.parse_args()
+    # positional arguments are ignored
+    return options
+
+def main(version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    options = _parse_args()
+    tarball = download_setuptools(download_base=options.download_base,
+        downloader_factory=options.downloader_factory)
+    return _install(tarball, _build_install_args(options))
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/astropy_helpers/licenses/LICENSE_COPYBUTTON.rst b/astropy_helpers/licenses/LICENSE_COPYBUTTON.rst
new file mode 100644
index 0000000..7b52bf4
--- /dev/null
+++ b/astropy_helpers/licenses/LICENSE_COPYBUTTON.rst
@@ -0,0 +1,50 @@
+Copyright 2014 Python Software Foundation
+License: PSF
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+ --------------------------------------------
+ .
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation
+ ("PSF"), and the Individual or Organization ("Licensee") accessing and
+ otherwise using this software ("Python") in source or binary form and
+ its associated documentation.
+ .
+ 2. Subject to the terms and conditions of this License Agreement, PSF
+ hereby grants Licensee a nonexclusive, royalty-free, world-wide
+ license to reproduce, analyze, test, perform and/or display publicly,
+ prepare derivative works, distribute, and otherwise use Python
+ alone or in any derivative version, provided, however, that PSF's
+ License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+ 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
+ Reserved" are retained in Python alone or in any derivative version
+ prepared by Licensee.
+ .
+ 3. In the event Licensee prepares a derivative work that is based on
+ or incorporates Python or any part thereof, and wants to make
+ the derivative work available to others as provided herein, then
+ Licensee hereby agrees to include in any such work a brief summary of
+ the changes made to Python.
+ .
+ 4. PSF is making Python available to Licensee on an "AS IS"
+ basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+ INFRINGE ANY THIRD PARTY RIGHTS.
+ .
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+ .
+ 6. This License Agreement will automatically terminate upon a material
+ breach of its terms and conditions.
+ .
+ 7. Nothing in this License Agreement shall be deemed to create any
+ relationship of agency, partnership, or joint venture between PSF and
+ Licensee.  This License Agreement does not grant permission to use PSF
+ trademarks or trade name in a trademark sense to endorse or promote
+ products or services of Licensee, or any third party.
+ .
+ 8. By copying, installing or otherwise using Python, Licensee
+ agrees to be bound by the terms and conditions of this License
+ Agreement.
diff --git a/astropy_helpers/licenses/LICENSE_NUMPYDOC.rst b/astropy_helpers/licenses/LICENSE_NUMPYDOC.rst
new file mode 100644
index 0000000..b15c699
--- /dev/null
+++ b/astropy_helpers/licenses/LICENSE_NUMPYDOC.rst
@@ -0,0 +1,94 @@
+-------------------------------------------------------------------------------
+    The files
+    - numpydoc.py
+    - docscrape.py
+    - docscrape_sphinx.py
+    - phantom_import.py
+    have the following license:
+
+Copyright (C) 2008 Stefan van der Walt <stefan at mentat.za.net>, Pauli Virtanen <pav at iki.fi>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+    The files
+    - compiler_unparse.py
+    - comment_eater.py
+    - traitsdoc.py
+    have the following license:
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+
+Copyright (c) 2006, Enthought, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ * Neither the name of Enthought, Inc. nor the names of its contributors may
+   be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+-------------------------------------------------------------------------------
+    The file
+    - plot_directive.py
+    originates from Matplotlib (http://matplotlib.sf.net/) which has
+    the following license:
+
+Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved.
+
+1. This LICENSE AGREEMENT is between John D. Hunter (“JDH”), and the Individual or Organization (“Licensee”) accessing and otherwise using matplotlib software in source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, JDH hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use matplotlib 0.98.3 alone or in any derivative version, provided, however, that JDH’s License Agreement and JDH’s notice of copyright, i.e., “Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved” are retained in matplotlib 0.98 [...]
+
+3. In the event Licensee prepares a derivative work that is based on or incorporates matplotlib 0.98.3 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to matplotlib 0.98.3.
+
+4. JDH is making matplotlib 0.98.3 available to Licensee on an “AS IS” basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB 0.98.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB 0.98.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING MATPLOTLIB 0.98.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between JDH and Licensee. This License Agreement does not grant permission to use JDH trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using matplotlib 0.98.3, Licensee agrees to be bound by the terms and conditions of this License Agreement.
+
diff --git a/astropy_helpers/setup.cfg b/astropy_helpers/setup.cfg
new file mode 100644
index 0000000..780a828
--- /dev/null
+++ b/astropy_helpers/setup.cfg
@@ -0,0 +1,5 @@
+[pytest]
+norecursedirs =
+    .tox
+    astropy_helpers/tests/package_template
+python_functions = test_
diff --git a/astropy_helpers/setup.py b/astropy_helpers/setup.py
new file mode 100755
index 0000000..1f5b5e0
--- /dev/null
+++ b/astropy_helpers/setup.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+import ah_bootstrap
+import pkg_resources
+from setuptools import setup
+from astropy_helpers.setup_helpers import register_commands, get_package_info
+from astropy_helpers.version_helpers import generate_version_py
+
+NAME = 'astropy_helpers'
+VERSION = '0.5.dev'
+RELEASE = 'dev' not in VERSION
+DOWNLOAD_BASE_URL = 'http://pypi.python.org/packages/source/a/astropy-helpers'
+
+generate_version_py(NAME, VERSION, RELEASE, False)
+
+# Use the updated version including the git rev count
+from astropy_helpers.version import version as VERSION
+
+cmdclass = register_commands(NAME, VERSION, RELEASE)
+# This package actually doesn't use the Astropy test command
+del cmdclass['test']
+
+setup(
+    name=pkg_resources.safe_name(NAME),  # astropy_helpers -> astropy-helpers
+    version=VERSION,
+    description='Utilities for building and installing Astropy, Astropy '
+                'affiliated packages, and their respective documentation.',
+    author='The Astropy Developers',
+    author_email='astropy.team at gmail.com',
+    license='BSD',
+    url='http://astropy.org',
+    long_description=open('README.rst').read(),
+    download_url='{0}/astropy-helpers-{1}.tar.gz'.format(DOWNLOAD_BASE_URL,
+                                                         VERSION),
+    classifiers=[
+        'Development Status :: 4 - Beta',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: BSD License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 3',
+        'Topic :: Software Development :: Build Tools',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Topic :: System :: Archiving :: Packaging'
+    ],
+    cmdclass=cmdclass,
+    zip_safe=False,
+    **get_package_info(exclude=['astropy_helpers.tests'])
+)
diff --git a/astropy_helpers/tox.ini b/astropy_helpers/tox.ini
new file mode 100644
index 0000000..382131d
--- /dev/null
+++ b/astropy_helpers/tox.ini
@@ -0,0 +1,14 @@
+[tox]
+envlist = py26,py27,py32,py33,py34
+
+[testenv]
+deps =
+    pytest
+    numpy
+    Cython
+    Sphinx
+# Note: Sphinx is required to run the sphinx.ext tests
+commands = 
+    python setup.py clean --all
+    py.test {posargs}
+sitepackages = False
diff --git a/cextern/erfa/a2af.c b/cextern/erfa/a2af.c
new file mode 100644
index 0000000..3c4b1c7
--- /dev/null
+++ b/cextern/erfa/a2af.c
@@ -0,0 +1,129 @@
+#include "erfa.h"
+
+void eraA2af(int ndp, double angle, char *sign, int idmsf[4])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Hours to degrees * radians to turns */
+   const double F = 15.0 / ERFA_D2PI;
+
+
+/* Scale then use days to h,m,s function. */
+   eraD2tf(ndp, angle*F, sign, idmsf);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/a2tf.c b/cextern/erfa/a2tf.c
new file mode 100644
index 0000000..e91370c
--- /dev/null
+++ b/cextern/erfa/a2tf.c
@@ -0,0 +1,125 @@
+#include "erfa.h"
+
+void eraA2tf(int ndp, double angle, char *sign, int ihmsf[4])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Scale then use days to h,m,s function. */
+   eraD2tf(ndp, angle/ERFA_D2PI, sign, ihmsf);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ab.c b/cextern/erfa/ab.c
new file mode 100644
index 0000000..f662103
--- /dev/null
+++ b/cextern/erfa/ab.c
@@ -0,0 +1,137 @@
+#include "erfa.h"
+
+void eraAb(double pnat[3], double v[3], double s, double bm1,
+           double ppr[3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i;
+   double pdv, w1, w2, r2, w, p[3], r;
+
+
+   pdv = eraPdp(pnat, v);
+   w1 = 1.0 + pdv/(1.0 + bm1);
+   w2 = ERFA_SRS/s;
+   r2 = 0.0;
+   for (i = 0; i < 3; i++) {
+      w = pnat[i]*bm1 + w1*v[i] + w2*(v[i] - pdv*pnat[i]);
+      p[i] = w;
+      r2 = r2 + w*w;
+   }
+   r = sqrt(r2);
+   for (i = 0; i < 3; i++) {
+      ppr[i] = p[i]/r;
+   }
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/af2a.c b/cextern/erfa/af2a.c
new file mode 100644
index 0000000..c75e40f
--- /dev/null
+++ b/cextern/erfa/af2a.c
@@ -0,0 +1,116 @@
+#include "erfa.h"
+#include <stdlib.h>
+
+int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Compute the interval. */
+   *rad  = ( s == '-' ? -1.0 : 1.0 ) *
+           ( 60.0 * ( 60.0 * ( (double) abs(ideg) ) +
+                             ( (double) abs(iamin) ) ) +
+                                        fabs(asec) ) * ERFA_DAS2R;
+
+/* Validate arguments and return status. */
+   if ( ideg < 0 || ideg > 359 ) return 1;
+   if ( iamin < 0 || iamin > 59 ) return 2;
+   if ( asec < 0.0 || asec >= 60.0 ) return 3;
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/anp.c b/cextern/erfa/anp.c
new file mode 100644
index 0000000..70d45ef
--- /dev/null
+++ b/cextern/erfa/anp.c
@@ -0,0 +1,91 @@
+#include "erfa.h"
+
+double eraAnp(double a)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double w;
+
+
+   w = fmod(a, ERFA_D2PI);
+   if (w < 0) w += ERFA_D2PI;
+
+   return w;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/anpm.c b/cextern/erfa/anpm.c
new file mode 100644
index 0000000..db87a45
--- /dev/null
+++ b/cextern/erfa/anpm.c
@@ -0,0 +1,91 @@
+#include "erfa.h"
+
+double eraAnpm(double a)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double w;
+
+
+   w = fmod(a, ERFA_D2PI);
+   if (fabs(w) >= ERFA_DPI) w -= ERFA_DSIGN(ERFA_D2PI, a);
+
+   return w;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apcg.c b/cextern/erfa/apcg.c
new file mode 100644
index 0000000..7ee6fa3
--- /dev/null
+++ b/cextern/erfa/apcg.c
@@ -0,0 +1,181 @@
+#include "erfa.h"
+
+void eraApcg(double date1, double date2,
+             double ebpv[2][3], double ehp[3],
+             eraASTROM *astrom)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Geocentric observer */
+   double pv[2][3] = { { 0.0, 0.0, 0.0 },
+                       { 0.0, 0.0, 0.0 } };
+
+
+/* Compute the star-independent astrometry parameters. */
+   eraApcs(date1, date2, pv, ebpv, ehp, astrom);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apcg13.c b/cextern/erfa/apcg13.c
new file mode 100644
index 0000000..baa00be
--- /dev/null
+++ b/cextern/erfa/apcg13.c
@@ -0,0 +1,184 @@
+#include "erfa.h"
+
+void eraApcg13(double date1, double date2, eraASTROM *astrom)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double ehpv[2][3], ebpv[2][3];
+
+
+/* Earth barycentric & heliocentric position/velocity (au, au/d). */
+   (void) eraEpv00(date1, date2, ehpv, ebpv);
+
+/* Compute the star-independent astrometry parameters. */
+   eraApcg(date1, date2, ebpv, ehpv[0], astrom);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apci.c b/cextern/erfa/apci.c
new file mode 100644
index 0000000..ee84865
--- /dev/null
+++ b/cextern/erfa/apci.c
@@ -0,0 +1,190 @@
+#include "erfa.h"
+
+void eraApci(double date1, double date2,
+             double ebpv[2][3], double ehp[3],
+             double x, double y, double s,
+             eraASTROM *astrom)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Star-independent astrometry parameters for geocenter. */
+   eraApcg(date1, date2, ebpv, ehp, astrom);
+
+/* CIO based BPN matrix. */
+   eraC2ixys(x, y, s, astrom->bpn);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apci13.c b/cextern/erfa/apci13.c
new file mode 100644
index 0000000..d1e7e8d
--- /dev/null
+++ b/cextern/erfa/apci13.c
@@ -0,0 +1,202 @@
+#include "erfa.h"
+
+void eraApci13(double date1, double date2,
+               eraASTROM *astrom, double *eo)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double ehpv[2][3], ebpv[2][3], r[3][3], x, y, s;
+
+
+/* Earth barycentric & heliocentric position/velocity (au, au/d). */
+   (void) eraEpv00(date1, date2, ehpv, ebpv);
+
+/* Form the equinox based BPN matrix, IAU 2006/2000A. */
+   eraPnm06a(date1, date2, r);
+
+/* Extract CIP X,Y. */
+   eraBpn2xy(r, &x, &y);
+
+/* Obtain CIO locator s. */
+   s = eraS06(date1, date2, x, y);
+
+/* Compute the star-independent astrometry parameters. */
+   eraApci(date1, date2, ebpv, ehpv[0], x, y, s, astrom);
+
+/* Equation of the origins. */
+   *eo = eraEors(r, s);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apco.c b/cextern/erfa/apco.c
new file mode 100644
index 0000000..6681412
--- /dev/null
+++ b/cextern/erfa/apco.c
@@ -0,0 +1,264 @@
+#include "erfa.h"
+
+void eraApco(double date1, double date2,
+             double ebpv[2][3], double ehp[3],
+             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)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double sl, cl, r[3][3], pvc[2][3], pv[2][3];
+
+
+/* Longitude with adjustment for TIO locator s'. */
+   astrom->along = elong + sp;
+
+/* Polar motion, rotated onto the local meridian. */
+   sl = sin(astrom->along);
+   cl = cos(astrom->along);
+   astrom->xpl = xp*cl - yp*sl;
+   astrom->ypl = xp*sl + yp*cl;
+
+/* Functions of latitude. */
+   astrom->sphi = sin(phi);
+   astrom->cphi = cos(phi);
+
+/* Refraction constants. */
+   astrom->refa = refa;
+   astrom->refb = refb;
+
+/* Local Earth rotation angle. */
+   eraAper(theta, astrom);
+
+/* Disable the (redundant) diurnal aberration step. */
+   astrom->diurab = 0.0;
+
+/* CIO based BPN matrix. */
+   eraC2ixys(x, y, s, r);
+
+/* Observer's geocentric position and velocity (m, m/s, CIRS). */
+   eraPvtob(elong, phi, hm, xp, yp, sp, theta, pvc);
+
+/* Rotate into GCRS. */
+   eraTrxpv(r, pvc, pv);
+
+/* ICRS <-> GCRS parameters. */
+   eraApcs(date1, date2, pv, ebpv, ehp, astrom);
+
+/* Store the CIO based BPN matrix. */
+   eraCr(r, astrom->bpn );
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apco13.c b/cextern/erfa/apco13.c
new file mode 100644
index 0000000..e0374db
--- /dev/null
+++ b/cextern/erfa/apco13.c
@@ -0,0 +1,287 @@
+#include "erfa.h"
+
+int eraApco13(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   double tai1, tai2, tt1, tt2, ut11, ut12, ehpv[2][3], ebpv[2][3],
+          r[3][3], x, y, s, theta, sp, refa, refb;
+
+
+/* UTC to other time scales. */
+   j = eraUtctai(utc1, utc2, &tai1, &tai2);
+   if ( j < 0 ) return -1;
+   j = eraTaitt(tai1, tai2, &tt1, &tt2);
+   j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12);
+   if ( j < 0 ) return -1;
+
+/* Earth barycentric & heliocentric position/velocity (au, au/d). */
+   (void) eraEpv00(tt1, tt2, ehpv, ebpv);
+
+/* Form the equinox based BPN matrix, IAU 2006/2000A. */
+   eraPnm06a(tt1, tt2, r);
+
+/* Extract CIP X,Y. */
+   eraBpn2xy(r, &x, &y);
+
+/* Obtain CIO locator s. */
+   s = eraS06(tt1, tt2, x, y);
+
+/* Earth rotation angle. */
+   theta = eraEra00(ut11, ut12);
+
+/* TIO locator s'. */
+   sp = eraSp00(tt1, tt2);
+
+/* Refraction constants A and B. */
+   eraRefco(phpa, tc, rh, wl, &refa, &refb);
+
+/* Compute the star-independent astrometry parameters. */
+   eraApco(tt1, tt2, ebpv, ehpv[0], x, y, s, theta,
+           elong, phi, hm, xp, yp, sp, refa, refb, astrom);
+
+/* Equation of the origins. */
+   *eo = eraEors(r, s);
+
+/* Return any warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apcs.c b/cextern/erfa/apcs.c
new file mode 100644
index 0000000..b872ca6
--- /dev/null
+++ b/cextern/erfa/apcs.c
@@ -0,0 +1,233 @@
+#include "erfa.h"
+
+void eraApcs(double date1, double date2, double pv[2][3],
+             double ebpv[2][3], double ehp[3],
+             eraASTROM *astrom)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* au/d to m/s */
+   const double AUDMS = ERFA_DAU/ERFA_DAYSEC;
+
+/* Light time for 1 AU (day) */
+   const double CR = ERFA_AULT/ERFA_DAYSEC;
+
+   int i;
+   double dp, dv, pb[3], vb[3], ph[3], v2, w;
+
+
+/* Time since reference epoch, years (for proper motion calculation). */
+   astrom->pmt = ( (date1 - ERFA_DJ00) + date2 ) / ERFA_DJY;
+
+/* Adjust Earth ephemeris to observer. */
+   for (i = 0; i < 3; i++) {
+      dp = pv[0][i] / ERFA_DAU;
+      dv = pv[1][i] / AUDMS;
+      pb[i] = ebpv[0][i] + dp;
+      vb[i] = ebpv[1][i] + dv;
+      ph[i] = ehp[i] + dp;
+   }
+
+/* Barycentric position of observer (au). */
+   eraCp(pb, astrom->eb);
+
+/* Heliocentric direction and distance (unit vector and au). */
+   eraPn(ph, &astrom->em, astrom->eh);
+
+/* Barycentric vel. in units of c, and reciprocal of Lorenz factor. */
+   v2 = 0.0;
+   for (i = 0; i < 3; i++) {
+      w = vb[i] * CR;
+      astrom->v[i] = w;
+      v2 += w*w;
+   }
+   astrom->bm1 = sqrt(1.0 - v2);
+
+/* Reset the NPB matrix. */
+   eraIr(astrom->bpn);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apcs13.c b/cextern/erfa/apcs13.c
new file mode 100644
index 0000000..79e56ec
--- /dev/null
+++ b/cextern/erfa/apcs13.c
@@ -0,0 +1,191 @@
+#include "erfa.h"
+
+void eraApcs13(double date1, double date2, double pv[2][3],
+               eraASTROM *astrom)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double ehpv[2][3], ebpv[2][3];
+
+
+/* Earth barycentric & heliocentric position/velocity (au, au/d). */
+   (void) eraEpv00(date1, date2, ehpv, ebpv);
+
+/* Compute the star-independent astrometry parameters. */
+   eraApcs(date1, date2, pv, ebpv, ehpv[0], astrom);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/aper.c b/cextern/erfa/aper.c
new file mode 100644
index 0000000..4bd92b4
--- /dev/null
+++ b/cextern/erfa/aper.c
@@ -0,0 +1,162 @@
+#include "erfa.h"
+
+void eraAper(double theta, eraASTROM *astrom)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   astrom->eral = theta + astrom->along;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/aper13.c b/cextern/erfa/aper13.c
new file mode 100644
index 0000000..29a2e68
--- /dev/null
+++ b/cextern/erfa/aper13.c
@@ -0,0 +1,181 @@
+#include "erfa.h"
+
+void eraAper13(double ut11, double ut12, eraASTROM *astrom)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraAper(eraEra00(ut11,ut12), astrom);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apio.c b/cextern/erfa/apio.c
new file mode 100644
index 0000000..a42222f
--- /dev/null
+++ b/cextern/erfa/apio.c
@@ -0,0 +1,213 @@
+#include "erfa.h"
+
+void eraApio(double sp, double theta,
+             double elong, double phi, double hm, double xp, double yp,
+             double refa, double refb,
+             eraASTROM *astrom)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double sl, cl, pv[2][3];
+
+
+/* Longitude with adjustment for TIO locator s'. */
+   astrom->along = elong + sp;
+
+/* Polar motion, rotated onto the local meridian. */
+   sl = sin(astrom->along);
+   cl = cos(astrom->along);
+   astrom->xpl = xp*cl - yp*sl;
+   astrom->ypl = xp*sl + yp*cl;
+
+/* Functions of latitude. */
+   astrom->sphi = sin(phi);
+   astrom->cphi = cos(phi);
+
+/* Observer's geocentric position and velocity (m, m/s, CIRS). */
+   eraPvtob(elong, phi, hm, xp, yp, sp, theta, pv);
+
+/* Magnitude of diurnal aberration vector. */
+   astrom->diurab = sqrt(pv[1][0]*pv[1][0]+pv[1][1]*pv[1][1]) / ERFA_CMPS;
+
+/* Refraction constants. */
+   astrom->refa = refa;
+   astrom->refb = refb;
+
+/* Local Earth rotation angle. */
+   eraAper(theta, astrom);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/apio13.c b/cextern/erfa/apio13.c
new file mode 100644
index 0000000..b5e2248
--- /dev/null
+++ b/cextern/erfa/apio13.c
@@ -0,0 +1,259 @@
+#include "erfa.h"
+
+int eraApio13(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   double tai1, tai2, tt1, tt2, ut11, ut12, sp, theta, refa, refb;
+
+
+/* UTC to other time scales. */
+   j = eraUtctai(utc1, utc2, &tai1, &tai2);
+   if ( j < 0 ) return -1;
+   j = eraTaitt(tai1, tai2, &tt1, &tt2);
+   j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12);
+   if ( j < 0 ) return -1;
+
+/* TIO locator s'. */
+   sp = eraSp00(tt1, tt2);
+
+/* Earth rotation angle. */
+   theta = eraEra00(ut11, ut12);
+
+/* Refraction constants A and B. */
+   eraRefco(phpa, tc, rh, wl, &refa, &refb);
+
+/* CIRS <-> observed astrometry parameters. */
+   eraApio(sp, theta, elong, phi, hm, xp, yp, refa, refb, astrom);
+
+/* Return any warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atci13.c b/cextern/erfa/atci13.c
new file mode 100644
index 0000000..c85c2be
--- /dev/null
+++ b/cextern/erfa/atci13.c
@@ -0,0 +1,159 @@
+#include "erfa.h"
+
+void eraAtci13(double rc, double dc,
+               double pr, double pd, double px, double rv,
+               double date1, double date2,
+               double *ri, double *di, double *eo)
+/*
+**  - - - - - - - - - -
+**   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.8g could be expressed in any of these ways, among
+**     others:
+**
+**            date1          date2
+**
+**         2450123.8g           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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Star-independent astrometry parameters */
+   eraASTROM astrom;
+
+
+/* The transformation parameters. */
+   eraApci13(date1, date2, &astrom, eo);
+
+/* ICRS (epoch J2000.0) to CIRS. */
+   eraAtciq(rc, dc, pr, pd, px, rv, &astrom, ri, di);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atciq.c b/cextern/erfa/atciq.c
new file mode 100644
index 0000000..095a6b0
--- /dev/null
+++ b/cextern/erfa/atciq.c
@@ -0,0 +1,154 @@
+#include "erfa.h"
+
+void eraAtciq(double rc, double dc,
+              double pr, double pd, double px, double rv,
+              eraASTROM *astrom, double *ri, double *di)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double pco[3], pnat[3], ppr[3], pi[3], w;
+
+
+/* Proper motion and parallax, giving BCRS coordinate direction. */
+   eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco);
+
+/* Light deflection by the Sun, giving BCRS natural direction. */
+   eraLdsun(pco, astrom->eh, astrom->em, pnat);
+
+/* Aberration, giving GCRS proper direction. */
+   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
+
+/* Bias-precession-nutation, giving CIRS proper direction. */
+   eraRxp(astrom->bpn, ppr, pi);
+
+/* CIRS RA,Dec. */
+   eraC2s(pi, &w, di);
+   *ri = eraAnp(w);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atciqn.c b/cextern/erfa/atciqn.c
new file mode 100644
index 0000000..9a381f8
--- /dev/null
+++ b/cextern/erfa/atciqn.c
@@ -0,0 +1,191 @@
+#include "erfa.h"
+
+void eraAtciqn(double rc, double dc, double pr, double pd,
+               double px, double rv, eraASTROM *astrom,
+               int n, eraLDBODY b[], double *ri, double *di)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double pco[3], pnat[3], ppr[3], pi[3], w;
+
+
+/* Proper motion and parallax, giving BCRS coordinate direction. */
+   eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco);
+
+/* Light deflection, giving BCRS natural direction. */
+   eraLdn(n, b, astrom->eb, pco, pnat);
+
+/* Aberration, giving GCRS proper direction. */
+   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
+
+/* Bias-precession-nutation, giving CIRS proper direction. */
+   eraRxp(astrom->bpn, ppr, pi);
+
+/* CIRS RA,Dec. */
+   eraC2s(pi, &w, di);
+   *ri = eraAnp(w);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atciqz.c b/cextern/erfa/atciqz.c
new file mode 100644
index 0000000..983db53
--- /dev/null
+++ b/cextern/erfa/atciqz.c
@@ -0,0 +1,153 @@
+#include "erfa.h"
+
+void eraAtciqz(double rc, double dc, eraASTROM *astrom,
+               double *ri, double *di)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double pco[3], pnat[3], ppr[3], pi[3], w;
+
+
+/* BCRS coordinate direction (unit vector). */
+   eraS2c(rc, dc, pco);
+
+/* Light deflection by the Sun, giving BCRS natural direction. */
+   eraLdsun(pco, astrom->eh, astrom->em, pnat);
+
+/* Aberration, giving GCRS proper direction. */
+   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
+
+/* Bias-precession-nutation, giving CIRS proper direction. */
+   eraRxp(astrom->bpn, ppr, pi);
+
+/* CIRS RA,Dec. */
+   eraC2s(pi, &w, di);
+   *ri = eraAnp(w);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atco13.c b/cextern/erfa/atco13.c
new file mode 100644
index 0000000..c27fe3b
--- /dev/null
+++ b/cextern/erfa/atco13.c
@@ -0,0 +1,243 @@
+#include "erfa.h"
+
+int eraAtco13(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)
+/*
+**  - - - - - - - - - -
+**   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 ICRS to observed
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   eraASTROM astrom;
+   double ri, di;
+
+
+/* Star-independent astrometry parameters. */
+   j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
+                 phpa, tc, rh, wl, &astrom, eo);
+
+/* Abort if bad UTC. */
+   if ( j < 0 ) return j;
+
+/* Transform ICRS to CIRS. */
+   eraAtciq(rc, dc, pr, pd, px, rv, &astrom, &ri, &di);
+
+/* Transform CIRS to observed. */
+   eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob);
+
+/* Return OK/warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atic13.c b/cextern/erfa/atic13.c
new file mode 100644
index 0000000..35dcd13
--- /dev/null
+++ b/cextern/erfa/atic13.c
@@ -0,0 +1,152 @@
+#include "erfa.h"
+
+void eraAtic13(double ri, double di, double date1, double date2,
+               double *rc, double *dc, double *eo)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Star-independent astrometry parameters */
+   eraASTROM astrom;
+
+
+/* Star-independent astrometry parameters. */
+   eraApci13(date1, date2, &astrom, eo);
+
+/* CIRS to ICRS astrometric. */
+   eraAticq(ri, di, &astrom, rc, dc);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/aticq.c b/cextern/erfa/aticq.c
new file mode 100644
index 0000000..2401836
--- /dev/null
+++ b/cextern/erfa/aticq.c
@@ -0,0 +1,199 @@
+#include "erfa.h"
+
+void eraAticq(double ri, double di, eraASTROM *astrom,
+              double *rc, double *dc)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j, i;
+   double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r,
+          after[3];
+
+
+/* CIRS RA,Dec to Cartesian. */
+   eraS2c(ri, di, pi);
+
+/* Bias-precession-nutation, giving GCRS proper direction. */
+   eraTrxp(astrom->bpn, pi, ppr);
+
+/* Aberration, giving GCRS natural direction. */
+   eraZp(d);
+   for (j = 0; j < 2; j++) {
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         w = ppr[i] - d[i];
+         before[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         before[i] /= r;
+      }
+      eraAb(before, astrom->v, astrom->em, astrom->bm1, after);
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         d[i] = after[i] - before[i];
+         w = ppr[i] - d[i];
+         pnat[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         pnat[i] /= r;
+      }
+   }
+
+/* Light deflection by the Sun, giving BCRS coordinate direction. */
+   eraZp(d);
+   for (j = 0; j < 5; j++) {
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         w = pnat[i] - d[i];
+         before[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         before[i] /= r;
+      }
+      eraLdsun(before, astrom->eh, astrom->em, after);
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         d[i] = after[i] - before[i];
+         w = pnat[i] - d[i];
+         pco[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         pco[i] /= r;
+      }
+   }
+
+/* ICRS astrometric RA,Dec. */
+   eraC2s(pco, &w, dc);
+   *rc = eraAnp(w);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/aticqn.c b/cextern/erfa/aticqn.c
new file mode 100644
index 0000000..3c633a8
--- /dev/null
+++ b/cextern/erfa/aticqn.c
@@ -0,0 +1,237 @@
+#include "erfa.h"
+
+void eraAticqn(double ri, double di, eraASTROM *astrom,
+               int n, eraLDBODY b[], double *rc, double *dc)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j, i;
+   double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r,
+          after[3];
+
+
+/* CIRS RA,Dec to Cartesian. */
+   eraS2c(ri, di, pi);
+
+/* Bias-precession-nutation, giving GCRS proper direction. */
+   eraTrxp(astrom->bpn, pi, ppr);
+
+/* Aberration, giving GCRS natural direction. */
+   eraZp(d);
+   for (j = 0; j < 2; j++) {
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         w = ppr[i] - d[i];
+         before[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         before[i] /= r;
+      }
+      eraAb(before, astrom->v, astrom->em, astrom->bm1, after);
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         d[i] = after[i] - before[i];
+         w = ppr[i] - d[i];
+         pnat[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         pnat[i] /= r;
+      }
+   }
+
+/* Light deflection, giving BCRS coordinate direction. */
+   eraZp(d);
+   for (j = 0; j < 5; j++) {
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         w = pnat[i] - d[i];
+         before[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         before[i] /= r;
+      }
+      eraLdn(n, b, astrom->eb, before, after);
+      r2 = 0.0;
+      for (i = 0; i < 3; i++) {
+         d[i] = after[i] - before[i];
+         w = pnat[i] - d[i];
+         pco[i] = w;
+         r2 += w*w;
+      }
+      r = sqrt(r2);
+      for (i = 0; i < 3; i++) {
+         pco[i] /= r;
+      }
+   }
+
+/* ICRS astrometric RA,Dec. */
+   eraC2s(pco, &w, dc);
+   *rc = eraAnp(w);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atio13.c b/cextern/erfa/atio13.c
new file mode 100644
index 0000000..36a6452
--- /dev/null
+++ b/cextern/erfa/atio13.c
@@ -0,0 +1,222 @@
+#include "erfa.h"
+
+int eraAtio13(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)
+/*
+**  - - - - - - - - - -
+**   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 ICRS to observed
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   eraASTROM astrom;
+
+
+/* Star-independent astrometry parameters for CIRS->observed. */
+   j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
+                 phpa, tc, rh, wl, &astrom);
+
+/* Abort if bad UTC. */
+   if ( j < 0 ) return j;
+
+/* Transform CIRS to observed. */
+   eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob);
+
+/* Return OK/warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atioq.c b/cextern/erfa/atioq.c
new file mode 100644
index 0000000..be3dfbc
--- /dev/null
+++ b/cextern/erfa/atioq.c
@@ -0,0 +1,244 @@
+#include "erfa.h"
+
+void eraAtioq(double ri, double di, eraASTROM *astrom,
+              double *aob, double *zob,
+              double *hob, double *dob, double *rob)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Minimum cos(alt) and sin(alt) for refraction purposes */
+   const double CELMIN = 1e-6;
+   const double SELMIN = 0.05;
+
+   double v[3], x, y, z, xhd, yhd, zhd, f, xhdt, yhdt, zhdt,
+          xaet, yaet, zaet, azobs, r, tz, w, del, cosdel,
+          xaeo, yaeo, zaeo, zdobs, hmobs, dcobs, raobs;
+
+/*--------------------------------------------------------------------*/
+
+/* CIRS RA,Dec to Cartesian -HA,Dec. */
+   eraS2c(ri-astrom->eral, di, v);
+   x = v[0];
+   y = v[1];
+   z = v[2];
+
+/* Polar motion. */
+   xhd = x + astrom->xpl*z;
+   yhd = y - astrom->ypl*z;
+   zhd = z - astrom->xpl*x + astrom->ypl*y;
+
+/* Diurnal aberration. */
+   f = ( 1.0 - astrom->diurab*yhd );
+   xhdt = f * xhd;
+   yhdt = f * ( yhd + astrom->diurab );
+   zhdt = f * zhd;
+
+/* Cartesian -HA,Dec to Cartesian Az,El (S=0,E=90). */
+   xaet = astrom->sphi*xhdt - astrom->cphi*zhdt;
+   yaet = yhdt;
+   zaet = astrom->cphi*xhdt + astrom->sphi*zhdt;
+
+/* Azimuth (N=0,E=90). */
+   azobs = ( xaet != 0.0 || yaet != 0.0 ) ? atan2(yaet,-xaet) : 0.0;
+
+/* ---------- */
+/* Refraction */
+/* ---------- */
+
+/* Cosine and sine of altitude, with precautions. */
+   r = sqrt(xaet*xaet + yaet*yaet);
+   r = r > CELMIN ? r : CELMIN;
+   z = zaet > SELMIN ? zaet : SELMIN;
+
+/* A*tan(z)+B*tan^3(z) model, with Newton-Raphson correction. */
+   tz = r/z;
+   w = astrom->refb*tz*tz;
+   del = ( astrom->refa + w ) * tz /
+         ( 1.0 + ( astrom->refa + 3.0*w ) / ( z*z ) );
+
+/* Apply the change, giving observed vector. */
+   cosdel = 1.0 - del*del/2.0;
+   f = cosdel - del*z/r;
+   xaeo = xaet*f;
+   yaeo = yaet*f;
+   zaeo = cosdel*zaet + del*r;
+
+/* Observed ZD. */
+   zdobs = atan2(sqrt(xaeo*xaeo+yaeo*yaeo), zaeo);
+
+/* Az/El vector to HA,Dec vector (both right-handed). */
+   v[0] = astrom->sphi*xaeo + astrom->cphi*zaeo;
+   v[1] = yaeo;
+   v[2] = - astrom->cphi*xaeo + astrom->sphi*zaeo;
+
+/* To spherical -HA,Dec. */
+   eraC2s ( v, &hmobs, &dcobs );
+
+/* Right ascension (with respect to CIO). */
+   raobs = astrom->eral + hmobs;
+
+/* Return the results. */
+   *aob = eraAnp(azobs);
+   *zob = zdobs;
+   *hob = -hmobs;
+   *dob = dcobs;
+   *rob = eraAnp(raobs);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atoc13.c b/cextern/erfa/atoc13.c
new file mode 100644
index 0000000..071494b
--- /dev/null
+++ b/cextern/erfa/atoc13.c
@@ -0,0 +1,233 @@
+#include "erfa.h"
+
+int eraAtoc13(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   eraASTROM astrom;
+   double eo, ri, di;
+
+
+/* Star-independent astrometry parameters. */
+   j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
+                 phpa, tc, rh, wl, &astrom, &eo);
+
+/* Abort if bad UTC. */
+   if ( j < 0 ) return j;
+
+/* Transform observed to CIRS. */
+   eraAtoiq(type, ob1, ob2, &astrom, &ri, &di);
+
+/* Transform CIRS to ICRS. */
+   eraAticq(ri, di, &astrom, rc, dc);
+
+/* Return OK/warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atoi13.c b/cextern/erfa/atoi13.c
new file mode 100644
index 0000000..87d68c9
--- /dev/null
+++ b/cextern/erfa/atoi13.c
@@ -0,0 +1,228 @@
+#include "erfa.h"
+
+int eraAtoi13(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   eraASTROM astrom;
+
+
+/* Star-independent astrometry parameters for CIRS->observed. */
+   j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
+                 phpa, tc, rh, wl, &astrom);
+
+/* Abort if bad UTC. */
+   if ( j < 0 ) return j;
+
+/* Transform observed to CIRS. */
+   eraAtoiq(type, ob1, ob2, &astrom, ri, di);
+
+/* Return OK/warning status. */
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/atoiq.c b/cextern/erfa/atoiq.c
new file mode 100644
index 0000000..646f9ae
--- /dev/null
+++ b/cextern/erfa/atoiq.c
@@ -0,0 +1,260 @@
+#include "erfa.h"
+
+void eraAtoiq(const char *type,
+              double ob1, double ob2, eraASTROM *astrom,
+              double *ri, double *di)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int c;
+   double c1, c2, sphi, cphi, ce, xaeo, yaeo, zaeo, v[3],
+          xmhdo, ymhdo, zmhdo, az, sz, zdo, refa, refb, tz, dref,
+          zdt, xaet, yaet, zaet, xmhda, ymhda, zmhda,
+          f, xhd, yhd, zhd, xpl, ypl, w, hma;
+
+
+/* Coordinate type. */
+   c = (int) type[0];
+
+/* Coordinates. */
+   c1 = ob1;
+   c2 = ob2;
+
+/* Sin, cos of latitude. */
+   sphi = astrom->sphi;
+   cphi = astrom->cphi;
+
+/* Standardize coordinate type. */
+   if ( c == 'r' || c == 'R' ) {
+      c = 'R';
+   } else if ( c == 'h' || c == 'H' ) {
+      c = 'H';
+   } else {
+      c = 'A';
+   }
+
+/* If Az,ZD, convert to Cartesian (S=0,E=90). */
+   if ( c == 'A' ) {
+      ce = sin(c2);
+      xaeo = - cos(c1) * ce;
+      yaeo = sin(c1) * ce;
+      zaeo = cos(c2);
+
+   } else {
+
+   /* If RA,Dec, convert to HA,Dec. */
+      if ( c == 'R' ) c1 = astrom->eral - c1;
+
+   /* To Cartesian -HA,Dec. */
+      eraS2c ( -c1, c2, v );
+      xmhdo = v[0];
+      ymhdo = v[1];
+      zmhdo = v[2];
+
+   /* To Cartesian Az,El (S=0,E=90). */
+      xaeo = sphi*xmhdo - cphi*zmhdo;
+      yaeo = ymhdo;
+      zaeo = cphi*xmhdo + sphi*zmhdo;
+   }
+
+/* Azimuth (S=0,E=90). */
+   az = ( xaeo != 0.0 || yaeo != 0.0 ) ? atan2(yaeo,xaeo) : 0.0;
+
+/* Sine of observed ZD, and observed ZD. */
+   sz = sqrt ( xaeo*xaeo + yaeo*yaeo );
+   zdo = atan2 ( sz, zaeo );
+
+/*
+** Refraction
+** ----------
+*/
+
+/* Fast algorithm using two constant model. */
+   refa = astrom->refa;
+   refb = astrom->refb;
+   tz = sz / zaeo;
+   dref = ( refa + refb*tz*tz ) * tz;
+   zdt = zdo + dref;
+
+/* To Cartesian Az,ZD. */
+   ce = sin(zdt);
+   xaet = cos(az) * ce;
+   yaet = sin(az) * ce;
+   zaet = cos(zdt);
+
+/* Cartesian Az,ZD to Cartesian -HA,Dec. */
+   xmhda = sphi*xaet + cphi*zaet;
+   ymhda = yaet;
+   zmhda = - cphi*xaet + sphi*zaet;
+
+/* Diurnal aberration. */
+   f = ( 1.0 + astrom->diurab*ymhda );
+   xhd = f * xmhda;
+   yhd = f * ( ymhda - astrom->diurab );
+   zhd = f * zmhda;
+
+/* Polar motion. */
+   xpl = astrom->xpl;
+   ypl = astrom->ypl;
+   w = xpl*xhd - ypl*yhd + zhd;
+   v[0] = xhd - xpl*w;
+   v[1] = yhd + ypl*w;
+   v[2] = w - ( xpl*xpl + ypl*ypl ) * zhd;
+
+/* To spherical -HA,Dec. */
+   eraC2s(v, &hma, di);
+
+/* Right ascension. */
+   *ri = eraAnp(astrom->eral + hma);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/bi00.c b/cextern/erfa/bi00.c
new file mode 100644
index 0000000..8d0a303
--- /dev/null
+++ b/cextern/erfa/bi00.c
@@ -0,0 +1,125 @@
+#include "erfa.h"
+
+void eraBi00(double *dpsibi, double *depsbi, double *dra)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* The frame bias corrections in longitude and obliquity */
+   const double DPBIAS = -0.041775  * ERFA_DAS2R,
+                DEBIAS = -0.0068192 * ERFA_DAS2R;
+
+/* The ICRS RA of the J2000.0 equinox (Chapront et al., 2002) */
+   const double DRA0 = -0.0146 * ERFA_DAS2R;
+
+
+/* Return the results (which are fixed). */
+   *dpsibi = DPBIAS;
+   *depsbi = DEBIAS;
+   *dra = DRA0;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/bp00.c b/cextern/erfa/bp00.c
new file mode 100644
index 0000000..b626322
--- /dev/null
+++ b/cextern/erfa/bp00.c
@@ -0,0 +1,181 @@
+#include "erfa.h"
+
+void eraBp00(double date1, double date2,
+             double rb[3][3], double rp[3][3], double rbp[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* J2000.0 obliquity (Lieske et al. 1977) */
+   const double EPS0 = 84381.448 * ERFA_DAS2R;
+
+   double t, dpsibi, depsbi, dra0, psia77, oma77, chia,
+          dpsipr, depspr, psia, oma, rbw[3][3];
+
+
+/* Interval between fundamental epoch J2000.0 and current date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Frame bias. */
+   eraBi00(&dpsibi, &depsbi, &dra0);
+
+/* Precession angles (Lieske et al. 1977) */
+   psia77 = (5038.7784 + (-1.07259 + (-0.001147) * t) * t) * t * ERFA_DAS2R;
+   oma77  =       EPS0 + ((0.05127 + (-0.007726) * t) * t) * t * ERFA_DAS2R;
+   chia   = (  10.5526 + (-2.38064 + (-0.001125) * t) * t) * t * ERFA_DAS2R;
+
+/* Apply IAU 2000 precession corrections. */
+   eraPr00(date1, date2, &dpsipr, &depspr);
+   psia = psia77 + dpsipr;
+   oma  = oma77  + depspr;
+
+/* Frame bias matrix: GCRS to J2000.0. */
+   eraIr(rbw);
+   eraRz(dra0, rbw);
+   eraRy(dpsibi*sin(EPS0), rbw);
+   eraRx(-depsbi, rbw);
+   eraCr(rbw, rb);
+
+/* Precession matrix: J2000.0 to mean of date. */
+   eraIr(rp);
+   eraRx(EPS0, rp);
+   eraRz(-psia, rp);
+   eraRx(-oma, rp);
+   eraRz(chia, rp);
+
+/* Bias-precession matrix: GCRS to mean of date. */
+   eraRxr(rp, rbw, rbp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/bp06.c b/cextern/erfa/bp06.c
new file mode 100644
index 0000000..18d07b7
--- /dev/null
+++ b/cextern/erfa/bp06.c
@@ -0,0 +1,152 @@
+#include "erfa.h"
+
+void eraBp06(double date1, double date2,
+             double rb[3][3], double rp[3][3], double rbp[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gamb, phib, psib, epsa, rbpw[3][3], rbt[3][3];
+
+
+/* B matrix. */
+   eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &epsa);
+   eraFw2m(gamb, phib, psib, epsa, rb);
+
+/* PxB matrix (temporary). */
+   eraPmat06(date1, date2, rbpw);
+
+/* P matrix. */
+   eraTr(rb, rbt);
+   eraRxr(rbpw, rbt, rp);
+
+/* PxB matrix. */
+   eraCr(rbpw, rbp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/bpn2xy.c b/cextern/erfa/bpn2xy.c
new file mode 100644
index 0000000..0424601
--- /dev/null
+++ b/cextern/erfa/bpn2xy.c
@@ -0,0 +1,109 @@
+#include "erfa.h"
+
+void eraBpn2xy(double rbpn[3][3], double *x, double *y)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Extract the X,Y coordinates. */
+   *x = rbpn[2][0];
+   *y = rbpn[2][1];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2i00a.c b/cextern/erfa/c2i00a.c
new file mode 100644
index 0000000..a41552d
--- /dev/null
+++ b/cextern/erfa/c2i00a.c
@@ -0,0 +1,148 @@
+#include "erfa.h"
+
+void eraC2i00a(double date1, double date2, double rc2i[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3];
+
+
+/* Obtain the celestial-to-true matrix (IAU 2000A). */
+   eraPnm00a(date1, date2, rbpn);
+
+/* Form the celestial-to-intermediate matrix. */
+   eraC2ibpn(date1, date2, rbpn, rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2i00b.c b/cextern/erfa/c2i00b.c
new file mode 100644
index 0000000..5f95a8b
--- /dev/null
+++ b/cextern/erfa/c2i00b.c
@@ -0,0 +1,148 @@
+#include "erfa.h"
+
+void eraC2i00b(double date1, double date2, double rc2i[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3];
+
+
+/* Obtain the celestial-to-true matrix (IAU 2000B). */
+   eraPnm00b(date1, date2, rbpn);
+
+/* Form the celestial-to-intermediate matrix. */
+   eraC2ibpn(date1, date2, rbpn, rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2i06a.c b/cextern/erfa/c2i06a.c
new file mode 100644
index 0000000..b8561e5
--- /dev/null
+++ b/cextern/erfa/c2i06a.c
@@ -0,0 +1,145 @@
+#include "erfa.h"
+
+void eraC2i06a(double date1, double date2, double rc2i[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3], x, y, s;
+
+
+/* Obtain the celestial-to-true matrix (IAU 2006/2000A). */
+   eraPnm06a(date1, date2, rbpn);
+
+/* Extract the X,Y coordinates. */
+   eraBpn2xy(rbpn, &x, &y);
+
+/* Obtain the CIO locator. */
+   s = eraS06(date1, date2, x, y);
+
+/* Form the celestial-to-intermediate matrix. */
+   eraC2ixys(x, y, s, rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2ibpn.c b/cextern/erfa/c2ibpn.c
new file mode 100644
index 0000000..74cd10b
--- /dev/null
+++ b/cextern/erfa/c2ibpn.c
@@ -0,0 +1,151 @@
+#include "erfa.h"
+
+void eraC2ibpn(double date1, double date2, double rbpn[3][3],
+               double rc2i[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y;
+
+
+/* Extract the X,Y coordinates. */
+   eraBpn2xy(rbpn, &x, &y);
+
+/* Form the celestial-to-intermediate matrix (n.b. IAU 2000 specific). */
+   eraC2ixy(date1, date2, x, y, rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2ixy.c b/cextern/erfa/c2ixy.c
new file mode 100644
index 0000000..95451b1
--- /dev/null
+++ b/cextern/erfa/c2ixy.c
@@ -0,0 +1,140 @@
+#include "erfa.h"
+
+void eraC2ixy(double date1, double date2, double x, double y,
+              double rc2i[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+
+{
+/* Compute s and then the matrix. */
+   eraC2ixys(x, y, eraS00(date1, date2, x, y), rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2ixys.c b/cextern/erfa/c2ixys.c
new file mode 100644
index 0000000..c676df8
--- /dev/null
+++ b/cextern/erfa/c2ixys.c
@@ -0,0 +1,132 @@
+#include "erfa.h"
+
+void eraC2ixys(double x, double y, double s, double rc2i[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r2, e, d;
+
+
+/* Obtain the spherical angles E and d. */
+   r2 = x*x + y*y;
+   e = (r2 != 0.0) ? atan2(y, x) : 0.0;
+   d = atan(sqrt(r2 / (1.0 - r2)));
+
+/* Form the matrix. */
+   eraIr(rc2i);
+   eraRz(e, rc2i);
+   eraRy(d, rc2i);
+   eraRz(-(e+s), rc2i);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2s.c b/cextern/erfa/c2s.c
new file mode 100644
index 0000000..c5feb6c
--- /dev/null
+++ b/cextern/erfa/c2s.c
@@ -0,0 +1,105 @@
+#include "erfa.h"
+
+void eraC2s(double p[3], double *theta, double *phi)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y, z, d2;
+
+
+   x  = p[0];
+   y  = p[1];
+   z  = p[2];
+   d2 = x*x + y*y;
+
+   *theta = (d2 == 0.0) ? 0.0 : atan2(y, x);
+   *phi = (z == 0.0) ? 0.0 : atan2(z, sqrt(d2));
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2t00a.c b/cextern/erfa/c2t00a.c
new file mode 100644
index 0000000..7d15e3e
--- /dev/null
+++ b/cextern/erfa/c2t00a.c
@@ -0,0 +1,163 @@
+#include "erfa.h"
+
+void eraC2t00a(double tta, double ttb, double uta, double utb,
+               double xp, double yp, double rc2t[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rc2i[3][3], era, sp, rpom[3][3];
+
+
+/* Form the celestial-to-intermediate matrix for this TT (IAU 2000A). */
+   eraC2i00a(tta, ttb, rc2i );
+
+/* Predict the Earth rotation angle for this UT1. */
+   era = eraEra00(uta, utb);
+
+/* Estimate s'. */
+   sp = eraSp00(tta, ttb);
+
+/* Form the polar motion matrix. */
+   eraPom00(xp, yp, sp, rpom);
+
+/* Combine to form the celestial-to-terrestrial matrix. */
+   eraC2tcio(rc2i, era, rpom, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2t00b.c b/cextern/erfa/c2t00b.c
new file mode 100644
index 0000000..5d228bb
--- /dev/null
+++ b/cextern/erfa/c2t00b.c
@@ -0,0 +1,159 @@
+#include "erfa.h"
+
+void eraC2t00b(double tta, double ttb, double uta, double utb,
+               double xp, double yp, double rc2t[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rc2i[3][3], era, rpom[3][3];
+
+
+/* Form the celestial-to-intermediate matrix for this TT (IAU 2000B). */
+   eraC2i00b(tta, ttb, rc2i);
+
+/* Predict the Earth rotation angle for this UT1. */
+   era = eraEra00(uta, utb);
+
+/* Form the polar motion matrix (neglecting s'). */
+   eraPom00(xp, yp, 0.0, rpom);
+
+/* Combine to form the celestial-to-terrestrial matrix. */
+   eraC2tcio(rc2i, era, rpom, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2t06a.c b/cextern/erfa/c2t06a.c
new file mode 100644
index 0000000..ea98d9d
--- /dev/null
+++ b/cextern/erfa/c2t06a.c
@@ -0,0 +1,161 @@
+#include "erfa.h"
+
+void eraC2t06a(double tta, double ttb, double uta, double utb,
+               double xp, double yp, double rc2t[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rc2i[3][3], era, sp, rpom[3][3];
+
+
+/* Form the celestial-to-intermediate matrix for this TT. */
+   eraC2i06a(tta, ttb, rc2i);
+
+/* Predict the Earth rotation angle for this UT1. */
+   era = eraEra00(uta, utb);
+
+/* Estimate s'. */
+   sp = eraSp00(tta, ttb);
+
+/* Form the polar motion matrix. */
+   eraPom00(xp, yp, sp, rpom);
+
+/* Combine to form the celestial-to-terrestrial matrix. */
+   eraC2tcio(rc2i, era, rpom, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2tcio.c b/cextern/erfa/c2tcio.c
new file mode 100644
index 0000000..aa2ba29
--- /dev/null
+++ b/cextern/erfa/c2tcio.c
@@ -0,0 +1,131 @@
+#include "erfa.h"
+
+void eraC2tcio(double rc2i[3][3], double era, double rpom[3][3],
+               double rc2t[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r[3][3];
+
+
+/* Construct the matrix. */
+   eraCr(rc2i, r);
+   eraRz(era, r);
+   eraRxr(rpom, r, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2teqx.c b/cextern/erfa/c2teqx.c
new file mode 100644
index 0000000..57649ee
--- /dev/null
+++ b/cextern/erfa/c2teqx.c
@@ -0,0 +1,131 @@
+#include "erfa.h"
+
+void eraC2teqx(double rbpn[3][3], double gst, double rpom[3][3],
+               double rc2t[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r[3][3];
+
+
+/* Construct the matrix. */
+   eraCr(rbpn, r);
+   eraRz(gst, r);
+   eraRxr(rpom, r, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2tpe.c b/cextern/erfa/c2tpe.c
new file mode 100644
index 0000000..1894b7b
--- /dev/null
+++ b/cextern/erfa/c2tpe.c
@@ -0,0 +1,176 @@
+#include "erfa.h"
+
+void eraC2tpe(double tta, double ttb, double uta, double utb,
+              double dpsi, double deps, double xp, double yp,
+              double rc2t[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3],
+          rbpn[3][3], gmst, ee, sp, rpom[3][3];
+
+
+/* Form the celestial-to-true matrix for this TT. */
+   eraPn00(tta, ttb, dpsi, deps, &epsa, rb, rp, rbp, rn, rbpn);
+
+/* Predict the Greenwich Mean Sidereal Time for this UT1 and TT. */
+   gmst = eraGmst00(uta, utb, tta, ttb);
+
+/* Predict the equation of the equinoxes given TT and nutation. */
+   ee = eraEe00(tta, ttb, epsa, dpsi);
+
+/* Estimate s'. */
+   sp = eraSp00(tta, ttb);
+
+/* Form the polar motion matrix. */
+   eraPom00(xp, yp, sp, rpom);
+
+/* Combine to form the celestial-to-terrestrial matrix. */
+   eraC2teqx(rbpn, gmst + ee, rpom, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/c2txy.c b/cextern/erfa/c2txy.c
new file mode 100644
index 0000000..bae827e
--- /dev/null
+++ b/cextern/erfa/c2txy.c
@@ -0,0 +1,168 @@
+#include "erfa.h"
+
+void eraC2txy(double tta, double ttb, double uta, double utb,
+              double x, double y, double xp, double yp,
+              double rc2t[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rc2i[3][3], era, sp, rpom[3][3];
+
+
+/* Form the celestial-to-intermediate matrix for this TT. */
+   eraC2ixy(tta, ttb, x, y, rc2i);
+
+/* Predict the Earth rotation angle for this UT1. */
+   era = eraEra00(uta, utb);
+
+/* Estimate s'. */
+   sp = eraSp00(tta, ttb);
+
+/* Form the polar motion matrix. */
+   eraPom00(xp, yp, sp, rpom);
+
+/* Combine to form the celestial-to-terrestrial matrix. */
+   eraC2tcio(rc2i, era, rpom, rc2t);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/cal2jd.c b/cextern/erfa/cal2jd.c
new file mode 100644
index 0000000..e0a3439
--- /dev/null
+++ b/cextern/erfa/cal2jd.c
@@ -0,0 +1,148 @@
+#include "erfa.h"
+
+int eraCal2jd(int iy, int im, int id, double *djm0, double *djm)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j, ly, my;
+   long iypmy;
+
+/* Earliest year allowed (4800BC) */
+   const int IYMIN = -4799;
+
+/* Month lengths in days */
+   static const int mtab[]
+                     = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+
+/* Preset status. */
+   j = 0;
+
+/* Validate year and month. */
+   if (iy < IYMIN) return -1;
+   if (im < 1 || im > 12) return -2;
+
+/* If February in a leap year, 1, otherwise 0. */
+   ly = ((im == 2) && !(iy%4) && (iy%100 || !(iy%400)));
+
+/* Validate day, taking into account leap years. */
+   if ( (id < 1) || (id > (mtab[im-1] + ly))) j = -3;
+
+/* Return result. */
+   my = (im - 14) / 12;
+   iypmy = (long) (iy + my);
+   *djm0 = ERFA_DJM0;
+   *djm = (double)((1461L * (iypmy + 4800L)) / 4L
+                 + (367L * (long) (im - 2 - 12 * my)) / 12L
+                 - (3L * ((iypmy + 4900L) / 100L)) / 4L
+                 + (long) id - 2432076L);
+
+/* Return status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/cp.c b/cextern/erfa/cp.c
new file mode 100644
index 0000000..3b9614a
--- /dev/null
+++ b/cextern/erfa/cp.c
@@ -0,0 +1,89 @@
+#include "erfa.h"
+
+void eraCp(double p[3], double c[3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   c[0] = p[0];
+   c[1] = p[1];
+   c[2] = p[2];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/cpv.c b/cextern/erfa/cpv.c
new file mode 100644
index 0000000..8423102
--- /dev/null
+++ b/cextern/erfa/cpv.c
@@ -0,0 +1,91 @@
+#include "erfa.h"
+
+void eraCpv(double pv[2][3], double c[2][3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraCp(pv[0], c[0]);
+   eraCp(pv[1], c[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/cr.c b/cextern/erfa/cr.c
new file mode 100644
index 0000000..651bdb5
--- /dev/null
+++ b/cextern/erfa/cr.c
@@ -0,0 +1,92 @@
+#include "erfa.h"
+
+void eraCr(double r[3][3], double c[3][3])
+/*
+**  - - - - - -
+**   e r a C r
+**  - - - - - -
+**
+**  Copy an r-matrix.
+**
+**  Given:
+**     r        double[3][3]    r-matrix to be copied
+**
+**  Returned:
+**   char[]     double[3][3]    copy
+**
+**  Called:
+**     eraCp        copy p-vector
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraCp(r[0], c[0]);
+   eraCp(r[1], c[1]);
+   eraCp(r[2], c[2]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/d2dtf.c b/cextern/erfa/d2dtf.c
new file mode 100644
index 0000000..d9b8f90
--- /dev/null
+++ b/cextern/erfa/d2dtf.c
@@ -0,0 +1,245 @@
+#include "erfa.h"
+#include <string.h>
+
+int eraD2dtf(const char *scale, int ndp, double d1, double d2,
+             int *iy, int *im, int *id, int ihmsf[4])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int leap;
+   char s;
+   int iy1, im1, id1, js, iy2, im2, id2, ihmsf1[4], i;
+   double a1, b1, fd, dat0, dat12, w, dat24, dleap;
+
+
+/* The two-part JD. */
+   a1 = d1;
+   b1 = d2;
+
+/* Provisional calendar date. */
+   js = eraJd2cal(a1, b1, &iy1, &im1, &id1, &fd);
+   if ( js ) return -1;
+
+/* Is this a leap second day? */
+   leap = 0;
+   if ( ! strcmp(scale,"UTC") ) {
+
+   /* TAI-UTC at 0h today. */
+      js = eraDat(iy1, im1, id1, 0.0, &dat0);
+      if ( js < 0 ) return -1;
+
+   /* TAI-UTC at 12h today (to detect drift). */
+      js = eraDat(iy1, im1, id1, 0.5, &dat12);
+      if ( js < 0 ) return -1;
+
+   /* TAI-UTC at 0h tomorrow (to detect jumps). */
+      js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w);
+      if ( js ) return -1;
+      js = eraDat(iy2, im2, id2, 0.0, &dat24);
+      if ( js < 0 ) return -1;
+
+   /* Any sudden change in TAI-UTC (seconds). */
+      dleap = dat24 - (2.0*dat12 - dat0);
+
+   /* If leap second day, scale the fraction of a day into SI. */
+      leap = (dleap != 0.0);
+      if (leap) fd += fd * dleap/ERFA_DAYSEC;
+   }
+
+/* Provisional time of day. */
+   eraD2tf ( ndp, fd, &s, ihmsf1 );
+
+/* Has the (rounded) time gone past 24h? */
+   if ( ihmsf1[0] > 23 ) {
+
+   /* Yes.  We probably need tomorrow's calendar date. */
+      js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w);
+      if ( js ) return -1;
+
+   /* Is today a leap second day? */
+      if ( ! leap ) {
+
+      /* No.  Use 0h tomorrow. */
+         iy1 = iy2;
+         im1 = im2;
+         id1 = id2;
+         ihmsf1[0] = 0;
+         ihmsf1[1] = 0;
+         ihmsf1[2] = 0;
+
+      } else {
+
+      /* Yes.  Are we past the leap second itself? */
+         if ( ihmsf1[2] > 0 ) {
+
+         /* Yes.  Use tomorrow but allow for the leap second. */
+            iy1 = iy2;
+            im1 = im2;
+            id1 = id2;
+            ihmsf1[0] = 0;
+            ihmsf1[1] = 0;
+            ihmsf1[2] = 0;
+
+         } else {
+
+         /* No.  Use 23 59 60... today. */
+            ihmsf1[0] = 23;
+            ihmsf1[1] = 59;
+            ihmsf1[2] = 60;
+         }
+
+      /* If rounding to 10s or coarser always go up to new day. */
+         if ( ndp < 0 && ihmsf1[2] == 60 ) {
+            iy1 = iy2;
+            im1 = im2;
+            id1 = id2;
+            ihmsf1[0] = 0;
+            ihmsf1[1] = 0;
+            ihmsf1[2] = 0;
+         }
+      }
+   }
+
+/* Results. */
+   *iy = iy1;
+   *im = im1;
+   *id = id1;
+   for ( i = 0; i < 4; i++ ) {
+      ihmsf[i] = ihmsf1[i];
+   }
+
+/* Status. */
+   return js;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/d2tf.c b/cextern/erfa/d2tf.c
new file mode 100644
index 0000000..132dfe9
--- /dev/null
+++ b/cextern/erfa/d2tf.c
@@ -0,0 +1,169 @@
+#include "erfa.h"
+
+void eraD2tf(int ndp, double days, char *sign, int ihmsf[4])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int nrs, n;
+   double rs, rm, rh, a, w, ah, am, as, af;
+
+
+/* Handle sign. */
+   *sign = (char) ( ( days >= 0.0 ) ? '+' : '-' );
+
+/* Interval in seconds. */
+   a = ERFA_DAYSEC * fabs(days);
+
+/* Pre-round if resolution coarser than 1s (then pretend ndp=1). */
+   if (ndp < 0) {
+      nrs = 1;
+      for (n = 1; n <= -ndp; n++) {
+          nrs *= (n == 2 || n == 4) ? 6 : 10;
+      }
+      rs = (double) nrs;
+      w = a / rs;
+      a = rs * ERFA_DNINT(w);
+   }
+
+/* Express the unit of each field in resolution units. */
+   nrs = 1;
+   for (n = 1; n <= ndp; n++) {
+      nrs *= 10;
+   }
+   rs = (double) nrs;
+   rm = rs * 60.0;
+   rh = rm * 60.0;
+
+/* Round the interval and express in resolution units. */
+   a = ERFA_DNINT(rs * a);
+
+/* Break into fields. */
+   ah = a / rh;
+   ah = ERFA_DINT(ah);
+   a -= ah * rh;
+   am = a / rm;
+   am = ERFA_DINT(am);
+   a -= am * rm;
+   as = a / rs;
+   as = ERFA_DINT(as);
+   af = a - as * rs;
+
+/* Return results. */
+   ihmsf[0] = (int) ah;
+   ihmsf[1] = (int) am;
+   ihmsf[2] = (int) as;
+   ihmsf[3] = (int) af;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/dat.c b/cextern/erfa/dat.c
new file mode 100644
index 0000000..f8ae681
--- /dev/null
+++ b/cextern/erfa/dat.c
@@ -0,0 +1,304 @@
+#include "erfa.h"
+
+int eraDat(int iy, int im, int id, double fd, double *deltat )
+/*
+**  - - - - - - -
+**   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:  2012 June 30       :
+**     :                                          :
+**     :__________________________________________:
+**
+**  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
+**
+**  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 UTC-TAI 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 UTC-TAI 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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Release year for this version of eraDat */
+   enum { IYV = 2014};
+
+/* Reference dates (MJD) and drift rates (s/day), pre leap seconds */
+   static const double drift[][2] = {
+      { 37300.0, 0.0012960 },
+      { 37300.0, 0.0012960 },
+      { 37300.0, 0.0012960 },
+      { 37665.0, 0.0011232 },
+      { 37665.0, 0.0011232 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 38761.0, 0.0012960 },
+      { 39126.0, 0.0025920 },
+      { 39126.0, 0.0025920 }
+   };
+
+/* Number of Delta(AT) expressions before leap seconds were introduced */
+   enum { NERA1 = (int) (sizeof drift / sizeof (double) / 2) };
+
+/* Dates and Delta(AT)s */
+   static const struct {
+      int iyear, month;
+      double delat;
+   } changes[] = {
+      { 1960,  1,  1.4178180 },
+      { 1961,  1,  1.4228180 },
+      { 1961,  8,  1.3728180 },
+      { 1962,  1,  1.8458580 },
+      { 1963, 11,  1.9458580 },
+      { 1964,  1,  3.2401300 },
+      { 1964,  4,  3.3401300 },
+      { 1964,  9,  3.4401300 },
+      { 1965,  1,  3.5401300 },
+      { 1965,  3,  3.6401300 },
+      { 1965,  7,  3.7401300 },
+      { 1965,  9,  3.8401300 },
+      { 1966,  1,  4.3131700 },
+      { 1968,  2,  4.2131700 },
+      { 1972,  1, 10.0       },
+      { 1972,  7, 11.0       },
+      { 1973,  1, 12.0       },
+      { 1974,  1, 13.0       },
+      { 1975,  1, 14.0       },
+      { 1976,  1, 15.0       },
+      { 1977,  1, 16.0       },
+      { 1978,  1, 17.0       },
+      { 1979,  1, 18.0       },
+      { 1980,  1, 19.0       },
+      { 1981,  7, 20.0       },
+      { 1982,  7, 21.0       },
+      { 1983,  7, 22.0       },
+      { 1985,  7, 23.0       },
+      { 1988,  1, 24.0       },
+      { 1990,  1, 25.0       },
+      { 1991,  1, 26.0       },
+      { 1992,  7, 27.0       },
+      { 1993,  7, 28.0       },
+      { 1994,  7, 29.0       },
+      { 1996,  1, 30.0       },
+      { 1997,  7, 31.0       },
+      { 1999,  1, 32.0       },
+      { 2006,  1, 33.0       },
+      { 2009,  1, 34.0       },
+      { 2012,  7, 35.0       }
+   };
+
+/* Number of Delta(AT) changes */
+   enum { NDAT = (int) (sizeof changes / sizeof changes[0]) };
+
+/* Miscellaneous local variables */
+   int j, i, m;
+   double da, djm0, djm;
+
+
+/* Initialize the result to zero. */
+   *deltat = da = 0.0;
+
+/* If invalid fraction of a day, set error status and give up. */
+   if (fd < 0.0 || fd > 1.0) return -4;
+
+/* Convert the date into an MJD. */
+   j = eraCal2jd(iy, im, id, &djm0, &djm);
+
+/* If invalid year, month, or day, give up. */
+   if (j < 0) return j;
+
+/* If pre-UTC year, set warning status and give up. */
+   if (iy < changes[0].iyear) return 1;
+
+/* If suspiciously late year, set warning status but proceed. */
+   if (iy > IYV + 5) j = 1;
+
+/* Combine year and month to form a date-ordered integer... */
+   m = 12*iy + im;
+
+/* ...and use it to find the preceding table entry. */
+   for (i = NDAT-1; i >=0; i--) {
+      if (m >= (12 * changes[i].iyear + changes[i].month)) break;
+   }
+
+/* Prevent underflow warnings. */
+   if (i < 0) return -5;
+
+/* Get the Delta(AT). */
+   da = changes[(i < 0) ? 0 : i].delat;
+
+/* If pre-1972, adjust for drift. */
+   if (i < NERA1) da += (djm + fd - drift[i][0]) * drift[i][1];
+
+/* Return the Delta(AT) value. */
+   *deltat = da;
+
+/* Return the status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/dtdb.c b/cextern/erfa/dtdb.c
new file mode 100644
index 0000000..9f387e9
--- /dev/null
+++ b/cextern/erfa/dtdb.c
@@ -0,0 +1,1222 @@
+#include "erfa.h"
+
+double eraDtdb(double date1, double date2,
+               double ut, double elong, double u, double v)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, tsol, w, elsun, emsun, d, elj, els, wt, w0, w1, w2, w3, w4,
+          wf, wj;
+   int j;
+
+/*
+** =====================
+** Fairhead et al. model
+** =====================
+**
+** 787 sets of three coefficients.
+**
+** Each set is
+**    amplitude (microseconds)
+**      frequency (radians per Julian millennium since J2000.0)
+**      phase (radians)
+**
+** Sets   1-474 are the T**0 terms
+**  "   475-679  "   "  T**1
+**  "   680-764  "   "  T**2
+**  "   765-784  "   "  T**3
+**  "   785-787  "   "  T**4
+*/
+
+   static const double fairhd[787][3] = {
+   /* 1, 10 */
+      { 1656.674564e-6,     6283.075849991,  6.240054195 },
+      {   22.417471e-6,     5753.384884897,  4.296977442 },
+      {   13.839792e-6,    12566.151699983,  6.196904410 },
+      {    4.770086e-6,      529.690965095,  0.444401603 },
+      {    4.676740e-6,     6069.776754553,  4.021195093 },
+      {    2.256707e-6,      213.299095438,  5.543113262 },
+      {    1.694205e-6,      -3.523118349,   5.025132748 },
+      {    1.554905e-6,    77713.771467920,  5.198467090 },
+      {    1.276839e-6,     7860.419392439,  5.988822341 },
+      {    1.193379e-6,     5223.693919802,  3.649823730 },
+   /* 11, 20 */
+      {    1.115322e-6,     3930.209696220,  1.422745069 },
+      {    0.794185e-6,    11506.769769794,  2.322313077 },
+      {    0.447061e-6,       26.298319800,  3.615796498 },
+      {    0.435206e-6,     -398.149003408,  4.349338347 },
+      {    0.600309e-6,     1577.343542448,  2.678271909 },
+      {    0.496817e-6,     6208.294251424,  5.696701824 },
+      {    0.486306e-6,     5884.926846583,  0.520007179 },
+      {    0.432392e-6,       74.781598567,  2.435898309 },
+      {    0.468597e-6,     6244.942814354,  5.866398759 },
+      {    0.375510e-6,     5507.553238667,  4.103476804 },
+   /* 21, 30 */
+      {    0.243085e-6,     -775.522611324,  3.651837925 },
+      {    0.173435e-6,    18849.227549974,  6.153743485 },
+      {    0.230685e-6,     5856.477659115,  4.773852582 },
+      {    0.203747e-6,    12036.460734888,  4.333987818 },
+      {    0.143935e-6,     -796.298006816,  5.957517795 },
+      {    0.159080e-6,    10977.078804699,  1.890075226 },
+      {    0.119979e-6,       38.133035638,  4.551585768 },
+      {    0.118971e-6,     5486.777843175,  1.914547226 },
+      {    0.116120e-6,     1059.381930189,  0.873504123 },
+      {    0.137927e-6,    11790.629088659,  1.135934669 },
+   /* 31, 40 */
+      {    0.098358e-6,     2544.314419883,  0.092793886 },
+      {    0.101868e-6,    -5573.142801634,  5.984503847 },
+      {    0.080164e-6,      206.185548437,  2.095377709 },
+      {    0.079645e-6,     4694.002954708,  2.949233637 },
+      {    0.062617e-6,       20.775395492,  2.654394814 },
+      {    0.075019e-6,     2942.463423292,  4.980931759 },
+      {    0.064397e-6,     5746.271337896,  1.280308748 },
+      {    0.063814e-6,     5760.498431898,  4.167901731 },
+      {    0.048042e-6,     2146.165416475,  1.495846011 },
+      {    0.048373e-6,      155.420399434,  2.251573730 },
+   /* 41, 50 */
+      {    0.058844e-6,      426.598190876,  4.839650148 },
+      {    0.046551e-6,       -0.980321068,  0.921573539 },
+      {    0.054139e-6,    17260.154654690,  3.411091093 },
+      {    0.042411e-6,     6275.962302991,  2.869567043 },
+      {    0.040184e-6,       -7.113547001,  3.565975565 },
+      {    0.036564e-6,     5088.628839767,  3.324679049 },
+      {    0.040759e-6,    12352.852604545,  3.981496998 },
+      {    0.036507e-6,      801.820931124,  6.248866009 },
+      {    0.036955e-6,     3154.687084896,  5.071801441 },
+      {    0.042732e-6,      632.783739313,  5.720622217 },
+   /* 51, 60 */
+      {    0.042560e-6,   161000.685737473,  1.270837679 },
+      {    0.040480e-6,    15720.838784878,  2.546610123 },
+      {    0.028244e-6,    -6286.598968340,  5.069663519 },
+      {    0.033477e-6,     6062.663207553,  4.144987272 },
+      {    0.034867e-6,      522.577418094,  5.210064075 },
+      {    0.032438e-6,     6076.890301554,  0.749317412 },
+      {    0.030215e-6,     7084.896781115,  3.389610345 },
+      {    0.029247e-6,   -71430.695617928,  4.183178762 },
+      {    0.033529e-6,     9437.762934887,  2.404714239 },
+      {    0.032423e-6,     8827.390269875,  5.541473556 },
+   /* 61, 70 */
+      {    0.027567e-6,     6279.552731642,  5.040846034 },
+      {    0.029862e-6,    12139.553509107,  1.770181024 },
+      {    0.022509e-6,    10447.387839604,  1.460726241 },
+      {    0.020937e-6,     8429.241266467,  0.652303414 },
+      {    0.020322e-6,      419.484643875,  3.735430632 },
+      {    0.024816e-6,    -1194.447010225,  1.087136918 },
+      {    0.025196e-6,     1748.016413067,  2.901883301 },
+      {    0.021691e-6,    14143.495242431,  5.952658009 },
+      {    0.017673e-6,     6812.766815086,  3.186129845 },
+      {    0.022567e-6,     6133.512652857,  3.307984806 },
+   /* 71, 80 */
+      {    0.016155e-6,    10213.285546211,  1.331103168 },
+      {    0.014751e-6,     1349.867409659,  4.308933301 },
+      {    0.015949e-6,     -220.412642439,  4.005298270 },
+      {    0.015974e-6,    -2352.866153772,  6.145309371 },
+      {    0.014223e-6,    17789.845619785,  2.104551349 },
+      {    0.017806e-6,       73.297125859,  3.475975097 },
+      {    0.013671e-6,     -536.804512095,  5.971672571 },
+      {    0.011942e-6,     8031.092263058,  2.053414715 },
+      {    0.014318e-6,    16730.463689596,  3.016058075 },
+      {    0.012462e-6,      103.092774219,  1.737438797 },
+   /* 81, 90 */
+      {    0.010962e-6,        3.590428652,  2.196567739 },
+      {    0.015078e-6,    19651.048481098,  3.969480770 },
+      {    0.010396e-6,      951.718406251,  5.717799605 },
+      {    0.011707e-6,    -4705.732307544,  2.654125618 },
+      {    0.010453e-6,     5863.591206116,  1.913704550 },
+      {    0.012420e-6,     4690.479836359,  4.734090399 },
+      {    0.011847e-6,     5643.178563677,  5.489005403 },
+      {    0.008610e-6,     3340.612426700,  3.661698944 },
+      {    0.011622e-6,     5120.601145584,  4.863931876 },
+      {    0.010825e-6,      553.569402842,  0.842715011 },
+   /* 91, 100 */
+      {    0.008666e-6,     -135.065080035,  3.293406547 },
+      {    0.009963e-6,      149.563197135,  4.870690598 },
+      {    0.009858e-6,     6309.374169791,  1.061816410 },
+      {    0.007959e-6,      316.391869657,  2.465042647 },
+      {    0.010099e-6,      283.859318865,  1.942176992 },
+      {    0.007147e-6,     -242.728603974,  3.661486981 },
+      {    0.007505e-6,     5230.807466803,  4.920937029 },
+      {    0.008323e-6,    11769.853693166,  1.229392026 },
+      {    0.007490e-6,    -6256.777530192,  3.658444681 },
+      {    0.009370e-6,   149854.400134205,  0.673880395 },
+   /* 101, 110 */
+      {    0.007117e-6,       38.027672636,  5.294249518 },
+      {    0.007857e-6,    12168.002696575,  0.525733528 },
+      {    0.007019e-6,     6206.809778716,  0.837688810 },
+      {    0.006056e-6,      955.599741609,  4.194535082 },
+      {    0.008107e-6,    13367.972631107,  3.793235253 },
+      {    0.006731e-6,     5650.292110678,  5.639906583 },
+      {    0.007332e-6,       36.648562930,  0.114858677 },
+      {    0.006366e-6,     4164.311989613,  2.262081818 },
+      {    0.006858e-6,     5216.580372801,  0.642063318 },
+      {    0.006919e-6,     6681.224853400,  6.018501522 },
+   /* 111, 120 */
+      {    0.006826e-6,     7632.943259650,  3.458654112 },
+      {    0.005308e-6,    -1592.596013633,  2.500382359 },
+      {    0.005096e-6,    11371.704689758,  2.547107806 },
+      {    0.004841e-6,     5333.900241022,  0.437078094 },
+      {    0.005582e-6,     5966.683980335,  2.246174308 },
+      {    0.006304e-6,    11926.254413669,  2.512929171 },
+      {    0.006603e-6,    23581.258177318,  5.393136889 },
+      {    0.005123e-6,       -1.484472708,  2.999641028 },
+      {    0.004648e-6,     1589.072895284,  1.275847090 },
+      {    0.005119e-6,     6438.496249426,  1.486539246 },
+   /* 121, 130 */
+      {    0.004521e-6,     4292.330832950,  6.140635794 },
+      {    0.005680e-6,    23013.539539587,  4.557814849 },
+      {    0.005488e-6,       -3.455808046,  0.090675389 },
+      {    0.004193e-6,     7234.794256242,  4.869091389 },
+      {    0.003742e-6,     7238.675591600,  4.691976180 },
+      {    0.004148e-6,     -110.206321219,  3.016173439 },
+      {    0.004553e-6,    11499.656222793,  5.554998314 },
+      {    0.004892e-6,     5436.993015240,  1.475415597 },
+      {    0.004044e-6,     4732.030627343,  1.398784824 },
+      {    0.004164e-6,    12491.370101415,  5.650931916 },
+   /* 131, 140 */
+      {    0.004349e-6,    11513.883316794,  2.181745369 },
+      {    0.003919e-6,    12528.018664345,  5.823319737 },
+      {    0.003129e-6,     6836.645252834,  0.003844094 },
+      {    0.004080e-6,    -7058.598461315,  3.690360123 },
+      {    0.003270e-6,       76.266071276,  1.517189902 },
+      {    0.002954e-6,     6283.143160294,  4.447203799 },
+      {    0.002872e-6,       28.449187468,  1.158692983 },
+      {    0.002881e-6,      735.876513532,  0.349250250 },
+      {    0.003279e-6,     5849.364112115,  4.893384368 },
+      {    0.003625e-6,     6209.778724132,  1.473760578 },
+   /* 141, 150 */
+      {    0.003074e-6,      949.175608970,  5.185878737 },
+      {    0.002775e-6,     9917.696874510,  1.030026325 },
+      {    0.002646e-6,    10973.555686350,  3.918259169 },
+      {    0.002575e-6,    25132.303399966,  6.109659023 },
+      {    0.003500e-6,      263.083923373,  1.892100742 },
+      {    0.002740e-6,    18319.536584880,  4.320519510 },
+      {    0.002464e-6,      202.253395174,  4.698203059 },
+      {    0.002409e-6,        2.542797281,  5.325009315 },
+      {    0.003354e-6,   -90955.551694697,  1.942656623 },
+      {    0.002296e-6,     6496.374945429,  5.061810696 },
+   /* 151, 160 */
+      {    0.003002e-6,     6172.869528772,  2.797822767 },
+      {    0.003202e-6,    27511.467873537,  0.531673101 },
+      {    0.002954e-6,    -6283.008539689,  4.533471191 },
+      {    0.002353e-6,      639.897286314,  3.734548088 },
+      {    0.002401e-6,    16200.772724501,  2.605547070 },
+      {    0.003053e-6,   233141.314403759,  3.029030662 },
+      {    0.003024e-6,    83286.914269554,  2.355556099 },
+      {    0.002863e-6,    17298.182327326,  5.240963796 },
+      {    0.002103e-6,    -7079.373856808,  5.756641637 },
+      {    0.002303e-6,    83996.847317911,  2.013686814 },
+   /* 161, 170 */
+      {    0.002303e-6,    18073.704938650,  1.089100410 },
+      {    0.002381e-6,       63.735898303,  0.759188178 },
+      {    0.002493e-6,     6386.168624210,  0.645026535 },
+      {    0.002366e-6,        3.932153263,  6.215885448 },
+      {    0.002169e-6,    11015.106477335,  4.845297676 },
+      {    0.002397e-6,     6243.458341645,  3.809290043 },
+      {    0.002183e-6,     1162.474704408,  6.179611691 },
+      {    0.002353e-6,     6246.427287062,  4.781719760 },
+      {    0.002199e-6,     -245.831646229,  5.956152284 },
+      {    0.001729e-6,     3894.181829542,  1.264976635 },
+   /* 171, 180 */
+      {    0.001896e-6,    -3128.388765096,  4.914231596 },
+      {    0.002085e-6,       35.164090221,  1.405158503 },
+      {    0.002024e-6,    14712.317116458,  2.752035928 },
+      {    0.001737e-6,     6290.189396992,  5.280820144 },
+      {    0.002229e-6,      491.557929457,  1.571007057 },
+      {    0.001602e-6,    14314.168113050,  4.203664806 },
+      {    0.002186e-6,      454.909366527,  1.402101526 },
+      {    0.001897e-6,    22483.848574493,  4.167932508 },
+      {    0.001825e-6,    -3738.761430108,  0.545828785 },
+      {    0.001894e-6,     1052.268383188,  5.817167450 },
+   /* 181, 190 */
+      {    0.001421e-6,       20.355319399,  2.419886601 },
+      {    0.001408e-6,    10984.192351700,  2.732084787 },
+      {    0.001847e-6,    10873.986030480,  2.903477885 },
+      {    0.001391e-6,    -8635.942003763,  0.593891500 },
+      {    0.001388e-6,       -7.046236698,  1.166145902 },
+      {    0.001810e-6,   -88860.057071188,  0.487355242 },
+      {    0.001288e-6,    -1990.745017041,  3.913022880 },
+      {    0.001297e-6,    23543.230504682,  3.063805171 },
+      {    0.001335e-6,     -266.607041722,  3.995764039 },
+      {    0.001376e-6,    10969.965257698,  5.152914309 },
+   /* 191, 200 */
+      {    0.001745e-6,   244287.600007027,  3.626395673 },
+      {    0.001649e-6,    31441.677569757,  1.952049260 },
+      {    0.001416e-6,     9225.539273283,  4.996408389 },
+      {    0.001238e-6,     4804.209275927,  5.503379738 },
+      {    0.001472e-6,     4590.910180489,  4.164913291 },
+      {    0.001169e-6,     6040.347246017,  5.841719038 },
+      {    0.001039e-6,     5540.085789459,  2.769753519 },
+      {    0.001004e-6,     -170.672870619,  0.755008103 },
+      {    0.001284e-6,    10575.406682942,  5.306538209 },
+      {    0.001278e-6,       71.812653151,  4.713486491 },
+   /* 201, 210 */
+      {    0.001321e-6,    18209.330263660,  2.624866359 },
+      {    0.001297e-6,    21228.392023546,  0.382603541 },
+      {    0.000954e-6,     6282.095528923,  0.882213514 },
+      {    0.001145e-6,     6058.731054289,  1.169483931 },
+      {    0.000979e-6,     5547.199336460,  5.448375984 },
+      {    0.000987e-6,    -6262.300454499,  2.656486959 },
+      {    0.001070e-6,  -154717.609887482,  1.827624012 },
+      {    0.000991e-6,     4701.116501708,  4.387001801 },
+      {    0.001155e-6,      -14.227094002,  3.042700750 },
+      {    0.001176e-6,      277.034993741,  3.335519004 },
+   /* 211, 220 */
+      {    0.000890e-6,    13916.019109642,  5.601498297 },
+      {    0.000884e-6,    -1551.045222648,  1.088831705 },
+      {    0.000876e-6,     5017.508371365,  3.969902609 },
+      {    0.000806e-6,    15110.466119866,  5.142876744 },
+      {    0.000773e-6,    -4136.910433516,  0.022067765 },
+      {    0.001077e-6,      175.166059800,  1.844913056 },
+      {    0.000954e-6,    -6284.056171060,  0.968480906 },
+      {    0.000737e-6,     5326.786694021,  4.923831588 },
+      {    0.000845e-6,     -433.711737877,  4.749245231 },
+      {    0.000819e-6,     8662.240323563,  5.991247817 },
+   /* 221, 230 */
+      {    0.000852e-6,      199.072001436,  2.189604979 },
+      {    0.000723e-6,    17256.631536341,  6.068719637 },
+      {    0.000940e-6,     6037.244203762,  6.197428148 },
+      {    0.000885e-6,    11712.955318231,  3.280414875 },
+      {    0.000706e-6,    12559.038152982,  2.824848947 },
+      {    0.000732e-6,     2379.164473572,  2.501813417 },
+      {    0.000764e-6,    -6127.655450557,  2.236346329 },
+      {    0.000908e-6,      131.541961686,  2.521257490 },
+      {    0.000907e-6,    35371.887265976,  3.370195967 },
+      {    0.000673e-6,     1066.495477190,  3.876512374 },
+   /* 231, 240 */
+      {    0.000814e-6,    17654.780539750,  4.627122566 },
+      {    0.000630e-6,       36.027866677,  0.156368499 },
+      {    0.000798e-6,      515.463871093,  5.151962502 },
+      {    0.000798e-6,      148.078724426,  5.909225055 },
+      {    0.000806e-6,      309.278322656,  6.054064447 },
+      {    0.000607e-6,      -39.617508346,  2.839021623 },
+      {    0.000601e-6,      412.371096874,  3.984225404 },
+      {    0.000646e-6,    11403.676995575,  3.852959484 },
+      {    0.000704e-6,    13521.751441591,  2.300991267 },
+      {    0.000603e-6,   -65147.619767937,  4.140083146 },
+   /* 241, 250 */
+      {    0.000609e-6,    10177.257679534,  0.437122327 },
+      {    0.000631e-6,     5767.611978898,  4.026532329 },
+      {    0.000576e-6,    11087.285125918,  4.760293101 },
+      {    0.000674e-6,    14945.316173554,  6.270510511 },
+      {    0.000726e-6,     5429.879468239,  6.039606892 },
+      {    0.000710e-6,    28766.924424484,  5.672617711 },
+      {    0.000647e-6,    11856.218651625,  3.397132627 },
+      {    0.000678e-6,    -5481.254918868,  6.249666675 },
+      {    0.000618e-6,    22003.914634870,  2.466427018 },
+      {    0.000738e-6,     6134.997125565,  2.242668890 },
+   /* 251, 260 */
+      {    0.000660e-6,      625.670192312,  5.864091907 },
+      {    0.000694e-6,     3496.032826134,  2.668309141 },
+      {    0.000531e-6,     6489.261398429,  1.681888780 },
+      {    0.000611e-6,  -143571.324284214,  2.424978312 },
+      {    0.000575e-6,    12043.574281889,  4.216492400 },
+      {    0.000553e-6,    12416.588502848,  4.772158039 },
+      {    0.000689e-6,     4686.889407707,  6.224271088 },
+      {    0.000495e-6,     7342.457780181,  3.817285811 },
+      {    0.000567e-6,     3634.621024518,  1.649264690 },
+      {    0.000515e-6,    18635.928454536,  3.945345892 },
+   /* 261, 270 */
+      {    0.000486e-6,     -323.505416657,  4.061673868 },
+      {    0.000662e-6,    25158.601719765,  1.794058369 },
+      {    0.000509e-6,      846.082834751,  3.053874588 },
+      {    0.000472e-6,   -12569.674818332,  5.112133338 },
+      {    0.000461e-6,     6179.983075773,  0.513669325 },
+      {    0.000641e-6,    83467.156352816,  3.210727723 },
+      {    0.000520e-6,    10344.295065386,  2.445597761 },
+      {    0.000493e-6,    18422.629359098,  1.676939306 },
+      {    0.000478e-6,     1265.567478626,  5.487314569 },
+      {    0.000472e-6,      -18.159247265,  1.999707589 },
+   /* 271, 280 */
+      {    0.000559e-6,    11190.377900137,  5.783236356 },
+      {    0.000494e-6,     9623.688276691,  3.022645053 },
+      {    0.000463e-6,     5739.157790895,  1.411223013 },
+      {    0.000432e-6,    16858.482532933,  1.179256434 },
+      {    0.000574e-6,    72140.628666286,  1.758191830 },
+      {    0.000484e-6,    17267.268201691,  3.290589143 },
+      {    0.000550e-6,     4907.302050146,  0.864024298 },
+      {    0.000399e-6,       14.977853527,  2.094441910 },
+      {    0.000491e-6,      224.344795702,  0.878372791 },
+      {    0.000432e-6,    20426.571092422,  6.003829241 },
+   /* 281, 290 */
+      {    0.000481e-6,     5749.452731634,  4.309591964 },
+      {    0.000480e-6,     5757.317038160,  1.142348571 },
+      {    0.000485e-6,     6702.560493867,  0.210580917 },
+      {    0.000426e-6,     6055.549660552,  4.274476529 },
+      {    0.000480e-6,     5959.570433334,  5.031351030 },
+      {    0.000466e-6,    12562.628581634,  4.959581597 },
+      {    0.000520e-6,    39302.096962196,  4.788002889 },
+      {    0.000458e-6,    12132.439962106,  1.880103788 },
+      {    0.000470e-6,    12029.347187887,  1.405611197 },
+      {    0.000416e-6,    -7477.522860216,  1.082356330 },
+   /* 291, 300 */
+      {    0.000449e-6,    11609.862544012,  4.179989585 },
+      {    0.000465e-6,    17253.041107690,  0.353496295 },
+      {    0.000362e-6,    -4535.059436924,  1.583849576 },
+      {    0.000383e-6,    21954.157609398,  3.747376371 },
+      {    0.000389e-6,       17.252277143,  1.395753179 },
+      {    0.000331e-6,    18052.929543158,  0.566790582 },
+      {    0.000430e-6,    13517.870106233,  0.685827538 },
+      {    0.000368e-6,    -5756.908003246,  0.731374317 },
+      {    0.000330e-6,    10557.594160824,  3.710043680 },
+      {    0.000332e-6,    20199.094959633,  1.652901407 },
+   /* 301, 310 */
+      {    0.000384e-6,    11933.367960670,  5.827781531 },
+      {    0.000387e-6,    10454.501386605,  2.541182564 },
+      {    0.000325e-6,    15671.081759407,  2.178850542 },
+      {    0.000318e-6,      138.517496871,  2.253253037 },
+      {    0.000305e-6,     9388.005909415,  0.578340206 },
+      {    0.000352e-6,     5749.861766548,  3.000297967 },
+      {    0.000311e-6,     6915.859589305,  1.693574249 },
+      {    0.000297e-6,    24072.921469776,  1.997249392 },
+      {    0.000363e-6,     -640.877607382,  5.071820966 },
+      {    0.000323e-6,    12592.450019783,  1.072262823 },
+   /* 311, 320 */
+      {    0.000341e-6,    12146.667056108,  4.700657997 },
+      {    0.000290e-6,     9779.108676125,  1.812320441 },
+      {    0.000342e-6,     6132.028180148,  4.322238614 },
+      {    0.000329e-6,     6268.848755990,  3.033827743 },
+      {    0.000374e-6,    17996.031168222,  3.388716544 },
+      {    0.000285e-6,     -533.214083444,  4.687313233 },
+      {    0.000338e-6,     6065.844601290,  0.877776108 },
+      {    0.000276e-6,       24.298513841,  0.770299429 },
+      {    0.000336e-6,    -2388.894020449,  5.353796034 },
+      {    0.000290e-6,     3097.883822726,  4.075291557 },
+   /* 321, 330 */
+      {    0.000318e-6,      709.933048357,  5.941207518 },
+      {    0.000271e-6,    13095.842665077,  3.208912203 },
+      {    0.000331e-6,     6073.708907816,  4.007881169 },
+      {    0.000292e-6,      742.990060533,  2.714333592 },
+      {    0.000362e-6,    29088.811415985,  3.215977013 },
+      {    0.000280e-6,    12359.966151546,  0.710872502 },
+      {    0.000267e-6,    10440.274292604,  4.730108488 },
+      {    0.000262e-6,      838.969287750,  1.327720272 },
+      {    0.000250e-6,    16496.361396202,  0.898769761 },
+      {    0.000325e-6,    20597.243963041,  0.180044365 },
+   /* 331, 340 */
+      {    0.000268e-6,     6148.010769956,  5.152666276 },
+      {    0.000284e-6,     5636.065016677,  5.655385808 },
+      {    0.000301e-6,     6080.822454817,  2.135396205 },
+      {    0.000294e-6,     -377.373607916,  3.708784168 },
+      {    0.000236e-6,     2118.763860378,  1.733578756 },
+      {    0.000234e-6,     5867.523359379,  5.575209112 },
+      {    0.000268e-6,  -226858.238553767,  0.069432392 },
+      {    0.000265e-6,   167283.761587465,  4.369302826 },
+      {    0.000280e-6,    28237.233459389,  5.304829118 },
+      {    0.000292e-6,    12345.739057544,  4.096094132 },
+   /* 341, 350 */
+      {    0.000223e-6,    19800.945956225,  3.069327406 },
+      {    0.000301e-6,    43232.306658416,  6.205311188 },
+      {    0.000264e-6,    18875.525869774,  1.417263408 },
+      {    0.000304e-6,    -1823.175188677,  3.409035232 },
+      {    0.000301e-6,      109.945688789,  0.510922054 },
+      {    0.000260e-6,      813.550283960,  2.389438934 },
+      {    0.000299e-6,   316428.228673312,  5.384595078 },
+      {    0.000211e-6,     5756.566278634,  3.789392838 },
+      {    0.000209e-6,     5750.203491159,  1.661943545 },
+      {    0.000240e-6,    12489.885628707,  5.684549045 },
+   /* 351, 360 */
+      {    0.000216e-6,     6303.851245484,  3.862942261 },
+      {    0.000203e-6,     1581.959348283,  5.549853589 },
+      {    0.000200e-6,     5642.198242609,  1.016115785 },
+      {    0.000197e-6,      -70.849445304,  4.690702525 },
+      {    0.000227e-6,     6287.008003254,  2.911891613 },
+      {    0.000197e-6,      533.623118358,  1.048982898 },
+      {    0.000205e-6,    -6279.485421340,  1.829362730 },
+      {    0.000209e-6,   -10988.808157535,  2.636140084 },
+      {    0.000208e-6,     -227.526189440,  4.127883842 },
+      {    0.000191e-6,      415.552490612,  4.401165650 },
+   /* 361, 370 */
+      {    0.000190e-6,    29296.615389579,  4.175658539 },
+      {    0.000264e-6,    66567.485864652,  4.601102551 },
+      {    0.000256e-6,    -3646.350377354,  0.506364778 },
+      {    0.000188e-6,    13119.721102825,  2.032195842 },
+      {    0.000185e-6,     -209.366942175,  4.694756586 },
+      {    0.000198e-6,    25934.124331089,  3.832703118 },
+      {    0.000195e-6,     4061.219215394,  3.308463427 },
+      {    0.000234e-6,     5113.487598583,  1.716090661 },
+      {    0.000188e-6,     1478.866574064,  5.686865780 },
+      {    0.000222e-6,    11823.161639450,  1.942386641 },
+   /* 371, 380 */
+      {    0.000181e-6,    10770.893256262,  1.999482059 },
+      {    0.000171e-6,     6546.159773364,  1.182807992 },
+      {    0.000206e-6,       70.328180442,  5.934076062 },
+      {    0.000169e-6,    20995.392966449,  2.169080622 },
+      {    0.000191e-6,    10660.686935042,  5.405515999 },
+      {    0.000228e-6,    33019.021112205,  4.656985514 },
+      {    0.000184e-6,    -4933.208440333,  3.327476868 },
+      {    0.000220e-6,     -135.625325010,  1.765430262 },
+      {    0.000166e-6,    23141.558382925,  3.454132746 },
+      {    0.000191e-6,     6144.558353121,  5.020393445 },
+   /* 381, 390 */
+      {    0.000180e-6,     6084.003848555,  0.602182191 },
+      {    0.000163e-6,    17782.732072784,  4.960593133 },
+      {    0.000225e-6,    16460.333529525,  2.596451817 },
+      {    0.000222e-6,     5905.702242076,  3.731990323 },
+      {    0.000204e-6,      227.476132789,  5.636192701 },
+      {    0.000159e-6,    16737.577236597,  3.600691544 },
+      {    0.000200e-6,     6805.653268085,  0.868220961 },
+      {    0.000187e-6,    11919.140866668,  2.629456641 },
+      {    0.000161e-6,      127.471796607,  2.862574720 },
+      {    0.000205e-6,     6286.666278643,  1.742882331 },
+   /* 391, 400 */
+      {    0.000189e-6,      153.778810485,  4.812372643 },
+      {    0.000168e-6,    16723.350142595,  0.027860588 },
+      {    0.000149e-6,    11720.068865232,  0.659721876 },
+      {    0.000189e-6,     5237.921013804,  5.245313000 },
+      {    0.000143e-6,     6709.674040867,  4.317625647 },
+      {    0.000146e-6,     4487.817406270,  4.815297007 },
+      {    0.000144e-6,     -664.756045130,  5.381366880 },
+      {    0.000175e-6,     5127.714692584,  4.728443327 },
+      {    0.000162e-6,     6254.626662524,  1.435132069 },
+      {    0.000187e-6,    47162.516354635,  1.354371923 },
+   /* 401, 410 */
+      {    0.000146e-6,    11080.171578918,  3.369695406 },
+      {    0.000180e-6,     -348.924420448,  2.490902145 },
+      {    0.000148e-6,      151.047669843,  3.799109588 },
+      {    0.000157e-6,     6197.248551160,  1.284375887 },
+      {    0.000167e-6,      146.594251718,  0.759969109 },
+      {    0.000133e-6,    -5331.357443741,  5.409701889 },
+      {    0.000154e-6,       95.979227218,  3.366890614 },
+      {    0.000148e-6,    -6418.140930027,  3.384104996 },
+      {    0.000128e-6,    -6525.804453965,  3.803419985 },
+      {    0.000130e-6,    11293.470674356,  0.939039445 },
+   /* 411, 420 */
+      {    0.000152e-6,    -5729.506447149,  0.734117523 },
+      {    0.000138e-6,      210.117701700,  2.564216078 },
+      {    0.000123e-6,     6066.595360816,  4.517099537 },
+      {    0.000140e-6,    18451.078546566,  0.642049130 },
+      {    0.000126e-6,    11300.584221356,  3.485280663 },
+      {    0.000119e-6,    10027.903195729,  3.217431161 },
+      {    0.000151e-6,     4274.518310832,  4.404359108 },
+      {    0.000117e-6,     6072.958148291,  0.366324650 },
+      {    0.000165e-6,    -7668.637425143,  4.298212528 },
+      {    0.000117e-6,    -6245.048177356,  5.379518958 },
+   /* 421, 430 */
+      {    0.000130e-6,    -5888.449964932,  4.527681115 },
+      {    0.000121e-6,     -543.918059096,  6.109429504 },
+      {    0.000162e-6,     9683.594581116,  5.720092446 },
+      {    0.000141e-6,     6219.339951688,  0.679068671 },
+      {    0.000118e-6,    22743.409379516,  4.881123092 },
+      {    0.000129e-6,     1692.165669502,  0.351407289 },
+      {    0.000126e-6,     5657.405657679,  5.146592349 },
+      {    0.000114e-6,      728.762966531,  0.520791814 },
+      {    0.000120e-6,       52.596639600,  0.948516300 },
+      {    0.000115e-6,       65.220371012,  3.504914846 },
+   /* 431, 440 */
+      {    0.000126e-6,     5881.403728234,  5.577502482 },
+      {    0.000158e-6,   163096.180360983,  2.957128968 },
+      {    0.000134e-6,    12341.806904281,  2.598576764 },
+      {    0.000151e-6,    16627.370915377,  3.985702050 },
+      {    0.000109e-6,     1368.660252845,  0.014730471 },
+      {    0.000131e-6,     6211.263196841,  0.085077024 },
+      {    0.000146e-6,     5792.741760812,  0.708426604 },
+      {    0.000146e-6,      -77.750543984,  3.121576600 },
+      {    0.000107e-6,     5341.013788022,  0.288231904 },
+      {    0.000138e-6,     6281.591377283,  2.797450317 },
+   /* 441, 450 */
+      {    0.000113e-6,    -6277.552925684,  2.788904128 },
+      {    0.000115e-6,     -525.758811831,  5.895222200 },
+      {    0.000138e-6,     6016.468808270,  6.096188999 },
+      {    0.000139e-6,    23539.707386333,  2.028195445 },
+      {    0.000146e-6,    -4176.041342449,  4.660008502 },
+      {    0.000107e-6,    16062.184526117,  4.066520001 },
+      {    0.000142e-6,    83783.548222473,  2.936315115 },
+      {    0.000128e-6,     9380.959672717,  3.223844306 },
+      {    0.000135e-6,     6205.325306007,  1.638054048 },
+      {    0.000101e-6,     2699.734819318,  5.481603249 },
+   /* 451, 460 */
+      {    0.000104e-6,     -568.821874027,  2.205734493 },
+      {    0.000103e-6,     6321.103522627,  2.440421099 },
+      {    0.000119e-6,     6321.208885629,  2.547496264 },
+      {    0.000138e-6,     1975.492545856,  2.314608466 },
+      {    0.000121e-6,      137.033024162,  4.539108237 },
+      {    0.000123e-6,    19402.796952817,  4.538074405 },
+      {    0.000119e-6,    22805.735565994,  2.869040566 },
+      {    0.000133e-6,    64471.991241142,  6.056405489 },
+      {    0.000129e-6,      -85.827298831,  2.540635083 },
+      {    0.000131e-6,    13613.804277336,  4.005732868 },
+   /* 461, 470 */
+      {    0.000104e-6,     9814.604100291,  1.959967212 },
+      {    0.000112e-6,    16097.679950283,  3.589026260 },
+      {    0.000123e-6,     2107.034507542,  1.728627253 },
+      {    0.000121e-6,    36949.230808424,  6.072332087 },
+      {    0.000108e-6,   -12539.853380183,  3.716133846 },
+      {    0.000113e-6,    -7875.671863624,  2.725771122 },
+      {    0.000109e-6,     4171.425536614,  4.033338079 },
+      {    0.000101e-6,     6247.911759770,  3.441347021 },
+      {    0.000113e-6,     7330.728427345,  0.656372122 },
+      {    0.000113e-6,    51092.726050855,  2.791483066 },
+   /* 471, 480 */
+      {    0.000106e-6,     5621.842923210,  1.815323326 },
+      {    0.000101e-6,      111.430161497,  5.711033677 },
+      {    0.000103e-6,      909.818733055,  2.812745443 },
+      {    0.000101e-6,     1790.642637886,  1.965746028 },
+
+   /* T */
+      {  102.156724e-6,     6283.075849991,  4.249032005 },
+      {    1.706807e-6,    12566.151699983,  4.205904248 },
+      {    0.269668e-6,      213.299095438,  3.400290479 },
+      {    0.265919e-6,      529.690965095,  5.836047367 },
+      {    0.210568e-6,       -3.523118349,  6.262738348 },
+      {    0.077996e-6,     5223.693919802,  4.670344204 },
+   /* 481, 490 */
+      {    0.054764e-6,     1577.343542448,  4.534800170 },
+      {    0.059146e-6,       26.298319800,  1.083044735 },
+      {    0.034420e-6,     -398.149003408,  5.980077351 },
+      {    0.032088e-6,    18849.227549974,  4.162913471 },
+      {    0.033595e-6,     5507.553238667,  5.980162321 },
+      {    0.029198e-6,     5856.477659115,  0.623811863 },
+      {    0.027764e-6,      155.420399434,  3.745318113 },
+      {    0.025190e-6,     5746.271337896,  2.980330535 },
+      {    0.022997e-6,     -796.298006816,  1.174411803 },
+      {    0.024976e-6,     5760.498431898,  2.467913690 },
+   /* 491, 500 */
+      {    0.021774e-6,      206.185548437,  3.854787540 },
+      {    0.017925e-6,     -775.522611324,  1.092065955 },
+      {    0.013794e-6,      426.598190876,  2.699831988 },
+      {    0.013276e-6,     6062.663207553,  5.845801920 },
+      {    0.011774e-6,    12036.460734888,  2.292832062 },
+      {    0.012869e-6,     6076.890301554,  5.333425680 },
+      {    0.012152e-6,     1059.381930189,  6.222874454 },
+      {    0.011081e-6,       -7.113547001,  5.154724984 },
+      {    0.010143e-6,     4694.002954708,  4.044013795 },
+      {    0.009357e-6,     5486.777843175,  3.416081409 },
+   /* 501, 510 */
+      {    0.010084e-6,      522.577418094,  0.749320262 },
+      {    0.008587e-6,    10977.078804699,  2.777152598 },
+      {    0.008628e-6,     6275.962302991,  4.562060226 },
+      {    0.008158e-6,     -220.412642439,  5.806891533 },
+      {    0.007746e-6,     2544.314419883,  1.603197066 },
+      {    0.007670e-6,     2146.165416475,  3.000200440 },
+      {    0.007098e-6,       74.781598567,  0.443725817 },
+      {    0.006180e-6,     -536.804512095,  1.302642751 },
+      {    0.005818e-6,     5088.628839767,  4.827723531 },
+      {    0.004945e-6,    -6286.598968340,  0.268305170 },
+   /* 511, 520 */
+      {    0.004774e-6,     1349.867409659,  5.808636673 },
+      {    0.004687e-6,     -242.728603974,  5.154890570 },
+      {    0.006089e-6,     1748.016413067,  4.403765209 },
+      {    0.005975e-6,    -1194.447010225,  2.583472591 },
+      {    0.004229e-6,      951.718406251,  0.931172179 },
+      {    0.005264e-6,      553.569402842,  2.336107252 },
+      {    0.003049e-6,     5643.178563677,  1.362634430 },
+      {    0.002974e-6,     6812.766815086,  1.583012668 },
+      {    0.003403e-6,    -2352.866153772,  2.552189886 },
+      {    0.003030e-6,      419.484643875,  5.286473844 },
+   /* 521, 530 */
+      {    0.003210e-6,       -7.046236698,  1.863796539 },
+      {    0.003058e-6,     9437.762934887,  4.226420633 },
+      {    0.002589e-6,    12352.852604545,  1.991935820 },
+      {    0.002927e-6,     5216.580372801,  2.319951253 },
+      {    0.002425e-6,     5230.807466803,  3.084752833 },
+      {    0.002656e-6,     3154.687084896,  2.487447866 },
+      {    0.002445e-6,    10447.387839604,  2.347139160 },
+      {    0.002990e-6,     4690.479836359,  6.235872050 },
+      {    0.002890e-6,     5863.591206116,  0.095197563 },
+      {    0.002498e-6,     6438.496249426,  2.994779800 },
+   /* 531, 540 */
+      {    0.001889e-6,     8031.092263058,  3.569003717 },
+      {    0.002567e-6,      801.820931124,  3.425611498 },
+      {    0.001803e-6,   -71430.695617928,  2.192295512 },
+      {    0.001782e-6,        3.932153263,  5.180433689 },
+      {    0.001694e-6,    -4705.732307544,  4.641779174 },
+      {    0.001704e-6,    -1592.596013633,  3.997097652 },
+      {    0.001735e-6,     5849.364112115,  0.417558428 },
+      {    0.001643e-6,     8429.241266467,  2.180619584 },
+      {    0.001680e-6,       38.133035638,  4.164529426 },
+      {    0.002045e-6,     7084.896781115,  0.526323854 },
+   /* 541, 550 */
+      {    0.001458e-6,     4292.330832950,  1.356098141 },
+      {    0.001437e-6,       20.355319399,  3.895439360 },
+      {    0.001738e-6,     6279.552731642,  0.087484036 },
+      {    0.001367e-6,    14143.495242431,  3.987576591 },
+      {    0.001344e-6,     7234.794256242,  0.090454338 },
+      {    0.001438e-6,    11499.656222793,  0.974387904 },
+      {    0.001257e-6,     6836.645252834,  1.509069366 },
+      {    0.001358e-6,    11513.883316794,  0.495572260 },
+      {    0.001628e-6,     7632.943259650,  4.968445721 },
+      {    0.001169e-6,      103.092774219,  2.838496795 },
+   /* 551, 560 */
+      {    0.001162e-6,     4164.311989613,  3.408387778 },
+      {    0.001092e-6,     6069.776754553,  3.617942651 },
+      {    0.001008e-6,    17789.845619785,  0.286350174 },
+      {    0.001008e-6,      639.897286314,  1.610762073 },
+      {    0.000918e-6,    10213.285546211,  5.532798067 },
+      {    0.001011e-6,    -6256.777530192,  0.661826484 },
+      {    0.000753e-6,    16730.463689596,  3.905030235 },
+      {    0.000737e-6,    11926.254413669,  4.641956361 },
+      {    0.000694e-6,     3340.612426700,  2.111120332 },
+      {    0.000701e-6,     3894.181829542,  2.760823491 },
+   /* 561, 570 */
+      {    0.000689e-6,     -135.065080035,  4.768800780 },
+      {    0.000700e-6,    13367.972631107,  5.760439898 },
+      {    0.000664e-6,     6040.347246017,  1.051215840 },
+      {    0.000654e-6,     5650.292110678,  4.911332503 },
+      {    0.000788e-6,     6681.224853400,  4.699648011 },
+      {    0.000628e-6,     5333.900241022,  5.024608847 },
+      {    0.000755e-6,     -110.206321219,  4.370971253 },
+      {    0.000628e-6,     6290.189396992,  3.660478857 },
+      {    0.000635e-6,    25132.303399966,  4.121051532 },
+      {    0.000534e-6,     5966.683980335,  1.173284524 },
+   /* 571, 580 */
+      {    0.000543e-6,     -433.711737877,  0.345585464 },
+      {    0.000517e-6,    -1990.745017041,  5.414571768 },
+      {    0.000504e-6,     5767.611978898,  2.328281115 },
+      {    0.000485e-6,     5753.384884897,  1.685874771 },
+      {    0.000463e-6,     7860.419392439,  5.297703006 },
+      {    0.000604e-6,      515.463871093,  0.591998446 },
+      {    0.000443e-6,    12168.002696575,  4.830881244 },
+      {    0.000570e-6,      199.072001436,  3.899190272 },
+      {    0.000465e-6,    10969.965257698,  0.476681802 },
+      {    0.000424e-6,    -7079.373856808,  1.112242763 },
+   /* 581, 590 */
+      {    0.000427e-6,      735.876513532,  1.994214480 },
+      {    0.000478e-6,    -6127.655450557,  3.778025483 },
+      {    0.000414e-6,    10973.555686350,  5.441088327 },
+      {    0.000512e-6,     1589.072895284,  0.107123853 },
+      {    0.000378e-6,    10984.192351700,  0.915087231 },
+      {    0.000402e-6,    11371.704689758,  4.107281715 },
+      {    0.000453e-6,     9917.696874510,  1.917490952 },
+      {    0.000395e-6,      149.563197135,  2.763124165 },
+      {    0.000371e-6,     5739.157790895,  3.112111866 },
+      {    0.000350e-6,    11790.629088659,  0.440639857 },
+   /* 591, 600 */
+      {    0.000356e-6,     6133.512652857,  5.444568842 },
+      {    0.000344e-6,      412.371096874,  5.676832684 },
+      {    0.000383e-6,      955.599741609,  5.559734846 },
+      {    0.000333e-6,     6496.374945429,  0.261537984 },
+      {    0.000340e-6,     6055.549660552,  5.975534987 },
+      {    0.000334e-6,     1066.495477190,  2.335063907 },
+      {    0.000399e-6,    11506.769769794,  5.321230910 },
+      {    0.000314e-6,    18319.536584880,  2.313312404 },
+      {    0.000424e-6,     1052.268383188,  1.211961766 },
+      {    0.000307e-6,       63.735898303,  3.169551388 },
+   /* 601, 610 */
+      {    0.000329e-6,       29.821438149,  6.106912080 },
+      {    0.000357e-6,     6309.374169791,  4.223760346 },
+      {    0.000312e-6,    -3738.761430108,  2.180556645 },
+      {    0.000301e-6,      309.278322656,  1.499984572 },
+      {    0.000268e-6,    12043.574281889,  2.447520648 },
+      {    0.000257e-6,    12491.370101415,  3.662331761 },
+      {    0.000290e-6,      625.670192312,  1.272834584 },
+      {    0.000256e-6,     5429.879468239,  1.913426912 },
+      {    0.000339e-6,     3496.032826134,  4.165930011 },
+      {    0.000283e-6,     3930.209696220,  4.325565754 },
+   /* 611, 620 */
+      {    0.000241e-6,    12528.018664345,  3.832324536 },
+      {    0.000304e-6,     4686.889407707,  1.612348468 },
+      {    0.000259e-6,    16200.772724501,  3.470173146 },
+      {    0.000238e-6,    12139.553509107,  1.147977842 },
+      {    0.000236e-6,     6172.869528772,  3.776271728 },
+      {    0.000296e-6,    -7058.598461315,  0.460368852 },
+      {    0.000306e-6,    10575.406682942,  0.554749016 },
+      {    0.000251e-6,    17298.182327326,  0.834332510 },
+      {    0.000290e-6,     4732.030627343,  4.759564091 },
+      {    0.000261e-6,     5884.926846583,  0.298259862 },
+   /* 621, 630 */
+      {    0.000249e-6,     5547.199336460,  3.749366406 },
+      {    0.000213e-6,    11712.955318231,  5.415666119 },
+      {    0.000223e-6,     4701.116501708,  2.703203558 },
+      {    0.000268e-6,     -640.877607382,  0.283670793 },
+      {    0.000209e-6,     5636.065016677,  1.238477199 },
+      {    0.000193e-6,    10177.257679534,  1.943251340 },
+      {    0.000182e-6,     6283.143160294,  2.456157599 },
+      {    0.000184e-6,     -227.526189440,  5.888038582 },
+      {    0.000182e-6,    -6283.008539689,  0.241332086 },
+      {    0.000228e-6,    -6284.056171060,  2.657323816 },
+   /* 631, 640 */
+      {    0.000166e-6,     7238.675591600,  5.930629110 },
+      {    0.000167e-6,     3097.883822726,  5.570955333 },
+      {    0.000159e-6,     -323.505416657,  5.786670700 },
+      {    0.000154e-6,    -4136.910433516,  1.517805532 },
+      {    0.000176e-6,    12029.347187887,  3.139266834 },
+      {    0.000167e-6,    12132.439962106,  3.556352289 },
+      {    0.000153e-6,      202.253395174,  1.463313961 },
+      {    0.000157e-6,    17267.268201691,  1.586837396 },
+      {    0.000142e-6,    83996.847317911,  0.022670115 },
+      {    0.000152e-6,    17260.154654690,  0.708528947 },
+   /* 641, 650 */
+      {    0.000144e-6,     6084.003848555,  5.187075177 },
+      {    0.000135e-6,     5756.566278634,  1.993229262 },
+      {    0.000134e-6,     5750.203491159,  3.457197134 },
+      {    0.000144e-6,     5326.786694021,  6.066193291 },
+      {    0.000160e-6,    11015.106477335,  1.710431974 },
+      {    0.000133e-6,     3634.621024518,  2.836451652 },
+      {    0.000134e-6,    18073.704938650,  5.453106665 },
+      {    0.000134e-6,     1162.474704408,  5.326898811 },
+      {    0.000128e-6,     5642.198242609,  2.511652591 },
+      {    0.000160e-6,      632.783739313,  5.628785365 },
+   /* 651, 660 */
+      {    0.000132e-6,    13916.019109642,  0.819294053 },
+      {    0.000122e-6,    14314.168113050,  5.677408071 },
+      {    0.000125e-6,    12359.966151546,  5.251984735 },
+      {    0.000121e-6,     5749.452731634,  2.210924603 },
+      {    0.000136e-6,     -245.831646229,  1.646502367 },
+      {    0.000120e-6,     5757.317038160,  3.240883049 },
+      {    0.000134e-6,    12146.667056108,  3.059480037 },
+      {    0.000137e-6,     6206.809778716,  1.867105418 },
+      {    0.000141e-6,    17253.041107690,  2.069217456 },
+      {    0.000129e-6,    -7477.522860216,  2.781469314 },
+   /* 661, 670 */
+      {    0.000116e-6,     5540.085789459,  4.281176991 },
+      {    0.000116e-6,     9779.108676125,  3.320925381 },
+      {    0.000129e-6,     5237.921013804,  3.497704076 },
+      {    0.000113e-6,     5959.570433334,  0.983210840 },
+      {    0.000122e-6,     6282.095528923,  2.674938860 },
+      {    0.000140e-6,      -11.045700264,  4.957936982 },
+      {    0.000108e-6,    23543.230504682,  1.390113589 },
+      {    0.000106e-6,   -12569.674818332,  0.429631317 },
+      {    0.000110e-6,     -266.607041722,  5.501340197 },
+      {    0.000115e-6,    12559.038152982,  4.691456618 },
+   /* 671, 680 */
+      {    0.000134e-6,    -2388.894020449,  0.577313584 },
+      {    0.000109e-6,    10440.274292604,  6.218148717 },
+      {    0.000102e-6,     -543.918059096,  1.477842615 },
+      {    0.000108e-6,    21228.392023546,  2.237753948 },
+      {    0.000101e-6,    -4535.059436924,  3.100492232 },
+      {    0.000103e-6,       76.266071276,  5.594294322 },
+      {    0.000104e-6,      949.175608970,  5.674287810 },
+      {    0.000101e-6,    13517.870106233,  2.196632348 },
+      {    0.000100e-6,    11933.367960670,  4.056084160 },
+
+   /* T^2 */
+      {    4.322990e-6,     6283.075849991,  2.642893748 },
+   /* 681, 690 */
+      {    0.406495e-6,        0.000000000,  4.712388980 },
+      {    0.122605e-6,    12566.151699983,  2.438140634 },
+      {    0.019476e-6,      213.299095438,  1.642186981 },
+      {    0.016916e-6,      529.690965095,  4.510959344 },
+      {    0.013374e-6,       -3.523118349,  1.502210314 },
+      {    0.008042e-6,       26.298319800,  0.478549024 },
+      {    0.007824e-6,      155.420399434,  5.254710405 },
+      {    0.004894e-6,     5746.271337896,  4.683210850 },
+      {    0.004875e-6,     5760.498431898,  0.759507698 },
+      {    0.004416e-6,     5223.693919802,  6.028853166 },
+   /* 691, 700 */
+      {    0.004088e-6,       -7.113547001,  0.060926389 },
+      {    0.004433e-6,    77713.771467920,  3.627734103 },
+      {    0.003277e-6,    18849.227549974,  2.327912542 },
+      {    0.002703e-6,     6062.663207553,  1.271941729 },
+      {    0.003435e-6,     -775.522611324,  0.747446224 },
+      {    0.002618e-6,     6076.890301554,  3.633715689 },
+      {    0.003146e-6,      206.185548437,  5.647874613 },
+      {    0.002544e-6,     1577.343542448,  6.232904270 },
+      {    0.002218e-6,     -220.412642439,  1.309509946 },
+      {    0.002197e-6,     5856.477659115,  2.407212349 },
+   /* 701, 710 */
+      {    0.002897e-6,     5753.384884897,  5.863842246 },
+      {    0.001766e-6,      426.598190876,  0.754113147 },
+      {    0.001738e-6,     -796.298006816,  2.714942671 },
+      {    0.001695e-6,      522.577418094,  2.629369842 },
+      {    0.001584e-6,     5507.553238667,  1.341138229 },
+      {    0.001503e-6,     -242.728603974,  0.377699736 },
+      {    0.001552e-6,     -536.804512095,  2.904684667 },
+      {    0.001370e-6,     -398.149003408,  1.265599125 },
+      {    0.001889e-6,    -5573.142801634,  4.413514859 },
+      {    0.001722e-6,     6069.776754553,  2.445966339 },
+   /* 711, 720 */
+      {    0.001124e-6,     1059.381930189,  5.041799657 },
+      {    0.001258e-6,      553.569402842,  3.849557278 },
+      {    0.000831e-6,      951.718406251,  2.471094709 },
+      {    0.000767e-6,     4694.002954708,  5.363125422 },
+      {    0.000756e-6,     1349.867409659,  1.046195744 },
+      {    0.000775e-6,      -11.045700264,  0.245548001 },
+      {    0.000597e-6,     2146.165416475,  4.543268798 },
+      {    0.000568e-6,     5216.580372801,  4.178853144 },
+      {    0.000711e-6,     1748.016413067,  5.934271972 },
+      {    0.000499e-6,    12036.460734888,  0.624434410 },
+   /* 721, 730 */
+      {    0.000671e-6,    -1194.447010225,  4.136047594 },
+      {    0.000488e-6,     5849.364112115,  2.209679987 },
+      {    0.000621e-6,     6438.496249426,  4.518860804 },
+      {    0.000495e-6,    -6286.598968340,  1.868201275 },
+      {    0.000456e-6,     5230.807466803,  1.271231591 },
+      {    0.000451e-6,     5088.628839767,  0.084060889 },
+      {    0.000435e-6,     5643.178563677,  3.324456609 },
+      {    0.000387e-6,    10977.078804699,  4.052488477 },
+      {    0.000547e-6,   161000.685737473,  2.841633844 },
+      {    0.000522e-6,     3154.687084896,  2.171979966 },
+   /* 731, 740 */
+      {    0.000375e-6,     5486.777843175,  4.983027306 },
+      {    0.000421e-6,     5863.591206116,  4.546432249 },
+      {    0.000439e-6,     7084.896781115,  0.522967921 },
+      {    0.000309e-6,     2544.314419883,  3.172606705 },
+      {    0.000347e-6,     4690.479836359,  1.479586566 },
+      {    0.000317e-6,      801.820931124,  3.553088096 },
+      {    0.000262e-6,      419.484643875,  0.606635550 },
+      {    0.000248e-6,     6836.645252834,  3.014082064 },
+      {    0.000245e-6,    -1592.596013633,  5.519526220 },
+      {    0.000225e-6,     4292.330832950,  2.877956536 },
+   /* 741, 750 */
+      {    0.000214e-6,     7234.794256242,  1.605227587 },
+      {    0.000205e-6,     5767.611978898,  0.625804796 },
+      {    0.000180e-6,    10447.387839604,  3.499954526 },
+      {    0.000229e-6,      199.072001436,  5.632304604 },
+      {    0.000214e-6,      639.897286314,  5.960227667 },
+      {    0.000175e-6,     -433.711737877,  2.162417992 },
+      {    0.000209e-6,      515.463871093,  2.322150893 },
+      {    0.000173e-6,     6040.347246017,  2.556183691 },
+      {    0.000184e-6,     6309.374169791,  4.732296790 },
+      {    0.000227e-6,   149854.400134205,  5.385812217 },
+   /* 751, 760 */
+      {    0.000154e-6,     8031.092263058,  5.120720920 },
+      {    0.000151e-6,     5739.157790895,  4.815000443 },
+      {    0.000197e-6,     7632.943259650,  0.222827271 },
+      {    0.000197e-6,       74.781598567,  3.910456770 },
+      {    0.000138e-6,     6055.549660552,  1.397484253 },
+      {    0.000149e-6,    -6127.655450557,  5.333727496 },
+      {    0.000137e-6,     3894.181829542,  4.281749907 },
+      {    0.000135e-6,     9437.762934887,  5.979971885 },
+      {    0.000139e-6,    -2352.866153772,  4.715630782 },
+      {    0.000142e-6,     6812.766815086,  0.513330157 },
+   /* 761, 770 */
+      {    0.000120e-6,    -4705.732307544,  0.194160689 },
+      {    0.000131e-6,   -71430.695617928,  0.000379226 },
+      {    0.000124e-6,     6279.552731642,  2.122264908 },
+      {    0.000108e-6,    -6256.777530192,  0.883445696 },
+
+   /* T^3 */
+      {    0.143388e-6,     6283.075849991,  1.131453581 },
+      {    0.006671e-6,    12566.151699983,  0.775148887 },
+      {    0.001480e-6,      155.420399434,  0.480016880 },
+      {    0.000934e-6,      213.299095438,  6.144453084 },
+      {    0.000795e-6,      529.690965095,  2.941595619 },
+      {    0.000673e-6,     5746.271337896,  0.120415406 },
+   /* 771, 780 */
+      {    0.000672e-6,     5760.498431898,  5.317009738 },
+      {    0.000389e-6,     -220.412642439,  3.090323467 },
+      {    0.000373e-6,     6062.663207553,  3.003551964 },
+      {    0.000360e-6,     6076.890301554,  1.918913041 },
+      {    0.000316e-6,      -21.340641002,  5.545798121 },
+      {    0.000315e-6,     -242.728603974,  1.884932563 },
+      {    0.000278e-6,      206.185548437,  1.266254859 },
+      {    0.000238e-6,     -536.804512095,  4.532664830 },
+      {    0.000185e-6,      522.577418094,  4.578313856 },
+      {    0.000245e-6,    18849.227549974,  0.587467082 },
+   /* 781, 787 */
+      {    0.000180e-6,      426.598190876,  5.151178553 },
+      {    0.000200e-6,      553.569402842,  5.355983739 },
+      {    0.000141e-6,     5223.693919802,  1.336556009 },
+      {    0.000104e-6,     5856.477659115,  4.239842759 },
+
+   /* T^4 */
+      {    0.003826e-6,     6283.075849991,  5.705257275 },
+      {    0.000303e-6,    12566.151699983,  5.407132842 },
+      {    0.000209e-6,      155.420399434,  1.989815753 }
+   };
+
+
+/* Time since J2000.0 in Julian millennia. */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM;
+
+/* ================= */
+/* Topocentric terms */
+/* ================= */
+
+/* Convert UT to local solar time in radians. */
+   tsol = fmod(ut, 1.0) * ERFA_D2PI + elong;
+
+/* FUNDAMENTAL ARGUMENTS:  Simon et al. 1994. */
+
+/* Combine time argument (millennia) with deg/arcsec factor. */
+   w = t / 3600.0;
+
+/* Sun Mean Longitude. */
+   elsun = fmod(280.46645683 + 1296027711.03429 * w, 360.0) * ERFA_DD2R;
+
+/* Sun Mean Anomaly. */
+   emsun = fmod(357.52910918 + 1295965810.481 * w, 360.0) * ERFA_DD2R;
+
+/* Mean Elongation of Moon from Sun. */
+   d = fmod(297.85019547 + 16029616012.090 * w, 360.0) * ERFA_DD2R;
+
+/* Mean Longitude of Jupiter. */
+   elj = fmod(34.35151874 + 109306899.89453 * w, 360.0) * ERFA_DD2R;
+
+/* Mean Longitude of Saturn. */
+   els = fmod(50.07744430 + 44046398.47038 * w, 360.0) * ERFA_DD2R;
+
+/* TOPOCENTRIC TERMS:  Moyer 1981 and Murray 1983. */
+   wt =   +  0.00029e-10 * u * sin(tsol + elsun - els)
+          +  0.00100e-10 * u * sin(tsol - 2.0 * emsun)
+          +  0.00133e-10 * u * sin(tsol - d)
+          +  0.00133e-10 * u * sin(tsol + elsun - elj)
+          -  0.00229e-10 * u * sin(tsol + 2.0 * elsun + emsun)
+          -  0.02200e-10 * v * cos(elsun + emsun)
+          +  0.05312e-10 * u * sin(tsol - emsun)
+          -  0.13677e-10 * u * sin(tsol + 2.0 * elsun)
+          -  1.31840e-10 * v * cos(elsun)
+          +  3.17679e-10 * u * sin(tsol);
+
+/* ===================== */
+/* Fairhead et al. model */
+/* ===================== */
+
+/* T**0 */
+   w0 = 0;
+   for (j = 473; j >= 0; j--) {
+      w0 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
+   }
+
+/* T**1 */
+   w1 = 0;
+   for (j = 678; j >= 474; j--) {
+      w1 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
+   }
+
+/* T**2 */
+   w2 = 0;
+   for (j = 763; j >= 679; j--) {
+      w2 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
+   }
+
+/* T**3 */
+   w3 = 0;
+   for (j = 783; j >= 764; j--) {
+      w3 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
+   }
+
+/* T**4 */
+   w4 = 0;
+   for (j = 786; j >= 784; j--) {
+      w4 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
+   }
+
+/* Multiply by powers of T and combine. */
+   wf = t * (t * (t * (t * w4 + w3) + w2) + w1) + w0;
+
+/* Adjustments to use JPL planetary masses instead of IAU. */
+   wj =   0.00065e-6 * sin(6069.776754 * t + 4.021194) +
+          0.00033e-6 * sin( 213.299095 * t + 5.543132) +
+        (-0.00196e-6 * sin(6208.294251 * t + 5.696701)) +
+        (-0.00173e-6 * sin(  74.781599 * t + 2.435900)) +
+          0.03638e-6 * t * t;
+
+/* ============ */
+/* Final result */
+/* ============ */
+
+/* TDB-TT in seconds. */
+   w = wt + wf + wj;
+
+   return w;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/dtf2d.c b/cextern/erfa/dtf2d.c
new file mode 100644
index 0000000..551d1c4
--- /dev/null
+++ b/cextern/erfa/dtf2d.c
@@ -0,0 +1,212 @@
+#include "erfa.h"
+#include <string.h>
+
+int eraDtf2d(const char *scale, int iy, int im, int id,
+             int ihr, int imn, double sec, double *d1, double *d2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int js, iy2, im2, id2;
+   double dj, w, day, seclim, dat0, dat12, dat24, dleap, time;
+
+
+/* Today's Julian Day Number. */
+   js = eraCal2jd(iy, im, id, &dj, &w);
+   if ( js ) return js;
+   dj += w;
+
+/* Day length and final minute length in seconds (provisional). */
+   day = ERFA_DAYSEC;
+   seclim = 60.0;
+
+/* Deal with the UTC leap second case. */
+   if ( ! strcmp(scale,"UTC") ) {
+
+   /* TAI-UTC at 0h today. */
+      js = eraDat(iy, im, id, 0.0, &dat0);
+      if ( js < 0 ) return js;
+
+   /* TAI-UTC at 12h today (to detect drift). */
+      js = eraDat(iy, im, id, 0.5, &dat12);
+      if ( js < 0 ) return js;
+
+   /* TAI-UTC at 0h tomorrow (to detect jumps). */
+      js = eraJd2cal ( dj, 1.5, &iy2, &im2, &id2, &w);
+      if ( js ) return js;
+      js = eraDat(iy2, im2, id2, 0.0, &dat24);
+      if ( js < 0 ) return js;
+
+   /* Any sudden change in TAI-UTC between today and tomorrow. */
+      dleap = dat24 - (2.0*dat12 - dat0);
+
+   /* If leap second day, correct the day and final minute lengths. */
+      day += dleap;
+      if ( ihr == 23 && imn == 59 ) seclim += dleap;
+
+   /* End of UTC-specific actions. */
+   }
+
+/* Validate the time. */
+   if ( ihr >= 0 && ihr <= 23 ) {
+      if ( imn >= 0 && imn <= 59 ) {
+         if ( sec >= 0 ) {
+            if ( sec >= seclim ) {
+               js += 2;
+            }
+         } else {
+            js = -6;
+         }
+      } else {
+         js = -5;
+      }
+   } else {
+      js = -4;
+   }
+   if ( js < 0 ) return js;
+
+/* The time in days. */
+   time  = ( 60.0 * ( (double) ( 60 * ihr + imn ) ) + sec ) / day;
+
+/* Return the date and time. */
+   *d1 = dj;
+   *d2 = time;
+
+/* Status. */
+   return js;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ee00.c b/cextern/erfa/ee00.c
new file mode 100644
index 0000000..d66981d
--- /dev/null
+++ b/cextern/erfa/ee00.c
@@ -0,0 +1,137 @@
+#include "erfa.h"
+
+double eraEe00(double date1, double date2, double epsa, double dpsi)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double ee;
+
+
+/* Equation of the equinoxes. */
+   ee = dpsi * cos(epsa) + eraEect00(date1, date2);
+
+   return ee;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ee00a.c b/cextern/erfa/ee00a.c
new file mode 100644
index 0000000..c21d65d
--- /dev/null
+++ b/cextern/erfa/ee00a.c
@@ -0,0 +1,144 @@
+#include "erfa.h"
+
+double eraEe00a(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsipr, depspr, epsa, dpsi, deps, ee;
+
+
+/* IAU 2000 precession-rate adjustments. */
+   eraPr00(date1, date2, &dpsipr, &depspr);
+
+/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
+   epsa = eraObl80(date1, date2) + depspr;
+
+/* Nutation in longitude. */
+   eraNut00a(date1, date2, &dpsi, &deps);
+
+/* Equation of the equinoxes. */
+   ee = eraEe00(date1, date2, epsa, dpsi);
+
+   return ee;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ee00b.c b/cextern/erfa/ee00b.c
new file mode 100644
index 0000000..b3c7984
--- /dev/null
+++ b/cextern/erfa/ee00b.c
@@ -0,0 +1,150 @@
+#include "erfa.h"
+
+double eraEe00b(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsipr, depspr, epsa, dpsi, deps, ee;
+
+
+/* IAU 2000 precession-rate adjustments. */
+   eraPr00(date1, date2, &dpsipr, &depspr);
+
+/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
+   epsa = eraObl80(date1, date2) + depspr;
+
+/* Nutation in longitude. */
+   eraNut00b(date1, date2, &dpsi, &deps);
+
+/* Equation of the equinoxes. */
+   ee = eraEe00(date1, date2, epsa, dpsi);
+
+   return ee;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ee06a.c b/cextern/erfa/ee06a.c
new file mode 100644
index 0000000..9eb15ed
--- /dev/null
+++ b/cextern/erfa/ee06a.c
@@ -0,0 +1,131 @@
+#include "erfa.h"
+
+double eraEe06a(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gst06a, gmst06, ee;
+
+
+/* Apparent and mean sidereal times. */
+   gst06a = eraGst06a(0.0, 0.0, date1, date2);
+   gmst06 = eraGmst06(0.0, 0.0, date1, date2);
+
+/* Equation of the equinoxes. */
+   ee  = eraAnpm(gst06a - gmst06);
+
+   return ee;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/eect00.c b/cextern/erfa/eect00.c
new file mode 100644
index 0000000..d2af497
--- /dev/null
+++ b/cextern/erfa/eect00.c
@@ -0,0 +1,291 @@
+#include "erfa.h"
+
+double eraEect00(double date1, double date2)
+/*
+**  - - - - - - - - - -
+**   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", Astronomy &
+**     Astrophysics, 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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Time since J2000.0, in Julian centuries */
+   double t;
+
+/* Miscellaneous */
+   int i, j;
+   double a, s0, s1;
+
+/* Fundamental arguments */
+   double fa[14];
+
+/* Returned value. */
+   double eect;
+
+/* ----------------------------------------- */
+/* The series for the EE complementary terms */
+/* ----------------------------------------- */
+
+   typedef struct {
+      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
+      double s, c;     /* sine and cosine coefficients */
+   } TERM;
+
+/* Terms of order t^0 */
+   static const TERM e0[] = {
+
+   /* 1-10 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0}, 2640.96e-6, -0.39e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},   63.52e-6, -0.02e-6 },
+      {{ 0,  0,  2, -2,  3,  0,  0,  0},   11.75e-6,  0.01e-6 },
+      {{ 0,  0,  2, -2,  1,  0,  0,  0},   11.21e-6,  0.01e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},   -4.55e-6,  0.00e-6 },
+      {{ 0,  0,  2,  0,  3,  0,  0,  0},    2.02e-6,  0.00e-6 },
+      {{ 0,  0,  2,  0,  1,  0,  0,  0},    1.98e-6,  0.00e-6 },
+      {{ 0,  0,  0,  0,  3,  0,  0,  0},   -1.72e-6,  0.00e-6 },
+      {{ 0,  1,  0,  0,  1,  0,  0,  0},   -1.41e-6, -0.01e-6 },
+      {{ 0,  1,  0,  0, -1,  0,  0,  0},   -1.26e-6, -0.01e-6 },
+
+   /* 11-20 */
+      {{ 1,  0,  0,  0, -1,  0,  0,  0},   -0.63e-6,  0.00e-6 },
+      {{ 1,  0,  0,  0,  1,  0,  0,  0},   -0.63e-6,  0.00e-6 },
+      {{ 0,  1,  2, -2,  3,  0,  0,  0},    0.46e-6,  0.00e-6 },
+      {{ 0,  1,  2, -2,  1,  0,  0,  0},    0.45e-6,  0.00e-6 },
+      {{ 0,  0,  4, -4,  4,  0,  0,  0},    0.36e-6,  0.00e-6 },
+      {{ 0,  0,  1, -1,  1, -8, 12,  0},   -0.24e-6, -0.12e-6 },
+      {{ 0,  0,  2,  0,  0,  0,  0,  0},    0.32e-6,  0.00e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},    0.28e-6,  0.00e-6 },
+      {{ 1,  0,  2,  0,  3,  0,  0,  0},    0.27e-6,  0.00e-6 },
+      {{ 1,  0,  2,  0,  1,  0,  0,  0},    0.26e-6,  0.00e-6 },
+
+   /* 21-30 */
+      {{ 0,  0,  2, -2,  0,  0,  0,  0},   -0.21e-6,  0.00e-6 },
+      {{ 0,  1, -2,  2, -3,  0,  0,  0},    0.19e-6,  0.00e-6 },
+      {{ 0,  1, -2,  2, -1,  0,  0,  0},    0.18e-6,  0.00e-6 },
+      {{ 0,  0,  0,  0,  0,  8,-13, -1},   -0.10e-6,  0.05e-6 },
+      {{ 0,  0,  0,  2,  0,  0,  0,  0},    0.15e-6,  0.00e-6 },
+      {{ 2,  0, -2,  0, -1,  0,  0,  0},   -0.14e-6,  0.00e-6 },
+      {{ 1,  0,  0, -2,  1,  0,  0,  0},    0.14e-6,  0.00e-6 },
+      {{ 0,  1,  2, -2,  2,  0,  0,  0},   -0.14e-6,  0.00e-6 },
+      {{ 1,  0,  0, -2, -1,  0,  0,  0},    0.14e-6,  0.00e-6 },
+      {{ 0,  0,  4, -2,  4,  0,  0,  0},    0.13e-6,  0.00e-6 },
+
+   /* 31-33 */
+      {{ 0,  0,  2, -2,  4,  0,  0,  0},   -0.11e-6,  0.00e-6 },
+      {{ 1,  0, -2,  0, -3,  0,  0,  0},    0.11e-6,  0.00e-6 },
+      {{ 1,  0, -2,  0, -1,  0,  0,  0},    0.11e-6,  0.00e-6 }
+   };
+
+/* Terms of order t^1 */
+   static const TERM e1[] = {
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.87e-6,  0.00e-6 }
+   };
+
+/* Number of terms in the series */
+   const int NE0 = (int) (sizeof e0 / sizeof (TERM));
+   const int NE1 = (int) (sizeof e1 / sizeof (TERM));
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental epoch J2000.0 and current date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Fundamental Arguments (from IERS Conventions 2003) */
+
+/* Mean anomaly of the Moon. */
+   fa[0] = eraFal03(t);
+
+/* Mean anomaly of the Sun. */
+   fa[1] = eraFalp03(t);
+
+/* Mean longitude of the Moon minus that of the ascending node. */
+   fa[2] = eraFaf03(t);
+
+/* Mean elongation of the Moon from the Sun. */
+   fa[3] = eraFad03(t);
+
+/* Mean longitude of the ascending node of the Moon. */
+   fa[4] = eraFaom03(t);
+
+/* Mean longitude of Venus. */
+   fa[5] = eraFave03(t);
+
+/* Mean longitude of Earth. */
+   fa[6] = eraFae03(t);
+
+/* General precession in longitude. */
+   fa[7] = eraFapa03(t);
+
+/* Evaluate the EE complementary terms. */
+   s0 = 0.0;
+   s1 = 0.0;
+
+   for (i = NE0-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)(e0[i].nfa[j]) * fa[j];
+      }
+      s0 += e0[i].s * sin(a) + e0[i].c * cos(a);
+   }
+
+   for (i = NE1-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)(e1[i].nfa[j]) * fa[j];
+      }
+      s1 += e1[i].s * sin(a) + e1[i].c * cos(a);
+   }
+
+   eect = (s0 + s1 * t ) * ERFA_DAS2R;
+
+   return eect;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/eform.c b/cextern/erfa/eform.c
new file mode 100644
index 0000000..2c30412
--- /dev/null
+++ b/cextern/erfa/eform.c
@@ -0,0 +1,155 @@
+#include "erfa.h"
+
+int eraEform ( int n, double *a, double *f )
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Look up a and f for the specified reference ellipsoid. */
+   switch ( n ) {
+
+   case ERFA_WGS84:
+      *a = 6378137.0;
+      *f = 1.0 / 298.257223563;
+      break;
+
+   case ERFA_GRS80:
+      *a = 6378137.0;
+      *f = 1.0 / 298.257222101;
+      break;
+
+   case ERFA_WGS72:
+      *a = 6378135.0;
+      *f = 1.0 / 298.26;
+      break;
+
+   default:
+
+   /* Invalid identifier. */
+      *a = 0.0;
+      *f = 0.0;
+      return -1;
+
+   }
+
+/* OK status. */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/eo06a.c b/cextern/erfa/eo06a.c
new file mode 100644
index 0000000..86ec8cb
--- /dev/null
+++ b/cextern/erfa/eo06a.c
@@ -0,0 +1,140 @@
+#include "erfa.h"
+
+double eraEo06a(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r[3][3], x, y, s, eo;
+
+
+/* Classical nutation x precession x bias matrix. */
+   eraPnm06a(date1, date2, r);
+
+/* Extract CIP coordinates. */
+   eraBpn2xy(r, &x, &y);
+
+/* The CIO locator, s. */
+   s = eraS06(date1, date2, x, y);
+
+/* Solve for the EO. */
+   eo = eraEors(r, s);
+
+   return eo;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/eors.c b/cextern/erfa/eors.c
new file mode 100644
index 0000000..c16d452
--- /dev/null
+++ b/cextern/erfa/eors.c
@@ -0,0 +1,117 @@
+#include "erfa.h"
+
+double eraEors(double rnpb[3][3], double s)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, ax, xs, ys, zs, p, q, eo;
+
+
+/* Evaluate Wallace & Capitaine (2006) expression (16). */
+   x = rnpb[2][0];
+   ax = x / (1.0 + rnpb[2][2]);
+   xs = 1.0 - ax * x;
+   ys = -ax * rnpb[2][1];
+   zs = -x;
+   p = rnpb[0][0] * xs + rnpb[0][1] * ys + rnpb[0][2] * zs;
+   q = rnpb[1][0] * xs + rnpb[1][1] * ys + rnpb[1][2] * zs;
+   eo = ((p != 0) || (q != 0)) ? s - atan2(q, p) : s;
+
+   return eo;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/epb.c b/cextern/erfa/epb.c
new file mode 100644
index 0000000..cd50ea8
--- /dev/null
+++ b/cextern/erfa/epb.c
@@ -0,0 +1,100 @@
+#include "erfa.h"
+
+double eraEpb(double dj1, double dj2)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* J2000.0-B1900.0 (2415019.81352) in days */
+   const double D1900 = 36524.68648;
+
+   return 1900.0 + ((dj1 - ERFA_DJ00) + (dj2 + D1900)) / ERFA_DTY;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/epb2jd.c b/cextern/erfa/epb2jd.c
new file mode 100644
index 0000000..0cee330
--- /dev/null
+++ b/cextern/erfa/epb2jd.c
@@ -0,0 +1,100 @@
+#include "erfa.h"
+
+void eraEpb2jd(double epb, double *djm0, double *djm)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   *djm0 = ERFA_DJM0;
+   *djm  =   15019.81352 + (epb - 1900.0) * ERFA_DTY;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/epj.c b/cextern/erfa/epj.c
new file mode 100644
index 0000000..1a2b957
--- /dev/null
+++ b/cextern/erfa/epj.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+double eraEpj(double dj1, double dj2)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double epj;
+
+
+   epj = 2000.0 + ((dj1 - ERFA_DJ00) + dj2) / ERFA_DJY;
+
+   return epj;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/epj2jd.c b/cextern/erfa/epj2jd.c
new file mode 100644
index 0000000..8fe1479
--- /dev/null
+++ b/cextern/erfa/epj2jd.c
@@ -0,0 +1,100 @@
+#include "erfa.h"
+
+void eraEpj2jd(double epj, double *djm0, double *djm)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   *djm0 = ERFA_DJM0;
+   *djm  = ERFA_DJM00 + (epj - 2000.0) * 365.25;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/epv00.c b/cextern/erfa/epv00.c
new file mode 100644
index 0000000..56d5fc8
--- /dev/null
+++ b/cextern/erfa/epv00.c
@@ -0,0 +1,2598 @@
+#include "erfa.h"
+
+int eraEpv00(double date1, double date2,
+             double pvh[2][3], double pvb[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/*
+** Matrix elements for orienting the analytical model to DE405.
+**
+** The corresponding Euler angles are:
+**
+**                       d  '  "
+**   1st rotation    -  23 26 21.4091 about the x-axis  (obliquity)
+**   2nd rotation    +         0.0475 about the z-axis  (RA offset)
+**
+** These were obtained empirically, by comparisons with DE405 over
+** 1900-2100.
+*/
+   static const double am12 =  0.000000211284,
+                       am13 = -0.000000091603,
+                       am21 = -0.000000230286,
+                       am22 =  0.917482137087,
+                       am23 = -0.397776982902,
+                       am32 =  0.397776982902,
+                       am33 =  0.917482137087;
+
+/*
+** ----------------------
+** Ephemeris Coefficients
+** ----------------------
+**
+** The ephemeris consists of harmonic terms for predicting (i) the Sun
+** to Earth vector and (ii) the Solar-System-barycenter to Sun vector
+** respectively.  The coefficients are stored in arrays which, although
+** 1-demensional, contain groups of three.  Each triplet of
+** coefficients is the amplitude, phase and frequency for one term in
+** the model, and each array contains the number of terms called for by
+** the model.
+**
+** There are eighteen such arrays, named as follows:
+**
+**     array         model      power of T      component
+**
+**      e0x      Sun-to-Earth        0              x
+**      e0y      Sun-to-Earth        0              y
+**      e0z      Sun-to-Earth        0              z
+**
+**      e1x      Sun-to-Earth        1              x
+**      e1y      Sun-to-Earth        1              y
+**      e1z      Sun-to-Earth        1              z
+**
+**      e2x      Sun-to-Earth        2              x
+**      e2y      Sun-to-Earth        2              y
+**      e2z      Sun-to-Earth        2              z
+**
+**      s0x      SSB-to-Sun          0              x
+**      s0y      SSB-to-Sun          0              y
+**      s0z      SSB-to-Sun          0              z
+**
+**      s1x      SSB-to-Sun          1              x
+**      s1y      SSB-to-Sun          1              y
+**      s1z      SSB-to-Sun          1              z
+**
+**      s2x      SSB-to-Sun          2              x
+**      s2y      SSB-to-Sun          2              y
+**      s2z      SSB-to-Sun          2              z
+*/
+
+/* Sun-to-Earth, T^0, X */
+   static const double e0x[] = {
+      0.9998292878132e+00, 0.1753485171504e+01, 0.6283075850446e+01,
+      0.8352579567414e-02, 0.1710344404582e+01, 0.1256615170089e+02,
+      0.5611445335148e-02, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.1046664295572e-03, 0.1667225416770e+01, 0.1884922755134e+02,
+      0.3110842534677e-04, 0.6687513390251e+00, 0.8399684731857e+02,
+      0.2552413503550e-04, 0.5830637358413e+00, 0.5296909721118e+00,
+      0.2137207845781e-04, 0.1092330954011e+01, 0.1577343543434e+01,
+      0.1680240182951e-04, 0.4955366134987e+00, 0.6279552690824e+01,
+      0.1679012370795e-04, 0.6153014091901e+01, 0.6286599010068e+01,
+      0.1445526946777e-04, 0.3472744100492e+01, 0.2352866153506e+01,
+
+      0.1091038246184e-04, 0.3689845786119e+01, 0.5223693906222e+01,
+      0.9344399733932e-05, 0.6073934645672e+01, 0.1203646072878e+02,
+      0.8993182910652e-05, 0.3175705249069e+01, 0.1021328554739e+02,
+      0.5665546034116e-05, 0.2152484672246e+01, 0.1059381944224e+01,
+      0.6844146703035e-05, 0.1306964099750e+01, 0.5753384878334e+01,
+      0.7346610905565e-05, 0.4354980070466e+01, 0.3981490189893e+00,
+      0.6815396474414e-05, 0.2218229211267e+01, 0.4705732307012e+01,
+      0.6112787253053e-05, 0.5384788425458e+01, 0.6812766822558e+01,
+      0.4518120711239e-05, 0.6087604012291e+01, 0.5884926831456e+01,
+      0.4521963430706e-05, 0.1279424524906e+01, 0.6256777527156e+01,
+
+      0.4497426764085e-05, 0.5369129144266e+01, 0.6309374173736e+01,
+      0.4062190566959e-05, 0.5436473303367e+00, 0.6681224869435e+01,
+      0.5412193480192e-05, 0.7867838528395e+00, 0.7755226100720e+00,
+      0.5469839049386e-05, 0.1461440311134e+01, 0.1414349524433e+02,
+      0.5205264083477e-05, 0.4432944696116e+01, 0.7860419393880e+01,
+      0.2149759935455e-05, 0.4502237496846e+01, 0.1150676975667e+02,
+      0.2279109618501e-05, 0.1239441308815e+01, 0.7058598460518e+01,
+      0.2259282939683e-05, 0.3272430985331e+01, 0.4694002934110e+01,
+      0.2558950271319e-05, 0.2265471086404e+01, 0.1216800268190e+02,
+      0.2561581447555e-05, 0.1454740653245e+01, 0.7099330490126e+00,
+
+      0.1781441115440e-05, 0.2962068630206e+01, 0.7962980379786e+00,
+      0.1612005874644e-05, 0.1473255041006e+01, 0.5486777812467e+01,
+      0.1818630667105e-05, 0.3743903293447e+00, 0.6283008715021e+01,
+      0.1818601377529e-05, 0.6274174354554e+01, 0.6283142985870e+01,
+      0.1554475925257e-05, 0.1624110906816e+01, 0.2513230340178e+02,
+      0.2090948029241e-05, 0.5852052276256e+01, 0.1179062909082e+02,
+      0.2000176345460e-05, 0.4072093298513e+01, 0.1778984560711e+02,
+      0.1289535917759e-05, 0.5217019331069e+01, 0.7079373888424e+01,
+      0.1281135307881e-05, 0.4802054538934e+01, 0.3738761453707e+01,
+      0.1518229005692e-05, 0.8691914742502e+00, 0.2132990797783e+00,
+
+      0.9450128579027e-06, 0.4601859529950e+01, 0.1097707878456e+02,
+      0.7781119494996e-06, 0.1844352816694e+01, 0.8827390247185e+01,
+      0.7733407759912e-06, 0.3582790154750e+01, 0.5507553240374e+01,
+      0.7350644318120e-06, 0.2695277788230e+01, 0.1589072916335e+01,
+      0.6535928827023e-06, 0.3651327986142e+01, 0.1176985366291e+02,
+      0.6324624183656e-06, 0.2241302375862e+01, 0.6262300422539e+01,
+      0.6298565300557e-06, 0.4407122406081e+01, 0.6303851278352e+01,
+      0.8587037089179e-06, 0.3024307223119e+01, 0.1672837615881e+03,
+      0.8299954491035e-06, 0.6192539428237e+01, 0.3340612434717e+01,
+      0.6311263503401e-06, 0.2014758795416e+01, 0.7113454667900e-02,
+
+      0.6005646745452e-06, 0.3399500503397e+01, 0.4136910472696e+01,
+      0.7917715109929e-06, 0.2493386877837e+01, 0.6069776770667e+01,
+      0.7556958099685e-06, 0.4159491740143e+01, 0.6496374930224e+01,
+      0.6773228244949e-06, 0.4034162934230e+01, 0.9437762937313e+01,
+      0.5370708577847e-06, 0.1562219163734e+01, 0.1194447056968e+01,
+      0.5710804266203e-06, 0.2662730803386e+01, 0.6282095334605e+01,
+      0.5709824583726e-06, 0.3985828430833e+01, 0.6284056366286e+01,
+      0.5143950896447e-06, 0.1308144688689e+01, 0.6290189305114e+01,
+      0.5088010604546e-06, 0.5352817214804e+01, 0.6275962395778e+01,
+      0.4960369085172e-06, 0.2644267922349e+01, 0.6127655567643e+01,
+
+      0.4803137891183e-06, 0.4008844192080e+01, 0.6438496133249e+01,
+      0.5731747768225e-06, 0.3794550174597e+01, 0.3154687086868e+01,
+      0.4735947960579e-06, 0.6107118308982e+01, 0.3128388763578e+01,
+      0.4808348796625e-06, 0.4771458618163e+01, 0.8018209333619e+00,
+      0.4115073743137e-06, 0.3327111335159e+01, 0.8429241228195e+01,
+      0.5230575889287e-06, 0.5305708551694e+01, 0.1336797263425e+02,
+      0.5133977889215e-06, 0.5784230738814e+01, 0.1235285262111e+02,
+      0.5065815825327e-06, 0.2052064793679e+01, 0.1185621865188e+02,
+      0.4339831593868e-06, 0.3644994195830e+01, 0.1726015463500e+02,
+      0.3952928638953e-06, 0.4930376436758e+01, 0.5481254917084e+01,
+
+      0.4898498111942e-06, 0.4542084219731e+00, 0.9225539266174e+01,
+      0.4757490209328e-06, 0.3161126388878e+01, 0.5856477690889e+01,
+      0.4727701669749e-06, 0.6214993845446e+00, 0.2544314396739e+01,
+      0.3800966681863e-06, 0.3040132339297e+01, 0.4265981595566e+00,
+      0.3257301077939e-06, 0.8064977360087e+00, 0.3930209696940e+01,
+      0.3255810528674e-06, 0.1974147981034e+01, 0.2146165377750e+01,
+      0.3252029748187e-06, 0.2845924913135e+01, 0.4164311961999e+01,
+      0.3255505635308e-06, 0.3017900824120e+01, 0.5088628793478e+01,
+      0.2801345211990e-06, 0.6109717793179e+01, 0.1256967486051e+02,
+      0.3688987740970e-06, 0.2911550235289e+01, 0.1807370494127e+02,
+
+      0.2475153429458e-06, 0.2179146025856e+01, 0.2629832328990e-01,
+      0.3033457749150e-06, 0.1994161050744e+01, 0.4535059491685e+01,
+      0.2186743763110e-06, 0.5125687237936e+01, 0.1137170464392e+02,
+      0.2764777032774e-06, 0.4822646860252e+00, 0.1256262854127e+02,
+      0.2199028768592e-06, 0.4637633293831e+01, 0.1255903824622e+02,
+      0.2046482824760e-06, 0.1467038733093e+01, 0.7084896783808e+01,
+      0.2611209147507e-06, 0.3044718783485e+00, 0.7143069561767e+02,
+      0.2286079656818e-06, 0.4764220356805e+01, 0.8031092209206e+01,
+      0.1855071202587e-06, 0.3383637774428e+01, 0.1748016358760e+01,
+      0.2324669506784e-06, 0.6189088449251e+01, 0.1831953657923e+02,
+
+      0.1709528015688e-06, 0.5874966729774e+00, 0.4933208510675e+01,
+      0.2168156875828e-06, 0.4302994009132e+01, 0.1044738781244e+02,
+      0.2106675556535e-06, 0.3800475419891e+01, 0.7477522907414e+01,
+      0.1430213830465e-06, 0.1294660846502e+01, 0.2942463415728e+01,
+      0.1388396901944e-06, 0.4594797202114e+01, 0.8635942003952e+01,
+      0.1922258844190e-06, 0.4943044543591e+00, 0.1729818233119e+02,
+      0.1888460058292e-06, 0.2426943912028e+01, 0.1561374759853e+03,
+      0.1789449386107e-06, 0.1582973303499e+00, 0.1592596075957e+01,
+      0.1360803685374e-06, 0.5197240440504e+01, 0.1309584267300e+02,
+      0.1504038014709e-06, 0.3120360916217e+01, 0.1649636139783e+02,
+
+      0.1382769533389e-06, 0.6164702888205e+01, 0.7632943190217e+01,
+      0.1438059769079e-06, 0.1437423770979e+01, 0.2042657109477e+02,
+      0.1326303260037e-06, 0.3609688799679e+01, 0.1213955354133e+02,
+      0.1159244950540e-06, 0.5463018167225e+01, 0.5331357529664e+01,
+      0.1433118149136e-06, 0.6028909912097e+01, 0.7342457794669e+01,
+      0.1234623148594e-06, 0.3109645574997e+01, 0.6279485555400e+01,
+      0.1233949875344e-06, 0.3539359332866e+01, 0.6286666145492e+01,
+      0.9927196061299e-07, 0.1259321569772e+01, 0.7234794171227e+01,
+      0.1242302191316e-06, 0.1065949392609e+01, 0.1511046609763e+02,
+      0.1098402195201e-06, 0.2192508743837e+01, 0.1098880815746e+02,
+
+      0.1158191395315e-06, 0.4054411278650e+01, 0.5729506548653e+01,
+      0.9048475596241e-07, 0.5429764748518e+01, 0.9623688285163e+01,
+      0.8889853269023e-07, 0.5046586206575e+01, 0.6148010737701e+01,
+      0.1048694242164e-06, 0.2628858030806e+01, 0.6836645152238e+01,
+      0.1112308378646e-06, 0.4177292719907e+01, 0.1572083878776e+02,
+      0.8631729709901e-07, 0.1601345232557e+01, 0.6418140963190e+01,
+      0.8527816951664e-07, 0.2463888997513e+01, 0.1471231707864e+02,
+      0.7892139456991e-07, 0.3154022088718e+01, 0.2118763888447e+01,
+      0.1051782905236e-06, 0.4795035816088e+01, 0.1349867339771e+01,
+      0.1048219943164e-06, 0.2952983395230e+01, 0.5999216516294e+01,
+
+      0.7435760775143e-07, 0.5420547991464e+01, 0.6040347114260e+01,
+      0.9869574106949e-07, 0.3695646753667e+01, 0.6566935184597e+01,
+      0.9156886364226e-07, 0.3922675306609e+01, 0.5643178611111e+01,
+      0.7006834356188e-07, 0.1233968624861e+01, 0.6525804586632e+01,
+      0.9806170182601e-07, 0.1919542280684e+01, 0.2122839202813e+02,
+      0.9052289673607e-07, 0.4615902724369e+01, 0.4690479774488e+01,
+      0.7554200867893e-07, 0.1236863719072e+01, 0.1253985337760e+02,
+      0.8215741286498e-07, 0.3286800101559e+00, 0.1097355562493e+02,
+      0.7185178575397e-07, 0.5880942158367e+01, 0.6245048154254e+01,
+      0.7130726476180e-07, 0.7674871987661e+00, 0.6321103546637e+01,
+
+      0.6650894461162e-07, 0.6987129150116e+00, 0.5327476111629e+01,
+      0.7396888823688e-07, 0.3576824794443e+01, 0.5368044267797e+00,
+      0.7420588884775e-07, 0.5033615245369e+01, 0.2354323048545e+02,
+      0.6141181642908e-07, 0.9449927045673e+00, 0.1296430071988e+02,
+      0.6373557924058e-07, 0.6206342280341e+01, 0.9517183207817e+00,
+      0.6359474329261e-07, 0.5036079095757e+01, 0.1990745094947e+01,
+      0.5740173582646e-07, 0.6105106371350e+01, 0.9555997388169e+00,
+      0.7019864084602e-07, 0.7237747359018e+00, 0.5225775174439e+00,
+      0.6398054487042e-07, 0.3976367969666e+01, 0.2407292145756e+02,
+      0.7797092650498e-07, 0.4305423910623e+01, 0.2200391463820e+02,
+
+      0.6466760000900e-07, 0.3500136825200e+01, 0.5230807360890e+01,
+      0.7529417043890e-07, 0.3514779246100e+01, 0.1842262939178e+02,
+      0.6924571140892e-07, 0.2743457928679e+01, 0.1554202828031e+00,
+      0.6220798650222e-07, 0.2242598118209e+01, 0.1845107853235e+02,
+      0.5870209391853e-07, 0.2332832707527e+01, 0.6398972393349e+00,
+      0.6263953473888e-07, 0.2191105358956e+01, 0.6277552955062e+01,
+      0.6257781390012e-07, 0.4457559396698e+01, 0.6288598745829e+01,
+      0.5697304945123e-07, 0.3499234761404e+01, 0.1551045220144e+01,
+      0.6335438746791e-07, 0.6441691079251e+00, 0.5216580451554e+01,
+      0.6377258441152e-07, 0.2252599151092e+01, 0.5650292065779e+01,
+
+      0.6484841818165e-07, 0.1992812417646e+01, 0.1030928125552e+00,
+      0.4735551485250e-07, 0.3744672082942e+01, 0.1431416805965e+02,
+      0.4628595996170e-07, 0.1334226211745e+01, 0.5535693017924e+00,
+      0.6258152336933e-07, 0.4395836159154e+01, 0.2608790314060e+02,
+      0.6196171366594e-07, 0.2587043007997e+01, 0.8467247584405e+02,
+      0.6159556952126e-07, 0.4782499769128e+01, 0.2394243902548e+03,
+      0.4987741172394e-07, 0.7312257619924e+00, 0.7771377146812e+02,
+      0.5459280703142e-07, 0.3001376372532e+01, 0.6179983037890e+01,
+      0.4863461189999e-07, 0.3767222128541e+01, 0.9027992316901e+02,
+      0.5349912093158e-07, 0.3663594450273e+01, 0.6386168663001e+01,
+
+      0.5673725607806e-07, 0.4331187919049e+01, 0.6915859635113e+01,
+      0.4745485060512e-07, 0.5816195745518e+01, 0.6282970628506e+01,
+      0.4745379005326e-07, 0.8323672435672e+00, 0.6283181072386e+01,
+      0.4049002796321e-07, 0.3785023976293e+01, 0.6254626709878e+01,
+      0.4247084014515e-07, 0.2378220728783e+01, 0.7875671926403e+01,
+      0.4026912363055e-07, 0.2864103423269e+01, 0.6311524991013e+01,
+      0.4062935011774e-07, 0.2415408595975e+01, 0.3634620989887e+01,
+      0.5347771048509e-07, 0.3343479309801e+01, 0.2515860172507e+02,
+      0.4829494136505e-07, 0.2821742398262e+01, 0.5760498333002e+01,
+      0.4342554404599e-07, 0.5624662458712e+01, 0.7238675589263e+01,
+
+      0.4021599184361e-07, 0.5557250275009e+00, 0.1101510648075e+02,
+      0.4104900474558e-07, 0.3296691780005e+01, 0.6709674010002e+01,
+      0.4376532905131e-07, 0.3814443999443e+01, 0.6805653367890e+01,
+      0.3314590480650e-07, 0.3560229189250e+01, 0.1259245002418e+02,
+      0.3232421839643e-07, 0.5185389180568e+01, 0.1066495398892e+01,
+      0.3541176318876e-07, 0.3921381909679e+01, 0.9917696840332e+01,
+      0.3689831242681e-07, 0.4190658955386e+01, 0.1192625446156e+02,
+      0.3890605376774e-07, 0.5546023371097e+01, 0.7478166569050e-01,
+      0.3038559339780e-07, 0.6231032794494e+01, 0.1256621883632e+02,
+      0.3137083969782e-07, 0.6207063419190e+01, 0.4292330755499e+01,
+
+      0.4024004081854e-07, 0.1195257375713e+01, 0.1334167431096e+02,
+      0.3300234879283e-07, 0.1804694240998e+01, 0.1057540660594e+02,
+      0.3635399155575e-07, 0.5597811343500e+01, 0.6208294184755e+01,
+      0.3032668691356e-07, 0.3191059366530e+01, 0.1805292951336e+02,
+      0.2809652069058e-07, 0.4094348032570e+01, 0.3523159621801e-02,
+      0.3696955383823e-07, 0.5219282738794e+01, 0.5966683958112e+01,
+      0.3562894142503e-07, 0.1037247544554e+01, 0.6357857516136e+01,
+      0.3510598524148e-07, 0.1430020816116e+01, 0.6599467742779e+01,
+      0.3617736142953e-07, 0.3002911403677e+01, 0.6019991944201e+01,
+      0.2624524910730e-07, 0.2437046757292e+01, 0.6702560555334e+01,
+
+      0.2535824204490e-07, 0.1581594689647e+01, 0.3141537925223e+02,
+      0.3519787226257e-07, 0.5379863121521e+01, 0.2505706758577e+03,
+      0.2578406709982e-07, 0.4904222639329e+01, 0.1673046366289e+02,
+      0.3423887981473e-07, 0.3646448997315e+01, 0.6546159756691e+01,
+      0.2776083886467e-07, 0.3307829300144e+01, 0.1272157198369e+02,
+      0.3379592818379e-07, 0.1747541251125e+01, 0.1494531617769e+02,
+      0.3050255426284e-07, 0.1784689432607e-01, 0.4732030630302e+01,
+      0.2652378350236e-07, 0.4420055276260e+01, 0.5863591145557e+01,
+      0.2374498173768e-07, 0.3629773929208e+01, 0.2388894113936e+01,
+      0.2716451255140e-07, 0.3079623706780e+01, 0.1202934727411e+02,
+
+      0.3038583699229e-07, 0.3312487903507e+00, 0.1256608456547e+02,
+      0.2220681228760e-07, 0.5265520401774e+01, 0.1336244973887e+02,
+      0.3044156540912e-07, 0.4766664081250e+01, 0.2908881142201e+02,
+      0.2731859923561e-07, 0.5069146530691e+01, 0.1391601904066e+02,
+      0.2285603018171e-07, 0.5954935112271e+01, 0.6076890225335e+01,
+      0.2025006454555e-07, 0.4061789589267e+01, 0.4701116388778e+01,
+      0.2012597519804e-07, 0.2485047705241e+01, 0.6262720680387e+01,
+      0.2003406962258e-07, 0.4163779209320e+01, 0.6303431020504e+01,
+      0.2207863441371e-07, 0.6923839133828e+00, 0.6489261475556e+01,
+      0.2481374305624e-07, 0.5944173595676e+01, 0.1204357418345e+02,
+
+      0.2130923288870e-07, 0.4641013671967e+01, 0.5746271423666e+01,
+      0.2446370543391e-07, 0.6125796518757e+01, 0.1495633313810e+00,
+      0.1932492759052e-07, 0.2234572324504e+00, 0.1352175143971e+02,
+      0.2600122568049e-07, 0.4281012405440e+01, 0.4590910121555e+01,
+      0.2431754047488e-07, 0.1429943874870e+00, 0.1162474756779e+01,
+      0.1875902869209e-07, 0.9781803816948e+00, 0.6279194432410e+01,
+      0.1874381139426e-07, 0.5670368130173e+01, 0.6286957268481e+01,
+      0.2156696047173e-07, 0.2008985006833e+01, 0.1813929450232e+02,
+      0.1965076182484e-07, 0.2566186202453e+00, 0.4686889479442e+01,
+      0.2334816372359e-07, 0.4408121891493e+01, 0.1002183730415e+02,
+
+      0.1869937408802e-07, 0.5272745038656e+01, 0.2427287361862e+00,
+      0.2436236460883e-07, 0.4407720479029e+01, 0.9514313292143e+02,
+      0.1761365216611e-07, 0.1943892315074e+00, 0.1351787002167e+02,
+      0.2156289480503e-07, 0.1418570924545e+01, 0.6037244212485e+01,
+      0.2164748979255e-07, 0.4724603439430e+01, 0.2301353951334e+02,
+      0.2222286670853e-07, 0.2400266874598e+01, 0.1266924451345e+02,
+      0.2070901414929e-07, 0.5230348028732e+01, 0.6528907488406e+01,
+      0.1792745177020e-07, 0.2099190328945e+01, 0.6819880277225e+01,
+      0.1841802068445e-07, 0.3467527844848e+00, 0.6514761976723e+02,
+      0.1578401631718e-07, 0.7098642356340e+00, 0.2077542790660e-01,
+
+      0.1561690152531e-07, 0.5943349620372e+01, 0.6272439236156e+01,
+      0.1558591045463e-07, 0.7040653478980e+00, 0.6293712464735e+01,
+      0.1737356469576e-07, 0.4487064760345e+01, 0.1765478049437e+02,
+      0.1434755619991e-07, 0.2993391570995e+01, 0.1102062672231e+00,
+      0.1482187806654e-07, 0.2278049198251e+01, 0.1052268489556e+01,
+      0.1424812827089e-07, 0.1682114725827e+01, 0.1311972100268e+02,
+      0.1380282448623e-07, 0.3262668602579e+01, 0.1017725758696e+02,
+      0.1811481244566e-07, 0.3187771221777e+01, 0.1887552587463e+02,
+      0.1504446185696e-07, 0.5650162308647e+01, 0.7626583626240e-01,
+      0.1740776154137e-07, 0.5487068607507e+01, 0.1965104848470e+02,
+
+      0.1374339536251e-07, 0.5745688172201e+01, 0.6016468784579e+01,
+      0.1761377477704e-07, 0.5748060203659e+01, 0.2593412433514e+02,
+      0.1535138225795e-07, 0.6226848505790e+01, 0.9411464614024e+01,
+      0.1788140543676e-07, 0.6189318878563e+01, 0.3301902111895e+02,
+      0.1375002807996e-07, 0.5371812884394e+01, 0.6327837846670e+00,
+      0.1242115758632e-07, 0.1471687569712e+01, 0.3894181736510e+01,
+      0.1450977333938e-07, 0.4143836662127e+01, 0.1277945078067e+02,
+      0.1297579575023e-07, 0.9003477661957e+00, 0.6549682916313e+01,
+      0.1462667934821e-07, 0.5760505536428e+01, 0.1863592847156e+02,
+      0.1381774374799e-07, 0.1085471729463e+01, 0.2379164476796e+01,
+
+      0.1682333169307e-07, 0.5409870870133e+01, 0.1620077269078e+02,
+      0.1190812918837e-07, 0.1397205174601e+01, 0.1149965630200e+02,
+      0.1221434762106e-07, 0.9001804809095e+00, 0.1257326515556e+02,
+      0.1549934644860e-07, 0.4262528275544e+01, 0.1820933031200e+02,
+      0.1252138953050e-07, 0.1411642012027e+01, 0.6993008899458e+01,
+      0.1237078905387e-07, 0.2844472403615e+01, 0.2435678079171e+02,
+      0.1446953389615e-07, 0.5295835522223e+01, 0.3813291813120e-01,
+      0.1388446457170e-07, 0.4969428135497e+01, 0.2458316379602e+00,
+      0.1019339179228e-07, 0.2491369561806e+01, 0.6112403035119e+01,
+      0.1258880815343e-07, 0.4679426248976e+01, 0.5429879531333e+01,
+
+      0.1297768238261e-07, 0.1074509953328e+01, 0.1249137003520e+02,
+      0.9913505718094e-08, 0.4735097918224e+01, 0.6247047890016e+01,
+      0.9830453155969e-08, 0.4158649187338e+01, 0.6453748665772e+01,
+      0.1192615865309e-07, 0.3438208613699e+01, 0.6290122169689e+01,
+      0.9835874798277e-08, 0.1913300781229e+01, 0.6319103810876e+01,
+      0.9639087569277e-08, 0.9487683644125e+00, 0.8273820945392e+01,
+      0.1175716107001e-07, 0.3228141664287e+01, 0.6276029531202e+01,
+      0.1018926508678e-07, 0.2216607854300e+01, 0.1254537627298e+02,
+      0.9500087869225e-08, 0.2625116459733e+01, 0.1256517118505e+02,
+      0.9664192916575e-08, 0.5860562449214e+01, 0.6259197520765e+01,
+
+      0.9612858712203e-08, 0.7885682917381e+00, 0.6306954180126e+01,
+      0.1117645675413e-07, 0.3932148831189e+01, 0.1779695906178e+02,
+      0.1158864052160e-07, 0.9995605521691e+00, 0.1778273215245e+02,
+      0.9021043467028e-08, 0.5263769742673e+01, 0.6172869583223e+01,
+      0.8836134773563e-08, 0.1496843220365e+01, 0.1692165728891e+01,
+      0.1045872200691e-07, 0.7009039517214e+00, 0.2204125344462e+00,
+      0.1211463487798e-07, 0.4041544938511e+01, 0.8257698122054e+02,
+      0.8541990804094e-08, 0.1447586692316e+01, 0.6393282117669e+01,
+      0.1038720703636e-07, 0.4594249718112e+00, 0.1550861511662e+02,
+      0.1126722351445e-07, 0.3925550579036e+01, 0.2061856251104e+00,
+
+      0.8697373859631e-08, 0.4411341856037e+01, 0.9491756770005e+00,
+      0.8869380028441e-08, 0.2402659724813e+01, 0.3903911373650e+01,
+      0.9247014693258e-08, 0.1401579743423e+01, 0.6267823317922e+01,
+      0.9205062930950e-08, 0.5245978000814e+01, 0.6298328382969e+01,
+      0.8000745038049e-08, 0.3590803356945e+01, 0.2648454860559e+01,
+      0.9168973650819e-08, 0.2470150501679e+01, 0.1498544001348e+03,
+      0.1075444949238e-07, 0.1328606161230e+01, 0.3694923081589e+02,
+      0.7817298525817e-08, 0.6162256225998e+01, 0.4804209201333e+01,
+      0.9541469226356e-08, 0.3942568967039e+01, 0.1256713221673e+02,
+      0.9821910122027e-08, 0.2360246287233e+00, 0.1140367694411e+02,
+
+      0.9897822023777e-08, 0.4619805634280e+01, 0.2280573557157e+02,
+      0.7737289283765e-08, 0.3784727847451e+01, 0.7834121070590e+01,
+      0.9260204034710e-08, 0.2223352487601e+01, 0.2787043132925e+01,
+      0.7320252888486e-08, 0.1288694636874e+01, 0.6282655592598e+01,
+      0.7319785780946e-08, 0.5359869567774e+01, 0.6283496108294e+01,
+      0.7147219933778e-08, 0.5516616675856e+01, 0.1725663147538e+02,
+      0.7946502829878e-08, 0.2630459984567e+01, 0.1241073141809e+02,
+      0.9001711808932e-08, 0.2849815827227e+01, 0.6281591679874e+01,
+      0.8994041507257e-08, 0.3795244450750e+01, 0.6284560021018e+01,
+      0.8298582787358e-08, 0.5236413127363e+00, 0.1241658836951e+02,
+
+      0.8526596520710e-08, 0.4794605424426e+01, 0.1098419223922e+02,
+      0.8209822103197e-08, 0.1578752370328e+01, 0.1096996532989e+02,
+      0.6357049861094e-08, 0.5708926113761e+01, 0.1596186371003e+01,
+      0.7370473179049e-08, 0.3842402530241e+01, 0.4061219149443e+01,
+      0.7232154664726e-08, 0.3067548981535e+01, 0.1610006857377e+03,
+      0.6328765494903e-08, 0.1313930030069e+01, 0.1193336791622e+02,
+      0.8030064908595e-08, 0.3488500408886e+01, 0.8460828644453e+00,
+      0.6275464259232e-08, 0.1532061626198e+01, 0.8531963191132e+00,
+      0.7051897446325e-08, 0.3285859929993e+01, 0.5849364236221e+01,
+      0.6161593705428e-08, 0.1477341999464e+01, 0.5573142801433e+01,
+
+      0.7754683957278e-08, 0.1586118663096e+01, 0.8662240327241e+01,
+      0.5889928990701e-08, 0.1304887868803e+01, 0.1232342296471e+02,
+      0.5705756047075e-08, 0.4555333589350e+01, 0.1258692712880e+02,
+      0.5964178808332e-08, 0.3001762842062e+01, 0.5333900173445e+01,
+      0.6712446027467e-08, 0.4886780007595e+01, 0.1171295538178e+02,
+      0.5941809275464e-08, 0.4701509603824e+01, 0.9779108567966e+01,
+      0.5466993627395e-08, 0.4588357817278e+01, 0.1884211409667e+02,
+      0.6340512090980e-08, 0.1164543038893e+01, 0.5217580628120e+02,
+      0.6325505710045e-08, 0.3919171259645e+01, 0.1041998632314e+02,
+      0.6164789509685e-08, 0.2143828253542e+01, 0.6151533897323e+01,
+
+      0.5263330812430e-08, 0.6066564434241e+01, 0.1885275071096e+02,
+      0.5597087780221e-08, 0.2926316429472e+01, 0.4337116142245e+00,
+      0.5396556236817e-08, 0.3244303591505e+01, 0.6286362197481e+01,
+      0.5396615148223e-08, 0.3404304703662e+01, 0.6279789503410e+01,
+      0.7091832443341e-08, 0.8532377803192e+00, 0.4907302013889e+01,
+      0.6572352589782e-08, 0.4901966774419e+01, 0.1176433076753e+02,
+      0.5960236060795e-08, 0.1874672315797e+01, 0.1422690933580e-01,
+      0.5125480043511e-08, 0.3735726064334e+01, 0.1245594543367e+02,
+      0.5928241866410e-08, 0.4502033899935e+01, 0.6414617803568e+01,
+      0.5249600357424e-08, 0.4372334799878e+01, 0.1151388321134e+02,
+
+      0.6059171276087e-08, 0.2581617302908e+01, 0.6062663316000e+01,
+      0.5295235081662e-08, 0.2974811513158e+01, 0.3496032717521e+01,
+      0.5820561875933e-08, 0.1796073748244e+00, 0.2838593341516e+00,
+      0.4754696606440e-08, 0.1981998136973e+01, 0.3104930017775e+01,
+      0.6385053548955e-08, 0.2559174171605e+00, 0.6133512519065e+01,
+      0.6589828273941e-08, 0.2750967106776e+01, 0.4087944051283e+02,
+      0.5383376567189e-08, 0.6325947523578e+00, 0.2248384854122e+02,
+      0.5928941683538e-08, 0.1672304519067e+01, 0.1581959461667e+01,
+      0.4816060709794e-08, 0.3512566172575e+01, 0.9388005868221e+01,
+      0.6003381586512e-08, 0.5610932219189e+01, 0.5326786718777e+01,
+
+      0.5504225393105e-08, 0.4037501131256e+01, 0.6503488384892e+01,
+      0.5353772620129e-08, 0.6122774968240e+01, 0.1735668374386e+03,
+      0.5786253768544e-08, 0.5527984999515e+01, 0.1350651127443e+00,
+      0.5065706702002e-08, 0.9980765573624e+00, 0.1248988586463e+02,
+      0.5972838885276e-08, 0.6044489493203e+01, 0.2673594526851e+02,
+      0.5323585877961e-08, 0.3924265998147e+01, 0.4171425416666e+01,
+      0.5210772682858e-08, 0.6220111376901e+01, 0.2460261242967e+02,
+      0.4726549040535e-08, 0.3716043206862e+01, 0.7232251527446e+01,
+      0.6029425105059e-08, 0.8548704071116e+00, 0.3227113045244e+03,
+      0.4481542826513e-08, 0.1426925072829e+01, 0.5547199253223e+01,
+
+      0.5836024505068e-08, 0.7135651752625e-01, 0.7285056171570e+02,
+      0.4137046613272e-08, 0.5330767643283e+01, 0.1087398597200e+02,
+      0.5171977473924e-08, 0.4494262335353e+00, 0.1884570439172e+02,
+      0.5694429833732e-08, 0.2952369582215e+01, 0.9723862754494e+02,
+      0.4009158925298e-08, 0.3500003416535e+01, 0.6244942932314e+01,
+      0.4784939596873e-08, 0.6196709413181e+01, 0.2929661536378e+02,
+      0.3983725022610e-08, 0.5103690031897e+01, 0.4274518229222e+01,
+      0.3870535232462e-08, 0.3187569587401e+01, 0.6321208768577e+01,
+      0.5140501213951e-08, 0.1668924357457e+01, 0.1232032006293e+02,
+      0.3849034819355e-08, 0.4445722510309e+01, 0.1726726808967e+02,
+
+      0.4002383075060e-08, 0.5226224152423e+01, 0.7018952447668e+01,
+      0.3890719543549e-08, 0.4371166550274e+01, 0.1491901785440e+02,
+      0.4887084607881e-08, 0.5973556689693e+01, 0.1478866649112e+01,
+      0.3739939287592e-08, 0.2089084714600e+01, 0.6922973089781e+01,
+      0.5031925918209e-08, 0.4658371936827e+01, 0.1715706182245e+02,
+      0.4387748764954e-08, 0.4825580552819e+01, 0.2331413144044e+03,
+      0.4147398098865e-08, 0.3739003524998e+01, 0.1376059875786e+02,
+      0.3719089993586e-08, 0.1148941386536e+01, 0.6297302759782e+01,
+      0.3934238461056e-08, 0.1559893008343e+01, 0.7872148766781e+01,
+      0.3672471375622e-08, 0.5516145383612e+01, 0.6268848941110e+01,
+
+      0.3768911277583e-08, 0.6116053700563e+01, 0.4157198507331e+01,
+      0.4033388417295e-08, 0.5076821746017e+01, 0.1567108171867e+02,
+      0.3764194617832e-08, 0.8164676232075e+00, 0.3185192151914e+01,
+      0.4840628226284e-08, 0.1360479453671e+01, 0.1252801878276e+02,
+      0.4949443923785e-08, 0.2725622229926e+01, 0.1617106187867e+03,
+      0.4117393089971e-08, 0.6054459628492e+00, 0.5642198095270e+01,
+      0.3925754020428e-08, 0.8570462135210e+00, 0.2139354194808e+02,
+      0.3630551757923e-08, 0.3552067338279e+01, 0.6294805223347e+01,
+      0.3627274802357e-08, 0.3096565085313e+01, 0.6271346477544e+01,
+      0.3806143885093e-08, 0.6367751709777e+00, 0.1725304118033e+02,
+
+      0.4433254641565e-08, 0.4848461503937e+01, 0.7445550607224e+01,
+      0.3712319846576e-08, 0.1331950643655e+01, 0.4194847048887e+00,
+      0.3849847534783e-08, 0.4958368297746e+00, 0.9562891316684e+00,
+      0.3483955430165e-08, 0.2237215515707e+01, 0.1161697602389e+02,
+      0.3961912730982e-08, 0.3332402188575e+01, 0.2277943724828e+02,
+      0.3419978244481e-08, 0.5785600576016e+01, 0.1362553364512e+02,
+      0.3329417758177e-08, 0.9812676559709e-01, 0.1685848245639e+02,
+      0.4207206893193e-08, 0.9494780468236e+00, 0.2986433403208e+02,
+      0.3268548976410e-08, 0.1739332095686e+00, 0.5749861718712e+01,
+      0.3321880082685e-08, 0.1423354800666e+01, 0.6279143387820e+01,
+
+      0.4503173010852e-08, 0.2314972675293e+00, 0.1385561574497e+01,
+      0.4316599090954e-08, 0.1012646782616e+00, 0.4176041334900e+01,
+      0.3283493323850e-08, 0.5233306881265e+01, 0.6287008313071e+01,
+      0.3164033542343e-08, 0.4005597257511e+01, 0.2099539292909e+02,
+      0.4159720956725e-08, 0.5365676242020e+01, 0.5905702259363e+01,
+      0.3565176892217e-08, 0.4284440620612e+01, 0.3932462625300e-02,
+      0.3514440950221e-08, 0.4270562636575e+01, 0.7335344340001e+01,
+      0.3540596871909e-08, 0.5953553201060e+01, 0.1234573916645e+02,
+      0.2960769905118e-08, 0.1115180417718e+01, 0.2670964694522e+02,
+      0.2962213739684e-08, 0.3863811918186e+01, 0.6408777551755e+00,
+
+      0.3883556700251e-08, 0.1268617928302e+01, 0.6660449441528e+01,
+      0.2919225516346e-08, 0.4908605223265e+01, 0.1375773836557e+01,
+      0.3115158863370e-08, 0.3744519976885e+01, 0.3802769619140e-01,
+      0.4099438144212e-08, 0.4173244670532e+01, 0.4480965020977e+02,
+      0.2899531858964e-08, 0.5910601428850e+01, 0.2059724391010e+02,
+      0.3289733429855e-08, 0.2488050078239e+01, 0.1081813534213e+02,
+      0.3933075612875e-08, 0.1122363652883e+01, 0.3773735910827e+00,
+      0.3021403764467e-08, 0.4951973724904e+01, 0.2982630633589e+02,
+      0.2798598949757e-08, 0.5117057845513e+01, 0.1937891852345e+02,
+      0.3397421302707e-08, 0.6104159180476e+01, 0.6923953605621e+01,
+
+      0.3720398002179e-08, 0.1184933429829e+01, 0.3066615496545e+02,
+      0.3598484186267e-08, 0.3505282086105e+01, 0.6147450479709e+01,
+      0.3694594027310e-08, 0.2286651088141e+01, 0.2636725487657e+01,
+      0.2680444152969e-08, 0.1871816775482e+00, 0.6816289982179e+01,
+      0.3497574865641e-08, 0.3143251755431e+01, 0.6418701221183e+01,
+      0.3130274129494e-08, 0.2462167316018e+01, 0.1235996607578e+02,
+      0.3241119069551e-08, 0.4256374004686e+01, 0.1652265972112e+02,
+      0.2601960842061e-08, 0.4970362941425e+01, 0.1045450126711e+02,
+      0.2690601527504e-08, 0.2372657824898e+01, 0.3163918923335e+00,
+      0.2908688152664e-08, 0.4232652627721e+01, 0.2828699048865e+02,
+
+      0.3120456131875e-08, 0.3925747001137e+00, 0.2195415756911e+02,
+      0.3148855423384e-08, 0.3093478330445e+01, 0.1172006883645e+02,
+      0.3051044261017e-08, 0.5560948248212e+01, 0.6055599646783e+01,
+      0.2826006876660e-08, 0.5072790310072e+01, 0.5120601093667e+01,
+      0.3100034191711e-08, 0.4998530231096e+01, 0.1799603123222e+02,
+      0.2398771640101e-08, 0.2561739802176e+01, 0.6255674361143e+01,
+      0.2384002842728e-08, 0.4087420284111e+01, 0.6310477339748e+01,
+      0.2842146517568e-08, 0.2515048217955e+01, 0.5469525544182e+01,
+      0.2847674371340e-08, 0.5235326497443e+01, 0.1034429499989e+02,
+      0.2903722140764e-08, 0.1088200795797e+01, 0.6510552054109e+01,
+
+      0.3187610710605e-08, 0.4710624424816e+01, 0.1693792562116e+03,
+      0.3048869992813e-08, 0.2857975896445e+00, 0.8390110365991e+01,
+      0.2860216950984e-08, 0.2241619020815e+01, 0.2243449970715e+00,
+      0.2701117683113e-08, 0.6651573305272e-01, 0.6129297044991e+01,
+      0.2509891590152e-08, 0.1285135324585e+01, 0.1044027435778e+02,
+      0.2623200252223e-08, 0.2981229834530e+00, 0.6436854655901e+01,
+      0.2622541669202e-08, 0.6122470726189e+01, 0.9380959548977e+01,
+      0.2818435667099e-08, 0.4251087148947e+01, 0.5934151399930e+01,
+      0.2365196797465e-08, 0.3465070460790e+01, 0.2470570524223e+02,
+      0.2358704646143e-08, 0.5791603815350e+01, 0.8671969964381e+01,
+
+      0.2388299481390e-08, 0.4142483772941e+01, 0.7096626156709e+01,
+      0.1996041217224e-08, 0.2101901889496e+01, 0.1727188400790e+02,
+      0.2687593060336e-08, 0.1526689456959e+01, 0.7075506709219e+02,
+      0.2618913670810e-08, 0.2397684236095e+01, 0.6632000300961e+01,
+      0.2571523050364e-08, 0.5751929456787e+00, 0.6206810014183e+01,
+      0.2582135006946e-08, 0.5595464352926e+01, 0.4873985990671e+02,
+      0.2372530190361e-08, 0.5092689490655e+01, 0.1590676413561e+02,
+      0.2357178484712e-08, 0.4444363527851e+01, 0.3097883698531e+01,
+      0.2451590394723e-08, 0.3108251687661e+01, 0.6612329252343e+00,
+      0.2370045949608e-08, 0.2608133861079e+01, 0.3459636466239e+02,
+
+      0.2268997267358e-08, 0.3639717753384e+01, 0.2844914056730e-01,
+      0.1731432137906e-08, 0.1741898445707e+00, 0.2019909489111e+02,
+      0.1629869741622e-08, 0.3902225646724e+01, 0.3035599730800e+02,
+      0.2206215801974e-08, 0.4971131250731e+01, 0.6281667977667e+01,
+      0.2205469554680e-08, 0.1677462357110e+01, 0.6284483723224e+01,
+      0.2148792362509e-08, 0.4236259604006e+01, 0.1980482729015e+02,
+      0.1873733657847e-08, 0.5926814998687e+01, 0.2876692439167e+02,
+      0.2026573758959e-08, 0.4349643351962e+01, 0.2449240616245e+02,
+      0.1807770325110e-08, 0.5700940482701e+01, 0.2045286941806e+02,
+      0.1881174408581e-08, 0.6601286363430e+00, 0.2358125818164e+02,
+
+      0.1368023671690e-08, 0.2211098592752e+01, 0.2473415438279e+02,
+      0.1720017916280e-08, 0.4942488551129e+01, 0.1679593901136e+03,
+      0.1702427665131e-08, 0.1452233856386e+01, 0.3338575901272e+03,
+      0.1414032510054e-08, 0.5525357721439e+01, 0.1624205518357e+03,
+      0.1652626045364e-08, 0.4108794283624e+01, 0.8956999012000e+02,
+      0.1642957769686e-08, 0.7344335209984e+00, 0.5267006960365e+02,
+      0.1614952403624e-08, 0.3541213951363e+01, 0.3332657872986e+02,
+      0.1535988291188e-08, 0.4031094072151e+01, 0.3852657435933e+02,
+      0.1593193738177e-08, 0.4185136203609e+01, 0.2282781046519e+03,
+      0.1074569126382e-08, 0.1720485636868e+01, 0.8397383534231e+02,
+
+      0.1074408214509e-08, 0.2758613420318e+01, 0.8401985929482e+02,
+      0.9700199670465e-09, 0.4216686842097e+01, 0.7826370942180e+02,
+      0.1258433517061e-08, 0.2575068876639e+00, 0.3115650189215e+03,
+      0.1240303229539e-08, 0.4800844956756e+00, 0.1784300471910e+03,
+      0.9018345948127e-09, 0.3896756361552e+00, 0.5886454391678e+02,
+      0.1135301432805e-08, 0.3700805023550e+00, 0.7842370451713e+02,
+      0.9215887951370e-09, 0.4364579276638e+01, 0.1014262087719e+03,
+      0.1055401054147e-08, 0.2156564222111e+01, 0.5660027930059e+02,
+      0.1008725979831e-08, 0.5454015785234e+01, 0.4245678405627e+02,
+      0.7217398104321e-09, 0.1597772562175e+01, 0.2457074661053e+03,
+
+      0.6912033134447e-09, 0.5824090621461e+01, 0.1679936946371e+03,
+      0.6833881523549e-09, 0.3578778482835e+01, 0.6053048899753e+02,
+      0.4887304205142e-09, 0.3724362812423e+01, 0.9656299901946e+02,
+      0.5173709754788e-09, 0.5422427507933e+01, 0.2442876000072e+03,
+      0.4671353097145e-09, 0.2396106924439e+01, 0.1435713242844e+03,
+      0.5652608439480e-09, 0.2804028838685e+01, 0.8365903305582e+02,
+      0.5604061331253e-09, 0.1638816006247e+01, 0.8433466158131e+02,
+      0.4712723365400e-09, 0.8979003224474e+00, 0.3164282286739e+03,
+      0.4909967465112e-09, 0.3210426725516e+01, 0.4059982187939e+03,
+      0.4771358267658e-09, 0.5308027211629e+01, 0.1805255418145e+03,
+
+      0.3943451445989e-09, 0.2195145341074e+01, 0.2568537517081e+03,
+      0.3952109120244e-09, 0.5081189491586e+01, 0.2449975330562e+03,
+      0.3788134594789e-09, 0.4345171264441e+01, 0.1568131045107e+03,
+      0.3738330190479e-09, 0.2613062847997e+01, 0.3948519331910e+03,
+      0.3099866678136e-09, 0.2846760817689e+01, 0.1547176098872e+03,
+      0.2002962716768e-09, 0.4921360989412e+01, 0.2268582385539e+03,
+      0.2198291338754e-09, 0.1130360117454e+00, 0.1658638954901e+03,
+      0.1491958330784e-09, 0.4228195232278e+01, 0.2219950288015e+03,
+      0.1475384076173e-09, 0.3005721811604e+00, 0.3052819430710e+03,
+      0.1661626624624e-09, 0.7830125621203e+00, 0.2526661704812e+03,
+
+      0.9015823460025e-10, 0.3807792942715e+01, 0.4171445043968e+03 };
+
+/* Sun-to-Earth, T^0, Y */
+   static const double e0y[] = {
+      0.9998921098898e+00, 0.1826583913846e+00, 0.6283075850446e+01,
+     -0.2442700893735e-01, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.8352929742915e-02, 0.1395277998680e+00, 0.1256615170089e+02,
+      0.1046697300177e-03, 0.9641423109763e-01, 0.1884922755134e+02,
+      0.3110841876663e-04, 0.5381140401712e+01, 0.8399684731857e+02,
+      0.2570269094593e-04, 0.5301016407128e+01, 0.5296909721118e+00,
+      0.2147389623610e-04, 0.2662510869850e+01, 0.1577343543434e+01,
+      0.1680344384050e-04, 0.5207904119704e+01, 0.6279552690824e+01,
+      0.1679117312193e-04, 0.4582187486968e+01, 0.6286599010068e+01,
+      0.1440512068440e-04, 0.1900688517726e+01, 0.2352866153506e+01,
+
+      0.1135139664999e-04, 0.5273108538556e+01, 0.5223693906222e+01,
+      0.9345482571018e-05, 0.4503047687738e+01, 0.1203646072878e+02,
+      0.9007418719568e-05, 0.1605621059637e+01, 0.1021328554739e+02,
+      0.5671536712314e-05, 0.5812849070861e+00, 0.1059381944224e+01,
+      0.7451401861666e-05, 0.2807346794836e+01, 0.3981490189893e+00,
+      0.6393470057114e-05, 0.6029224133855e+01, 0.5753384878334e+01,
+      0.6814275881697e-05, 0.6472990145974e+00, 0.4705732307012e+01,
+      0.6113705628887e-05, 0.3813843419700e+01, 0.6812766822558e+01,
+      0.4503851367273e-05, 0.4527804370996e+01, 0.5884926831456e+01,
+      0.4522249141926e-05, 0.5991783029224e+01, 0.6256777527156e+01,
+
+      0.4501794307018e-05, 0.3798703844397e+01, 0.6309374173736e+01,
+      0.5514927480180e-05, 0.3961257833388e+01, 0.5507553240374e+01,
+      0.4062862799995e-05, 0.5256247296369e+01, 0.6681224869435e+01,
+      0.5414900429712e-05, 0.5499032014097e+01, 0.7755226100720e+00,
+      0.5463153987424e-05, 0.6173092454097e+01, 0.1414349524433e+02,
+      0.5071611859329e-05, 0.2870244247651e+01, 0.7860419393880e+01,
+      0.2195112094455e-05, 0.2952338617201e+01, 0.1150676975667e+02,
+      0.2279139233919e-05, 0.5951775132933e+01, 0.7058598460518e+01,
+      0.2278386100876e-05, 0.4845456398785e+01, 0.4694002934110e+01,
+      0.2559088003308e-05, 0.6945321117311e+00, 0.1216800268190e+02,
+
+      0.2561079286856e-05, 0.6167224608301e+01, 0.7099330490126e+00,
+      0.1792755796387e-05, 0.1400122509632e+01, 0.7962980379786e+00,
+      0.1818715656502e-05, 0.4703347611830e+01, 0.6283142985870e+01,
+      0.1818744924791e-05, 0.5086748900237e+01, 0.6283008715021e+01,
+      0.1554518791390e-05, 0.5331008042713e-01, 0.2513230340178e+02,
+      0.2063265737239e-05, 0.4283680484178e+01, 0.1179062909082e+02,
+      0.1497613520041e-05, 0.6074207826073e+01, 0.5486777812467e+01,
+      0.2000617940427e-05, 0.2501426281450e+01, 0.1778984560711e+02,
+      0.1289731195580e-05, 0.3646340599536e+01, 0.7079373888424e+01,
+      0.1282657998934e-05, 0.3232864804902e+01, 0.3738761453707e+01,
+
+      0.1528915968658e-05, 0.5581433416669e+01, 0.2132990797783e+00,
+      0.1187304098432e-05, 0.5453576453694e+01, 0.9437762937313e+01,
+      0.7842782928118e-06, 0.2823953922273e+00, 0.8827390247185e+01,
+      0.7352892280868e-06, 0.1124369580175e+01, 0.1589072916335e+01,
+      0.6570189360797e-06, 0.2089154042840e+01, 0.1176985366291e+02,
+      0.6324967590410e-06, 0.6704855581230e+00, 0.6262300422539e+01,
+      0.6298289872283e-06, 0.2836414855840e+01, 0.6303851278352e+01,
+      0.6476686465855e-06, 0.4852433866467e+00, 0.7113454667900e-02,
+      0.8587034651234e-06, 0.1453511005668e+01, 0.1672837615881e+03,
+      0.8068948788113e-06, 0.9224087798609e+00, 0.6069776770667e+01,
+
+      0.8353786011661e-06, 0.4631707184895e+01, 0.3340612434717e+01,
+      0.6009324532132e-06, 0.1829498827726e+01, 0.4136910472696e+01,
+      0.7558158559566e-06, 0.2588596800317e+01, 0.6496374930224e+01,
+      0.5809279504503e-06, 0.5516818853476e+00, 0.1097707878456e+02,
+      0.5374131950254e-06, 0.6275674734960e+01, 0.1194447056968e+01,
+      0.5711160507326e-06, 0.1091905956872e+01, 0.6282095334605e+01,
+      0.5710183170746e-06, 0.2415001635090e+01, 0.6284056366286e+01,
+      0.5144373590610e-06, 0.6020336443438e+01, 0.6290189305114e+01,
+      0.5103108927267e-06, 0.3775634564605e+01, 0.6275962395778e+01,
+      0.4960654697891e-06, 0.1073450946756e+01, 0.6127655567643e+01,
+
+      0.4786385689280e-06, 0.2431178012310e+01, 0.6438496133249e+01,
+      0.6109911263665e-06, 0.5343356157914e+01, 0.3154687086868e+01,
+      0.4839898944024e-06, 0.5830833594047e-01, 0.8018209333619e+00,
+      0.4734822623919e-06, 0.4536080134821e+01, 0.3128388763578e+01,
+      0.4834741473290e-06, 0.2585090489754e+00, 0.7084896783808e+01,
+      0.5134858581156e-06, 0.4213317172603e+01, 0.1235285262111e+02,
+      0.5064004264978e-06, 0.4814418806478e+00, 0.1185621865188e+02,
+      0.3753476772761e-06, 0.1599953399788e+01, 0.8429241228195e+01,
+      0.4935264014283e-06, 0.2157417556873e+01, 0.2544314396739e+01,
+      0.3950929600897e-06, 0.3359394184254e+01, 0.5481254917084e+01,
+
+      0.4895849789777e-06, 0.5165704376558e+01, 0.9225539266174e+01,
+      0.4215241688886e-06, 0.2065368800993e+01, 0.1726015463500e+02,
+      0.3796773731132e-06, 0.1468606346612e+01, 0.4265981595566e+00,
+      0.3114178142515e-06, 0.3615638079474e+01, 0.2146165377750e+01,
+      0.3260664220838e-06, 0.4417134922435e+01, 0.4164311961999e+01,
+      0.3976996123008e-06, 0.4700866883004e+01, 0.5856477690889e+01,
+      0.2801459672924e-06, 0.4538902060922e+01, 0.1256967486051e+02,
+      0.3638931868861e-06, 0.1334197991475e+01, 0.1807370494127e+02,
+      0.2487013269476e-06, 0.3749275558275e+01, 0.2629832328990e-01,
+      0.3034165481994e-06, 0.4236622030873e+00, 0.4535059491685e+01,
+
+      0.2676278825586e-06, 0.5970848007811e+01, 0.3930209696940e+01,
+      0.2764903818918e-06, 0.5194636754501e+01, 0.1256262854127e+02,
+      0.2485149930507e-06, 0.1002434207846e+01, 0.5088628793478e+01,
+      0.2199305540941e-06, 0.3066773098403e+01, 0.1255903824622e+02,
+      0.2571106500435e-06, 0.7588312459063e+00, 0.1336797263425e+02,
+      0.2049751817158e-06, 0.3444977434856e+01, 0.1137170464392e+02,
+      0.2599707296297e-06, 0.1873128542205e+01, 0.7143069561767e+02,
+      0.1785018072217e-06, 0.5015891306615e+01, 0.1748016358760e+01,
+      0.2324833891115e-06, 0.4618271239730e+01, 0.1831953657923e+02,
+      0.1709711119545e-06, 0.5300003455669e+01, 0.4933208510675e+01,
+
+      0.2107159351716e-06, 0.2229819815115e+01, 0.7477522907414e+01,
+      0.1750333080295e-06, 0.6161485880008e+01, 0.1044738781244e+02,
+      0.2000598210339e-06, 0.2967357299999e+01, 0.8031092209206e+01,
+      0.1380920248681e-06, 0.3027007923917e+01, 0.8635942003952e+01,
+      0.1412460470299e-06, 0.6037597163798e+01, 0.2942463415728e+01,
+      0.1888459803001e-06, 0.8561476243374e+00, 0.1561374759853e+03,
+      0.1788370542585e-06, 0.4869736290209e+01, 0.1592596075957e+01,
+      0.1360893296167e-06, 0.3626411886436e+01, 0.1309584267300e+02,
+      0.1506846530160e-06, 0.1550975377427e+01, 0.1649636139783e+02,
+      0.1800913376176e-06, 0.2075826033190e+01, 0.1729818233119e+02,
+
+      0.1436261390649e-06, 0.6148876420255e+01, 0.2042657109477e+02,
+      0.1220227114151e-06, 0.4382583879906e+01, 0.7632943190217e+01,
+      0.1337883603592e-06, 0.2036644327361e+01, 0.1213955354133e+02,
+      0.1159326650738e-06, 0.3892276994687e+01, 0.5331357529664e+01,
+      0.1352853128569e-06, 0.1447950649744e+01, 0.1673046366289e+02,
+      0.1433408296083e-06, 0.4457854692961e+01, 0.7342457794669e+01,
+      0.1234701666518e-06, 0.1538818147151e+01, 0.6279485555400e+01,
+      0.1234027192007e-06, 0.1968523220760e+01, 0.6286666145492e+01,
+      0.1244024091797e-06, 0.5779803499985e+01, 0.1511046609763e+02,
+      0.1097934945516e-06, 0.6210975221388e+00, 0.1098880815746e+02,
+
+      0.1254611329856e-06, 0.2591963807998e+01, 0.1572083878776e+02,
+      0.1158247286784e-06, 0.2483612812670e+01, 0.5729506548653e+01,
+      0.9039078252960e-07, 0.3857554579796e+01, 0.9623688285163e+01,
+      0.9108024978836e-07, 0.5826368512984e+01, 0.7234794171227e+01,
+      0.8887068108436e-07, 0.3475694573987e+01, 0.6148010737701e+01,
+      0.8632374035438e-07, 0.3059070488983e-01, 0.6418140963190e+01,
+      0.7893186992967e-07, 0.1583194837728e+01, 0.2118763888447e+01,
+      0.8297650201172e-07, 0.8519770534637e+00, 0.1471231707864e+02,
+      0.1019759578988e-06, 0.1319598738732e+00, 0.1349867339771e+01,
+      0.1010037696236e-06, 0.9937860115618e+00, 0.6836645152238e+01,
+
+      0.1047727548266e-06, 0.1382138405399e+01, 0.5999216516294e+01,
+      0.7351993881086e-07, 0.3833397851735e+01, 0.6040347114260e+01,
+      0.9868771092341e-07, 0.2124913814390e+01, 0.6566935184597e+01,
+      0.7007321959390e-07, 0.5946305343763e+01, 0.6525804586632e+01,
+      0.6861411679709e-07, 0.4574654977089e+01, 0.7238675589263e+01,
+      0.7554519809614e-07, 0.5949232686844e+01, 0.1253985337760e+02,
+      0.9541880448335e-07, 0.3495242990564e+01, 0.2122839202813e+02,
+      0.7185606722155e-07, 0.4310113471661e+01, 0.6245048154254e+01,
+      0.7131360871710e-07, 0.5480309323650e+01, 0.6321103546637e+01,
+      0.6651142021039e-07, 0.5411097713654e+01, 0.5327476111629e+01,
+
+      0.8538618213667e-07, 0.1827849973951e+01, 0.1101510648075e+02,
+      0.8634954288044e-07, 0.5443584943349e+01, 0.5643178611111e+01,
+      0.7449415051484e-07, 0.2011535459060e+01, 0.5368044267797e+00,
+      0.7421047599169e-07, 0.3464562529249e+01, 0.2354323048545e+02,
+      0.6140694354424e-07, 0.5657556228815e+01, 0.1296430071988e+02,
+      0.6353525143033e-07, 0.3463816593821e+01, 0.1990745094947e+01,
+      0.6221964013447e-07, 0.1532259498697e+01, 0.9517183207817e+00,
+      0.5852480257244e-07, 0.1375396598875e+01, 0.9555997388169e+00,
+      0.6398637498911e-07, 0.2405645801972e+01, 0.2407292145756e+02,
+      0.7039744069878e-07, 0.5397541799027e+01, 0.5225775174439e+00,
+
+      0.6977997694382e-07, 0.4762347105419e+01, 0.1097355562493e+02,
+      0.7460629558396e-07, 0.2711944692164e+01, 0.2200391463820e+02,
+      0.5376577536101e-07, 0.2352980430239e+01, 0.1431416805965e+02,
+      0.7530607893556e-07, 0.1943940180699e+01, 0.1842262939178e+02,
+      0.6822928971605e-07, 0.4337651846959e+01, 0.1554202828031e+00,
+      0.6220772380094e-07, 0.6716871369278e+00, 0.1845107853235e+02,
+      0.6586950799043e-07, 0.2229714460505e+01, 0.5216580451554e+01,
+      0.5873800565771e-07, 0.7627013920580e+00, 0.6398972393349e+00,
+      0.6264346929745e-07, 0.6202785478961e+00, 0.6277552955062e+01,
+      0.6257929115669e-07, 0.2886775596668e+01, 0.6288598745829e+01,
+
+      0.5343536033409e-07, 0.1977241012051e+01, 0.4690479774488e+01,
+      0.5587849781714e-07, 0.1922923484825e+01, 0.1551045220144e+01,
+      0.6905100845603e-07, 0.3570757164631e+01, 0.1030928125552e+00,
+      0.6178957066649e-07, 0.5197558947765e+01, 0.5230807360890e+01,
+      0.6187270224331e-07, 0.8193497368922e+00, 0.5650292065779e+01,
+      0.5385664291426e-07, 0.5406336665586e+01, 0.7771377146812e+02,
+      0.6329363917926e-07, 0.2837760654536e+01, 0.2608790314060e+02,
+      0.4546018761604e-07, 0.2933580297050e+01, 0.5535693017924e+00,
+      0.6196091049375e-07, 0.4157871494377e+01, 0.8467247584405e+02,
+      0.6159555108218e-07, 0.3211703561703e+01, 0.2394243902548e+03,
+
+      0.4995340539317e-07, 0.1459098102922e+01, 0.4732030630302e+01,
+      0.5457031243572e-07, 0.1430457676136e+01, 0.6179983037890e+01,
+      0.4863461418397e-07, 0.2196425916730e+01, 0.9027992316901e+02,
+      0.5342947626870e-07, 0.2086612890268e+01, 0.6386168663001e+01,
+      0.5674296648439e-07, 0.2760204966535e+01, 0.6915859635113e+01,
+      0.4745783120161e-07, 0.4245368971862e+01, 0.6282970628506e+01,
+      0.4745676961198e-07, 0.5544725787016e+01, 0.6283181072386e+01,
+      0.4049796869973e-07, 0.2213984363586e+01, 0.6254626709878e+01,
+      0.4248333596940e-07, 0.8075781952896e+00, 0.7875671926403e+01,
+      0.4027178070205e-07, 0.1293268540378e+01, 0.6311524991013e+01,
+
+      0.4066543943476e-07, 0.3986141175804e+01, 0.3634620989887e+01,
+      0.4858863787880e-07, 0.1276112738231e+01, 0.5760498333002e+01,
+      0.5277398263530e-07, 0.4916111741527e+01, 0.2515860172507e+02,
+      0.4105635656559e-07, 0.1725805864426e+01, 0.6709674010002e+01,
+      0.4376781925772e-07, 0.2243642442106e+01, 0.6805653367890e+01,
+      0.3235827894693e-07, 0.3614135118271e+01, 0.1066495398892e+01,
+      0.3073244740308e-07, 0.2460873393460e+01, 0.5863591145557e+01,
+      0.3088609271373e-07, 0.5678431771790e+01, 0.9917696840332e+01,
+      0.3393022279836e-07, 0.3814017477291e+01, 0.1391601904066e+02,
+      0.3038686508802e-07, 0.4660216229171e+01, 0.1256621883632e+02,
+
+      0.4019677752497e-07, 0.5906906243735e+01, 0.1334167431096e+02,
+      0.3288834998232e-07, 0.9536146445882e+00, 0.1620077269078e+02,
+      0.3889973794631e-07, 0.3942205097644e+01, 0.7478166569050e-01,
+      0.3050438987141e-07, 0.1624810271286e+01, 0.1805292951336e+02,
+      0.3601142564638e-07, 0.4030467142575e+01, 0.6208294184755e+01,
+      0.3689015557141e-07, 0.3648878818694e+01, 0.5966683958112e+01,
+      0.3563471893565e-07, 0.5749584017096e+01, 0.6357857516136e+01,
+      0.2776183170667e-07, 0.2630124187070e+01, 0.3523159621801e-02,
+      0.2922350530341e-07, 0.1790346403629e+01, 0.1272157198369e+02,
+      0.3511076917302e-07, 0.6142198301611e+01, 0.6599467742779e+01,
+
+      0.3619351007632e-07, 0.1432421386492e+01, 0.6019991944201e+01,
+      0.2561254711098e-07, 0.2302822475792e+01, 0.1259245002418e+02,
+      0.2626903942920e-07, 0.8660470994571e+00, 0.6702560555334e+01,
+      0.2550187397083e-07, 0.6069721995383e+01, 0.1057540660594e+02,
+      0.2535873526138e-07, 0.1079020331795e-01, 0.3141537925223e+02,
+      0.3519786153847e-07, 0.3809066902283e+01, 0.2505706758577e+03,
+      0.3424651492873e-07, 0.2075435114417e+01, 0.6546159756691e+01,
+      0.2372676630861e-07, 0.2057803120154e+01, 0.2388894113936e+01,
+      0.2710980779541e-07, 0.1510068488010e+01, 0.1202934727411e+02,
+      0.3038710889704e-07, 0.5043617528901e+01, 0.1256608456547e+02,
+
+      0.2220364130585e-07, 0.3694793218205e+01, 0.1336244973887e+02,
+      0.3025880825460e-07, 0.5450618999049e-01, 0.2908881142201e+02,
+      0.2784493486864e-07, 0.3381164084502e+01, 0.1494531617769e+02,
+      0.2294414142438e-07, 0.4382309025210e+01, 0.6076890225335e+01,
+      0.2012723294724e-07, 0.9142212256518e+00, 0.6262720680387e+01,
+      0.2036357831958e-07, 0.5676172293154e+01, 0.4701116388778e+01,
+      0.2003474823288e-07, 0.2592767977625e+01, 0.6303431020504e+01,
+      0.2207144900109e-07, 0.5404976271180e+01, 0.6489261475556e+01,
+      0.2481664905135e-07, 0.4373284587027e+01, 0.1204357418345e+02,
+      0.2674949182295e-07, 0.5859182188482e+01, 0.4590910121555e+01,
+
+      0.2450554720322e-07, 0.4555381557451e+01, 0.1495633313810e+00,
+      0.2601975986457e-07, 0.3933165584959e+01, 0.1965104848470e+02,
+      0.2199860022848e-07, 0.5227977189087e+01, 0.1351787002167e+02,
+      0.2448121172316e-07, 0.4858060353949e+01, 0.1162474756779e+01,
+      0.1876014864049e-07, 0.5690546553605e+01, 0.6279194432410e+01,
+      0.1874513219396e-07, 0.4099539297446e+01, 0.6286957268481e+01,
+      0.2156380842559e-07, 0.4382594769913e+00, 0.1813929450232e+02,
+      0.1981691240061e-07, 0.1829784152444e+01, 0.4686889479442e+01,
+      0.2329992648539e-07, 0.2836254278973e+01, 0.1002183730415e+02,
+      0.1765184135302e-07, 0.2803494925833e+01, 0.4292330755499e+01,
+
+      0.2436368366085e-07, 0.2836897959677e+01, 0.9514313292143e+02,
+      0.2164089203889e-07, 0.6127522446024e+01, 0.6037244212485e+01,
+      0.1847755034221e-07, 0.3683163635008e+01, 0.2427287361862e+00,
+      0.1674798769966e-07, 0.3316993867246e+00, 0.1311972100268e+02,
+      0.2222542124356e-07, 0.8294097805480e+00, 0.1266924451345e+02,
+      0.2071074505925e-07, 0.3659492220261e+01, 0.6528907488406e+01,
+      0.1608224471835e-07, 0.4774492067182e+01, 0.1352175143971e+02,
+      0.1857583439071e-07, 0.2873120597682e+01, 0.8662240327241e+01,
+      0.1793018836159e-07, 0.5282441177929e+00, 0.6819880277225e+01,
+      0.1575391221692e-07, 0.1320789654258e+01, 0.1102062672231e+00,
+
+      0.1840132009557e-07, 0.1917110916256e+01, 0.6514761976723e+02,
+      0.1760917288281e-07, 0.2972635937132e+01, 0.5746271423666e+01,
+      0.1561779518516e-07, 0.4372569261981e+01, 0.6272439236156e+01,
+      0.1558687885205e-07, 0.5416424926425e+01, 0.6293712464735e+01,
+      0.1951359382579e-07, 0.3094448898752e+01, 0.2301353951334e+02,
+      0.1569144275614e-07, 0.2802103689808e+01, 0.1765478049437e+02,
+      0.1479130389462e-07, 0.2136435020467e+01, 0.2077542790660e-01,
+      0.1467828510764e-07, 0.7072627435674e+00, 0.1052268489556e+01,
+      0.1627627337440e-07, 0.3947607143237e+01, 0.6327837846670e+00,
+      0.1503498479758e-07, 0.4079248909190e+01, 0.7626583626240e-01,
+
+      0.1297967708237e-07, 0.6269637122840e+01, 0.1149965630200e+02,
+      0.1374416896634e-07, 0.4175657970702e+01, 0.6016468784579e+01,
+      0.1783812325219e-07, 0.1476540547560e+01, 0.3301902111895e+02,
+      0.1525884228756e-07, 0.4653477715241e+01, 0.9411464614024e+01,
+      0.1451067396763e-07, 0.2573001128225e+01, 0.1277945078067e+02,
+      0.1297713111950e-07, 0.5612799618771e+01, 0.6549682916313e+01,
+      0.1462784012820e-07, 0.4189661623870e+01, 0.1863592847156e+02,
+      0.1384185980007e-07, 0.2656915472196e+01, 0.2379164476796e+01,
+      0.1221497599801e-07, 0.5612515760138e+01, 0.1257326515556e+02,
+      0.1560574525896e-07, 0.4783414317919e+01, 0.1887552587463e+02,
+
+      0.1544598372036e-07, 0.2694431138063e+01, 0.1820933031200e+02,
+      0.1531678928696e-07, 0.4105103489666e+01, 0.2593412433514e+02,
+      0.1349321503795e-07, 0.3082437194015e+00, 0.5120601093667e+01,
+      0.1252030290917e-07, 0.6124072334087e+01, 0.6993008899458e+01,
+      0.1459243816687e-07, 0.3733103981697e+01, 0.3813291813120e-01,
+      0.1226103625262e-07, 0.1267127706817e+01, 0.2435678079171e+02,
+      0.1019449641504e-07, 0.4367790112269e+01, 0.1725663147538e+02,
+      0.1380789433607e-07, 0.3387201768700e+01, 0.2458316379602e+00,
+      0.1019453421658e-07, 0.9204143073737e+00, 0.6112403035119e+01,
+      0.1297929434405e-07, 0.5786874896426e+01, 0.1249137003520e+02,
+
+      0.9912677786097e-08, 0.3164232870746e+01, 0.6247047890016e+01,
+      0.9829386098599e-08, 0.2586762413351e+01, 0.6453748665772e+01,
+      0.1226807746104e-07, 0.6239068436607e+01, 0.5429879531333e+01,
+      0.1192691755997e-07, 0.1867380051424e+01, 0.6290122169689e+01,
+      0.9836499227081e-08, 0.3424716293727e+00, 0.6319103810876e+01,
+      0.9642862564285e-08, 0.5661372990657e+01, 0.8273820945392e+01,
+      0.1165184404862e-07, 0.5768367239093e+01, 0.1778273215245e+02,
+      0.1175794418818e-07, 0.1657351222943e+01, 0.6276029531202e+01,
+      0.1018948635601e-07, 0.6458292350865e+00, 0.1254537627298e+02,
+      0.9500383606676e-08, 0.1054306140741e+01, 0.1256517118505e+02,
+
+      0.1227512202906e-07, 0.2505278379114e+01, 0.2248384854122e+02,
+      0.9664792009993e-08, 0.4289737277000e+01, 0.6259197520765e+01,
+      0.9613285666331e-08, 0.5500597673141e+01, 0.6306954180126e+01,
+      0.1117906736211e-07, 0.2361405953468e+01, 0.1779695906178e+02,
+      0.9611378640782e-08, 0.2851310576269e+01, 0.2061856251104e+00,
+      0.8845354852370e-08, 0.6208777705343e+01, 0.1692165728891e+01,
+      0.1054046966600e-07, 0.5413091423934e+01, 0.2204125344462e+00,
+      0.1215539124483e-07, 0.5613969479755e+01, 0.8257698122054e+02,
+      0.9932460955209e-08, 0.1106124877015e+01, 0.1017725758696e+02,
+      0.8785804715043e-08, 0.2869224476477e+01, 0.9491756770005e+00,
+
+      0.8538084097562e-08, 0.6159640899344e+01, 0.6393282117669e+01,
+      0.8648994369529e-08, 0.1374901198784e+01, 0.4804209201333e+01,
+      0.1039063219067e-07, 0.5171080641327e+01, 0.1550861511662e+02,
+      0.8867983926439e-08, 0.8317320304902e+00, 0.3903911373650e+01,
+      0.8327495955244e-08, 0.3605591969180e+01, 0.6172869583223e+01,
+      0.9243088356133e-08, 0.6114299196843e+01, 0.6267823317922e+01,
+      0.9205657357835e-08, 0.3675153683737e+01, 0.6298328382969e+01,
+      0.1033269714606e-07, 0.3313328813024e+01, 0.5573142801433e+01,
+      0.8001706275552e-08, 0.2019980960053e+01, 0.2648454860559e+01,
+      0.9171858254191e-08, 0.8992015524177e+00, 0.1498544001348e+03,
+
+      0.1075327150242e-07, 0.2898669963648e+01, 0.3694923081589e+02,
+      0.9884866689828e-08, 0.4946715904478e+01, 0.1140367694411e+02,
+      0.9541835576677e-08, 0.2371787888469e+01, 0.1256713221673e+02,
+      0.7739903376237e-08, 0.2213775190612e+01, 0.7834121070590e+01,
+      0.7311962684106e-08, 0.3429378787739e+01, 0.1192625446156e+02,
+      0.9724904869624e-08, 0.6195878564404e+01, 0.2280573557157e+02,
+      0.9251628983612e-08, 0.6511509527390e+00, 0.2787043132925e+01,
+      0.7320763787842e-08, 0.6001083639421e+01, 0.6282655592598e+01,
+      0.7320296650962e-08, 0.3789073265087e+01, 0.6283496108294e+01,
+      0.7947032271039e-08, 0.1059659582204e+01, 0.1241073141809e+02,
+
+      0.9005277053115e-08, 0.1280315624361e+01, 0.6281591679874e+01,
+      0.8995601652048e-08, 0.2224439106766e+01, 0.6284560021018e+01,
+      0.8288040568796e-08, 0.5234914433867e+01, 0.1241658836951e+02,
+      0.6359381347255e-08, 0.4137989441490e+01, 0.1596186371003e+01,
+      0.8699572228626e-08, 0.1758411009497e+01, 0.6133512519065e+01,
+      0.6456797542736e-08, 0.5919285089994e+01, 0.1685848245639e+02,
+      0.7424573475452e-08, 0.5414616938827e+01, 0.4061219149443e+01,
+      0.7235671196168e-08, 0.1496516557134e+01, 0.1610006857377e+03,
+      0.8104015182733e-08, 0.1919918242764e+01, 0.8460828644453e+00,
+      0.8098576535937e-08, 0.3819615855458e+01, 0.3894181736510e+01,
+
+      0.6275292346625e-08, 0.6244264115141e+01, 0.8531963191132e+00,
+      0.6052432989112e-08, 0.5037731872610e+00, 0.1567108171867e+02,
+      0.5705651535817e-08, 0.2984557271995e+01, 0.1258692712880e+02,
+      0.5789650115138e-08, 0.6087038140697e+01, 0.1193336791622e+02,
+      0.5512132153377e-08, 0.5855668994076e+01, 0.1232342296471e+02,
+      0.7388890819102e-08, 0.2443128574740e+01, 0.4907302013889e+01,
+      0.5467593991798e-08, 0.3017561234194e+01, 0.1884211409667e+02,
+      0.6388519802999e-08, 0.5887386712935e+01, 0.5217580628120e+02,
+      0.6106777149944e-08, 0.3483461059895e+00, 0.1422690933580e-01,
+      0.7383420275489e-08, 0.5417387056707e+01, 0.2358125818164e+02,
+
+      0.5505208141738e-08, 0.2848193644783e+01, 0.1151388321134e+02,
+      0.6310757462877e-08, 0.2349882520828e+01, 0.1041998632314e+02,
+      0.6166904929691e-08, 0.5728575944077e+00, 0.6151533897323e+01,
+      0.5263442042754e-08, 0.4495796125937e+01, 0.1885275071096e+02,
+      0.5591828082629e-08, 0.1355441967677e+01, 0.4337116142245e+00,
+      0.5397051680497e-08, 0.1673422864307e+01, 0.6286362197481e+01,
+      0.5396992745159e-08, 0.1833502206373e+01, 0.6279789503410e+01,
+      0.6572913000726e-08, 0.3331122065824e+01, 0.1176433076753e+02,
+      0.5123421866413e-08, 0.2165327142679e+01, 0.1245594543367e+02,
+      0.5930495725999e-08, 0.2931146089284e+01, 0.6414617803568e+01,
+
+      0.6431797403933e-08, 0.4134407994088e+01, 0.1350651127443e+00,
+      0.5003182207604e-08, 0.3805420303749e+01, 0.1096996532989e+02,
+      0.5587731032504e-08, 0.1082469260599e+01, 0.6062663316000e+01,
+      0.5935263407816e-08, 0.8384333678401e+00, 0.5326786718777e+01,
+      0.4756019827760e-08, 0.3552588749309e+01, 0.3104930017775e+01,
+      0.6599951172637e-08, 0.4320826409528e+01, 0.4087944051283e+02,
+      0.5902606868464e-08, 0.4811879454445e+01, 0.5849364236221e+01,
+      0.5921147809031e-08, 0.9942628922396e-01, 0.1581959461667e+01,
+      0.5505382581266e-08, 0.2466557607764e+01, 0.6503488384892e+01,
+      0.5353771071862e-08, 0.4551978748683e+01, 0.1735668374386e+03,
+
+      0.5063282210946e-08, 0.5710812312425e+01, 0.1248988586463e+02,
+      0.5926120403383e-08, 0.1333998428358e+01, 0.2673594526851e+02,
+      0.5211016176149e-08, 0.4649315360760e+01, 0.2460261242967e+02,
+      0.5347075084894e-08, 0.5512754081205e+01, 0.4171425416666e+01,
+      0.4872609773574e-08, 0.1308025299938e+01, 0.5333900173445e+01,
+      0.4727711321420e-08, 0.2144908368062e+01, 0.7232251527446e+01,
+      0.6029426018652e-08, 0.5567259412084e+01, 0.3227113045244e+03,
+      0.4321485284369e-08, 0.5230667156451e+01, 0.9388005868221e+01,
+      0.4476406760553e-08, 0.6134081115303e+01, 0.5547199253223e+01,
+      0.5835268277420e-08, 0.4783808492071e+01, 0.7285056171570e+02,
+
+      0.5172183602748e-08, 0.5161817911099e+01, 0.1884570439172e+02,
+      0.5693571465184e-08, 0.1381646203111e+01, 0.9723862754494e+02,
+      0.4060634965349e-08, 0.3876705259495e+00, 0.4274518229222e+01,
+      0.3967398770473e-08, 0.5029491776223e+01, 0.3496032717521e+01,
+      0.3943754005255e-08, 0.1923162955490e+01, 0.6244942932314e+01,
+      0.4781323427824e-08, 0.4633332586423e+01, 0.2929661536378e+02,
+      0.3871483781204e-08, 0.1616650009743e+01, 0.6321208768577e+01,
+      0.5141741733997e-08, 0.9817316704659e-01, 0.1232032006293e+02,
+      0.4002385978497e-08, 0.3656161212139e+01, 0.7018952447668e+01,
+      0.4901092604097e-08, 0.4404098713092e+01, 0.1478866649112e+01,
+
+      0.3740932630345e-08, 0.5181188732639e+00, 0.6922973089781e+01,
+      0.4387283718538e-08, 0.3254859566869e+01, 0.2331413144044e+03,
+      0.5019197802033e-08, 0.3086773224677e+01, 0.1715706182245e+02,
+      0.3834931695175e-08, 0.2797882673542e+01, 0.1491901785440e+02,
+      0.3760413942497e-08, 0.2892676280217e+01, 0.1726726808967e+02,
+      0.3719717204628e-08, 0.5861046025739e+01, 0.6297302759782e+01,
+      0.4145623530149e-08, 0.2168239627033e+01, 0.1376059875786e+02,
+      0.3932788425380e-08, 0.6271811124181e+01, 0.7872148766781e+01,
+      0.3686377476857e-08, 0.3936853151404e+01, 0.6268848941110e+01,
+      0.3779077950339e-08, 0.1404148734043e+01, 0.4157198507331e+01,
+
+      0.4091334550598e-08, 0.2452436180854e+01, 0.9779108567966e+01,
+      0.3926694536146e-08, 0.6102292739040e+01, 0.1098419223922e+02,
+      0.4841000253289e-08, 0.6072760457276e+01, 0.1252801878276e+02,
+      0.4949340130240e-08, 0.1154832815171e+01, 0.1617106187867e+03,
+      0.3761557737360e-08, 0.5527545321897e+01, 0.3185192151914e+01,
+      0.3647396268188e-08, 0.1525035688629e+01, 0.6271346477544e+01,
+      0.3932405074189e-08, 0.5570681040569e+01, 0.2139354194808e+02,
+      0.3631322501141e-08, 0.1981240601160e+01, 0.6294805223347e+01,
+      0.4130007425139e-08, 0.2050060880201e+01, 0.2195415756911e+02,
+      0.4433905965176e-08, 0.3277477970321e+01, 0.7445550607224e+01,
+
+      0.3851814176947e-08, 0.5210690074886e+01, 0.9562891316684e+00,
+      0.3485807052785e-08, 0.6653274904611e+00, 0.1161697602389e+02,
+      0.3979772816991e-08, 0.1767941436148e+01, 0.2277943724828e+02,
+      0.3402607460500e-08, 0.3421746306465e+01, 0.1087398597200e+02,
+      0.4049993000926e-08, 0.1127144787547e+01, 0.3163918923335e+00,
+      0.3420511182382e-08, 0.4214794779161e+01, 0.1362553364512e+02,
+      0.3640772365012e-08, 0.5324905497687e+01, 0.1725304118033e+02,
+      0.3323037987501e-08, 0.6135761838271e+01, 0.6279143387820e+01,
+      0.4503141663637e-08, 0.1802305450666e+01, 0.1385561574497e+01,
+      0.4314560055588e-08, 0.4812299731574e+01, 0.4176041334900e+01,
+
+      0.3294226949110e-08, 0.3657547059723e+01, 0.6287008313071e+01,
+      0.3215657197281e-08, 0.4866676894425e+01, 0.5749861718712e+01,
+      0.4129362656266e-08, 0.3809342558906e+01, 0.5905702259363e+01,
+      0.3137762976388e-08, 0.2494635174443e+01, 0.2099539292909e+02,
+      0.3514010952384e-08, 0.2699961831678e+01, 0.7335344340001e+01,
+      0.3327607571530e-08, 0.3318457714816e+01, 0.5436992986000e+01,
+      0.3541066946675e-08, 0.4382703582466e+01, 0.1234573916645e+02,
+      0.3216179847052e-08, 0.5271066317054e+01, 0.3802769619140e-01,
+      0.2959045059570e-08, 0.5819591585302e+01, 0.2670964694522e+02,
+      0.3884040326665e-08, 0.5980934960428e+01, 0.6660449441528e+01,
+
+      0.2922027539886e-08, 0.3337290282483e+01, 0.1375773836557e+01,
+      0.4110846382042e-08, 0.5742978187327e+01, 0.4480965020977e+02,
+      0.2934508411032e-08, 0.2278075804200e+01, 0.6408777551755e+00,
+      0.3966896193000e-08, 0.5835747858477e+01, 0.3773735910827e+00,
+      0.3286695827610e-08, 0.5838898193902e+01, 0.3932462625300e-02,
+      0.3720643094196e-08, 0.1122212337858e+01, 0.1646033343740e+02,
+      0.3285508906174e-08, 0.9182250996416e+00, 0.1081813534213e+02,
+      0.3753880575973e-08, 0.5174761973266e+01, 0.5642198095270e+01,
+      0.3022129385587e-08, 0.3381611020639e+01, 0.2982630633589e+02,
+      0.2798569205621e-08, 0.3546193723922e+01, 0.1937891852345e+02,
+
+      0.3397872070505e-08, 0.4533203197934e+01, 0.6923953605621e+01,
+      0.3708099772977e-08, 0.2756168198616e+01, 0.3066615496545e+02,
+      0.3599283541510e-08, 0.1934395469918e+01, 0.6147450479709e+01,
+      0.3688702753059e-08, 0.7149920971109e+00, 0.2636725487657e+01,
+      0.2681084724003e-08, 0.4899819493154e+01, 0.6816289982179e+01,
+      0.3495993460759e-08, 0.1572418915115e+01, 0.6418701221183e+01,
+      0.3130770324995e-08, 0.8912190180489e+00, 0.1235996607578e+02,
+      0.2744353821941e-08, 0.3800821940055e+01, 0.2059724391010e+02,
+      0.2842732906341e-08, 0.2644717440029e+01, 0.2828699048865e+02,
+      0.3046882682154e-08, 0.3987793020179e+01, 0.6055599646783e+01,
+
+      0.2399072455143e-08, 0.9908826440764e+00, 0.6255674361143e+01,
+      0.2384306274204e-08, 0.2516149752220e+01, 0.6310477339748e+01,
+      0.2977324500559e-08, 0.5849195642118e+01, 0.1652265972112e+02,
+      0.3062835258972e-08, 0.1681660100162e+01, 0.1172006883645e+02,
+      0.3109682589231e-08, 0.5804143987737e+00, 0.2751146787858e+02,
+      0.2903920355299e-08, 0.5800768280123e+01, 0.6510552054109e+01,
+      0.2823221989212e-08, 0.9241118370216e+00, 0.5469525544182e+01,
+      0.3187949696649e-08, 0.3139776445735e+01, 0.1693792562116e+03,
+      0.2922559771655e-08, 0.3549440782984e+01, 0.2630839062450e+00,
+      0.2436302066603e-08, 0.4735540696319e+01, 0.3946258593675e+00,
+
+      0.3049473043606e-08, 0.4998289124561e+01, 0.8390110365991e+01,
+      0.2863682575784e-08, 0.6709515671102e+00, 0.2243449970715e+00,
+      0.2641750517966e-08, 0.5410978257284e+01, 0.2986433403208e+02,
+      0.2704093466243e-08, 0.4778317207821e+01, 0.6129297044991e+01,
+      0.2445522177011e-08, 0.6009020662222e+01, 0.1171295538178e+02,
+      0.2623608810230e-08, 0.5010449777147e+01, 0.6436854655901e+01,
+      0.2079259704053e-08, 0.5980943768809e+01, 0.2019909489111e+02,
+      0.2820225596771e-08, 0.2679965110468e+01, 0.5934151399930e+01,
+      0.2365221950927e-08, 0.1894231148810e+01, 0.2470570524223e+02,
+      0.2359682077149e-08, 0.4220752950780e+01, 0.8671969964381e+01,
+
+      0.2387577137206e-08, 0.2571783940617e+01, 0.7096626156709e+01,
+      0.1982102089816e-08, 0.5169765997119e+00, 0.1727188400790e+02,
+      0.2687502389925e-08, 0.6239078264579e+01, 0.7075506709219e+02,
+      0.2207751669135e-08, 0.2031184412677e+01, 0.4377611041777e+01,
+      0.2618370214274e-08, 0.8266079985979e+00, 0.6632000300961e+01,
+      0.2591951887361e-08, 0.8819350522008e+00, 0.4873985990671e+02,
+      0.2375055656248e-08, 0.3520944177789e+01, 0.1590676413561e+02,
+      0.2472019978911e-08, 0.1551431908671e+01, 0.6612329252343e+00,
+      0.2368157127199e-08, 0.4178610147412e+01, 0.3459636466239e+02,
+      0.1764846605693e-08, 0.1506764000157e+01, 0.1980094587212e+02,
+
+      0.2291769608798e-08, 0.2118250611782e+01, 0.2844914056730e-01,
+      0.2209997316943e-08, 0.3363255261678e+01, 0.2666070658668e+00,
+      0.2292699097923e-08, 0.4200423956460e+00, 0.1484170571900e-02,
+      0.1629683015329e-08, 0.2331362582487e+01, 0.3035599730800e+02,
+      0.2206492862426e-08, 0.3400274026992e+01, 0.6281667977667e+01,
+      0.2205746568257e-08, 0.1066051230724e+00, 0.6284483723224e+01,
+      0.2026310767991e-08, 0.2779066487979e+01, 0.2449240616245e+02,
+      0.1762977622163e-08, 0.9951450691840e+00, 0.2045286941806e+02,
+      0.1368535049606e-08, 0.6402447365817e+00, 0.2473415438279e+02,
+      0.1720598775450e-08, 0.2303524214705e+00, 0.1679593901136e+03,
+
+      0.1702429015449e-08, 0.6164622655048e+01, 0.3338575901272e+03,
+      0.1414033197685e-08, 0.3954561185580e+01, 0.1624205518357e+03,
+      0.1573768958043e-08, 0.2028286308984e+01, 0.3144167757552e+02,
+      0.1650705184447e-08, 0.2304040666128e+01, 0.5267006960365e+02,
+      0.1651087618855e-08, 0.2538461057280e+01, 0.8956999012000e+02,
+      0.1616409518983e-08, 0.5111054348152e+01, 0.3332657872986e+02,
+      0.1537175173581e-08, 0.5601130666603e+01, 0.3852657435933e+02,
+      0.1593191980553e-08, 0.2614340453411e+01, 0.2282781046519e+03,
+      0.1499480170643e-08, 0.3624721577264e+01, 0.2823723341956e+02,
+      0.1493807843235e-08, 0.4214569879008e+01, 0.2876692439167e+02,
+
+      0.1074571199328e-08, 0.1496911744704e+00, 0.8397383534231e+02,
+      0.1074406983417e-08, 0.1187817671922e+01, 0.8401985929482e+02,
+      0.9757576855851e-09, 0.2655703035858e+01, 0.7826370942180e+02,
+      0.1258432887565e-08, 0.4969896184844e+01, 0.3115650189215e+03,
+      0.1240336343282e-08, 0.5192460776926e+01, 0.1784300471910e+03,
+      0.9016107005164e-09, 0.1960356923057e+01, 0.5886454391678e+02,
+      0.1135392360918e-08, 0.5082427809068e+01, 0.7842370451713e+02,
+      0.9216046089565e-09, 0.2793775037273e+01, 0.1014262087719e+03,
+      0.1061276615030e-08, 0.3726144311409e+01, 0.5660027930059e+02,
+      0.1010110596263e-08, 0.7404080708937e+00, 0.4245678405627e+02,
+
+      0.7217424756199e-09, 0.2697449980577e-01, 0.2457074661053e+03,
+      0.6912003846756e-09, 0.4253296276335e+01, 0.1679936946371e+03,
+      0.6871814664847e-09, 0.5148072412354e+01, 0.6053048899753e+02,
+      0.4887158016343e-09, 0.2153581148294e+01, 0.9656299901946e+02,
+      0.5161802866314e-09, 0.3852750634351e+01, 0.2442876000072e+03,
+      0.5652599559057e-09, 0.1233233356270e+01, 0.8365903305582e+02,
+      0.4710812608586e-09, 0.5610486976767e+01, 0.3164282286739e+03,
+      0.4909977500324e-09, 0.1639629524123e+01, 0.4059982187939e+03,
+      0.4772641839378e-09, 0.3737100368583e+01, 0.1805255418145e+03,
+      0.4487562567153e-09, 0.1158417054478e+00, 0.8433466158131e+02,
+
+      0.3943441230497e-09, 0.6243502862796e+00, 0.2568537517081e+03,
+      0.3952236913598e-09, 0.3510377382385e+01, 0.2449975330562e+03,
+      0.3788898363417e-09, 0.5916128302299e+01, 0.1568131045107e+03,
+      0.3738329328831e-09, 0.1042266763456e+01, 0.3948519331910e+03,
+      0.2451199165151e-09, 0.1166788435700e+01, 0.1435713242844e+03,
+      0.2436734402904e-09, 0.3254726114901e+01, 0.2268582385539e+03,
+      0.2213605274325e-09, 0.1687210598530e+01, 0.1658638954901e+03,
+      0.1491521204829e-09, 0.2657541786794e+01, 0.2219950288015e+03,
+      0.1474995329744e-09, 0.5013089805819e+01, 0.3052819430710e+03,
+      0.1661939475656e-09, 0.5495315428418e+01, 0.2526661704812e+03,
+
+      0.9015946748003e-10, 0.2236989966505e+01, 0.4171445043968e+03 };
+
+/* Sun-to-Earth, T^0, Z */
+   static const double e0z[] = {
+      0.2796207639075e-05, 0.3198701560209e+01, 0.8433466158131e+02,
+      0.1016042198142e-05, 0.5422360395913e+01, 0.5507553240374e+01,
+      0.8044305033647e-06, 0.3880222866652e+01, 0.5223693906222e+01,
+      0.4385347909274e-06, 0.3704369937468e+01, 0.2352866153506e+01,
+      0.3186156414906e-06, 0.3999639363235e+01, 0.1577343543434e+01,
+      0.2272412285792e-06, 0.3984738315952e+01, 0.1047747311755e+01,
+      0.1645620103007e-06, 0.3565412516841e+01, 0.5856477690889e+01,
+      0.1815836921166e-06, 0.4984507059020e+01, 0.6283075850446e+01,
+      0.1447461676364e-06, 0.3702753570108e+01, 0.9437762937313e+01,
+      0.1430760876382e-06, 0.3409658712357e+01, 0.1021328554739e+02,
+
+      0.1120445753226e-06, 0.4829561570246e+01, 0.1414349524433e+02,
+      0.1090232840797e-06, 0.2080729178066e+01, 0.6812766822558e+01,
+      0.9715727346551e-07, 0.3476295881948e+01, 0.4694002934110e+01,
+      0.1036267136217e-06, 0.4056639536648e+01, 0.7109288135493e+02,
+      0.8752665271340e-07, 0.4448159519911e+01, 0.5753384878334e+01,
+      0.8331864956004e-07, 0.4991704044208e+01, 0.7084896783808e+01,
+      0.6901658670245e-07, 0.4325358994219e+01, 0.6275962395778e+01,
+      0.9144536848998e-07, 0.1141826375363e+01, 0.6620890113188e+01,
+      0.7205085037435e-07, 0.3624344170143e+01, 0.5296909721118e+00,
+      0.7697874654176e-07, 0.5554257458998e+01, 0.1676215758509e+03,
+
+      0.5197545738384e-07, 0.6251760961735e+01, 0.1807370494127e+02,
+      0.5031345378608e-07, 0.2497341091913e+01, 0.4705732307012e+01,
+      0.4527110205840e-07, 0.2335079920992e+01, 0.6309374173736e+01,
+      0.4753355798089e-07, 0.7094148987474e+00, 0.5884926831456e+01,
+      0.4296951977516e-07, 0.1101916352091e+01, 0.6681224869435e+01,
+      0.3855341568387e-07, 0.1825495405486e+01, 0.5486777812467e+01,
+      0.5253930970990e-07, 0.4424740687208e+01, 0.7860419393880e+01,
+      0.4024630496471e-07, 0.5120498157053e+01, 0.1336797263425e+02,
+      0.4061069791453e-07, 0.6029771435451e+01, 0.3930209696940e+01,
+      0.3797883804205e-07, 0.4435193600836e+00, 0.3154687086868e+01,
+
+      0.2933033225587e-07, 0.5124157356507e+01, 0.1059381944224e+01,
+      0.3503000930426e-07, 0.5421830162065e+01, 0.6069776770667e+01,
+      0.3670096214050e-07, 0.4582101667297e+01, 0.1219403291462e+02,
+      0.2905609437008e-07, 0.1926566420072e+01, 0.1097707878456e+02,
+      0.2466827821713e-07, 0.6090174539834e+00, 0.6496374930224e+01,
+      0.2691647295332e-07, 0.1393432595077e+01, 0.2200391463820e+02,
+      0.2150554667946e-07, 0.4308671715951e+01, 0.5643178611111e+01,
+      0.2237481922680e-07, 0.8133968269414e+00, 0.8635942003952e+01,
+      0.1817741038157e-07, 0.3755205127454e+01, 0.3340612434717e+01,
+      0.2227820762132e-07, 0.2759558596664e+01, 0.1203646072878e+02,
+
+      0.1944713772307e-07, 0.5699645869121e+01, 0.1179062909082e+02,
+      0.1527340520662e-07, 0.1986749091746e+01, 0.3981490189893e+00,
+      0.1577282574914e-07, 0.3205017217983e+01, 0.5088628793478e+01,
+      0.1424738825424e-07, 0.6256747903666e+01, 0.2544314396739e+01,
+      0.1616563121701e-07, 0.2601671259394e+00, 0.1729818233119e+02,
+      0.1401210391692e-07, 0.4686939173506e+01, 0.7058598460518e+01,
+      0.1488726974214e-07, 0.2815862451372e+01, 0.2593412433514e+02,
+      0.1692626442388e-07, 0.4956894109797e+01, 0.1564752902480e+03,
+      0.1123571582910e-07, 0.2381192697696e+01, 0.3738761453707e+01,
+      0.9903308606317e-08, 0.4294851657684e+01, 0.9225539266174e+01,
+
+      0.9174533187191e-08, 0.3075171510642e+01, 0.4164311961999e+01,
+      0.8645985631457e-08, 0.5477534821633e+00, 0.8429241228195e+01,
+     -0.1085876492688e-07, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.9264309077815e-08, 0.5968571670097e+01, 0.7079373888424e+01,
+      0.8243116984954e-08, 0.1489098777643e+01, 0.1044738781244e+02,
+      0.8268102113708e-08, 0.3512977691983e+01, 0.1150676975667e+02,
+      0.9043613988227e-08, 0.1290704408221e+00, 0.1101510648075e+02,
+      0.7432912038789e-08, 0.1991086893337e+01, 0.2608790314060e+02,
+      0.8586233727285e-08, 0.4238357924414e+01, 0.2986433403208e+02,
+      0.7612230060131e-08, 0.2911090150166e+01, 0.4732030630302e+01,
+
+      0.7097787751408e-08, 0.1908938392390e+01, 0.8031092209206e+01,
+      0.7640237040175e-08, 0.6129219000168e+00, 0.7962980379786e+00,
+      0.7070445688081e-08, 0.1380417036651e+01, 0.2146165377750e+01,
+      0.7690770957702e-08, 0.1680504249084e+01, 0.2122839202813e+02,
+      0.8051292542594e-08, 0.5127423484511e+01, 0.2942463415728e+01,
+      0.5902709104515e-08, 0.2020274190917e+01, 0.7755226100720e+00,
+      0.5134567496462e-08, 0.2606778676418e+01, 0.1256615170089e+02,
+      0.5525802046102e-08, 0.1613011769663e+01, 0.8018209333619e+00,
+      0.5880724784221e-08, 0.4604483417236e+01, 0.4690479774488e+01,
+      0.5211699081370e-08, 0.5718964114193e+01, 0.8827390247185e+01,
+
+      0.4891849573562e-08, 0.3689658932196e+01, 0.2132990797783e+00,
+      0.5150246069997e-08, 0.4099769855122e+01, 0.6480980550449e+02,
+      0.5102434319633e-08, 0.5660834602509e+01, 0.3379454372902e+02,
+      0.5083405254252e-08, 0.9842221218974e+00, 0.4136910472696e+01,
+      0.4206562585682e-08, 0.1341363634163e+00, 0.3128388763578e+01,
+      0.4663249683579e-08, 0.8130132735866e+00, 0.5216580451554e+01,
+      0.4099474416530e-08, 0.5791497770644e+01, 0.4265981595566e+00,
+      0.4628251220767e-08, 0.1249802769331e+01, 0.1572083878776e+02,
+      0.5024068728142e-08, 0.4795684802743e+01, 0.6290189305114e+01,
+      0.5120234327758e-08, 0.3810420387208e+01, 0.5230807360890e+01,
+
+      0.5524029815280e-08, 0.1029264714351e+01, 0.2397622045175e+03,
+      0.4757415718860e-08, 0.3528044781779e+01, 0.1649636139783e+02,
+      0.3915786131127e-08, 0.5593889282646e+01, 0.1589072916335e+01,
+      0.4869053149991e-08, 0.3299636454433e+01, 0.7632943190217e+01,
+      0.3649365703729e-08, 0.1286049002584e+01, 0.6206810014183e+01,
+      0.3992493949002e-08, 0.3100307589464e+01, 0.2515860172507e+02,
+      0.3320247477418e-08, 0.6212683940807e+01, 0.1216800268190e+02,
+      0.3287123739696e-08, 0.4699118445928e+01, 0.7234794171227e+01,
+      0.3472776811103e-08, 0.2630507142004e+01, 0.7342457794669e+01,
+      0.3423253294767e-08, 0.2946432844305e+01, 0.9623688285163e+01,
+
+      0.3896173898244e-08, 0.1224834179264e+01, 0.6438496133249e+01,
+      0.3388455337924e-08, 0.1543807616351e+01, 0.1494531617769e+02,
+      0.3062704716523e-08, 0.1191777572310e+01, 0.8662240327241e+01,
+      0.3270075600400e-08, 0.5483498767737e+01, 0.1194447056968e+01,
+      0.3101209215259e-08, 0.8000833804348e+00, 0.3772475342596e+02,
+      0.2780883347311e-08, 0.4077980721888e+00, 0.5863591145557e+01,
+      0.2903605931824e-08, 0.2617490302147e+01, 0.1965104848470e+02,
+      0.2682014743119e-08, 0.2634703158290e+01, 0.7238675589263e+01,
+      0.2534360108492e-08, 0.6102446114873e+01, 0.6836645152238e+01,
+      0.2392564882509e-08, 0.3681820208691e+01, 0.5849364236221e+01,
+
+      0.2656667254856e-08, 0.6216045388886e+01, 0.6133512519065e+01,
+      0.2331242096773e-08, 0.5864949777744e+01, 0.4535059491685e+01,
+      0.2287898363668e-08, 0.4566628532802e+01, 0.7477522907414e+01,
+      0.2336944521306e-08, 0.2442722126930e+01, 0.1137170464392e+02,
+      0.3156632236269e-08, 0.1626628050682e+01, 0.2509084901204e+03,
+      0.2982612402766e-08, 0.2803604512609e+01, 0.1748016358760e+01,
+      0.2774031674807e-08, 0.4654002897158e+01, 0.8223916695780e+02,
+      0.2295236548638e-08, 0.4326518333253e+01, 0.3378142627421e+00,
+      0.2190714699873e-08, 0.4519614578328e+01, 0.2908881142201e+02,
+      0.2191495845045e-08, 0.3012626912549e+01, 0.1673046366289e+02,
+
+      0.2492901628386e-08, 0.1290101424052e+00, 0.1543797956245e+03,
+      0.1993778064319e-08, 0.3864046799414e+01, 0.1778984560711e+02,
+      0.1898146479022e-08, 0.5053777235891e+01, 0.2042657109477e+02,
+      0.1918280127634e-08, 0.2222470192548e+01, 0.4165496312290e+02,
+      0.1916351061607e-08, 0.8719067257774e+00, 0.7737595720538e+02,
+      0.1834720181466e-08, 0.4031491098040e+01, 0.2358125818164e+02,
+      0.1249201523806e-08, 0.5938379466835e+01, 0.3301902111895e+02,
+      0.1477304050539e-08, 0.6544722606797e+00, 0.9548094718417e+02,
+      0.1264316431249e-08, 0.2059072853236e+01, 0.8399684731857e+02,
+      0.1203526495039e-08, 0.3644813532605e+01, 0.4558517281984e+02,
+
+      0.9221681059831e-09, 0.3241815055602e+01, 0.7805158573086e+02,
+      0.7849278367646e-09, 0.5043812342457e+01, 0.5217580628120e+02,
+      0.7983392077387e-09, 0.5000024502753e+01, 0.1501922143975e+03,
+      0.7925395431654e-09, 0.1398734871821e-01, 0.9061773743175e+02,
+      0.7640473285886e-09, 0.5067111723130e+01, 0.4951538251678e+02,
+      0.5398937754482e-09, 0.5597382200075e+01, 0.1613385000004e+03,
+      0.5626247550193e-09, 0.2601338209422e+01, 0.7318837597844e+02,
+      0.5525197197855e-09, 0.5814832109256e+01, 0.1432335100216e+03,
+      0.5407629837898e-09, 0.3384820609076e+01, 0.3230491187871e+03,
+      0.3856739119801e-09, 0.1072391840473e+01, 0.2334791286671e+03,
+
+      0.3856425239987e-09, 0.2369540393327e+01, 0.1739046517013e+03,
+      0.4350867755983e-09, 0.5255575751082e+01, 0.1620484330494e+03,
+      0.3844113924996e-09, 0.5482356246182e+01, 0.9757644180768e+02,
+      0.2854869155431e-09, 0.9573634763143e+00, 0.1697170704744e+03,
+      0.1719227671416e-09, 0.1887203025202e+01, 0.2265204242912e+03,
+      0.1527846879755e-09, 0.3982183931157e+01, 0.3341954043900e+03,
+      0.1128229264847e-09, 0.2787457156298e+01, 0.3119028331842e+03 };
+
+/* Sun-to-Earth, T^1, X */
+   static const double e1x[] = {
+      0.1234046326004e-05, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.5150068824701e-06, 0.6002664557501e+01, 0.1256615170089e+02,
+      0.1290743923245e-07, 0.5959437664199e+01, 0.1884922755134e+02,
+      0.1068615564952e-07, 0.2015529654209e+01, 0.6283075850446e+01,
+      0.2079619142538e-08, 0.1732960531432e+01, 0.6279552690824e+01,
+      0.2078009243969e-08, 0.4915604476996e+01, 0.6286599010068e+01,
+      0.6206330058856e-09, 0.3616457953824e+00, 0.4705732307012e+01,
+      0.5989335313746e-09, 0.3802607304474e+01, 0.6256777527156e+01,
+      0.5958495663840e-09, 0.2845866560031e+01, 0.6309374173736e+01,
+      0.4866923261539e-09, 0.5213203771824e+01, 0.7755226100720e+00,
+
+      0.4267785823142e-09, 0.4368189727818e+00, 0.1059381944224e+01,
+      0.4610675141648e-09, 0.1837249181372e-01, 0.7860419393880e+01,
+      0.3626989993973e-09, 0.2161590545326e+01, 0.5753384878334e+01,
+      0.3563071194389e-09, 0.1452631954746e+01, 0.5884926831456e+01,
+      0.3557015642807e-09, 0.4470593393054e+01, 0.6812766822558e+01,
+      0.3210412089122e-09, 0.5195926078314e+01, 0.6681224869435e+01,
+      0.2875473577986e-09, 0.5916256610193e+01, 0.2513230340178e+02,
+      0.2842913681629e-09, 0.1149902426047e+01, 0.6127655567643e+01,
+      0.2751248215916e-09, 0.5502088574662e+01, 0.6438496133249e+01,
+      0.2481432881127e-09, 0.2921989846637e+01, 0.5486777812467e+01,
+
+      0.2059885976560e-09, 0.3718070376585e+01, 0.7079373888424e+01,
+      0.2015522342591e-09, 0.5979395259740e+01, 0.6290189305114e+01,
+      0.1995364084253e-09, 0.6772087985494e+00, 0.6275962395778e+01,
+      0.1957436436943e-09, 0.2899210654665e+01, 0.5507553240374e+01,
+      0.1651609818948e-09, 0.6228206482192e+01, 0.1150676975667e+02,
+      0.1822980550699e-09, 0.1469348746179e+01, 0.1179062909082e+02,
+      0.1675223159760e-09, 0.3813910555688e+01, 0.7058598460518e+01,
+      0.1706491764745e-09, 0.3004380506684e+00, 0.7113454667900e-02,
+      0.1392952362615e-09, 0.1440393973406e+01, 0.7962980379786e+00,
+      0.1209868266342e-09, 0.4150425791727e+01, 0.4694002934110e+01,
+
+      0.1009827202611e-09, 0.3290040429843e+01, 0.3738761453707e+01,
+      0.1047261388602e-09, 0.4229590090227e+01, 0.6282095334605e+01,
+      0.1047006652004e-09, 0.2418967680575e+01, 0.6284056366286e+01,
+      0.9609993143095e-10, 0.4627943659201e+01, 0.6069776770667e+01,
+      0.9590900593873e-10, 0.1894393939924e+01, 0.4136910472696e+01,
+      0.9146249188071e-10, 0.2010647519562e+01, 0.6496374930224e+01,
+      0.8545274480290e-10, 0.5529846956226e-01, 0.1194447056968e+01,
+      0.8224377881194e-10, 0.1254304102174e+01, 0.1589072916335e+01,
+      0.6183529510410e-10, 0.3360862168815e+01, 0.8827390247185e+01,
+      0.6259255147141e-10, 0.4755628243179e+01, 0.8429241228195e+01,
+
+      0.5539291694151e-10, 0.5371746955142e+01, 0.4933208510675e+01,
+      0.7328259466314e-10, 0.4927699613906e+00, 0.4535059491685e+01,
+      0.6017835843560e-10, 0.5776682001734e-01, 0.1255903824622e+02,
+      0.7079827775243e-10, 0.4395059432251e+01, 0.5088628793478e+01,
+      0.5170358878213e-10, 0.5154062619954e+01, 0.1176985366291e+02,
+      0.4872301838682e-10, 0.6289611648973e+00, 0.6040347114260e+01,
+      0.5249869411058e-10, 0.5617272046949e+01, 0.3154687086868e+01,
+      0.4716172354411e-10, 0.3965901800877e+01, 0.5331357529664e+01,
+      0.4871214940964e-10, 0.4627507050093e+01, 0.1256967486051e+02,
+      0.4598076850751e-10, 0.6023631226459e+01, 0.6525804586632e+01,
+
+      0.4562196089485e-10, 0.4138562084068e+01, 0.3930209696940e+01,
+      0.4325493872224e-10, 0.1330845906564e+01, 0.7632943190217e+01,
+      0.5673781176748e-10, 0.2558752615657e+01, 0.5729506548653e+01,
+      0.3961436642503e-10, 0.2728071734630e+01, 0.7234794171227e+01,
+      0.5101868209058e-10, 0.4113444965144e+01, 0.6836645152238e+01,
+      0.5257043167676e-10, 0.6195089830590e+01, 0.8031092209206e+01,
+      0.5076613989393e-10, 0.2305124132918e+01, 0.7477522907414e+01,
+      0.3342169352778e-10, 0.5415998155071e+01, 0.1097707878456e+02,
+      0.3545881983591e-10, 0.3727160564574e+01, 0.4164311961999e+01,
+      0.3364063738599e-10, 0.2901121049204e+00, 0.1137170464392e+02,
+
+      0.3357039670776e-10, 0.1652229354331e+01, 0.5223693906222e+01,
+      0.4307412268687e-10, 0.4938909587445e+01, 0.1592596075957e+01,
+      0.3405769115435e-10, 0.2408890766511e+01, 0.3128388763578e+01,
+      0.3001926198480e-10, 0.4862239006386e+01, 0.1748016358760e+01,
+      0.2778264787325e-10, 0.5241168661353e+01, 0.7342457794669e+01,
+      0.2676159480666e-10, 0.3423593942199e+01, 0.2146165377750e+01,
+      0.2954273399939e-10, 0.1881721265406e+01, 0.5368044267797e+00,
+      0.3309362888795e-10, 0.1931525677349e+01, 0.8018209333619e+00,
+      0.2810283608438e-10, 0.2414659495050e+01, 0.5225775174439e+00,
+      0.3378045637764e-10, 0.4238019163430e+01, 0.1554202828031e+00,
+
+      0.2558134979840e-10, 0.1828225235805e+01, 0.5230807360890e+01,
+      0.2273755578447e-10, 0.5858184283998e+01, 0.7084896783808e+01,
+      0.2294176037690e-10, 0.4514589779057e+01, 0.1726015463500e+02,
+      0.2533506099435e-10, 0.2355717851551e+01, 0.5216580451554e+01,
+      0.2716685375812e-10, 0.2221003625100e+01, 0.8635942003952e+01,
+      0.2419043435198e-10, 0.5955704951635e+01, 0.4690479774488e+01,
+      0.2521232544812e-10, 0.1395676848521e+01, 0.5481254917084e+01,
+      0.2630195021491e-10, 0.5727468918743e+01, 0.2629832328990e-01,
+      0.2548395840944e-10, 0.2628351859400e-03, 0.1349867339771e+01 };
+
+/* Sun-to-Earth, T^1, Y */
+   static const double e1y[] = {
+      0.9304690546528e-06, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.5150715570663e-06, 0.4431807116294e+01, 0.1256615170089e+02,
+      0.1290825411056e-07, 0.4388610039678e+01, 0.1884922755134e+02,
+      0.4645466665386e-08, 0.5827263376034e+01, 0.6283075850446e+01,
+      0.2079625310718e-08, 0.1621698662282e+00, 0.6279552690824e+01,
+      0.2078189850907e-08, 0.3344713435140e+01, 0.6286599010068e+01,
+      0.6207190138027e-09, 0.5074049319576e+01, 0.4705732307012e+01,
+      0.5989826532569e-09, 0.2231842216620e+01, 0.6256777527156e+01,
+      0.5961360812618e-09, 0.1274975769045e+01, 0.6309374173736e+01,
+      0.4874165471016e-09, 0.3642277426779e+01, 0.7755226100720e+00,
+
+      0.4283834034360e-09, 0.5148765510106e+01, 0.1059381944224e+01,
+      0.4652389287529e-09, 0.4715794792175e+01, 0.7860419393880e+01,
+      0.3751707476401e-09, 0.6617207370325e+00, 0.5753384878334e+01,
+      0.3559998806198e-09, 0.6155548875404e+01, 0.5884926831456e+01,
+      0.3558447558857e-09, 0.2898827297664e+01, 0.6812766822558e+01,
+      0.3211116927106e-09, 0.3625813502509e+01, 0.6681224869435e+01,
+      0.2875609914672e-09, 0.4345435813134e+01, 0.2513230340178e+02,
+      0.2843109704069e-09, 0.5862263940038e+01, 0.6127655567643e+01,
+      0.2744676468427e-09, 0.3926419475089e+01, 0.6438496133249e+01,
+      0.2481285237789e-09, 0.1351976572828e+01, 0.5486777812467e+01,
+
+      0.2060338481033e-09, 0.2147556998591e+01, 0.7079373888424e+01,
+      0.2015822358331e-09, 0.4408358972216e+01, 0.6290189305114e+01,
+      0.2001195944195e-09, 0.5385829822531e+01, 0.6275962395778e+01,
+      0.1953667642377e-09, 0.1304933746120e+01, 0.5507553240374e+01,
+      0.1839744078713e-09, 0.6173567228835e+01, 0.1179062909082e+02,
+      0.1643334294845e-09, 0.4635942997523e+01, 0.1150676975667e+02,
+      0.1768051018652e-09, 0.5086283558874e+01, 0.7113454667900e-02,
+      0.1674874205489e-09, 0.2243332137241e+01, 0.7058598460518e+01,
+      0.1421445397609e-09, 0.6186899771515e+01, 0.7962980379786e+00,
+      0.1255163958267e-09, 0.5730238465658e+01, 0.4694002934110e+01,
+
+      0.1013945281961e-09, 0.1726055228402e+01, 0.3738761453707e+01,
+      0.1047294335852e-09, 0.2658801228129e+01, 0.6282095334605e+01,
+      0.1047103879392e-09, 0.8481047835035e+00, 0.6284056366286e+01,
+      0.9530343962826e-10, 0.3079267149859e+01, 0.6069776770667e+01,
+      0.9604637611690e-10, 0.3258679792918e+00, 0.4136910472696e+01,
+      0.9153518537177e-10, 0.4398599886584e+00, 0.6496374930224e+01,
+      0.8562458214922e-10, 0.4772686794145e+01, 0.1194447056968e+01,
+      0.8232525360654e-10, 0.5966220721679e+01, 0.1589072916335e+01,
+      0.6150223411438e-10, 0.1780985591923e+01, 0.8827390247185e+01,
+      0.6272087858000e-10, 0.3184305429012e+01, 0.8429241228195e+01,
+
+      0.5540476311040e-10, 0.3801260595433e+01, 0.4933208510675e+01,
+      0.7331901699361e-10, 0.5205948591865e+01, 0.4535059491685e+01,
+      0.6018528702791e-10, 0.4770139083623e+01, 0.1255903824622e+02,
+      0.5150530724804e-10, 0.3574796899585e+01, 0.1176985366291e+02,
+      0.6471933741811e-10, 0.2679787266521e+01, 0.5088628793478e+01,
+      0.5317460644174e-10, 0.9528763345494e+00, 0.3154687086868e+01,
+      0.4832187748783e-10, 0.5329322498232e+01, 0.6040347114260e+01,
+      0.4716763555110e-10, 0.2395235316466e+01, 0.5331357529664e+01,
+      0.4871509139861e-10, 0.3056663648823e+01, 0.1256967486051e+02,
+      0.4598417696768e-10, 0.4452762609019e+01, 0.6525804586632e+01,
+
+      0.5674189533175e-10, 0.9879680872193e+00, 0.5729506548653e+01,
+      0.4073560328195e-10, 0.5939127696986e+01, 0.7632943190217e+01,
+      0.5040994945359e-10, 0.4549875824510e+01, 0.8031092209206e+01,
+      0.5078185134679e-10, 0.7346659893982e+00, 0.7477522907414e+01,
+      0.3769343537061e-10, 0.1071317188367e+01, 0.7234794171227e+01,
+      0.4980331365299e-10, 0.2500345341784e+01, 0.6836645152238e+01,
+      0.3458236594757e-10, 0.3825159450711e+01, 0.1097707878456e+02,
+      0.3578859493602e-10, 0.5299664791549e+01, 0.4164311961999e+01,
+      0.3370504646419e-10, 0.5002316301593e+01, 0.1137170464392e+02,
+      0.3299873338428e-10, 0.2526123275282e+01, 0.3930209696940e+01,
+
+      0.4304917318409e-10, 0.3368078557132e+01, 0.1592596075957e+01,
+      0.3402418753455e-10, 0.8385495425800e+00, 0.3128388763578e+01,
+      0.2778460572146e-10, 0.3669905203240e+01, 0.7342457794669e+01,
+      0.2782710128902e-10, 0.2691664812170e+00, 0.1748016358760e+01,
+      0.2711725179646e-10, 0.4707487217718e+01, 0.5296909721118e+00,
+      0.2981760946340e-10, 0.3190260867816e+00, 0.5368044267797e+00,
+      0.2811672977772e-10, 0.3196532315372e+01, 0.7084896783808e+01,
+      0.2863454474467e-10, 0.2263240324780e+00, 0.5223693906222e+01,
+      0.3333464634051e-10, 0.3498451685065e+01, 0.8018209333619e+00,
+      0.3312991747609e-10, 0.5839154477412e+01, 0.1554202828031e+00,
+
+      0.2813255564006e-10, 0.8268044346621e+00, 0.5225775174439e+00,
+      0.2665098083966e-10, 0.3934021725360e+01, 0.5216580451554e+01,
+      0.2349795705216e-10, 0.5197620913779e+01, 0.2146165377750e+01,
+      0.2330352293961e-10, 0.2984999231807e+01, 0.1726015463500e+02,
+      0.2728001683419e-10, 0.6521679638544e+00, 0.8635942003952e+01,
+      0.2484061007669e-10, 0.3468955561097e+01, 0.5230807360890e+01,
+      0.2646328768427e-10, 0.1013724533516e+01, 0.2629832328990e-01,
+      0.2518630264831e-10, 0.6108081057122e+01, 0.5481254917084e+01,
+      0.2421901455384e-10, 0.1651097776260e+01, 0.1349867339771e+01,
+      0.6348533267831e-11, 0.3220226560321e+01, 0.8433466158131e+02 };
+
+/* Sun-to-Earth, T^1, Z */
+   static const double e1z[] = {
+      0.2278290449966e-05, 0.3413716033863e+01, 0.6283075850446e+01,
+      0.5429458209830e-07, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.1903240492525e-07, 0.3370592358297e+01, 0.1256615170089e+02,
+      0.2385409276743e-09, 0.3327914718416e+01, 0.1884922755134e+02,
+      0.8676928342573e-10, 0.1824006811264e+01, 0.5223693906222e+01,
+      0.7765442593544e-10, 0.3888564279247e+01, 0.5507553240374e+01,
+      0.7066158332715e-10, 0.5194267231944e+01, 0.2352866153506e+01,
+      0.7092175288657e-10, 0.2333246960021e+01, 0.8399684731857e+02,
+      0.5357582213535e-10, 0.2224031176619e+01, 0.5296909721118e+00,
+      0.3828035865021e-10, 0.2156710933584e+01, 0.6279552690824e+01,
+
+      0.3824857220427e-10, 0.1529755219915e+01, 0.6286599010068e+01,
+      0.3286995181628e-10, 0.4879512900483e+01, 0.1021328554739e+02 };
+
+/* Sun-to-Earth, T^2, X */
+   static const double e2x[] = {
+     -0.4143818297913e-10, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.2171497694435e-10, 0.4398225628264e+01, 0.1256615170089e+02,
+      0.9845398442516e-11, 0.2079720838384e+00, 0.6283075850446e+01,
+      0.9256833552682e-12, 0.4191264694361e+01, 0.1884922755134e+02,
+      0.1022049384115e-12, 0.5381133195658e+01, 0.8399684731857e+02 };
+
+/* Sun-to-Earth, T^2, Y */
+   static const double e2y[] = {
+      0.5063375872532e-10, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.2173815785980e-10, 0.2827805833053e+01, 0.1256615170089e+02,
+      0.1010231999920e-10, 0.4634612377133e+01, 0.6283075850446e+01,
+      0.9259745317636e-12, 0.2620612076189e+01, 0.1884922755134e+02,
+      0.1022202095812e-12, 0.3809562326066e+01, 0.8399684731857e+02 };
+
+/* Sun-to-Earth, T^2, Z */
+   static const double e2z[] = {
+      0.9722666114891e-10, 0.5152219582658e+01, 0.6283075850446e+01,
+     -0.3494819171909e-11, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.6713034376076e-12, 0.6440188750495e+00, 0.1256615170089e+02 };
+
+/* SSB-to-Sun, T^0, X */
+   static const double s0x[] = {
+      0.4956757536410e-02, 0.3741073751789e+01, 0.5296909721118e+00,
+      0.2718490072522e-02, 0.4016011511425e+01, 0.2132990797783e+00,
+      0.1546493974344e-02, 0.2170528330642e+01, 0.3813291813120e-01,
+      0.8366855276341e-03, 0.2339614075294e+01, 0.7478166569050e-01,
+      0.2936777942117e-03, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.1201317439469e-03, 0.4090736353305e+01, 0.1059381944224e+01,
+      0.7578550887230e-04, 0.3241518088140e+01, 0.4265981595566e+00,
+      0.1941787367773e-04, 0.1012202064330e+01, 0.2061856251104e+00,
+      0.1889227765991e-04, 0.3892520416440e+01, 0.2204125344462e+00,
+      0.1937896968613e-04, 0.4797779441161e+01, 0.1495633313810e+00,
+
+      0.1434506110873e-04, 0.3868960697933e+01, 0.5225775174439e+00,
+      0.1406659911580e-04, 0.4759766557397e+00, 0.5368044267797e+00,
+      0.1179022300202e-04, 0.7774961520598e+00, 0.7626583626240e-01,
+      0.8085864460959e-05, 0.3254654471465e+01, 0.3664874755930e-01,
+      0.7622752967615e-05, 0.4227633103489e+01, 0.3961708870310e-01,
+      0.6209171139066e-05, 0.2791828325711e+00, 0.7329749511860e-01,
+      0.4366435633970e-05, 0.4440454875925e+01, 0.1589072916335e+01,
+      0.3792124889348e-05, 0.5156393842356e+01, 0.7113454667900e-02,
+      0.3154548963402e-05, 0.6157005730093e+01, 0.4194847048887e+00,
+      0.3088359882942e-05, 0.2494567553163e+01, 0.6398972393349e+00,
+
+      0.2788440902136e-05, 0.4934318747989e+01, 0.1102062672231e+00,
+      0.3039928456376e-05, 0.4895077702640e+01, 0.6283075850446e+01,
+      0.2272258457679e-05, 0.5278394064764e+01, 0.1030928125552e+00,
+      0.2162007057957e-05, 0.5802978019099e+01, 0.3163918923335e+00,
+      0.1767632855737e-05, 0.3415346595193e-01, 0.1021328554739e+02,
+      0.1349413459362e-05, 0.2001643230755e+01, 0.1484170571900e-02,
+      0.1170141900476e-05, 0.2424750491620e+01, 0.6327837846670e+00,
+      0.1054355266820e-05, 0.3123311487576e+01, 0.4337116142245e+00,
+      0.9800822461610e-06, 0.3026258088130e+01, 0.1052268489556e+01,
+      0.1091203749931e-05, 0.3157811670347e+01, 0.1162474756779e+01,
+
+      0.6960236715913e-06, 0.8219570542313e+00, 0.1066495398892e+01,
+      0.5689257296909e-06, 0.1323052375236e+01, 0.9491756770005e+00,
+      0.6613172135802e-06, 0.2765348881598e+00, 0.8460828644453e+00,
+      0.6277702517571e-06, 0.5794064466382e+01, 0.1480791608091e+00,
+      0.6304884066699e-06, 0.7323555380787e+00, 0.2243449970715e+00,
+      0.4897850467382e-06, 0.3062464235399e+01, 0.3340612434717e+01,
+      0.3759148598786e-06, 0.4588290469664e+01, 0.3516457698740e-01,
+      0.3110520548195e-06, 0.1374299536572e+01, 0.6373574839730e-01,
+      0.3064708359780e-06, 0.4222267485047e+01, 0.1104591729320e-01,
+      0.2856347168241e-06, 0.3714202944973e+01, 0.1510475019529e+00,
+
+      0.2840945514288e-06, 0.2847972875882e+01, 0.4110125927500e-01,
+      0.2378951599405e-06, 0.3762072563388e+01, 0.2275259891141e+00,
+      0.2714229481417e-06, 0.1036049980031e+01, 0.2535050500000e-01,
+      0.2323551717307e-06, 0.4682388599076e+00, 0.8582758298370e-01,
+      0.1881790512219e-06, 0.4790565425418e+01, 0.2118763888447e+01,
+      0.2261353968371e-06, 0.1669144912212e+01, 0.7181332454670e-01,
+      0.2214546389848e-06, 0.3937717281614e+01, 0.2968341143800e-02,
+      0.2184915594933e-06, 0.1129169845099e+00, 0.7775000683430e-01,
+      0.2000164937936e-06, 0.4030009638488e+01, 0.2093666171530e+00,
+      0.1966105136719e-06, 0.8745955786834e+00, 0.2172315424036e+00,
+
+      0.1904742332624e-06, 0.5919743598964e+01, 0.2022531624851e+00,
+      0.1657399705031e-06, 0.2549141484884e+01, 0.7358765972222e+00,
+      0.1574070533987e-06, 0.5277533020230e+01, 0.7429900518901e+00,
+      0.1832261651039e-06, 0.3064688127777e+01, 0.3235053470014e+00,
+      0.1733615346569e-06, 0.3011432799094e+01, 0.1385174140878e+00,
+      0.1549124014496e-06, 0.4005569132359e+01, 0.5154640627760e+00,
+      0.1637044713838e-06, 0.1831375966632e+01, 0.8531963191132e+00,
+      0.1123420082383e-06, 0.1180270407578e+01, 0.1990721704425e+00,
+      0.1083754165740e-06, 0.3414101320863e+00, 0.5439178814476e+00,
+      0.1156638012655e-06, 0.6130479452594e+00, 0.5257585094865e+00,
+
+      0.1142548785134e-06, 0.3724761948846e+01, 0.5336234347371e+00,
+      0.7921463895965e-07, 0.2435425589361e+01, 0.1478866649112e+01,
+      0.7428600285231e-07, 0.3542144398753e+01, 0.2164800718209e+00,
+      0.8323211246747e-07, 0.3525058072354e+01, 0.1692165728891e+01,
+      0.7257595116312e-07, 0.1364299431982e+01, 0.2101180877357e+00,
+      0.7111185833236e-07, 0.2460478875808e+01, 0.4155522422634e+00,
+      0.6868090383716e-07, 0.4397327670704e+01, 0.1173197218910e+00,
+      0.7226419974175e-07, 0.4042647308905e+01, 0.1265567569334e+01,
+      0.6955642383177e-07, 0.2865047906085e+01, 0.9562891316684e+00,
+      0.7492139296331e-07, 0.5014278994215e+01, 0.1422690933580e-01,
+
+      0.6598363128857e-07, 0.2376730020492e+01, 0.6470106940028e+00,
+      0.7381147293385e-07, 0.3272990384244e+01, 0.1581959461667e+01,
+      0.6402909624032e-07, 0.5302290955138e+01, 0.9597935788730e-01,
+      0.6237454263857e-07, 0.5444144425332e+01, 0.7084920306520e-01,
+      0.5241198544016e-07, 0.4215359579205e+01, 0.5265099800692e+00,
+      0.5144463853918e-07, 0.1218916689916e+00, 0.5328719641544e+00,
+      0.5868164772299e-07, 0.2369402002213e+01, 0.7871412831580e-01,
+      0.6233195669151e-07, 0.1254922242403e+01, 0.2608790314060e+02,
+      0.6068463791422e-07, 0.5679713760431e+01, 0.1114304132498e+00,
+      0.4359361135065e-07, 0.6097219641646e+00, 0.1375773836557e+01,
+
+      0.4686510366826e-07, 0.4786231041431e+01, 0.1143987543936e+00,
+      0.3758977287225e-07, 0.1167368068139e+01, 0.1596186371003e+01,
+      0.4282051974778e-07, 0.1519471064319e+01, 0.2770348281756e+00,
+      0.5153765386113e-07, 0.1860532322984e+01, 0.2228608264996e+00,
+      0.4575129387188e-07, 0.7632857887158e+00, 0.1465949902372e+00,
+      0.3326844933286e-07, 0.1298219485285e+01, 0.5070101000000e-01,
+      0.3748617450984e-07, 0.1046510321062e+01, 0.4903339079539e+00,
+      0.2816756661499e-07, 0.3434522346190e+01, 0.2991266627620e+00,
+      0.3412750405039e-07, 0.2523766270318e+01, 0.3518164938661e+00,
+      0.2655796761776e-07, 0.2904422260194e+01, 0.6256703299991e+00,
+
+      0.2963597929458e-07, 0.5923900431149e+00, 0.1099462426779e+00,
+      0.2539523734781e-07, 0.4851947722567e+01, 0.1256615170089e+02,
+      0.2283087914139e-07, 0.3400498595496e+01, 0.6681224869435e+01,
+      0.2321309799331e-07, 0.5789099148673e+01, 0.3368040641550e-01,
+      0.2549657649750e-07, 0.3991856479792e-01, 0.1169588211447e+01,
+      0.2290462303977e-07, 0.2788567577052e+01, 0.1045155034888e+01,
+      0.1945398522914e-07, 0.3290896998176e+01, 0.1155361302111e+01,
+      0.1849171512638e-07, 0.2698060129367e+01, 0.4452511715700e-02,
+      0.1647199834254e-07, 0.3016735644085e+01, 0.4408250688924e+00,
+      0.1529530765273e-07, 0.5573043116178e+01, 0.6521991896920e-01,
+
+      0.1433199339978e-07, 0.1481192356147e+01, 0.9420622223326e+00,
+      0.1729134193602e-07, 0.1422817538933e+01, 0.2108507877249e+00,
+      0.1716463931346e-07, 0.3469468901855e+01, 0.2157473718317e+00,
+      0.1391206061378e-07, 0.6122436220547e+01, 0.4123712502208e+00,
+      0.1404746661924e-07, 0.1647765641936e+01, 0.4258542984690e-01,
+      0.1410452399455e-07, 0.5989729161964e+01, 0.2258291676434e+00,
+      0.1089828772168e-07, 0.2833705509371e+01, 0.4226656969313e+00,
+      0.1047374564948e-07, 0.5090690007331e+00, 0.3092784376656e+00,
+      0.1358279126532e-07, 0.5128990262836e+01, 0.7923417740620e-01,
+      0.1020456476148e-07, 0.9632772880808e+00, 0.1456308687557e+00,
+
+      0.1033428735328e-07, 0.3223779318418e+01, 0.1795258541446e+01,
+      0.1412435841540e-07, 0.2410271572721e+01, 0.1525316725248e+00,
+      0.9722759371574e-08, 0.2333531395690e+01, 0.8434341241180e-01,
+      0.9657334084704e-08, 0.6199270974168e+01, 0.1272681024002e+01,
+      0.1083641148690e-07, 0.2864222292929e+01, 0.7032915397480e-01,
+      0.1067318403838e-07, 0.5833458866568e+00, 0.2123349582968e+00,
+      0.1062366201976e-07, 0.4307753989494e+01, 0.2142632012598e+00,
+      0.1236364149266e-07, 0.2873917870593e+01, 0.1847279083684e+00,
+      0.1092759489593e-07, 0.2959887266733e+01, 0.1370332435159e+00,
+      0.8912069362899e-08, 0.5141213702562e+01, 0.2648454860559e+01,
+
+      0.9656467707970e-08, 0.4532182462323e+01, 0.4376440768498e+00,
+      0.8098386150135e-08, 0.2268906338379e+01, 0.2880807454688e+00,
+      0.7857714675000e-08, 0.4055544260745e+01, 0.2037373330570e+00,
+      0.7288455940646e-08, 0.5357901655142e+01, 0.1129145838217e+00,
+      0.9450595950552e-08, 0.4264926963939e+01, 0.5272426800584e+00,
+      0.9381718247537e-08, 0.7489366976576e-01, 0.5321392641652e+00,
+      0.7079052646038e-08, 0.1923311052874e+01, 0.6288513220417e+00,
+      0.9259004415344e-08, 0.2970256853438e+01, 0.1606092486742e+00,
+      0.8259801499742e-08, 0.3327056314697e+01, 0.8389694097774e+00,
+      0.6476334355779e-08, 0.2954925505727e+01, 0.2008557621224e+01,
+
+      0.5984021492007e-08, 0.9138753105829e+00, 0.2042657109477e+02,
+      0.5989546863181e-08, 0.3244464082031e+01, 0.2111650433779e+01,
+      0.6233108606023e-08, 0.4995232638403e+00, 0.4305306221819e+00,
+      0.6877299149965e-08, 0.2834987233449e+01, 0.9561746721300e-02,
+      0.8311234227190e-08, 0.2202951835758e+01, 0.3801276407308e+00,
+      0.6599472832414e-08, 0.4478581462618e+01, 0.1063314406849e+01,
+      0.6160491096549e-08, 0.5145858696411e+01, 0.1368660381889e+01,
+      0.6164772043891e-08, 0.3762976697911e+00, 0.4234171675140e+00,
+      0.6363248684450e-08, 0.3162246718685e+01, 0.1253008786510e-01,
+      0.6448587520999e-08, 0.3442693302119e+01, 0.5287268506303e+00,
+
+      0.6431662283977e-08, 0.8977549136606e+00, 0.5306550935933e+00,
+      0.6351223158474e-08, 0.4306447410369e+01, 0.5217580628120e+02,
+      0.5476721393451e-08, 0.3888529177855e+01, 0.2221856701002e+01,
+      0.5341772572619e-08, 0.2655560662512e+01, 0.7466759693650e-01,
+      0.5337055758302e-08, 0.5164990735946e+01, 0.7489573444450e-01,
+      0.5373120816787e-08, 0.6041214553456e+01, 0.1274714967946e+00,
+      0.5392351705426e-08, 0.9177763485932e+00, 0.1055449481598e+01,
+      0.6688495850205e-08, 0.3089608126937e+01, 0.2213766559277e+00,
+      0.5072003660362e-08, 0.4311316541553e+01, 0.2132517061319e+00,
+      0.5070726650455e-08, 0.5790675464444e+00, 0.2133464534247e+00,
+
+      0.5658012950032e-08, 0.2703945510675e+01, 0.7287631425543e+00,
+      0.4835509924854e-08, 0.2975422976065e+01, 0.7160067364790e-01,
+      0.6479821978012e-08, 0.1324168733114e+01, 0.2209183458640e-01,
+      0.6230636494980e-08, 0.2860103632836e+01, 0.3306188016693e+00,
+      0.4649239516213e-08, 0.4832259763403e+01, 0.7796265773310e-01,
+      0.6487325792700e-08, 0.2726165825042e+01, 0.3884652414254e+00,
+      0.4682823682770e-08, 0.6966602455408e+00, 0.1073608853559e+01,
+      0.5704230804976e-08, 0.5669634104606e+01, 0.8731175355560e-01,
+      0.6125413585489e-08, 0.1513386538915e+01, 0.7605151500000e-01,
+      0.6035825038187e-08, 0.1983509168227e+01, 0.9846002785331e+00,
+
+      0.4331123462303e-08, 0.2782892992807e+01, 0.4297791515992e+00,
+      0.4681107685143e-08, 0.5337232886836e+01, 0.2127790306879e+00,
+      0.4669105829655e-08, 0.5837133792160e+01, 0.2138191288687e+00,
+      0.5138823602365e-08, 0.3080560200507e+01, 0.7233337363710e-01,
+      0.4615856664534e-08, 0.1661747897471e+01, 0.8603097737811e+00,
+      0.4496916702197e-08, 0.2112508027068e+01, 0.7381754420900e-01,
+      0.4278479042945e-08, 0.5716528462627e+01, 0.7574578717200e-01,
+      0.3840525503932e-08, 0.6424172726492e+00, 0.3407705765729e+00,
+      0.4866636509685e-08, 0.4919244697715e+01, 0.7722995774390e-01,
+      0.3526100639296e-08, 0.2550821052734e+01, 0.6225157782540e-01,
+
+      0.3939558488075e-08, 0.3939331491710e+01, 0.5268983110410e-01,
+      0.4041268772576e-08, 0.2275337571218e+01, 0.3503323232942e+00,
+      0.3948761842853e-08, 0.1999324200790e+01, 0.1451108196653e+00,
+      0.3258394550029e-08, 0.9121001378200e+00, 0.5296435984654e+00,
+      0.3257897048761e-08, 0.3428428660869e+01, 0.5297383457582e+00,
+      0.3842559031298e-08, 0.6132927720035e+01, 0.9098186128426e+00,
+      0.3109920095448e-08, 0.7693650193003e+00, 0.3932462625300e-02,
+      0.3132237775119e-08, 0.3621293854908e+01, 0.2346394437820e+00,
+      0.3942189421510e-08, 0.4841863659733e+01, 0.3180992042600e-02,
+      0.3796972285340e-08, 0.1814174994268e+01, 0.1862120789403e+00,
+
+      0.3995640233688e-08, 0.1386990406091e+01, 0.4549093064213e+00,
+      0.2875013727414e-08, 0.9178318587177e+00, 0.1905464808669e+01,
+      0.3073719932844e-08, 0.2688923811835e+01, 0.3628624111593e+00,
+      0.2731016580075e-08, 0.1188259127584e+01, 0.2131850110243e+00,
+      0.2729549896546e-08, 0.3702160634273e+01, 0.2134131485323e+00,
+      0.3339372892449e-08, 0.7199163960331e+00, 0.2007689919132e+00,
+      0.2898833764204e-08, 0.1916709364999e+01, 0.5291709230214e+00,
+      0.2894536549362e-08, 0.2424043195547e+01, 0.5302110212022e+00,
+      0.3096872473843e-08, 0.4445894977497e+01, 0.2976424921901e+00,
+      0.2635672326810e-08, 0.3814366984117e+01, 0.1485980103780e+01,
+
+      0.3649302697001e-08, 0.2924200596084e+01, 0.6044726378023e+00,
+      0.3127954585895e-08, 0.1842251648327e+01, 0.1084620721060e+00,
+      0.2616040173947e-08, 0.4155841921984e+01, 0.1258454114666e+01,
+      0.2597395859860e-08, 0.1158045978874e+00, 0.2103781122809e+00,
+      0.2593286172210e-08, 0.4771850408691e+01, 0.2162200472757e+00,
+      0.2481823585747e-08, 0.4608842558889e+00, 0.1062562936266e+01,
+      0.2742219550725e-08, 0.1538781127028e+01, 0.5651155736444e+00,
+      0.3199558469610e-08, 0.3226647822878e+00, 0.7036329877322e+00,
+      0.2666088542957e-08, 0.1967991731219e+00, 0.1400015846597e+00,
+      0.2397067430580e-08, 0.3707036669873e+01, 0.2125476091956e+00,
+
+      0.2376570772738e-08, 0.1182086628042e+01, 0.2140505503610e+00,
+      0.2547228007887e-08, 0.4906256820629e+01, 0.1534957940063e+00,
+      0.2265575594114e-08, 0.3414949866857e+01, 0.2235935264888e+00,
+      0.2464381430585e-08, 0.4599122275378e+01, 0.2091065926078e+00,
+      0.2433408527044e-08, 0.2830751145445e+00, 0.2174915669488e+00,
+      0.2443605509076e-08, 0.4212046432538e+01, 0.1739420156204e+00,
+      0.2319779262465e-08, 0.9881978408630e+00, 0.7530171478090e-01,
+      0.2284622835465e-08, 0.5565347331588e+00, 0.7426161660010e-01,
+      0.2467268750783e-08, 0.5655708150766e+00, 0.2526561439362e+00,
+      0.2808513492782e-08, 0.1418405053408e+01, 0.5636314030725e+00,
+
+      0.2329528932532e-08, 0.4069557545675e+01, 0.1056200952181e+01,
+      0.9698639532817e-09, 0.1074134313634e+01, 0.7826370942180e+02 };
+
+/* SSB-to-Sun, T^0, Y */
+   static const double s0y[] = {
+      0.4955392320126e-02, 0.2170467313679e+01, 0.5296909721118e+00,
+      0.2722325167392e-02, 0.2444433682196e+01, 0.2132990797783e+00,
+      0.1546579925346e-02, 0.5992779281546e+00, 0.3813291813120e-01,
+      0.8363140252966e-03, 0.7687356310801e+00, 0.7478166569050e-01,
+      0.3385792683603e-03, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.1201192221613e-03, 0.2520035601514e+01, 0.1059381944224e+01,
+      0.7587125720554e-04, 0.1669954006449e+01, 0.4265981595566e+00,
+      0.1964155361250e-04, 0.5707743963343e+01, 0.2061856251104e+00,
+      0.1891900364909e-04, 0.2320960679937e+01, 0.2204125344462e+00,
+      0.1937373433356e-04, 0.3226940689555e+01, 0.1495633313810e+00,
+
+      0.1437139941351e-04, 0.2301626908096e+01, 0.5225775174439e+00,
+      0.1406267683099e-04, 0.5188579265542e+01, 0.5368044267797e+00,
+      0.1178703080346e-04, 0.5489483248476e+01, 0.7626583626240e-01,
+      0.8079835186041e-05, 0.1683751835264e+01, 0.3664874755930e-01,
+      0.7623253594652e-05, 0.2656400462961e+01, 0.3961708870310e-01,
+      0.6248667483971e-05, 0.4992775362055e+01, 0.7329749511860e-01,
+      0.4366353695038e-05, 0.2869706279678e+01, 0.1589072916335e+01,
+      0.3829101568895e-05, 0.3572131359950e+01, 0.7113454667900e-02,
+      0.3175733773908e-05, 0.4535372530045e+01, 0.4194847048887e+00,
+      0.3092437902159e-05, 0.9230153317909e+00, 0.6398972393349e+00,
+
+      0.2874168812154e-05, 0.3363143761101e+01, 0.1102062672231e+00,
+      0.3040119321826e-05, 0.3324250895675e+01, 0.6283075850446e+01,
+      0.2699723308006e-05, 0.2917882441928e+00, 0.1030928125552e+00,
+      0.2134832683534e-05, 0.4220997202487e+01, 0.3163918923335e+00,
+      0.1770412139433e-05, 0.4747318496462e+01, 0.1021328554739e+02,
+      0.1377264209373e-05, 0.4305058462401e+00, 0.1484170571900e-02,
+      0.1127814538960e-05, 0.8538177240740e+00, 0.6327837846670e+00,
+      0.1055608090130e-05, 0.1551800742580e+01, 0.4337116142245e+00,
+      0.9802673861420e-06, 0.1459646735377e+01, 0.1052268489556e+01,
+      0.1090329461951e-05, 0.1587351228711e+01, 0.1162474756779e+01,
+
+      0.6959590025090e-06, 0.5534442628766e+01, 0.1066495398892e+01,
+      0.5664914529542e-06, 0.6030673003297e+01, 0.9491756770005e+00,
+      0.6607787763599e-06, 0.4989507233927e+01, 0.8460828644453e+00,
+      0.6269725742838e-06, 0.4222951804572e+01, 0.1480791608091e+00,
+      0.6301889697863e-06, 0.5444316669126e+01, 0.2243449970715e+00,
+      0.4891042662861e-06, 0.1490552839784e+01, 0.3340612434717e+01,
+      0.3457083123290e-06, 0.3030475486049e+01, 0.3516457698740e-01,
+      0.3032559967314e-06, 0.2652038793632e+01, 0.1104591729320e-01,
+      0.2841133988903e-06, 0.1276744786829e+01, 0.4110125927500e-01,
+      0.2855564444432e-06, 0.2143368674733e+01, 0.1510475019529e+00,
+
+      0.2765157135038e-06, 0.5444186109077e+01, 0.6373574839730e-01,
+      0.2382312465034e-06, 0.2190521137593e+01, 0.2275259891141e+00,
+      0.2808060365077e-06, 0.5735195064841e+01, 0.2535050500000e-01,
+      0.2332175234405e-06, 0.9481985524859e-01, 0.7181332454670e-01,
+      0.2322488199659e-06, 0.5180499361533e+01, 0.8582758298370e-01,
+      0.1881850258423e-06, 0.3219788273885e+01, 0.2118763888447e+01,
+      0.2196111392808e-06, 0.2366941159761e+01, 0.2968341143800e-02,
+      0.2183810335519e-06, 0.4825445110915e+01, 0.7775000683430e-01,
+      0.2002733093326e-06, 0.2457148995307e+01, 0.2093666171530e+00,
+      0.1967111767229e-06, 0.5586291545459e+01, 0.2172315424036e+00,
+
+      0.1568473250543e-06, 0.3708003123320e+01, 0.7429900518901e+00,
+      0.1852528314300e-06, 0.4310638151560e+01, 0.2022531624851e+00,
+      0.1832111226447e-06, 0.1494665322656e+01, 0.3235053470014e+00,
+      0.1746805502310e-06, 0.1451378500784e+01, 0.1385174140878e+00,
+      0.1555730966650e-06, 0.1068040418198e+01, 0.7358765972222e+00,
+      0.1554883462559e-06, 0.2442579035461e+01, 0.5154640627760e+00,
+      0.1638380568746e-06, 0.2597913420625e+00, 0.8531963191132e+00,
+      0.1159938593640e-06, 0.5834512021280e+01, 0.1990721704425e+00,
+      0.1083427965695e-06, 0.5054033177950e+01, 0.5439178814476e+00,
+      0.1156480369431e-06, 0.5325677432457e+01, 0.5257585094865e+00,
+
+      0.1141308860095e-06, 0.2153403923857e+01, 0.5336234347371e+00,
+      0.7913146470946e-07, 0.8642846847027e+00, 0.1478866649112e+01,
+      0.7439752463733e-07, 0.1970628496213e+01, 0.2164800718209e+00,
+      0.7280277104079e-07, 0.6073307250609e+01, 0.2101180877357e+00,
+      0.8319567719136e-07, 0.1954371928334e+01, 0.1692165728891e+01,
+      0.7137705549290e-07, 0.8904989440909e+00, 0.4155522422634e+00,
+      0.6900825396225e-07, 0.2825717714977e+01, 0.1173197218910e+00,
+      0.7245757216635e-07, 0.2481677513331e+01, 0.1265567569334e+01,
+      0.6961165696255e-07, 0.1292955312978e+01, 0.9562891316684e+00,
+      0.7571804456890e-07, 0.3427517575069e+01, 0.1422690933580e-01,
+
+      0.6605425721904e-07, 0.8052192701492e+00, 0.6470106940028e+00,
+      0.7375477357248e-07, 0.1705076390088e+01, 0.1581959461667e+01,
+      0.7041664951470e-07, 0.4848356967891e+00, 0.9597935788730e-01,
+      0.6322199535763e-07, 0.3878069473909e+01, 0.7084920306520e-01,
+      0.5244380279191e-07, 0.2645560544125e+01, 0.5265099800692e+00,
+      0.5143125704988e-07, 0.4834486101370e+01, 0.5328719641544e+00,
+      0.5871866319373e-07, 0.7981472548900e+00, 0.7871412831580e-01,
+      0.6300822573871e-07, 0.5979398788281e+01, 0.2608790314060e+02,
+      0.6062154271548e-07, 0.4108655402756e+01, 0.1114304132498e+00,
+      0.4361912339976e-07, 0.5322624319280e+01, 0.1375773836557e+01,
+
+      0.4417005920067e-07, 0.6240817359284e+01, 0.2770348281756e+00,
+      0.4686806749936e-07, 0.3214977301156e+01, 0.1143987543936e+00,
+      0.3758892132305e-07, 0.5879809634765e+01, 0.1596186371003e+01,
+      0.5151351332319e-07, 0.2893377688007e+00, 0.2228608264996e+00,
+      0.4554683578572e-07, 0.5475427144122e+01, 0.1465949902372e+00,
+      0.3442381385338e-07, 0.5992034796640e+01, 0.5070101000000e-01,
+      0.2831093954933e-07, 0.5367350273914e+01, 0.3092784376656e+00,
+      0.3756267090084e-07, 0.5758171285420e+01, 0.4903339079539e+00,
+      0.2816374679892e-07, 0.1863718700923e+01, 0.2991266627620e+00,
+      0.3419307025569e-07, 0.9524347534130e+00, 0.3518164938661e+00,
+
+      0.2904250494239e-07, 0.5304471615602e+01, 0.1099462426779e+00,
+      0.2471734511206e-07, 0.1297069793530e+01, 0.6256703299991e+00,
+      0.2539620831872e-07, 0.3281126083375e+01, 0.1256615170089e+02,
+      0.2281017868007e-07, 0.1829122133165e+01, 0.6681224869435e+01,
+      0.2275319473335e-07, 0.5797198160181e+01, 0.3932462625300e-02,
+      0.2547755368442e-07, 0.4752697708330e+01, 0.1169588211447e+01,
+      0.2285979669317e-07, 0.1223205292886e+01, 0.1045155034888e+01,
+      0.1913386560994e-07, 0.1757532993389e+01, 0.1155361302111e+01,
+      0.1809020525147e-07, 0.4246116108791e+01, 0.3368040641550e-01,
+      0.1649213300201e-07, 0.1445162890627e+01, 0.4408250688924e+00,
+
+      0.1834972793932e-07, 0.1126917567225e+01, 0.4452511715700e-02,
+      0.1439550648138e-07, 0.6160756834764e+01, 0.9420622223326e+00,
+      0.1487645457041e-07, 0.4358761931792e+01, 0.4123712502208e+00,
+      0.1731729516660e-07, 0.6134456753344e+01, 0.2108507877249e+00,
+      0.1717747163567e-07, 0.1898186084455e+01, 0.2157473718317e+00,
+      0.1418190430374e-07, 0.4180286741266e+01, 0.6521991896920e-01,
+      0.1404844134873e-07, 0.7654053565412e-01, 0.4258542984690e-01,
+      0.1409842846538e-07, 0.4418612420312e+01, 0.2258291676434e+00,
+      0.1090948346291e-07, 0.1260615686131e+01, 0.4226656969313e+00,
+      0.1357577323612e-07, 0.3558248818690e+01, 0.7923417740620e-01,
+
+      0.1018154061960e-07, 0.5676087241256e+01, 0.1456308687557e+00,
+      0.1412073972109e-07, 0.8394392632422e+00, 0.1525316725248e+00,
+      0.1030938326496e-07, 0.1653593274064e+01, 0.1795258541446e+01,
+      0.1180081567104e-07, 0.1285802592036e+01, 0.7032915397480e-01,
+      0.9708510575650e-08, 0.7631889488106e+00, 0.8434341241180e-01,
+      0.9637689663447e-08, 0.4630642649176e+01, 0.1272681024002e+01,
+      0.1068910429389e-07, 0.5294934032165e+01, 0.2123349582968e+00,
+      0.1063716179336e-07, 0.2736266800832e+01, 0.2142632012598e+00,
+      0.1234858713814e-07, 0.1302891146570e+01, 0.1847279083684e+00,
+      0.8912631189738e-08, 0.3570415993621e+01, 0.2648454860559e+01,
+
+      0.1036378285534e-07, 0.4236693440949e+01, 0.1370332435159e+00,
+      0.9667798501561e-08, 0.2960768892398e+01, 0.4376440768498e+00,
+      0.8108314201902e-08, 0.6987781646841e+00, 0.2880807454688e+00,
+      0.7648364324628e-08, 0.2499017863863e+01, 0.2037373330570e+00,
+      0.7286136828406e-08, 0.3787426951665e+01, 0.1129145838217e+00,
+      0.9448237743913e-08, 0.2694354332983e+01, 0.5272426800584e+00,
+      0.9374276106428e-08, 0.4787121277064e+01, 0.5321392641652e+00,
+      0.7100226287462e-08, 0.3530238792101e+00, 0.6288513220417e+00,
+      0.9253056659571e-08, 0.1399478925664e+01, 0.1606092486742e+00,
+      0.6636432145504e-08, 0.3479575438447e+01, 0.1368660381889e+01,
+
+      0.6469975312932e-08, 0.1383669964800e+01, 0.2008557621224e+01,
+      0.7335849729765e-08, 0.1243698166898e+01, 0.9561746721300e-02,
+      0.8743421205855e-08, 0.3776164289301e+01, 0.3801276407308e+00,
+      0.5993635744494e-08, 0.5627122113596e+01, 0.2042657109477e+02,
+      0.5981008479693e-08, 0.1674336636752e+01, 0.2111650433779e+01,
+      0.6188535145838e-08, 0.5214925208672e+01, 0.4305306221819e+00,
+      0.6596074017566e-08, 0.2907653268124e+01, 0.1063314406849e+01,
+      0.6630815126226e-08, 0.2127643669658e+01, 0.8389694097774e+00,
+      0.6156772830040e-08, 0.5082160803295e+01, 0.4234171675140e+00,
+      0.6446960563014e-08, 0.1872100916905e+01, 0.5287268506303e+00,
+
+      0.6429324424668e-08, 0.5610276103577e+01, 0.5306550935933e+00,
+      0.6302232396465e-08, 0.1592152049607e+01, 0.1253008786510e-01,
+      0.6399244436159e-08, 0.2746214421532e+01, 0.5217580628120e+02,
+      0.5474965172558e-08, 0.2317666374383e+01, 0.2221856701002e+01,
+      0.5339293190692e-08, 0.1084724961156e+01, 0.7466759693650e-01,
+      0.5334733683389e-08, 0.3594106067745e+01, 0.7489573444450e-01,
+      0.5392665782110e-08, 0.5630254365606e+01, 0.1055449481598e+01,
+      0.6682075673789e-08, 0.1518480041732e+01, 0.2213766559277e+00,
+      0.5079130495960e-08, 0.2739765115711e+01, 0.2132517061319e+00,
+      0.5077759793261e-08, 0.5290711290094e+01, 0.2133464534247e+00,
+
+      0.4832037368310e-08, 0.1404473217200e+01, 0.7160067364790e-01,
+      0.6463279674802e-08, 0.6038381695210e+01, 0.2209183458640e-01,
+      0.6240592771560e-08, 0.1290170653666e+01, 0.3306188016693e+00,
+      0.4672013521493e-08, 0.3261895939677e+01, 0.7796265773310e-01,
+      0.6500650750348e-08, 0.1154522312095e+01, 0.3884652414254e+00,
+      0.6344161389053e-08, 0.6206111545062e+01, 0.7605151500000e-01,
+      0.4682518370646e-08, 0.5409118796685e+01, 0.1073608853559e+01,
+      0.5329460015591e-08, 0.1202985784864e+01, 0.7287631425543e+00,
+      0.5701588675898e-08, 0.4098715257064e+01, 0.8731175355560e-01,
+      0.6030690867211e-08, 0.4132033218460e+00, 0.9846002785331e+00,
+
+      0.4336256312655e-08, 0.1211415991827e+01, 0.4297791515992e+00,
+      0.4688498808975e-08, 0.3765479072409e+01, 0.2127790306879e+00,
+      0.4675578609335e-08, 0.4265540037226e+01, 0.2138191288687e+00,
+      0.4225578112158e-08, 0.5237566010676e+01, 0.3407705765729e+00,
+      0.5139422230028e-08, 0.1507173079513e+01, 0.7233337363710e-01,
+      0.4619995093571e-08, 0.9023957449848e-01, 0.8603097737811e+00,
+      0.4494776255461e-08, 0.5414930552139e+00, 0.7381754420900e-01,
+      0.4274026276788e-08, 0.4145735303659e+01, 0.7574578717200e-01,
+      0.5018141789353e-08, 0.3344408829055e+01, 0.3180992042600e-02,
+      0.4866163952181e-08, 0.3348534657607e+01, 0.7722995774390e-01,
+
+      0.4111986020501e-08, 0.4198823597220e+00, 0.1451108196653e+00,
+      0.3356142784950e-08, 0.5609144747180e+01, 0.1274714967946e+00,
+      0.4070575554551e-08, 0.7028411059224e+00, 0.3503323232942e+00,
+      0.3257451857278e-08, 0.5624697983086e+01, 0.5296435984654e+00,
+      0.3256973703026e-08, 0.1857842076707e+01, 0.5297383457582e+00,
+      0.3830771508640e-08, 0.4562887279931e+01, 0.9098186128426e+00,
+      0.3725024005962e-08, 0.2358058692652e+00, 0.1084620721060e+00,
+      0.3136763921756e-08, 0.2049731526845e+01, 0.2346394437820e+00,
+      0.3795147256194e-08, 0.2432356296933e+00, 0.1862120789403e+00,
+      0.2877342229911e-08, 0.5631101279387e+01, 0.1905464808669e+01,
+
+      0.3076931798805e-08, 0.1117615737392e+01, 0.3628624111593e+00,
+      0.2734765945273e-08, 0.5899826516955e+01, 0.2131850110243e+00,
+      0.2733405296885e-08, 0.2130562964070e+01, 0.2134131485323e+00,
+      0.2898552353410e-08, 0.3462387048225e+00, 0.5291709230214e+00,
+      0.2893736103681e-08, 0.8534352781543e+00, 0.5302110212022e+00,
+      0.3095717734137e-08, 0.2875061429041e+01, 0.2976424921901e+00,
+      0.2636190425832e-08, 0.2242512846659e+01, 0.1485980103780e+01,
+      0.3645512095537e-08, 0.1354016903958e+01, 0.6044726378023e+00,
+      0.2808173547723e-08, 0.6705114365631e-01, 0.6225157782540e-01,
+      0.2625012866888e-08, 0.4775705748482e+01, 0.5268983110410e-01,
+
+      0.2572233995651e-08, 0.2638924216139e+01, 0.1258454114666e+01,
+      0.2604238824792e-08, 0.4826358927373e+01, 0.2103781122809e+00,
+      0.2596886385239e-08, 0.3200388483118e+01, 0.2162200472757e+00,
+      0.3228057304264e-08, 0.5384848409563e+01, 0.2007689919132e+00,
+      0.2481601798252e-08, 0.5173373487744e+01, 0.1062562936266e+01,
+      0.2745977498864e-08, 0.6250966149853e+01, 0.5651155736444e+00,
+      0.2669878833811e-08, 0.4906001352499e+01, 0.1400015846597e+00,
+      0.3203986611711e-08, 0.5034333010005e+01, 0.7036329877322e+00,
+      0.3354961227212e-08, 0.6108262423137e+01, 0.4549093064213e+00,
+      0.2400407324558e-08, 0.2135399294955e+01, 0.2125476091956e+00,
+
+      0.2379905859802e-08, 0.5893721933961e+01, 0.2140505503610e+00,
+      0.2550844302187e-08, 0.3331940762063e+01, 0.1534957940063e+00,
+      0.2268824211001e-08, 0.1843418461035e+01, 0.2235935264888e+00,
+      0.2464700891204e-08, 0.3029548547230e+01, 0.2091065926078e+00,
+      0.2436814726024e-08, 0.4994717970364e+01, 0.2174915669488e+00,
+      0.2443623894745e-08, 0.2645102591375e+01, 0.1739420156204e+00,
+      0.2318701783838e-08, 0.5700547397897e+01, 0.7530171478090e-01,
+      0.2284448700256e-08, 0.5268898905872e+01, 0.7426161660010e-01,
+      0.2468848123510e-08, 0.5276280575078e+01, 0.2526561439362e+00,
+      0.2814052350303e-08, 0.6130168623475e+01, 0.5636314030725e+00,
+
+      0.2243662755220e-08, 0.6631692457995e+00, 0.8886590321940e-01,
+      0.2330795855941e-08, 0.2499435487702e+01, 0.1056200952181e+01,
+      0.9757679038404e-09, 0.5796846023126e+01, 0.7826370942180e+02 };
+
+/* SSB-to-Sun, T^0, Z */
+   static const double s0z[] = {
+      0.1181255122986e-03, 0.4607918989164e+00, 0.2132990797783e+00,
+      0.1127777651095e-03, 0.4169146331296e+00, 0.5296909721118e+00,
+      0.4777754401806e-04, 0.4582657007130e+01, 0.3813291813120e-01,
+      0.1129354285772e-04, 0.5758735142480e+01, 0.7478166569050e-01,
+     -0.1149543637123e-04, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.3298730512306e-05, 0.5978801994625e+01, 0.4265981595566e+00,
+      0.2733376706079e-05, 0.7665413691040e+00, 0.1059381944224e+01,
+      0.9426389657270e-06, 0.3710201265838e+01, 0.2061856251104e+00,
+      0.8187517749552e-06, 0.3390675605802e+00, 0.2204125344462e+00,
+      0.4080447871819e-06, 0.4552296640088e+00, 0.5225775174439e+00,
+
+      0.3169973017028e-06, 0.3445455899321e+01, 0.5368044267797e+00,
+      0.2438098615549e-06, 0.5664675150648e+01, 0.3664874755930e-01,
+      0.2601897517235e-06, 0.1931894095697e+01, 0.1495633313810e+00,
+      0.2314558080079e-06, 0.3666319115574e+00, 0.3961708870310e-01,
+      0.1962549548002e-06, 0.3167411699020e+01, 0.7626583626240e-01,
+      0.2180518287925e-06, 0.1544420746580e+01, 0.7113454667900e-02,
+      0.1451382442868e-06, 0.1583756740070e+01, 0.1102062672231e+00,
+      0.1358439007389e-06, 0.5239941758280e+01, 0.6398972393349e+00,
+      0.1050585898028e-06, 0.2266958352859e+01, 0.3163918923335e+00,
+      0.1050029870186e-06, 0.2711495250354e+01, 0.4194847048887e+00,
+
+      0.9934920679800e-07, 0.1116208151396e+01, 0.1589072916335e+01,
+      0.1048395331560e-06, 0.3408619600206e+01, 0.1021328554739e+02,
+      0.8370147196668e-07, 0.3810459401087e+01, 0.2535050500000e-01,
+      0.7989856510998e-07, 0.3769910473647e+01, 0.7329749511860e-01,
+      0.5441221655233e-07, 0.2416994903374e+01, 0.1030928125552e+00,
+      0.4610812906784e-07, 0.5858503336994e+01, 0.4337116142245e+00,
+      0.3923022803444e-07, 0.3354170010125e+00, 0.1484170571900e-02,
+      0.2610725582128e-07, 0.5410600646324e+01, 0.6327837846670e+00,
+      0.2455279767721e-07, 0.6120216681403e+01, 0.1162474756779e+01,
+      0.2375530706525e-07, 0.6055443426143e+01, 0.1052268489556e+01,
+
+      0.1782967577553e-07, 0.3146108708004e+01, 0.8460828644453e+00,
+      0.1581687095238e-07, 0.6255496089819e+00, 0.3340612434717e+01,
+      0.1594657672461e-07, 0.3782604300261e+01, 0.1066495398892e+01,
+      0.1563448615040e-07, 0.1997775733196e+01, 0.2022531624851e+00,
+      0.1463624258525e-07, 0.1736316792088e+00, 0.3516457698740e-01,
+      0.1331585056673e-07, 0.4331941830747e+01, 0.9491756770005e+00,
+      0.1130634557637e-07, 0.6152017751825e+01, 0.2968341143800e-02,
+      0.1028949607145e-07, 0.2101792614637e+00, 0.2275259891141e+00,
+      0.1024074971618e-07, 0.4071833211074e+01, 0.5070101000000e-01,
+      0.8826956060303e-08, 0.4861633688145e+00, 0.2093666171530e+00,
+
+      0.8572230171541e-08, 0.5268190724302e+01, 0.4110125927500e-01,
+      0.7649332643544e-08, 0.5134543417106e+01, 0.2608790314060e+02,
+      0.8581673291033e-08, 0.2920218146681e+01, 0.1480791608091e+00,
+      0.8430589300938e-08, 0.3604576619108e+01, 0.2172315424036e+00,
+      0.7776165501012e-08, 0.3772942249792e+01, 0.6373574839730e-01,
+      0.8311070234408e-08, 0.6200412329888e+01, 0.3235053470014e+00,
+      0.6927365212582e-08, 0.4543353113437e+01, 0.8531963191132e+00,
+      0.6791574208598e-08, 0.2882188406238e+01, 0.7181332454670e-01,
+      0.5593100811839e-08, 0.1776646892780e+01, 0.7429900518901e+00,
+      0.4553381853021e-08, 0.3949617611240e+01, 0.7775000683430e-01,
+
+      0.5758000450068e-08, 0.3859251775075e+01, 0.1990721704425e+00,
+      0.4281283457133e-08, 0.1466294631206e+01, 0.2118763888447e+01,
+      0.4206935661097e-08, 0.5421776011706e+01, 0.1104591729320e-01,
+      0.4213751641837e-08, 0.3412048993322e+01, 0.2243449970715e+00,
+      0.5310506239878e-08, 0.5421641370995e+00, 0.5154640627760e+00,
+      0.3827450341320e-08, 0.8887314524995e+00, 0.1510475019529e+00,
+      0.4292435241187e-08, 0.1405043757194e+01, 0.1422690933580e-01,
+      0.3189780702289e-08, 0.1060049293445e+01, 0.1173197218910e+00,
+      0.3226611928069e-08, 0.6270858897442e+01, 0.2164800718209e+00,
+      0.2893897608830e-08, 0.5117563223301e+01, 0.6470106940028e+00,
+
+      0.3239852024578e-08, 0.4079092237983e+01, 0.2101180877357e+00,
+      0.2956892222200e-08, 0.1594917021704e+01, 0.3092784376656e+00,
+      0.2980177912437e-08, 0.5258787667564e+01, 0.4155522422634e+00,
+      0.3163725690776e-08, 0.3854589225479e+01, 0.8582758298370e-01,
+      0.2662262399118e-08, 0.3561326430187e+01, 0.5257585094865e+00,
+      0.2766689135729e-08, 0.3180732086830e+00, 0.1385174140878e+00,
+      0.2411600278464e-08, 0.3324798335058e+01, 0.5439178814476e+00,
+      0.2483527695131e-08, 0.4169069291947e+00, 0.5336234347371e+00,
+      0.7788777276590e-09, 0.1900569908215e+01, 0.5217580628120e+02 };
+
+/* SSB-to-Sun, T^1, X */
+   static const double s1x[] = {
+     -0.1296310361520e-07, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.8975769009438e-08, 0.1128891609250e+01, 0.4265981595566e+00,
+      0.7771113441307e-08, 0.2706039877077e+01, 0.2061856251104e+00,
+      0.7538303866642e-08, 0.2191281289498e+01, 0.2204125344462e+00,
+      0.6061384579336e-08, 0.3248167319958e+01, 0.1059381944224e+01,
+      0.5726994235594e-08, 0.5569981398610e+01, 0.5225775174439e+00,
+      0.5616492836424e-08, 0.5057386614909e+01, 0.5368044267797e+00,
+      0.1010881584769e-08, 0.3473577116095e+01, 0.7113454667900e-02,
+      0.7259606157626e-09, 0.3651858593665e+00, 0.6398972393349e+00,
+      0.8755095026935e-09, 0.1662835408338e+01, 0.4194847048887e+00,
+
+      0.5370491182812e-09, 0.1327673878077e+01, 0.4337116142245e+00,
+      0.5743773887665e-09, 0.4250200846687e+01, 0.2132990797783e+00,
+      0.4408103140300e-09, 0.3598752574277e+01, 0.1589072916335e+01,
+      0.3101892374445e-09, 0.4887822983319e+01, 0.1052268489556e+01,
+      0.3209453713578e-09, 0.9702272295114e+00, 0.5296909721118e+00,
+      0.3017228286064e-09, 0.5484462275949e+01, 0.1066495398892e+01,
+      0.3200700038601e-09, 0.2846613338643e+01, 0.1495633313810e+00,
+      0.2137637279911e-09, 0.5692163292729e+00, 0.3163918923335e+00,
+      0.1899686386727e-09, 0.2061077157189e+01, 0.2275259891141e+00,
+      0.1401994545308e-09, 0.4177771136967e+01, 0.1102062672231e+00,
+
+      0.1578057810499e-09, 0.5782460597335e+01, 0.7626583626240e-01,
+      0.1237713253351e-09, 0.5705900866881e+01, 0.5154640627760e+00,
+      0.1313076837395e-09, 0.5163438179576e+01, 0.3664874755930e-01,
+      0.1184963304860e-09, 0.3054804427242e+01, 0.6327837846670e+00,
+      0.1238130878565e-09, 0.2317292575962e+01, 0.3961708870310e-01,
+      0.1015959527736e-09, 0.2194643645526e+01, 0.7329749511860e-01,
+      0.9017954423714e-10, 0.2868603545435e+01, 0.1990721704425e+00,
+      0.8668024955603e-10, 0.4923849675082e+01, 0.5439178814476e+00,
+      0.7756083930103e-10, 0.3014334135200e+01, 0.9491756770005e+00,
+      0.7536503401741e-10, 0.2704886279769e+01, 0.1030928125552e+00,
+
+      0.5483308679332e-10, 0.6010983673799e+01, 0.8531963191132e+00,
+      0.5184339620428e-10, 0.1952704573291e+01, 0.2093666171530e+00,
+      0.5108658712030e-10, 0.2958575786649e+01, 0.2172315424036e+00,
+      0.5019424524650e-10, 0.1736317621318e+01, 0.2164800718209e+00,
+      0.4909312625978e-10, 0.3167216416257e+01, 0.2101180877357e+00,
+      0.4456638901107e-10, 0.7697579923471e+00, 0.3235053470014e+00,
+      0.4227030350925e-10, 0.3490910137928e+01, 0.6373574839730e-01,
+      0.4095456040093e-10, 0.5178888984491e+00, 0.6470106940028e+00,
+      0.4990537041422e-10, 0.3323887668974e+01, 0.1422690933580e-01,
+      0.4321170010845e-10, 0.4288484987118e+01, 0.7358765972222e+00,
+
+      0.3544072091802e-10, 0.6021051579251e+01, 0.5265099800692e+00,
+      0.3480198638687e-10, 0.4600027054714e+01, 0.5328719641544e+00,
+      0.3440287244435e-10, 0.4349525970742e+01, 0.8582758298370e-01,
+      0.3330628322713e-10, 0.2347391505082e+01, 0.1104591729320e-01,
+      0.2973060707184e-10, 0.4789409286400e+01, 0.5257585094865e+00,
+      0.2932606766089e-10, 0.5831693799927e+01, 0.5336234347371e+00,
+      0.2876972310953e-10, 0.2692638514771e+01, 0.1173197218910e+00,
+      0.2827488278556e-10, 0.2056052487960e+01, 0.2022531624851e+00,
+      0.2515028239756e-10, 0.7411863262449e+00, 0.9597935788730e-01,
+      0.2853033744415e-10, 0.3948481024894e+01, 0.2118763888447e+01 };
+
+/* SSB-to-Sun, T^1, Y */
+   static const double s1y[] = {
+      0.8989047573576e-08, 0.5840593672122e+01, 0.4265981595566e+00,
+      0.7815938401048e-08, 0.1129664707133e+01, 0.2061856251104e+00,
+      0.7550926713280e-08, 0.6196589104845e+00, 0.2204125344462e+00,
+      0.6056556925895e-08, 0.1677494667846e+01, 0.1059381944224e+01,
+      0.5734142698204e-08, 0.4000920852962e+01, 0.5225775174439e+00,
+      0.5614341822459e-08, 0.3486722577328e+01, 0.5368044267797e+00,
+      0.1028678147656e-08, 0.1877141024787e+01, 0.7113454667900e-02,
+      0.7270792075266e-09, 0.5077167301739e+01, 0.6398972393349e+00,
+      0.8734141726040e-09, 0.9069550282609e-01, 0.4194847048887e+00,
+      0.5377371402113e-09, 0.6039381844671e+01, 0.4337116142245e+00,
+
+      0.4729719431571e-09, 0.2153086311760e+01, 0.2132990797783e+00,
+      0.4458052820973e-09, 0.5059830025565e+01, 0.5296909721118e+00,
+      0.4406855467908e-09, 0.2027971692630e+01, 0.1589072916335e+01,
+      0.3101659310977e-09, 0.3317677981860e+01, 0.1052268489556e+01,
+      0.3016749232545e-09, 0.3913703482532e+01, 0.1066495398892e+01,
+      0.3198541352656e-09, 0.1275513098525e+01, 0.1495633313810e+00,
+      0.2142065389871e-09, 0.5301351614597e+01, 0.3163918923335e+00,
+      0.1902615247592e-09, 0.4894943352736e+00, 0.2275259891141e+00,
+      0.1613410990871e-09, 0.2449891130437e+01, 0.1102062672231e+00,
+      0.1576992165097e-09, 0.4211421447633e+01, 0.7626583626240e-01,
+
+      0.1241637259894e-09, 0.4140803368133e+01, 0.5154640627760e+00,
+      0.1313974830355e-09, 0.3591920305503e+01, 0.3664874755930e-01,
+      0.1181697118258e-09, 0.1506314382788e+01, 0.6327837846670e+00,
+      0.1238239742779e-09, 0.7461405378404e+00, 0.3961708870310e-01,
+      0.1010107068241e-09, 0.6271010795475e+00, 0.7329749511860e-01,
+      0.9226316616509e-10, 0.1259158839583e+01, 0.1990721704425e+00,
+      0.8664946419555e-10, 0.3353244696934e+01, 0.5439178814476e+00,
+      0.7757230468978e-10, 0.1447677295196e+01, 0.9491756770005e+00,
+      0.7693168628139e-10, 0.1120509896721e+01, 0.1030928125552e+00,
+      0.5487897454612e-10, 0.4439380426795e+01, 0.8531963191132e+00,
+
+      0.5196118677218e-10, 0.3788856619137e+00, 0.2093666171530e+00,
+      0.5110853339935e-10, 0.1386879372016e+01, 0.2172315424036e+00,
+      0.5027804534813e-10, 0.1647881805466e+00, 0.2164800718209e+00,
+      0.4922485922674e-10, 0.1594315079862e+01, 0.2101180877357e+00,
+      0.6155599524400e-10, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.4447147832161e-10, 0.5480720918976e+01, 0.3235053470014e+00,
+      0.4144691276422e-10, 0.1931371033660e+01, 0.6373574839730e-01,
+      0.4099950625452e-10, 0.5229611294335e+01, 0.6470106940028e+00,
+      0.5060541682953e-10, 0.1731112486298e+01, 0.1422690933580e-01,
+      0.4293615946300e-10, 0.2714571038925e+01, 0.7358765972222e+00,
+
+      0.3545659845763e-10, 0.4451041444634e+01, 0.5265099800692e+00,
+      0.3479112041196e-10, 0.3029385448081e+01, 0.5328719641544e+00,
+      0.3438516493570e-10, 0.2778507143731e+01, 0.8582758298370e-01,
+      0.3297341285033e-10, 0.7898709807584e+00, 0.1104591729320e-01,
+      0.2972585818015e-10, 0.3218785316973e+01, 0.5257585094865e+00,
+      0.2931707295017e-10, 0.4260731012098e+01, 0.5336234347371e+00,
+      0.2897198149403e-10, 0.1120753978101e+01, 0.1173197218910e+00,
+      0.2832293240878e-10, 0.4597682717827e+00, 0.2022531624851e+00,
+      0.2864348326612e-10, 0.2169939928448e+01, 0.9597935788730e-01,
+      0.2852714675471e-10, 0.2377659870578e+01, 0.2118763888447e+01 };
+
+/* SSB-to-Sun, T^1, Z */
+   static const double s1z[] = {
+      0.5444220475678e-08, 0.1803825509310e+01, 0.2132990797783e+00,
+      0.3883412695596e-08, 0.4668616389392e+01, 0.5296909721118e+00,
+      0.1334341434551e-08, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.3730001266883e-09, 0.5401405918943e+01, 0.2061856251104e+00,
+      0.2894929197956e-09, 0.4932415609852e+01, 0.2204125344462e+00,
+      0.2857950357701e-09, 0.3154625362131e+01, 0.7478166569050e-01,
+      0.2499226432292e-09, 0.3657486128988e+01, 0.4265981595566e+00,
+      0.1937705443593e-09, 0.5740434679002e+01, 0.1059381944224e+01,
+      0.1374894396320e-09, 0.1712857366891e+01, 0.5368044267797e+00,
+      0.1217248678408e-09, 0.2312090870932e+01, 0.5225775174439e+00,
+
+      0.7961052740870e-10, 0.5283368554163e+01, 0.3813291813120e-01,
+      0.4979225949689e-10, 0.4298290471860e+01, 0.4194847048887e+00,
+      0.4388552286597e-10, 0.6145515047406e+01, 0.7113454667900e-02,
+      0.2586835212560e-10, 0.3019448001809e+01, 0.6398972393349e+00 };
+
+/* SSB-to-Sun, T^2, X */
+   static const double s2x[] = {
+      0.1603551636587e-11, 0.4404109410481e+01, 0.2061856251104e+00,
+      0.1556935889384e-11, 0.4818040873603e+00, 0.2204125344462e+00,
+      0.1182594414915e-11, 0.9935762734472e+00, 0.5225775174439e+00,
+      0.1158794583180e-11, 0.3353180966450e+01, 0.5368044267797e+00,
+      0.9597358943932e-12, 0.5567045358298e+01, 0.2132990797783e+00,
+      0.6511516579605e-12, 0.5630872420788e+01, 0.4265981595566e+00,
+      0.7419792747688e-12, 0.2156188581957e+01, 0.5296909721118e+00,
+      0.3951972655848e-12, 0.1981022541805e+01, 0.1059381944224e+01,
+      0.4478223877045e-12, 0.0000000000000e+00, 0.0000000000000e+00 };
+
+/* SSB-to-Sun, T^2, Y */
+   static const double s2y[] = {
+      0.1609114495091e-11, 0.2831096993481e+01, 0.2061856251104e+00,
+      0.1560330784946e-11, 0.5193058213906e+01, 0.2204125344462e+00,
+      0.1183535479202e-11, 0.5707003443890e+01, 0.5225775174439e+00,
+      0.1158183066182e-11, 0.1782400404928e+01, 0.5368044267797e+00,
+      0.1032868027407e-11, 0.4036925452011e+01, 0.2132990797783e+00,
+      0.6540142847741e-12, 0.4058241056717e+01, 0.4265981595566e+00,
+      0.7305236491596e-12, 0.6175401942957e+00, 0.5296909721118e+00,
+     -0.5580725052968e-12, 0.0000000000000e+00, 0.0000000000000e+00,
+      0.3946122651015e-12, 0.4108265279171e+00, 0.1059381944224e+01 };
+
+/* SSB-to-Sun, T^2, Z */
+   static const double s2z[] = {
+      0.3749920358054e-12, 0.3230285558668e+01, 0.2132990797783e+00,
+      0.2735037220939e-12, 0.6154322683046e+01, 0.5296909721118e+00 };
+
+/* Pointers to coefficient arrays, in x,y,z sets */
+   static const double *ce0[] = { e0x, e0y, e0z },
+                       *ce1[] = { e1x, e1y, e1z },
+                       *ce2[] = { e2x, e2y, e2z },
+                       *cs0[] = { s0x, s0y, s0z },
+                       *cs1[] = { s1x, s1y, s1z },
+                       *cs2[] = { s2x, s2y, s2z };
+   const double *coeffs;
+
+/* Numbers of terms for each component of the model, in x,y,z sets */
+   static const int ne0[3] = {(int)(sizeof e0x / sizeof (double) / 3),
+                              (int)(sizeof e0y / sizeof (double) / 3),
+                              (int)(sizeof e0z / sizeof (double) / 3) },
+                    ne1[3] = {(int)(sizeof e1x / sizeof (double) / 3),
+                              (int)(sizeof e1y / sizeof (double) / 3),
+                              (int)(sizeof e1z / sizeof (double) / 3) },
+                    ne2[3] = {(int)(sizeof e2x / sizeof (double) / 3),
+                              (int)(sizeof e2y / sizeof (double) / 3),
+                              (int)(sizeof e2z / sizeof (double) / 3) },
+                    ns0[3] = {(int)(sizeof s0x / sizeof (double) / 3),
+                              (int)(sizeof s0y / sizeof (double) / 3),
+                              (int)(sizeof s0z / sizeof (double) / 3) },
+                    ns1[3] = {(int)(sizeof s1x / sizeof (double) / 3),
+                              (int)(sizeof s1y / sizeof (double) / 3),
+                              (int)(sizeof s1z / sizeof (double) / 3) },
+                    ns2[3] = {(int)(sizeof s2x / sizeof (double) / 3),
+                              (int)(sizeof s2y / sizeof (double) / 3),
+                              (int)(sizeof s2z / sizeof (double) / 3) };
+   int nterms;
+
+/* Miscellaneous */
+   int jstat, i, j;
+   double t, t2, xyz, xyzd, a, b, c, ct, p, cp,
+          ph[3], vh[3], pb[3], vb[3], x, y, z;
+
+/*--------------------------------------------------------------------*/
+
+/* Time since reference epoch, Julian years. */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
+   t2 = t*t;
+
+/* Set status. */
+   jstat = fabs(t) <= 100.0 ? 0 : 1;
+
+/* X then Y then Z. */
+   for (i = 0; i < 3; i++) {
+
+   /* Initialize position and velocity component. */
+      xyz = 0.0;
+      xyzd = 0.0;
+
+   /* ------------------------------------------------ */
+   /* Obtain component of Sun to Earth ecliptic vector */
+   /* ------------------------------------------------ */
+
+   /* Sun to Earth, T^0 terms. */
+      coeffs = ce0[i];
+      nterms = ne0[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         p = b + c*t;
+         xyz  += a*cos(p);
+         xyzd -= a*c*sin(p);
+      }
+
+   /* Sun to Earth, T^1 terms. */
+      coeffs = ce1[i];
+      nterms = ne1[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         ct = c*t;
+         p = b + ct;
+         cp = cos(p);
+         xyz  += a*t*cp;
+         xyzd += a*( cp - ct*sin(p) );
+      }
+
+   /* Sun to Earth, T^2 terms. */
+      coeffs = ce2[i];
+      nterms = ne2[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         ct = c*t;
+         p = b + ct;
+         cp = cos(p);
+         xyz  += a*t2*cp;
+         xyzd += a*t*( 2.0*cp - ct*sin(p) );
+      }
+
+   /* Heliocentric Earth position and velocity component. */
+      ph[i] = xyz;
+      vh[i] = xyzd / ERFA_DJY;
+
+   /* ------------------------------------------------ */
+   /* Obtain component of SSB to Earth ecliptic vector */
+   /* ------------------------------------------------ */
+
+   /* SSB to Sun, T^0 terms. */
+      coeffs = cs0[i];
+      nterms = ns0[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         p = b + c*t;
+         xyz  += a*cos(p);
+         xyzd -= a*c*sin(p);
+      }
+
+   /* SSB to Sun, T^1 terms. */
+      coeffs = cs1[i];
+      nterms = ns1[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         ct = c*t;
+         p = b + ct;
+         cp = cos(p);
+         xyz  += a*t*cp;
+         xyzd += a*(cp - ct*sin(p));
+      }
+
+   /* SSB to Sun, T^2 terms. */
+      coeffs = cs2[i];
+      nterms = ns2[i];
+      for (j = 0; j < nterms; j++) {
+         a = *coeffs++;
+         b = *coeffs++;
+         c = *coeffs++;
+         ct = c*t;
+         p = b + ct;
+         cp = cos(p);
+         xyz  += a*t2*cp;
+         xyzd += a*t*(2.0*cp - ct*sin(p));
+     }
+
+   /* Barycentric Earth position and velocity component. */
+     pb[i] = xyz;
+     vb[i] = xyzd / ERFA_DJY;
+
+   /* Next Cartesian component. */
+   }
+
+/* Rotate from ecliptic to BCRS coordinates. */
+
+   x = ph[0];
+   y = ph[1];
+   z = ph[2];
+   pvh[0][0] =      x + am12*y + am13*z;
+   pvh[0][1] = am21*x + am22*y + am23*z;
+   pvh[0][2] =          am32*y + am33*z;
+
+   x = vh[0];
+   y = vh[1];
+   z = vh[2];
+   pvh[1][0] =      x + am12*y + am13*z;
+   pvh[1][1] = am21*x + am22*y + am23*z;
+   pvh[1][2] =          am32*y + am33*z;
+
+   x = pb[0];
+   y = pb[1];
+   z = pb[2];
+   pvb[0][0] =      x + am12*y + am13*z;
+   pvb[0][1] = am21*x + am22*y + am23*z;
+   pvb[0][2] =          am32*y + am33*z;
+
+   x = vb[0];
+   y = vb[1];
+   z = vb[2];
+   pvb[1][0] =      x + am12*y + am13*z;
+   pvb[1][1] = am21*x + am22*y + am23*z;
+   pvb[1][2] =          am32*y + am33*z;
+
+/* Return the status. */
+   return jstat;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/eqeq94.c b/cextern/erfa/eqeq94.c
new file mode 100644
index 0000000..669515d
--- /dev/null
+++ b/cextern/erfa/eqeq94.c
@@ -0,0 +1,141 @@
+#include "erfa.h"
+
+double eraEqeq94(double date1, double date2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t,  om,  dpsi,  deps,  eps0, ee;
+
+
+/* Interval between fundamental epoch J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Longitude of the mean ascending node of the lunar orbit on the */
+/* ecliptic, measured from the mean equinox of date. */
+   om = eraAnpm((450160.280 + (-482890.539
+           + (7.455 + 0.008 * t) * t) * t) * ERFA_DAS2R
+           + fmod(-5.0 * t, 1.0) * ERFA_D2PI);
+
+/* Nutation components and mean obliquity. */
+   eraNut80(date1, date2, &dpsi, &deps);
+   eps0 = eraObl80(date1, date2);
+
+/* Equation of the equinoxes. */
+   ee = dpsi*cos(eps0) + ERFA_DAS2R*(0.00264*sin(om) + 0.000063*sin(om+om));
+
+   return ee;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/era00.c b/cextern/erfa/era00.c
new file mode 100644
index 0000000..47f642c
--- /dev/null
+++ b/cextern/erfa/era00.c
@@ -0,0 +1,145 @@
+#include "erfa.h"
+
+double eraEra00(double dj1, double dj2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double d1, d2, t, f, theta;
+
+
+/* Days since fundamental epoch. */
+   if (dj1 < dj2) {
+      d1 = dj1;
+      d2 = dj2;
+   } else {
+      d1 = dj2;
+      d2 = dj1;
+   }
+   t = d1 + (d2- ERFA_DJ00);
+
+/* Fractional part of T (days). */
+   f = fmod(d1, 1.0) + fmod(d2, 1.0);
+
+/* Earth rotation angle at this UT1. */
+   theta = eraAnp(ERFA_D2PI * (f + 0.7790572732640
+                            + 0.00273781191135448 * t));
+
+   return theta;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/erfa.c b/cextern/erfa/erfa.c
deleted file mode 100644
index 20d3d72..0000000
--- a/cextern/erfa/erfa.c
+++ /dev/null
@@ -1,27361 +0,0 @@
-//Derived from erfa version 1.1.0
-
-#include "erfa.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-void eraA2af(int ndp, double angle, char *sign, int idmsf[4])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Hours to degrees * radians to turns */
-   const double F = 15.0 / ERFA_D2PI;
-
-
-/* Scale then use days to h,m,s function. */
-   eraD2tf(ndp, angle*F, sign, idmsf);
-
-   return;
-
-}
-
-void eraA2tf(int ndp, double angle, char *sign, int ihmsf[4])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Scale then use days to h,m,s function. */
-   eraD2tf(ndp, angle/ERFA_D2PI, sign, ihmsf);
-
-   return;
-
-}
-
-void eraAb(double pnat[3], double v[3], double s, double bm1,
-           double ppr[3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i;
-   double pdv, w1, w2, r2, w, p[3], r;
-
-
-   pdv = eraPdp(pnat, v);
-   w1 = 1.0 + pdv/(1.0 + bm1);
-   w2 = ERFA_SRS/s;
-   r2 = 0.0;
-   for (i = 0; i < 3; i++) {
-      w = pnat[i]*bm1 + w1*v[i] + w2*(v[i] - pdv*pnat[i]);
-      p[i] = w;
-      r2 = r2 + w*w;
-   }
-   r = sqrt(r2);
-   for (i = 0; i < 3; i++) {
-      ppr[i] = p[i]/r;
-   }
-
-/* Finished. */
-
-}
-
-int eraAf2a(char s, int ideg, int iamin, double asec, double *rad)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Compute the interval. */
-   *rad  = ( s == '-' ? -1.0 : 1.0 ) *
-           ( 60.0 * ( 60.0 * ( (double) abs(ideg) ) +
-                             ( (double) abs(iamin) ) ) +
-                                        fabs(asec) ) * ERFA_DAS2R;
-
-/* Validate arguments and return status. */
-   if ( ideg < 0 || ideg > 359 ) return 1;
-   if ( iamin < 0 || iamin > 59 ) return 2;
-   if ( asec < 0.0 || asec >= 60.0 ) return 3;
-   return 0;
-
-}
-
-double eraAnp(double a)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double w;
-
-
-   w = fmod(a, ERFA_D2PI);
-   if (w < 0) w += ERFA_D2PI;
-
-   return w;
-
-}
-
-double eraAnpm(double a)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double w;
-
-
-   w = fmod(a, ERFA_D2PI);
-   if (fabs(w) >= ERFA_DPI) w -= ERFA_DSIGN(ERFA_D2PI, a);
-
-   return w;
-
-}
-
-void eraApcg(double date1, double date2,
-             double ebpv[2][3], double ehp[3],
-             eraASTROM *astrom)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Geocentric observer */
-   double pv[2][3] = { { 0.0, 0.0, 0.0 },
-                       { 0.0, 0.0, 0.0 } };
-
-
-/* Compute the star-independent astrometry parameters. */
-   eraApcs(date1, date2, pv, ebpv, ehp, astrom);
-
-/* Finished. */
-
-}
-
-void eraApcg13(double date1, double date2, eraASTROM *astrom)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double ehpv[2][3], ebpv[2][3];
-
-
-/* Earth barycentric & heliocentric position/velocity (au, au/d). */
-   (void) eraEpv00(date1, date2, ehpv, ebpv);
-
-/* Compute the star-independent astrometry parameters. */
-   eraApcg(date1, date2, ebpv, ehpv[0], astrom);
-
-/* Finished. */
-
-}
-
-void eraApci(double date1, double date2,
-             double ebpv[2][3], double ehp[3],
-             double x, double y, double s,
-             eraASTROM *astrom)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Star-independent astrometry parameters for geocenter. */
-   eraApcg(date1, date2, ebpv, ehp, astrom);
-
-/* CIO based BPN matrix. */
-   eraC2ixys(x, y, s, astrom->bpn);
-
-/* Finished. */
-
-}
-
-void eraApci13(double date1, double date2,
-               eraASTROM *astrom, double *eo)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double ehpv[2][3], ebpv[2][3], r[3][3], x, y, s;
-
-
-/* Earth barycentric & heliocentric position/velocity (au, au/d). */
-   (void) eraEpv00(date1, date2, ehpv, ebpv);
-
-/* Form the equinox based BPN matrix, IAU 2006/2000A. */
-   eraPnm06a(date1, date2, r);
-
-/* Extract CIP X,Y. */
-   eraBpn2xy(r, &x, &y);
-
-/* Obtain CIO locator s. */
-   s = eraS06(date1, date2, x, y);
-
-/* Compute the star-independent astrometry parameters. */
-   eraApci(date1, date2, ebpv, ehpv[0], x, y, s, astrom);
-
-/* Equation of the origins. */
-   *eo = eraEors(r, s);
-
-/* Finished. */
-
-}
-
-void eraApco(double date1, double date2,
-             double ebpv[2][3], double ehp[3],
-             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)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double sl, cl, r[3][3], pvc[2][3], pv[2][3];
-
-
-/* Longitude with adjustment for TIO locator s'. */
-   astrom->along = elong + sp;
-
-/* Polar motion, rotated onto the local meridian. */
-   sl = sin(astrom->along);
-   cl = cos(astrom->along);
-   astrom->xpl = xp*cl - yp*sl;
-   astrom->ypl = xp*sl + yp*cl;
-
-/* Functions of latitude. */
-   astrom->sphi = sin(phi);
-   astrom->cphi = cos(phi);
-
-/* Refraction constants. */
-   astrom->refa = refa;
-   astrom->refb = refb;
-
-/* Local Earth rotation angle. */
-   eraAper(theta, astrom);
-
-/* Disable the (redundant) diurnal aberration step. */
-   astrom->diurab = 0.0;
-
-/* CIO based BPN matrix. */
-   eraC2ixys(x, y, s, r);
-
-/* Observer's geocentric position and velocity (m, m/s, CIRS). */
-   eraPvtob(elong, phi, hm, xp, yp, sp, theta, pvc);
-
-/* Rotate into GCRS. */
-   eraTrxpv(r, pvc, pv);
-
-/* ICRS <-> GCRS parameters. */
-   eraApcs(date1, date2, pv, ebpv, ehp, astrom);
-
-/* Store the CIO based BPN matrix. */
-   eraCr(r, astrom->bpn );
-
-/* Finished. */
-
-}
-
-int eraApco13(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   double tai1, tai2, tt1, tt2, ut11, ut12, ehpv[2][3], ebpv[2][3],
-          r[3][3], x, y, s, theta, sp, refa, refb;
-
-
-/* UTC to other time scales. */
-   j = eraUtctai(utc1, utc2, &tai1, &tai2);
-   if ( j < 0 ) return -1;
-   j = eraTaitt(tai1, tai2, &tt1, &tt2);
-   j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12);
-   if ( j < 0 ) return -1;
-
-/* Earth barycentric & heliocentric position/velocity (au, au/d). */
-   (void) eraEpv00(tt1, tt2, ehpv, ebpv);
-
-/* Form the equinox based BPN matrix, IAU 2006/2000A. */
-   eraPnm06a(tt1, tt2, r);
-
-/* Extract CIP X,Y. */
-   eraBpn2xy(r, &x, &y);
-
-/* Obtain CIO locator s. */
-   s = eraS06(tt1, tt2, x, y);
-
-/* Earth rotation angle. */
-   theta = eraEra00(ut11, ut12);
-
-/* TIO locator s'. */
-   sp = eraSp00(tt1, tt2);
-
-/* Refraction constants A and B. */
-   eraRefco(phpa, tc, rh, wl, &refa, &refb);
-
-/* Compute the star-independent astrometry parameters. */
-   eraApco(tt1, tt2, ebpv, ehpv[0], x, y, s, theta,
-           elong, phi, hm, xp, yp, sp, refa, refb, astrom);
-
-/* Equation of the origins. */
-   *eo = eraEors(r, s);
-
-/* Return any warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-void eraApcs(double date1, double date2, double pv[2][3],
-             double ebpv[2][3], double ehp[3],
-             eraASTROM *astrom)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* au/d to m/s */
-   const double AUDMS = ERFA_DAU/ERFA_DAYSEC;
-
-/* Light time for 1 AU (day) */
-   const double CR = ERFA_AULT/ERFA_DAYSEC;
-
-   int i;
-   double dp, dv, pb[3], vb[3], ph[3], v2, w;
-
-
-/* Time since reference epoch, years (for proper motion calculation). */
-   astrom->pmt = ( (date1 - ERFA_DJ00) + date2 ) / ERFA_DJY;
-
-/* Adjust Earth ephemeris to observer. */
-   for (i = 0; i < 3; i++) {
-      dp = pv[0][i] / ERFA_DAU;
-      dv = pv[1][i] / AUDMS;
-      pb[i] = ebpv[0][i] + dp;
-      vb[i] = ebpv[1][i] + dv;
-      ph[i] = ehp[i] + dp;
-   }
-
-/* Barycentric position of observer (au). */
-   eraCp(pb, astrom->eb);
-
-/* Heliocentric direction and distance (unit vector and au). */
-   eraPn(ph, &astrom->em, astrom->eh);
-
-/* Barycentric vel. in units of c, and reciprocal of Lorenz factor. */
-   v2 = 0.0;
-   for (i = 0; i < 3; i++) {
-      w = vb[i] * CR;
-      astrom->v[i] = w;
-      v2 += w*w;
-   }
-   astrom->bm1 = sqrt(1.0 - v2);
-
-/* Reset the NPB matrix. */
-   eraIr(astrom->bpn);
-
-/* Finished. */
-
-}
-
-void eraApcs13(double date1, double date2, double pv[2][3],
-               eraASTROM *astrom)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double ehpv[2][3], ebpv[2][3];
-
-
-/* Earth barycentric & heliocentric position/velocity (au, au/d). */
-   (void) eraEpv00(date1, date2, ehpv, ebpv);
-
-/* Compute the star-independent astrometry parameters. */
-   eraApcs(date1, date2, pv, ebpv, ehpv[0], astrom);
-
-/* Finished. */
-
-}
-
-void eraAper(double theta, eraASTROM *astrom)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   astrom->eral = theta + astrom->along;
-
-/* Finished. */
-
-}
-
-void eraAper13(double ut11, double ut12, eraASTROM *astrom)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraAper(eraEra00(ut11,ut12), astrom);
-
-/* Finished. */
-
-}
-
-void eraApio(double sp, double theta,
-             double elong, double phi, double hm, double xp, double yp,
-             double refa, double refb,
-             eraASTROM *astrom)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double sl, cl, pv[2][3];
-
-
-/* Longitude with adjustment for TIO locator s'. */
-   astrom->along = elong + sp;
-
-/* Polar motion, rotated onto the local meridian. */
-   sl = sin(astrom->along);
-   cl = cos(astrom->along);
-   astrom->xpl = xp*cl - yp*sl;
-   astrom->ypl = xp*sl + yp*cl;
-
-/* Functions of latitude. */
-   astrom->sphi = sin(phi);
-   astrom->cphi = cos(phi);
-
-/* Observer's geocentric position and velocity (m, m/s, CIRS). */
-   eraPvtob(elong, phi, hm, xp, yp, sp, theta, pv);
-
-/* Magnitude of diurnal aberration vector. */
-   astrom->diurab = sqrt(pv[1][0]*pv[1][0]+pv[1][1]*pv[1][1]) / ERFA_CMPS;
-
-/* Refraction constants. */
-   astrom->refa = refa;
-   astrom->refb = refb;
-
-/* Local Earth rotation angle. */
-   eraAper(theta, astrom);
-
-/* Finished. */
-
-}
-
-int eraApio13(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   double tai1, tai2, tt1, tt2, ut11, ut12, sp, theta, refa, refb;
-
-
-/* UTC to other time scales. */
-   j = eraUtctai(utc1, utc2, &tai1, &tai2);
-   if ( j < 0 ) return -1;
-   j = eraTaitt(tai1, tai2, &tt1, &tt2);
-   j = eraUtcut1(utc1, utc2, dut1, &ut11, &ut12);
-   if ( j < 0 ) return -1;
-
-/* TIO locator s'. */
-   sp = eraSp00(tt1, tt2);
-
-/* Earth rotation angle. */
-   theta = eraEra00(ut11, ut12);
-
-/* Refraction constants A and B. */
-   eraRefco(phpa, tc, rh, wl, &refa, &refb);
-
-/* CIRS <-> observed astrometry parameters. */
-   eraApio(sp, theta, elong, phi, hm, xp, yp, refa, refb, astrom);
-
-/* Return any warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-void eraAtci13(double rc, double dc,
-               double pr, double pd, double px, double rv,
-               double date1, double date2,
-               double *ri, double *di, double *eo)
-/*
-**  - - - - - - - - - -
-**   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.8g could be expressed in any of these ways, among
-**     others:
-**
-**            date1          date2
-**
-**         2450123.8g           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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Star-independent astrometry parameters */
-   eraASTROM astrom;
-
-
-/* The transformation parameters. */
-   eraApci13(date1, date2, &astrom, eo);
-
-/* ICRS (epoch J2000.0) to CIRS. */
-   eraAtciq(rc, dc, pr, pd, px, rv, &astrom, ri, di);
-
-/* Finished. */
-
-}
-
-void eraAtciq(double rc, double dc,
-              double pr, double pd, double px, double rv,
-              eraASTROM *astrom, double *ri, double *di)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double pco[3], pnat[3], ppr[3], pi[3], w;
-
-
-/* Proper motion and parallax, giving BCRS coordinate direction. */
-   eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco);
-
-/* Light deflection by the Sun, giving BCRS natural direction. */
-   eraLdsun(pco, astrom->eh, astrom->em, pnat);
-
-/* Aberration, giving GCRS proper direction. */
-   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
-
-/* Bias-precession-nutation, giving CIRS proper direction. */
-   eraRxp(astrom->bpn, ppr, pi);
-
-/* CIRS RA,Dec. */
-   eraC2s(pi, &w, di);
-   *ri = eraAnp(w);
-
-/* Finished. */
-
-}
-
-void eraAtciqn(double rc, double dc, double pr, double pd,
-               double px, double rv, eraASTROM *astrom,
-               int n, eraLDBODY b[], double *ri, double *di)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double pco[3], pnat[3], ppr[3], pi[3], w;
-
-
-/* Proper motion and parallax, giving BCRS coordinate direction. */
-   eraPmpx(rc, dc, pr, pd, px, rv, astrom->pmt, astrom->eb, pco);
-
-/* Light deflection, giving BCRS natural direction. */
-   eraLdn(n, b, astrom->eb, pco, pnat);
-
-/* Aberration, giving GCRS proper direction. */
-   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
-
-/* Bias-precession-nutation, giving CIRS proper direction. */
-   eraRxp(astrom->bpn, ppr, pi);
-
-/* CIRS RA,Dec. */
-   eraC2s(pi, &w, di);
-   *ri = eraAnp(w);
-
-/* Finished. */
-
-}
-
-void eraAtciqz(double rc, double dc, eraASTROM *astrom,
-               double *ri, double *di)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double pco[3], pnat[3], ppr[3], pi[3], w;
-
-
-/* BCRS coordinate direction (unit vector). */
-   eraS2c(rc, dc, pco);
-
-/* Light deflection by the Sun, giving BCRS natural direction. */
-   eraLdsun(pco, astrom->eh, astrom->em, pnat);
-
-/* Aberration, giving GCRS proper direction. */
-   eraAb(pnat, astrom->v, astrom->em, astrom->bm1, ppr);
-
-/* Bias-precession-nutation, giving CIRS proper direction. */
-   eraRxp(astrom->bpn, ppr, pi);
-
-/* CIRS RA,Dec. */
-   eraC2s(pi, &w, di);
-   *ri = eraAnp(w);
-
-/* Finished. */
-
-}
-
-int eraAtco13(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)
-/*
-**  - - - - - - - - - -
-**   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 ICRS to observed
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   eraASTROM astrom;
-   double ri, di;
-
-
-/* Star-independent astrometry parameters. */
-   j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
-                 phpa, tc, rh, wl, &astrom, eo);
-
-/* Abort if bad UTC. */
-   if ( j < 0 ) return j;
-
-/* Transform ICRS to CIRS. */
-   eraAtciq(rc, dc, pr, pd, px, rv, &astrom, &ri, &di);
-
-/* Transform CIRS to observed. */
-   eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob);
-
-/* Return OK/warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-void eraAtic13(double ri, double di, double date1, double date2,
-               double *rc, double *dc, double *eo)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Star-independent astrometry parameters */
-   eraASTROM astrom;
-
-
-/* Star-independent astrometry parameters. */
-   eraApci13(date1, date2, &astrom, eo);
-
-/* CIRS to ICRS astrometric. */
-   eraAticq(ri, di, &astrom, rc, dc);
-
-/* Finished. */
-
-}
-
-void eraAticq(double ri, double di, eraASTROM *astrom,
-              double *rc, double *dc)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j, i;
-   double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r,
-          after[3];
-
-
-/* CIRS RA,Dec to Cartesian. */
-   eraS2c(ri, di, pi);
-
-/* Bias-precession-nutation, giving GCRS proper direction. */
-   eraTrxp(astrom->bpn, pi, ppr);
-
-/* Aberration, giving GCRS natural direction. */
-   eraZp(d);
-   for (j = 0; j < 2; j++) {
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         w = ppr[i] - d[i];
-         before[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         before[i] /= r;
-      }
-      eraAb(before, astrom->v, astrom->em, astrom->bm1, after);
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         d[i] = after[i] - before[i];
-         w = ppr[i] - d[i];
-         pnat[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         pnat[i] /= r;
-      }
-   }
-
-/* Light deflection by the Sun, giving BCRS coordinate direction. */
-   eraZp(d);
-   for (j = 0; j < 5; j++) {
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         w = pnat[i] - d[i];
-         before[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         before[i] /= r;
-      }
-      eraLdsun(before, astrom->eh, astrom->em, after);
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         d[i] = after[i] - before[i];
-         w = pnat[i] - d[i];
-         pco[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         pco[i] /= r;
-      }
-   }
-
-/* ICRS astrometric RA,Dec. */
-   eraC2s(pco, &w, dc);
-   *rc = eraAnp(w);
-
-/* Finished. */
-
-}
-
-void eraAticqn(double ri, double di, eraASTROM *astrom,
-               int n, eraLDBODY b[], double *rc, double *dc)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j, i;
-   double pi[3], ppr[3], pnat[3], pco[3], w, d[3], before[3], r2, r,
-          after[3];
-
-
-/* CIRS RA,Dec to Cartesian. */
-   eraS2c(ri, di, pi);
-
-/* Bias-precession-nutation, giving GCRS proper direction. */
-   eraTrxp(astrom->bpn, pi, ppr);
-
-/* Aberration, giving GCRS natural direction. */
-   eraZp(d);
-   for (j = 0; j < 2; j++) {
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         w = ppr[i] - d[i];
-         before[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         before[i] /= r;
-      }
-      eraAb(before, astrom->v, astrom->em, astrom->bm1, after);
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         d[i] = after[i] - before[i];
-         w = ppr[i] - d[i];
-         pnat[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         pnat[i] /= r;
-      }
-   }
-
-/* Light deflection, giving BCRS coordinate direction. */
-   eraZp(d);
-   for (j = 0; j < 5; j++) {
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         w = pnat[i] - d[i];
-         before[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         before[i] /= r;
-      }
-      eraLdn(n, b, astrom->eb, before, after);
-      r2 = 0.0;
-      for (i = 0; i < 3; i++) {
-         d[i] = after[i] - before[i];
-         w = pnat[i] - d[i];
-         pco[i] = w;
-         r2 += w*w;
-      }
-      r = sqrt(r2);
-      for (i = 0; i < 3; i++) {
-         pco[i] /= r;
-      }
-   }
-
-/* ICRS astrometric RA,Dec. */
-   eraC2s(pco, &w, dc);
-   *rc = eraAnp(w);
-
-/* Finished. */
-
-}
-
-int eraAtio13(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)
-/*
-**  - - - - - - - - - -
-**   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 ICRS to observed
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   eraASTROM astrom;
-
-
-/* Star-independent astrometry parameters for CIRS->observed. */
-   j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
-                 phpa, tc, rh, wl, &astrom);
-
-/* Abort if bad UTC. */
-   if ( j < 0 ) return j;
-
-/* Transform CIRS to observed. */
-   eraAtioq(ri, di, &astrom, aob, zob, hob, dob, rob);
-
-/* Return OK/warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-void eraAtioq(double ri, double di, eraASTROM *astrom,
-              double *aob, double *zob,
-              double *hob, double *dob, double *rob)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Minimum cos(alt) and sin(alt) for refraction purposes */
-   const double CELMIN = 1e-6;
-   const double SELMIN = 0.05;
-
-   double v[3], x, y, z, xhd, yhd, zhd, f, xhdt, yhdt, zhdt,
-          xaet, yaet, zaet, azobs, r, tz, w, del, cosdel,
-          xaeo, yaeo, zaeo, zdobs, hmobs, dcobs, raobs;
-
-/*--------------------------------------------------------------------*/
-
-/* CIRS RA,Dec to Cartesian -HA,Dec. */
-   eraS2c(ri-astrom->eral, di, v);
-   x = v[0];
-   y = v[1];
-   z = v[2];
-
-/* Polar motion. */
-   xhd = x + astrom->xpl*z;
-   yhd = y - astrom->ypl*z;
-   zhd = z - astrom->xpl*x + astrom->ypl*y;
-
-/* Diurnal aberration. */
-   f = ( 1.0 - astrom->diurab*yhd );
-   xhdt = f * xhd;
-   yhdt = f * ( yhd + astrom->diurab );
-   zhdt = f * zhd;
-
-/* Cartesian -HA,Dec to Cartesian Az,El (S=0,E=90). */
-   xaet = astrom->sphi*xhdt - astrom->cphi*zhdt;
-   yaet = yhdt;
-   zaet = astrom->cphi*xhdt + astrom->sphi*zhdt;
-
-/* Azimuth (N=0,E=90). */
-   azobs = ( xaet != 0.0 || yaet != 0.0 ) ? atan2(yaet,-xaet) : 0.0;
-
-/* ---------- */
-/* Refraction */
-/* ---------- */
-
-/* Cosine and sine of altitude, with precautions. */
-   r = sqrt(xaet*xaet + yaet*yaet);
-   r = r > CELMIN ? r : CELMIN;
-   z = zaet > SELMIN ? zaet : SELMIN;
-
-/* A*tan(z)+B*tan^3(z) model, with Newton-Raphson correction. */
-   tz = r/z;
-   w = astrom->refb*tz*tz;
-   del = ( astrom->refa + w ) * tz /
-         ( 1.0 + ( astrom->refa + 3.0*w ) / ( z*z ) );
-
-/* Apply the change, giving observed vector. */
-   cosdel = 1.0 - del*del/2.0;
-   f = cosdel - del*z/r;
-   xaeo = xaet*f;
-   yaeo = yaet*f;
-   zaeo = cosdel*zaet + del*r;
-
-/* Observed ZD. */
-   zdobs = atan2(sqrt(xaeo*xaeo+yaeo*yaeo), zaeo);
-
-/* Az/El vector to HA,Dec vector (both right-handed). */
-   v[0] = astrom->sphi*xaeo + astrom->cphi*zaeo;
-   v[1] = yaeo;
-   v[2] = - astrom->cphi*xaeo + astrom->sphi*zaeo;
-
-/* To spherical -HA,Dec. */
-   eraC2s ( v, &hmobs, &dcobs );
-
-/* Right ascension (with respect to CIO). */
-   raobs = astrom->eral + hmobs;
-
-/* Return the results. */
-   *aob = eraAnp(azobs);
-   *zob = zdobs;
-   *hob = -hmobs;
-   *dob = dcobs;
-   *rob = eraAnp(raobs);
-
-/* Finished. */
-
-}
-
-int eraAtoc13(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   eraASTROM astrom;
-   double eo, ri, di;
-
-
-/* Star-independent astrometry parameters. */
-   j = eraApco13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
-                 phpa, tc, rh, wl, &astrom, &eo);
-
-/* Abort if bad UTC. */
-   if ( j < 0 ) return j;
-
-/* Transform observed to CIRS. */
-   eraAtoiq(type, ob1, ob2, &astrom, &ri, &di);
-
-/* Transform CIRS to ICRS. */
-   eraAticq(ri, di, &astrom, rc, dc);
-
-/* Return OK/warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-int eraAtoi13(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   eraASTROM astrom;
-
-
-/* Star-independent astrometry parameters for CIRS->observed. */
-   j = eraApio13(utc1, utc2, dut1, elong, phi, hm, xp, yp,
-                 phpa, tc, rh, wl, &astrom);
-
-/* Abort if bad UTC. */
-   if ( j < 0 ) return j;
-
-/* Transform observed to CIRS. */
-   eraAtoiq(type, ob1, ob2, &astrom, ri, di);
-
-/* Return OK/warning status. */
-   return j;
-
-/* Finished. */
-
-}
-
-void eraAtoiq(const char *type,
-              double ob1, double ob2, eraASTROM *astrom,
-              double *ri, double *di)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int c;
-   double c1, c2, sphi, cphi, ce, xaeo, yaeo, zaeo, v[3],
-          xmhdo, ymhdo, zmhdo, az, sz, zdo, refa, refb, tz, dref,
-          zdt, xaet, yaet, zaet, xmhda, ymhda, zmhda,
-          f, xhd, yhd, zhd, xpl, ypl, w, hma;
-
-
-/* Coordinate type. */
-   c = (int) type[0];
-
-/* Coordinates. */
-   c1 = ob1;
-   c2 = ob2;
-
-/* Sin, cos of latitude. */
-   sphi = astrom->sphi;
-   cphi = astrom->cphi;
-
-/* Standardize coordinate type. */
-   if ( c == 'r' || c == 'R' ) {
-      c = 'R';
-   } else if ( c == 'h' || c == 'H' ) {
-      c = 'H';
-   } else {
-      c = 'A';
-   }
-
-/* If Az,ZD, convert to Cartesian (S=0,E=90). */
-   if ( c == 'A' ) {
-      ce = sin(c2);
-      xaeo = - cos(c1) * ce;
-      yaeo = sin(c1) * ce;
-      zaeo = cos(c2);
-
-   } else {
-
-   /* If RA,Dec, convert to HA,Dec. */
-      if ( c == 'R' ) c1 = astrom->eral - c1;
-
-   /* To Cartesian -HA,Dec. */
-      eraS2c ( -c1, c2, v );
-      xmhdo = v[0];
-      ymhdo = v[1];
-      zmhdo = v[2];
-
-   /* To Cartesian Az,El (S=0,E=90). */
-      xaeo = sphi*xmhdo - cphi*zmhdo;
-      yaeo = ymhdo;
-      zaeo = cphi*xmhdo + sphi*zmhdo;
-   }
-
-/* Azimuth (S=0,E=90). */
-   az = ( xaeo != 0.0 || yaeo != 0.0 ) ? atan2(yaeo,xaeo) : 0.0;
-
-/* Sine of observed ZD, and observed ZD. */
-   sz = sqrt ( xaeo*xaeo + yaeo*yaeo );
-   zdo = atan2 ( sz, zaeo );
-
-/*
-** Refraction
-** ----------
-*/
-
-/* Fast algorithm using two constant model. */
-   refa = astrom->refa;
-   refb = astrom->refb;
-   tz = sz / zaeo;
-   dref = ( refa + refb*tz*tz ) * tz;
-   zdt = zdo + dref;
-
-/* To Cartesian Az,ZD. */
-   ce = sin(zdt);
-   xaet = cos(az) * ce;
-   yaet = sin(az) * ce;
-   zaet = cos(zdt);
-
-/* Cartesian Az,ZD to Cartesian -HA,Dec. */
-   xmhda = sphi*xaet + cphi*zaet;
-   ymhda = yaet;
-   zmhda = - cphi*xaet + sphi*zaet;
-
-/* Diurnal aberration. */
-   f = ( 1.0 + astrom->diurab*ymhda );
-   xhd = f * xmhda;
-   yhd = f * ( ymhda - astrom->diurab );
-   zhd = f * zmhda;
-
-/* Polar motion. */
-   xpl = astrom->xpl;
-   ypl = astrom->ypl;
-   w = xpl*xhd - ypl*yhd + zhd;
-   v[0] = xhd - xpl*w;
-   v[1] = yhd + ypl*w;
-   v[2] = w - ( xpl*xpl + ypl*ypl ) * zhd;
-
-/* To spherical -HA,Dec. */
-   eraC2s(v, &hma, di);
-
-/* Right ascension. */
-   *ri = eraAnp(astrom->eral + hma);
-
-/* Finished. */
-
-}
-
-void eraBi00(double *dpsibi, double *depsbi, double *dra)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* The frame bias corrections in longitude and obliquity */
-   const double DPBIAS = -0.041775  * ERFA_DAS2R,
-                DEBIAS = -0.0068192 * ERFA_DAS2R;
-
-/* The ICRS RA of the J2000.0 equinox (Chapront et al., 2002) */
-   const double DRA0 = -0.0146 * ERFA_DAS2R;
-
-
-/* Return the results (which are fixed). */
-   *dpsibi = DPBIAS;
-   *depsbi = DEBIAS;
-   *dra = DRA0;
-
-   return;
-
-}
-
-void eraBp00(double date1, double date2,
-             double rb[3][3], double rp[3][3], double rbp[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* J2000.0 obliquity (Lieske et al. 1977) */
-   const double EPS0 = 84381.448 * ERFA_DAS2R;
-
-   double t, dpsibi, depsbi, dra0, psia77, oma77, chia,
-          dpsipr, depspr, psia, oma, rbw[3][3];
-
-
-/* Interval between fundamental epoch J2000.0 and current date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Frame bias. */
-   eraBi00(&dpsibi, &depsbi, &dra0);
-
-/* Precession angles (Lieske et al. 1977) */
-   psia77 = (5038.7784 + (-1.07259 + (-0.001147) * t) * t) * t * ERFA_DAS2R;
-   oma77  =       EPS0 + ((0.05127 + (-0.007726) * t) * t) * t * ERFA_DAS2R;
-   chia   = (  10.5526 + (-2.38064 + (-0.001125) * t) * t) * t * ERFA_DAS2R;
-
-/* Apply IAU 2000 precession corrections. */
-   eraPr00(date1, date2, &dpsipr, &depspr);
-   psia = psia77 + dpsipr;
-   oma  = oma77  + depspr;
-
-/* Frame bias matrix: GCRS to J2000.0. */
-   eraIr(rbw);
-   eraRz(dra0, rbw);
-   eraRy(dpsibi*sin(EPS0), rbw);
-   eraRx(-depsbi, rbw);
-   eraCr(rbw, rb);
-
-/* Precession matrix: J2000.0 to mean of date. */
-   eraIr(rp);
-   eraRx(EPS0, rp);
-   eraRz(-psia, rp);
-   eraRx(-oma, rp);
-   eraRz(chia, rp);
-
-/* Bias-precession matrix: GCRS to mean of date. */
-   eraRxr(rp, rbw, rbp);
-
-   return;
-
-}
-
-void eraBp06(double date1, double date2,
-             double rb[3][3], double rp[3][3], double rbp[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gamb, phib, psib, epsa, rbpw[3][3], rbt[3][3];
-
-
-/* B matrix. */
-   eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &epsa);
-   eraFw2m(gamb, phib, psib, epsa, rb);
-
-/* PxB matrix (temporary). */
-   eraPmat06(date1, date2, rbpw);
-
-/* P matrix. */
-   eraTr(rb, rbt);
-   eraRxr(rbpw, rbt, rp);
-
-/* PxB matrix. */
-   eraCr(rbpw, rbp);
-
-   return;
-
-}
-
-void eraBpn2xy(double rbpn[3][3], double *x, double *y)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Extract the X,Y coordinates. */
-   *x = rbpn[2][0];
-   *y = rbpn[2][1];
-
-   return;
-
-}
-
-void eraC2i00a(double date1, double date2, double rc2i[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3];
-
-
-/* Obtain the celestial-to-true matrix (IAU 2000A). */
-   eraPnm00a(date1, date2, rbpn);
-
-/* Form the celestial-to-intermediate matrix. */
-   eraC2ibpn(date1, date2, rbpn, rc2i);
-
-   return;
-
-}
-
-void eraC2i00b(double date1, double date2, double rc2i[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3];
-
-
-/* Obtain the celestial-to-true matrix (IAU 2000B). */
-   eraPnm00b(date1, date2, rbpn);
-
-/* Form the celestial-to-intermediate matrix. */
-   eraC2ibpn(date1, date2, rbpn, rc2i);
-
-   return;
-
-}
-
-void eraC2i06a(double date1, double date2, double rc2i[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3], x, y, s;
-
-
-/* Obtain the celestial-to-true matrix (IAU 2006/2000A). */
-   eraPnm06a(date1, date2, rbpn);
-
-/* Extract the X,Y coordinates. */
-   eraBpn2xy(rbpn, &x, &y);
-
-/* Obtain the CIO locator. */
-   s = eraS06(date1, date2, x, y);
-
-/* Form the celestial-to-intermediate matrix. */
-   eraC2ixys(x, y, s, rc2i);
-
-   return;
-
-}
-
-void eraC2ibpn(double date1, double date2, double rbpn[3][3],
-               double rc2i[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y;
-
-
-/* Extract the X,Y coordinates. */
-   eraBpn2xy(rbpn, &x, &y);
-
-/* Form the celestial-to-intermediate matrix (n.b. IAU 2000 specific). */
-   eraC2ixy(date1, date2, x, y, rc2i);
-
-   return;
-
-}
-
-void eraC2ixy(double date1, double date2, double x, double y,
-              double rc2i[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-
-{
-/* Compute s and then the matrix. */
-   eraC2ixys(x, y, eraS00(date1, date2, x, y), rc2i);
-
-   return;
-
-}
-
-void eraC2ixys(double x, double y, double s, double rc2i[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r2, e, d;
-
-
-/* Obtain the spherical angles E and d. */
-   r2 = x*x + y*y;
-   e = (r2 != 0.0) ? atan2(y, x) : 0.0;
-   d = atan(sqrt(r2 / (1.0 - r2)));
-
-/* Form the matrix. */
-   eraIr(rc2i);
-   eraRz(e, rc2i);
-   eraRy(d, rc2i);
-   eraRz(-(e+s), rc2i);
-
-   return;
-
-}
-
-void eraC2s(double p[3], double *theta, double *phi)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y, z, d2;
-
-
-   x  = p[0];
-   y  = p[1];
-   z  = p[2];
-   d2 = x*x + y*y;
-
-   *theta = (d2 == 0.0) ? 0.0 : atan2(y, x);
-   *phi = (z == 0.0) ? 0.0 : atan2(z, sqrt(d2));
-
-   return;
-
-}
-
-void eraC2t00a(double tta, double ttb, double uta, double utb,
-               double xp, double yp, double rc2t[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rc2i[3][3], era, sp, rpom[3][3];
-
-
-/* Form the celestial-to-intermediate matrix for this TT (IAU 2000A). */
-   eraC2i00a(tta, ttb, rc2i );
-
-/* Predict the Earth rotation angle for this UT1. */
-   era = eraEra00(uta, utb);
-
-/* Estimate s'. */
-   sp = eraSp00(tta, ttb);
-
-/* Form the polar motion matrix. */
-   eraPom00(xp, yp, sp, rpom);
-
-/* Combine to form the celestial-to-terrestrial matrix. */
-   eraC2tcio(rc2i, era, rpom, rc2t);
-
-   return;
-
-}
-
-void eraC2t00b(double tta, double ttb, double uta, double utb,
-               double xp, double yp, double rc2t[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rc2i[3][3], era, rpom[3][3];
-
-
-/* Form the celestial-to-intermediate matrix for this TT (IAU 2000B). */
-   eraC2i00b(tta, ttb, rc2i);
-
-/* Predict the Earth rotation angle for this UT1. */
-   era = eraEra00(uta, utb);
-
-/* Form the polar motion matrix (neglecting s'). */
-   eraPom00(xp, yp, 0.0, rpom);
-
-/* Combine to form the celestial-to-terrestrial matrix. */
-   eraC2tcio(rc2i, era, rpom, rc2t);
-
-   return;
-
-}
-
-void eraC2t06a(double tta, double ttb, double uta, double utb,
-               double xp, double yp, double rc2t[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rc2i[3][3], era, sp, rpom[3][3];
-
-
-/* Form the celestial-to-intermediate matrix for this TT. */
-   eraC2i06a(tta, ttb, rc2i);
-
-/* Predict the Earth rotation angle for this UT1. */
-   era = eraEra00(uta, utb);
-
-/* Estimate s'. */
-   sp = eraSp00(tta, ttb);
-
-/* Form the polar motion matrix. */
-   eraPom00(xp, yp, sp, rpom);
-
-/* Combine to form the celestial-to-terrestrial matrix. */
-   eraC2tcio(rc2i, era, rpom, rc2t);
-
-   return;
-
-}
-
-void eraC2tcio(double rc2i[3][3], double era, double rpom[3][3],
-               double rc2t[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r[3][3];
-
-
-/* Construct the matrix. */
-   eraCr(rc2i, r);
-   eraRz(era, r);
-   eraRxr(rpom, r, rc2t);
-
-   return;
-
-}
-
-void eraC2teqx(double rbpn[3][3], double gst, double rpom[3][3],
-               double rc2t[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r[3][3];
-
-
-/* Construct the matrix. */
-   eraCr(rbpn, r);
-   eraRz(gst, r);
-   eraRxr(rpom, r, rc2t);
-
-   return;
-
-}
-
-void eraC2tpe(double tta, double ttb, double uta, double utb,
-              double dpsi, double deps, double xp, double yp,
-              double rc2t[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3],
-          rbpn[3][3], gmst, ee, sp, rpom[3][3];
-
-
-/* Form the celestial-to-true matrix for this TT. */
-   eraPn00(tta, ttb, dpsi, deps, &epsa, rb, rp, rbp, rn, rbpn);
-
-/* Predict the Greenwich Mean Sidereal Time for this UT1 and TT. */
-   gmst = eraGmst00(uta, utb, tta, ttb);
-
-/* Predict the equation of the equinoxes given TT and nutation. */
-   ee = eraEe00(tta, ttb, epsa, dpsi);
-
-/* Estimate s'. */
-   sp = eraSp00(tta, ttb);
-
-/* Form the polar motion matrix. */
-   eraPom00(xp, yp, sp, rpom);
-
-/* Combine to form the celestial-to-terrestrial matrix. */
-   eraC2teqx(rbpn, gmst + ee, rpom, rc2t);
-
-   return;
-
-}
-
-void eraC2txy(double tta, double ttb, double uta, double utb,
-              double x, double y, double xp, double yp,
-              double rc2t[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rc2i[3][3], era, sp, rpom[3][3];
-
-
-/* Form the celestial-to-intermediate matrix for this TT. */
-   eraC2ixy(tta, ttb, x, y, rc2i);
-
-/* Predict the Earth rotation angle for this UT1. */
-   era = eraEra00(uta, utb);
-
-/* Estimate s'. */
-   sp = eraSp00(tta, ttb);
-
-/* Form the polar motion matrix. */
-   eraPom00(xp, yp, sp, rpom);
-
-/* Combine to form the celestial-to-terrestrial matrix. */
-   eraC2tcio(rc2i, era, rpom, rc2t);
-
-   return;
-
-}
-
-int eraCal2jd(int iy, int im, int id, double *djm0, double *djm)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j, ly, my;
-   long iypmy;
-
-/* Earliest year allowed (4800BC) */
-   const int IYMIN = -4799;
-
-/* Month lengths in days */
-   static const int mtab[]
-                     = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-
-/* Preset status. */
-   j = 0;
-
-/* Validate year and month. */
-   if (iy < IYMIN) return -1;
-   if (im < 1 || im > 12) return -2;
-
-/* If February in a leap year, 1, otherwise 0. */
-   ly = ((im == 2) && !(iy%4) && (iy%100 || !(iy%400)));
-
-/* Validate day, taking into account leap years. */
-   if ( (id < 1) || (id > (mtab[im-1] + ly))) j = -3;
-
-/* Return result. */
-   my = (im - 14) / 12;
-   iypmy = (long) (iy + my);
-   *djm0 = ERFA_DJM0;
-   *djm = (double)((1461L * (iypmy + 4800L)) / 4L
-                 + (367L * (long) (im - 2 - 12 * my)) / 12L
-                 - (3L * ((iypmy + 4900L) / 100L)) / 4L
-                 + (long) id - 2432076L);
-
-/* Return status. */
-   return j;
-
-}
-
-void eraCp(double p[3], double c[3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   c[0] = p[0];
-   c[1] = p[1];
-   c[2] = p[2];
-
-   return;
-
-}
-
-void eraCpv(double pv[2][3], double c[2][3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraCp(pv[0], c[0]);
-   eraCp(pv[1], c[1]);
-
-   return;
-
-}
-
-void eraCr(double r[3][3], double c[3][3])
-/*
-**  - - - - - -
-**   e r a C r
-**  - - - - - -
-**
-**  Copy an r-matrix.
-**
-**  Given:
-**     r        double[3][3]    r-matrix to be copied
-**
-**  Returned:
-**   char[]     double[3][3]    copy
-**
-**  Called:
-**     eraCp        copy p-vector
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraCp(r[0], c[0]);
-   eraCp(r[1], c[1]);
-   eraCp(r[2], c[2]);
-
-   return;
-
-}
-
-int eraD2dtf(const char *scale, int ndp, double d1, double d2,
-             int *iy, int *im, int *id, int ihmsf[4])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int leap;
-   char s;
-   int iy1, im1, id1, js, iy2, im2, id2, ihmsf1[4], i;
-   double a1, b1, fd, dat0, dat12, w, dat24, dleap;
-
-
-/* The two-part JD. */
-   a1 = d1;
-   b1 = d2;
-
-/* Provisional calendar date. */
-   js = eraJd2cal(a1, b1, &iy1, &im1, &id1, &fd);
-   if ( js ) return -1;
-
-/* Is this a leap second day? */
-   leap = 0;
-   if ( ! strcmp(scale,"UTC") ) {
-
-   /* TAI-UTC at 0h today. */
-      js = eraDat(iy1, im1, id1, 0.0, &dat0);
-      if ( js < 0 ) return -1;
-
-   /* TAI-UTC at 12h today (to detect drift). */
-      js = eraDat(iy1, im1, id1, 0.5, &dat12);
-      if ( js < 0 ) return -1;
-
-   /* TAI-UTC at 0h tomorrow (to detect jumps). */
-      js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w);
-      if ( js ) return -1;
-      js = eraDat(iy2, im2, id2, 0.0, &dat24);
-      if ( js < 0 ) return -1;
-
-   /* Any sudden change in TAI-UTC (seconds). */
-      dleap = dat24 - (2.0*dat12 - dat0);
-
-   /* If leap second day, scale the fraction of a day into SI. */
-      leap = (dleap != 0.0);
-      if (leap) fd += fd * dleap/ERFA_DAYSEC;
-   }
-
-/* Provisional time of day. */
-   eraD2tf ( ndp, fd, &s, ihmsf1 );
-
-/* Has the (rounded) time gone past 24h? */
-   if ( ihmsf1[0] > 23 ) {
-
-   /* Yes.  We probably need tomorrow's calendar date. */
-      js = eraJd2cal(a1+1.5, b1-fd, &iy2, &im2, &id2, &w);
-      if ( js ) return -1;
-
-   /* Is today a leap second day? */
-      if ( ! leap ) {
-
-      /* No.  Use 0h tomorrow. */
-         iy1 = iy2;
-         im1 = im2;
-         id1 = id2;
-         ihmsf1[0] = 0;
-         ihmsf1[1] = 0;
-         ihmsf1[2] = 0;
-
-      } else {
-
-      /* Yes.  Are we past the leap second itself? */
-         if ( ihmsf1[2] > 0 ) {
-
-         /* Yes.  Use tomorrow but allow for the leap second. */
-            iy1 = iy2;
-            im1 = im2;
-            id1 = id2;
-            ihmsf1[0] = 0;
-            ihmsf1[1] = 0;
-            ihmsf1[2] = 0;
-
-         } else {
-
-         /* No.  Use 23 59 60... today. */
-            ihmsf1[0] = 23;
-            ihmsf1[1] = 59;
-            ihmsf1[2] = 60;
-         }
-
-      /* If rounding to 10s or coarser always go up to new day. */
-         if ( ndp < 0 && ihmsf1[2] == 60 ) {
-            iy1 = iy2;
-            im1 = im2;
-            id1 = id2;
-            ihmsf1[0] = 0;
-            ihmsf1[1] = 0;
-            ihmsf1[2] = 0;
-         }
-      }
-   }
-
-/* Results. */
-   *iy = iy1;
-   *im = im1;
-   *id = id1;
-   for ( i = 0; i < 4; i++ ) {
-      ihmsf[i] = ihmsf1[i];
-   }
-
-/* Status. */
-   return js;
-
-}
-
-void eraD2tf(int ndp, double days, char *sign, int ihmsf[4])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int nrs, n;
-   double rs, rm, rh, a, w, ah, am, as, af;
-
-
-/* Handle sign. */
-   *sign = (char) ( ( days >= 0.0 ) ? '+' : '-' );
-
-/* Interval in seconds. */
-   a = ERFA_DAYSEC * fabs(days);
-
-/* Pre-round if resolution coarser than 1s (then pretend ndp=1). */
-   if (ndp < 0) {
-      nrs = 1;
-      for (n = 1; n <= -ndp; n++) {
-          nrs *= (n == 2 || n == 4) ? 6 : 10;
-      }
-      rs = (double) nrs;
-      w = a / rs;
-      a = rs * ERFA_DNINT(w);
-   }
-
-/* Express the unit of each field in resolution units. */
-   nrs = 1;
-   for (n = 1; n <= ndp; n++) {
-      nrs *= 10;
-   }
-   rs = (double) nrs;
-   rm = rs * 60.0;
-   rh = rm * 60.0;
-
-/* Round the interval and express in resolution units. */
-   a = ERFA_DNINT(rs * a);
-
-/* Break into fields. */
-   ah = a / rh;
-   ah = ERFA_DINT(ah);
-   a -= ah * rh;
-   am = a / rm;
-   am = ERFA_DINT(am);
-   a -= am * rm;
-   as = a / rs;
-   as = ERFA_DINT(as);
-   af = a - as * rs;
-
-/* Return results. */
-   ihmsf[0] = (int) ah;
-   ihmsf[1] = (int) am;
-   ihmsf[2] = (int) as;
-   ihmsf[3] = (int) af;
-
-   return;
-
-}
-
-int eraDat(int iy, int im, int id, double fd, double *deltat )
-/*
-**  - - - - - - -
-**   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:  2012 June 30       :
-**     :                                          :
-**     :__________________________________________:
-**
-**  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)
-**
-**  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 UTC-TAI 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 UTC-TAI 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.
-**
-**  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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Release year for this version of eraDat */
-   enum { IYV = 2013};
-
-/* Reference dates (MJD) and drift rates (s/day), pre leap seconds */
-   static const double drift[][2] = {
-      { 37300.0, 0.0012960 },
-      { 37300.0, 0.0012960 },
-      { 37300.0, 0.0012960 },
-      { 37665.0, 0.0011232 },
-      { 37665.0, 0.0011232 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 38761.0, 0.0012960 },
-      { 39126.0, 0.0025920 },
-      { 39126.0, 0.0025920 }
-   };
-
-/* Number of Delta(AT) expressions before leap seconds were introduced */
-   enum { NERA1 = (int) (sizeof drift / sizeof (double) / 2) };
-
-/* Dates and Delta(AT)s */
-   static const struct {
-      int iyear, month;
-      double delat;
-   } changes[] = {
-      { 1960,  1,  1.4178180 },
-      { 1961,  1,  1.4228180 },
-      { 1961,  8,  1.3728180 },
-      { 1962,  1,  1.8458580 },
-      { 1963, 11,  1.9458580 },
-      { 1964,  1,  3.2401300 },
-      { 1964,  4,  3.3401300 },
-      { 1964,  9,  3.4401300 },
-      { 1965,  1,  3.5401300 },
-      { 1965,  3,  3.6401300 },
-      { 1965,  7,  3.7401300 },
-      { 1965,  9,  3.8401300 },
-      { 1966,  1,  4.3131700 },
-      { 1968,  2,  4.2131700 },
-      { 1972,  1, 10.0       },
-      { 1972,  7, 11.0       },
-      { 1973,  1, 12.0       },
-      { 1974,  1, 13.0       },
-      { 1975,  1, 14.0       },
-      { 1976,  1, 15.0       },
-      { 1977,  1, 16.0       },
-      { 1978,  1, 17.0       },
-      { 1979,  1, 18.0       },
-      { 1980,  1, 19.0       },
-      { 1981,  7, 20.0       },
-      { 1982,  7, 21.0       },
-      { 1983,  7, 22.0       },
-      { 1985,  7, 23.0       },
-      { 1988,  1, 24.0       },
-      { 1990,  1, 25.0       },
-      { 1991,  1, 26.0       },
-      { 1992,  7, 27.0       },
-      { 1993,  7, 28.0       },
-      { 1994,  7, 29.0       },
-      { 1996,  1, 30.0       },
-      { 1997,  7, 31.0       },
-      { 1999,  1, 32.0       },
-      { 2006,  1, 33.0       },
-      { 2009,  1, 34.0       },
-      { 2012,  7, 35.0       }
-   };
-
-/* Number of Delta(AT) changes */
-   const int NDAT = sizeof changes / sizeof changes[0];
-
-/* Miscellaneous local variables */
-   int j, i, m;
-   double da, djm0, djm;
-
-
-/* Initialize the result to zero. */
-   *deltat = da = 0.0;
-
-/* If invalid fraction of a day, set error status and give up. */
-   if (fd < 0.0 || fd > 1.0) return -4;
-
-/* Convert the date into an MJD. */
-   j = eraCal2jd(iy, im, id, &djm0, &djm);
-
-/* If invalid year, month, or day, give up. */
-   if (j < 0) return j;
-
-/* If pre-UTC year, set warning status and give up. */
-   if (iy < changes[0].iyear) return 1;
-
-/* If suspiciously late year, set warning status but proceed. */
-   if (iy > IYV + 5) j = 1;
-
-/* Combine year and month to form a date-ordered integer... */
-   m = 12*iy + im;
-
-/* ...and use it to find the preceding table entry. */
-   for (i = NDAT-1; i >=0; i--) {
-      if (m >= (12 * changes[i].iyear + changes[i].month)) break;
-   }
-
-/* Get the Delta(AT). */
-   da = changes[(i < 0) ? 0 : i].delat;
-
-/* If pre-1972, adjust for drift. */
-   if (i < NERA1) da += (djm + fd - drift[i][0]) * drift[i][1];
-
-/* Return the Delta(AT) value. */
-   *deltat = da;
-
-/* Return the status. */
-   return j;
-
-}
-
-double eraDtdb(double date1, double date2,
-               double ut, double elong, double u, double v)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, tsol, w, elsun, emsun, d, elj, els, wt, w0, w1, w2, w3, w4,
-          wf, wj;
-   int j;
-
-/*
-** =====================
-** Fairhead et al. model
-** =====================
-**
-** 787 sets of three coefficients.
-**
-** Each set is
-**    amplitude (microseconds)
-**      frequency (radians per Julian millennium since J2000.0)
-**      phase (radians)
-**
-** Sets   1-474 are the T**0 terms
-**  "   475-679  "   "  T**1
-**  "   680-764  "   "  T**2
-**  "   765-784  "   "  T**3
-**  "   785-787  "   "  T**4
-*/
-
-   static const double fairhd[787][3] = {
-   /* 1, 10 */
-      { 1656.674564e-6,     6283.075849991,  6.240054195 },
-      {   22.417471e-6,     5753.384884897,  4.296977442 },
-      {   13.839792e-6,    12566.151699983,  6.196904410 },
-      {    4.770086e-6,      529.690965095,  0.444401603 },
-      {    4.676740e-6,     6069.776754553,  4.021195093 },
-      {    2.256707e-6,      213.299095438,  5.543113262 },
-      {    1.694205e-6,      -3.523118349,   5.025132748 },
-      {    1.554905e-6,    77713.771467920,  5.198467090 },
-      {    1.276839e-6,     7860.419392439,  5.988822341 },
-      {    1.193379e-6,     5223.693919802,  3.649823730 },
-   /* 11, 20 */
-      {    1.115322e-6,     3930.209696220,  1.422745069 },
-      {    0.794185e-6,    11506.769769794,  2.322313077 },
-      {    0.447061e-6,       26.298319800,  3.615796498 },
-      {    0.435206e-6,     -398.149003408,  4.349338347 },
-      {    0.600309e-6,     1577.343542448,  2.678271909 },
-      {    0.496817e-6,     6208.294251424,  5.696701824 },
-      {    0.486306e-6,     5884.926846583,  0.520007179 },
-      {    0.432392e-6,       74.781598567,  2.435898309 },
-      {    0.468597e-6,     6244.942814354,  5.866398759 },
-      {    0.375510e-6,     5507.553238667,  4.103476804 },
-   /* 21, 30 */
-      {    0.243085e-6,     -775.522611324,  3.651837925 },
-      {    0.173435e-6,    18849.227549974,  6.153743485 },
-      {    0.230685e-6,     5856.477659115,  4.773852582 },
-      {    0.203747e-6,    12036.460734888,  4.333987818 },
-      {    0.143935e-6,     -796.298006816,  5.957517795 },
-      {    0.159080e-6,    10977.078804699,  1.890075226 },
-      {    0.119979e-6,       38.133035638,  4.551585768 },
-      {    0.118971e-6,     5486.777843175,  1.914547226 },
-      {    0.116120e-6,     1059.381930189,  0.873504123 },
-      {    0.137927e-6,    11790.629088659,  1.135934669 },
-   /* 31, 40 */
-      {    0.098358e-6,     2544.314419883,  0.092793886 },
-      {    0.101868e-6,    -5573.142801634,  5.984503847 },
-      {    0.080164e-6,      206.185548437,  2.095377709 },
-      {    0.079645e-6,     4694.002954708,  2.949233637 },
-      {    0.062617e-6,       20.775395492,  2.654394814 },
-      {    0.075019e-6,     2942.463423292,  4.980931759 },
-      {    0.064397e-6,     5746.271337896,  1.280308748 },
-      {    0.063814e-6,     5760.498431898,  4.167901731 },
-      {    0.048042e-6,     2146.165416475,  1.495846011 },
-      {    0.048373e-6,      155.420399434,  2.251573730 },
-   /* 41, 50 */
-      {    0.058844e-6,      426.598190876,  4.839650148 },
-      {    0.046551e-6,       -0.980321068,  0.921573539 },
-      {    0.054139e-6,    17260.154654690,  3.411091093 },
-      {    0.042411e-6,     6275.962302991,  2.869567043 },
-      {    0.040184e-6,       -7.113547001,  3.565975565 },
-      {    0.036564e-6,     5088.628839767,  3.324679049 },
-      {    0.040759e-6,    12352.852604545,  3.981496998 },
-      {    0.036507e-6,      801.820931124,  6.248866009 },
-      {    0.036955e-6,     3154.687084896,  5.071801441 },
-      {    0.042732e-6,      632.783739313,  5.720622217 },
-   /* 51, 60 */
-      {    0.042560e-6,   161000.685737473,  1.270837679 },
-      {    0.040480e-6,    15720.838784878,  2.546610123 },
-      {    0.028244e-6,    -6286.598968340,  5.069663519 },
-      {    0.033477e-6,     6062.663207553,  4.144987272 },
-      {    0.034867e-6,      522.577418094,  5.210064075 },
-      {    0.032438e-6,     6076.890301554,  0.749317412 },
-      {    0.030215e-6,     7084.896781115,  3.389610345 },
-      {    0.029247e-6,   -71430.695617928,  4.183178762 },
-      {    0.033529e-6,     9437.762934887,  2.404714239 },
-      {    0.032423e-6,     8827.390269875,  5.541473556 },
-   /* 61, 70 */
-      {    0.027567e-6,     6279.552731642,  5.040846034 },
-      {    0.029862e-6,    12139.553509107,  1.770181024 },
-      {    0.022509e-6,    10447.387839604,  1.460726241 },
-      {    0.020937e-6,     8429.241266467,  0.652303414 },
-      {    0.020322e-6,      419.484643875,  3.735430632 },
-      {    0.024816e-6,    -1194.447010225,  1.087136918 },
-      {    0.025196e-6,     1748.016413067,  2.901883301 },
-      {    0.021691e-6,    14143.495242431,  5.952658009 },
-      {    0.017673e-6,     6812.766815086,  3.186129845 },
-      {    0.022567e-6,     6133.512652857,  3.307984806 },
-   /* 71, 80 */
-      {    0.016155e-6,    10213.285546211,  1.331103168 },
-      {    0.014751e-6,     1349.867409659,  4.308933301 },
-      {    0.015949e-6,     -220.412642439,  4.005298270 },
-      {    0.015974e-6,    -2352.866153772,  6.145309371 },
-      {    0.014223e-6,    17789.845619785,  2.104551349 },
-      {    0.017806e-6,       73.297125859,  3.475975097 },
-      {    0.013671e-6,     -536.804512095,  5.971672571 },
-      {    0.011942e-6,     8031.092263058,  2.053414715 },
-      {    0.014318e-6,    16730.463689596,  3.016058075 },
-      {    0.012462e-6,      103.092774219,  1.737438797 },
-   /* 81, 90 */
-      {    0.010962e-6,        3.590428652,  2.196567739 },
-      {    0.015078e-6,    19651.048481098,  3.969480770 },
-      {    0.010396e-6,      951.718406251,  5.717799605 },
-      {    0.011707e-6,    -4705.732307544,  2.654125618 },
-      {    0.010453e-6,     5863.591206116,  1.913704550 },
-      {    0.012420e-6,     4690.479836359,  4.734090399 },
-      {    0.011847e-6,     5643.178563677,  5.489005403 },
-      {    0.008610e-6,     3340.612426700,  3.661698944 },
-      {    0.011622e-6,     5120.601145584,  4.863931876 },
-      {    0.010825e-6,      553.569402842,  0.842715011 },
-   /* 91, 100 */
-      {    0.008666e-6,     -135.065080035,  3.293406547 },
-      {    0.009963e-6,      149.563197135,  4.870690598 },
-      {    0.009858e-6,     6309.374169791,  1.061816410 },
-      {    0.007959e-6,      316.391869657,  2.465042647 },
-      {    0.010099e-6,      283.859318865,  1.942176992 },
-      {    0.007147e-6,     -242.728603974,  3.661486981 },
-      {    0.007505e-6,     5230.807466803,  4.920937029 },
-      {    0.008323e-6,    11769.853693166,  1.229392026 },
-      {    0.007490e-6,    -6256.777530192,  3.658444681 },
-      {    0.009370e-6,   149854.400134205,  0.673880395 },
-   /* 101, 110 */
-      {    0.007117e-6,       38.027672636,  5.294249518 },
-      {    0.007857e-6,    12168.002696575,  0.525733528 },
-      {    0.007019e-6,     6206.809778716,  0.837688810 },
-      {    0.006056e-6,      955.599741609,  4.194535082 },
-      {    0.008107e-6,    13367.972631107,  3.793235253 },
-      {    0.006731e-6,     5650.292110678,  5.639906583 },
-      {    0.007332e-6,       36.648562930,  0.114858677 },
-      {    0.006366e-6,     4164.311989613,  2.262081818 },
-      {    0.006858e-6,     5216.580372801,  0.642063318 },
-      {    0.006919e-6,     6681.224853400,  6.018501522 },
-   /* 111, 120 */
-      {    0.006826e-6,     7632.943259650,  3.458654112 },
-      {    0.005308e-6,    -1592.596013633,  2.500382359 },
-      {    0.005096e-6,    11371.704689758,  2.547107806 },
-      {    0.004841e-6,     5333.900241022,  0.437078094 },
-      {    0.005582e-6,     5966.683980335,  2.246174308 },
-      {    0.006304e-6,    11926.254413669,  2.512929171 },
-      {    0.006603e-6,    23581.258177318,  5.393136889 },
-      {    0.005123e-6,       -1.484472708,  2.999641028 },
-      {    0.004648e-6,     1589.072895284,  1.275847090 },
-      {    0.005119e-6,     6438.496249426,  1.486539246 },
-   /* 121, 130 */
-      {    0.004521e-6,     4292.330832950,  6.140635794 },
-      {    0.005680e-6,    23013.539539587,  4.557814849 },
-      {    0.005488e-6,       -3.455808046,  0.090675389 },
-      {    0.004193e-6,     7234.794256242,  4.869091389 },
-      {    0.003742e-6,     7238.675591600,  4.691976180 },
-      {    0.004148e-6,     -110.206321219,  3.016173439 },
-      {    0.004553e-6,    11499.656222793,  5.554998314 },
-      {    0.004892e-6,     5436.993015240,  1.475415597 },
-      {    0.004044e-6,     4732.030627343,  1.398784824 },
-      {    0.004164e-6,    12491.370101415,  5.650931916 },
-   /* 131, 140 */
-      {    0.004349e-6,    11513.883316794,  2.181745369 },
-      {    0.003919e-6,    12528.018664345,  5.823319737 },
-      {    0.003129e-6,     6836.645252834,  0.003844094 },
-      {    0.004080e-6,    -7058.598461315,  3.690360123 },
-      {    0.003270e-6,       76.266071276,  1.517189902 },
-      {    0.002954e-6,     6283.143160294,  4.447203799 },
-      {    0.002872e-6,       28.449187468,  1.158692983 },
-      {    0.002881e-6,      735.876513532,  0.349250250 },
-      {    0.003279e-6,     5849.364112115,  4.893384368 },
-      {    0.003625e-6,     6209.778724132,  1.473760578 },
-   /* 141, 150 */
-      {    0.003074e-6,      949.175608970,  5.185878737 },
-      {    0.002775e-6,     9917.696874510,  1.030026325 },
-      {    0.002646e-6,    10973.555686350,  3.918259169 },
-      {    0.002575e-6,    25132.303399966,  6.109659023 },
-      {    0.003500e-6,      263.083923373,  1.892100742 },
-      {    0.002740e-6,    18319.536584880,  4.320519510 },
-      {    0.002464e-6,      202.253395174,  4.698203059 },
-      {    0.002409e-6,        2.542797281,  5.325009315 },
-      {    0.003354e-6,   -90955.551694697,  1.942656623 },
-      {    0.002296e-6,     6496.374945429,  5.061810696 },
-   /* 151, 160 */
-      {    0.003002e-6,     6172.869528772,  2.797822767 },
-      {    0.003202e-6,    27511.467873537,  0.531673101 },
-      {    0.002954e-6,    -6283.008539689,  4.533471191 },
-      {    0.002353e-6,      639.897286314,  3.734548088 },
-      {    0.002401e-6,    16200.772724501,  2.605547070 },
-      {    0.003053e-6,   233141.314403759,  3.029030662 },
-      {    0.003024e-6,    83286.914269554,  2.355556099 },
-      {    0.002863e-6,    17298.182327326,  5.240963796 },
-      {    0.002103e-6,    -7079.373856808,  5.756641637 },
-      {    0.002303e-6,    83996.847317911,  2.013686814 },
-   /* 161, 170 */
-      {    0.002303e-6,    18073.704938650,  1.089100410 },
-      {    0.002381e-6,       63.735898303,  0.759188178 },
-      {    0.002493e-6,     6386.168624210,  0.645026535 },
-      {    0.002366e-6,        3.932153263,  6.215885448 },
-      {    0.002169e-6,    11015.106477335,  4.845297676 },
-      {    0.002397e-6,     6243.458341645,  3.809290043 },
-      {    0.002183e-6,     1162.474704408,  6.179611691 },
-      {    0.002353e-6,     6246.427287062,  4.781719760 },
-      {    0.002199e-6,     -245.831646229,  5.956152284 },
-      {    0.001729e-6,     3894.181829542,  1.264976635 },
-   /* 171, 180 */
-      {    0.001896e-6,    -3128.388765096,  4.914231596 },
-      {    0.002085e-6,       35.164090221,  1.405158503 },
-      {    0.002024e-6,    14712.317116458,  2.752035928 },
-      {    0.001737e-6,     6290.189396992,  5.280820144 },
-      {    0.002229e-6,      491.557929457,  1.571007057 },
-      {    0.001602e-6,    14314.168113050,  4.203664806 },
-      {    0.002186e-6,      454.909366527,  1.402101526 },
-      {    0.001897e-6,    22483.848574493,  4.167932508 },
-      {    0.001825e-6,    -3738.761430108,  0.545828785 },
-      {    0.001894e-6,     1052.268383188,  5.817167450 },
-   /* 181, 190 */
-      {    0.001421e-6,       20.355319399,  2.419886601 },
-      {    0.001408e-6,    10984.192351700,  2.732084787 },
-      {    0.001847e-6,    10873.986030480,  2.903477885 },
-      {    0.001391e-6,    -8635.942003763,  0.593891500 },
-      {    0.001388e-6,       -7.046236698,  1.166145902 },
-      {    0.001810e-6,   -88860.057071188,  0.487355242 },
-      {    0.001288e-6,    -1990.745017041,  3.913022880 },
-      {    0.001297e-6,    23543.230504682,  3.063805171 },
-      {    0.001335e-6,     -266.607041722,  3.995764039 },
-      {    0.001376e-6,    10969.965257698,  5.152914309 },
-   /* 191, 200 */
-      {    0.001745e-6,   244287.600007027,  3.626395673 },
-      {    0.001649e-6,    31441.677569757,  1.952049260 },
-      {    0.001416e-6,     9225.539273283,  4.996408389 },
-      {    0.001238e-6,     4804.209275927,  5.503379738 },
-      {    0.001472e-6,     4590.910180489,  4.164913291 },
-      {    0.001169e-6,     6040.347246017,  5.841719038 },
-      {    0.001039e-6,     5540.085789459,  2.769753519 },
-      {    0.001004e-6,     -170.672870619,  0.755008103 },
-      {    0.001284e-6,    10575.406682942,  5.306538209 },
-      {    0.001278e-6,       71.812653151,  4.713486491 },
-   /* 201, 210 */
-      {    0.001321e-6,    18209.330263660,  2.624866359 },
-      {    0.001297e-6,    21228.392023546,  0.382603541 },
-      {    0.000954e-6,     6282.095528923,  0.882213514 },
-      {    0.001145e-6,     6058.731054289,  1.169483931 },
-      {    0.000979e-6,     5547.199336460,  5.448375984 },
-      {    0.000987e-6,    -6262.300454499,  2.656486959 },
-      {    0.001070e-6,  -154717.609887482,  1.827624012 },
-      {    0.000991e-6,     4701.116501708,  4.387001801 },
-      {    0.001155e-6,      -14.227094002,  3.042700750 },
-      {    0.001176e-6,      277.034993741,  3.335519004 },
-   /* 211, 220 */
-      {    0.000890e-6,    13916.019109642,  5.601498297 },
-      {    0.000884e-6,    -1551.045222648,  1.088831705 },
-      {    0.000876e-6,     5017.508371365,  3.969902609 },
-      {    0.000806e-6,    15110.466119866,  5.142876744 },
-      {    0.000773e-6,    -4136.910433516,  0.022067765 },
-      {    0.001077e-6,      175.166059800,  1.844913056 },
-      {    0.000954e-6,    -6284.056171060,  0.968480906 },
-      {    0.000737e-6,     5326.786694021,  4.923831588 },
-      {    0.000845e-6,     -433.711737877,  4.749245231 },
-      {    0.000819e-6,     8662.240323563,  5.991247817 },
-   /* 221, 230 */
-      {    0.000852e-6,      199.072001436,  2.189604979 },
-      {    0.000723e-6,    17256.631536341,  6.068719637 },
-      {    0.000940e-6,     6037.244203762,  6.197428148 },
-      {    0.000885e-6,    11712.955318231,  3.280414875 },
-      {    0.000706e-6,    12559.038152982,  2.824848947 },
-      {    0.000732e-6,     2379.164473572,  2.501813417 },
-      {    0.000764e-6,    -6127.655450557,  2.236346329 },
-      {    0.000908e-6,      131.541961686,  2.521257490 },
-      {    0.000907e-6,    35371.887265976,  3.370195967 },
-      {    0.000673e-6,     1066.495477190,  3.876512374 },
-   /* 231, 240 */
-      {    0.000814e-6,    17654.780539750,  4.627122566 },
-      {    0.000630e-6,       36.027866677,  0.156368499 },
-      {    0.000798e-6,      515.463871093,  5.151962502 },
-      {    0.000798e-6,      148.078724426,  5.909225055 },
-      {    0.000806e-6,      309.278322656,  6.054064447 },
-      {    0.000607e-6,      -39.617508346,  2.839021623 },
-      {    0.000601e-6,      412.371096874,  3.984225404 },
-      {    0.000646e-6,    11403.676995575,  3.852959484 },
-      {    0.000704e-6,    13521.751441591,  2.300991267 },
-      {    0.000603e-6,   -65147.619767937,  4.140083146 },
-   /* 241, 250 */
-      {    0.000609e-6,    10177.257679534,  0.437122327 },
-      {    0.000631e-6,     5767.611978898,  4.026532329 },
-      {    0.000576e-6,    11087.285125918,  4.760293101 },
-      {    0.000674e-6,    14945.316173554,  6.270510511 },
-      {    0.000726e-6,     5429.879468239,  6.039606892 },
-      {    0.000710e-6,    28766.924424484,  5.672617711 },
-      {    0.000647e-6,    11856.218651625,  3.397132627 },
-      {    0.000678e-6,    -5481.254918868,  6.249666675 },
-      {    0.000618e-6,    22003.914634870,  2.466427018 },
-      {    0.000738e-6,     6134.997125565,  2.242668890 },
-   /* 251, 260 */
-      {    0.000660e-6,      625.670192312,  5.864091907 },
-      {    0.000694e-6,     3496.032826134,  2.668309141 },
-      {    0.000531e-6,     6489.261398429,  1.681888780 },
-      {    0.000611e-6,  -143571.324284214,  2.424978312 },
-      {    0.000575e-6,    12043.574281889,  4.216492400 },
-      {    0.000553e-6,    12416.588502848,  4.772158039 },
-      {    0.000689e-6,     4686.889407707,  6.224271088 },
-      {    0.000495e-6,     7342.457780181,  3.817285811 },
-      {    0.000567e-6,     3634.621024518,  1.649264690 },
-      {    0.000515e-6,    18635.928454536,  3.945345892 },
-   /* 261, 270 */
-      {    0.000486e-6,     -323.505416657,  4.061673868 },
-      {    0.000662e-6,    25158.601719765,  1.794058369 },
-      {    0.000509e-6,      846.082834751,  3.053874588 },
-      {    0.000472e-6,   -12569.674818332,  5.112133338 },
-      {    0.000461e-6,     6179.983075773,  0.513669325 },
-      {    0.000641e-6,    83467.156352816,  3.210727723 },
-      {    0.000520e-6,    10344.295065386,  2.445597761 },
-      {    0.000493e-6,    18422.629359098,  1.676939306 },
-      {    0.000478e-6,     1265.567478626,  5.487314569 },
-      {    0.000472e-6,      -18.159247265,  1.999707589 },
-   /* 271, 280 */
-      {    0.000559e-6,    11190.377900137,  5.783236356 },
-      {    0.000494e-6,     9623.688276691,  3.022645053 },
-      {    0.000463e-6,     5739.157790895,  1.411223013 },
-      {    0.000432e-6,    16858.482532933,  1.179256434 },
-      {    0.000574e-6,    72140.628666286,  1.758191830 },
-      {    0.000484e-6,    17267.268201691,  3.290589143 },
-      {    0.000550e-6,     4907.302050146,  0.864024298 },
-      {    0.000399e-6,       14.977853527,  2.094441910 },
-      {    0.000491e-6,      224.344795702,  0.878372791 },
-      {    0.000432e-6,    20426.571092422,  6.003829241 },
-   /* 281, 290 */
-      {    0.000481e-6,     5749.452731634,  4.309591964 },
-      {    0.000480e-6,     5757.317038160,  1.142348571 },
-      {    0.000485e-6,     6702.560493867,  0.210580917 },
-      {    0.000426e-6,     6055.549660552,  4.274476529 },
-      {    0.000480e-6,     5959.570433334,  5.031351030 },
-      {    0.000466e-6,    12562.628581634,  4.959581597 },
-      {    0.000520e-6,    39302.096962196,  4.788002889 },
-      {    0.000458e-6,    12132.439962106,  1.880103788 },
-      {    0.000470e-6,    12029.347187887,  1.405611197 },
-      {    0.000416e-6,    -7477.522860216,  1.082356330 },
-   /* 291, 300 */
-      {    0.000449e-6,    11609.862544012,  4.179989585 },
-      {    0.000465e-6,    17253.041107690,  0.353496295 },
-      {    0.000362e-6,    -4535.059436924,  1.583849576 },
-      {    0.000383e-6,    21954.157609398,  3.747376371 },
-      {    0.000389e-6,       17.252277143,  1.395753179 },
-      {    0.000331e-6,    18052.929543158,  0.566790582 },
-      {    0.000430e-6,    13517.870106233,  0.685827538 },
-      {    0.000368e-6,    -5756.908003246,  0.731374317 },
-      {    0.000330e-6,    10557.594160824,  3.710043680 },
-      {    0.000332e-6,    20199.094959633,  1.652901407 },
-   /* 301, 310 */
-      {    0.000384e-6,    11933.367960670,  5.827781531 },
-      {    0.000387e-6,    10454.501386605,  2.541182564 },
-      {    0.000325e-6,    15671.081759407,  2.178850542 },
-      {    0.000318e-6,      138.517496871,  2.253253037 },
-      {    0.000305e-6,     9388.005909415,  0.578340206 },
-      {    0.000352e-6,     5749.861766548,  3.000297967 },
-      {    0.000311e-6,     6915.859589305,  1.693574249 },
-      {    0.000297e-6,    24072.921469776,  1.997249392 },
-      {    0.000363e-6,     -640.877607382,  5.071820966 },
-      {    0.000323e-6,    12592.450019783,  1.072262823 },
-   /* 311, 320 */
-      {    0.000341e-6,    12146.667056108,  4.700657997 },
-      {    0.000290e-6,     9779.108676125,  1.812320441 },
-      {    0.000342e-6,     6132.028180148,  4.322238614 },
-      {    0.000329e-6,     6268.848755990,  3.033827743 },
-      {    0.000374e-6,    17996.031168222,  3.388716544 },
-      {    0.000285e-6,     -533.214083444,  4.687313233 },
-      {    0.000338e-6,     6065.844601290,  0.877776108 },
-      {    0.000276e-6,       24.298513841,  0.770299429 },
-      {    0.000336e-6,    -2388.894020449,  5.353796034 },
-      {    0.000290e-6,     3097.883822726,  4.075291557 },
-   /* 321, 330 */
-      {    0.000318e-6,      709.933048357,  5.941207518 },
-      {    0.000271e-6,    13095.842665077,  3.208912203 },
-      {    0.000331e-6,     6073.708907816,  4.007881169 },
-      {    0.000292e-6,      742.990060533,  2.714333592 },
-      {    0.000362e-6,    29088.811415985,  3.215977013 },
-      {    0.000280e-6,    12359.966151546,  0.710872502 },
-      {    0.000267e-6,    10440.274292604,  4.730108488 },
-      {    0.000262e-6,      838.969287750,  1.327720272 },
-      {    0.000250e-6,    16496.361396202,  0.898769761 },
-      {    0.000325e-6,    20597.243963041,  0.180044365 },
-   /* 331, 340 */
-      {    0.000268e-6,     6148.010769956,  5.152666276 },
-      {    0.000284e-6,     5636.065016677,  5.655385808 },
-      {    0.000301e-6,     6080.822454817,  2.135396205 },
-      {    0.000294e-6,     -377.373607916,  3.708784168 },
-      {    0.000236e-6,     2118.763860378,  1.733578756 },
-      {    0.000234e-6,     5867.523359379,  5.575209112 },
-      {    0.000268e-6,  -226858.238553767,  0.069432392 },
-      {    0.000265e-6,   167283.761587465,  4.369302826 },
-      {    0.000280e-6,    28237.233459389,  5.304829118 },
-      {    0.000292e-6,    12345.739057544,  4.096094132 },
-   /* 341, 350 */
-      {    0.000223e-6,    19800.945956225,  3.069327406 },
-      {    0.000301e-6,    43232.306658416,  6.205311188 },
-      {    0.000264e-6,    18875.525869774,  1.417263408 },
-      {    0.000304e-6,    -1823.175188677,  3.409035232 },
-      {    0.000301e-6,      109.945688789,  0.510922054 },
-      {    0.000260e-6,      813.550283960,  2.389438934 },
-      {    0.000299e-6,   316428.228673312,  5.384595078 },
-      {    0.000211e-6,     5756.566278634,  3.789392838 },
-      {    0.000209e-6,     5750.203491159,  1.661943545 },
-      {    0.000240e-6,    12489.885628707,  5.684549045 },
-   /* 351, 360 */
-      {    0.000216e-6,     6303.851245484,  3.862942261 },
-      {    0.000203e-6,     1581.959348283,  5.549853589 },
-      {    0.000200e-6,     5642.198242609,  1.016115785 },
-      {    0.000197e-6,      -70.849445304,  4.690702525 },
-      {    0.000227e-6,     6287.008003254,  2.911891613 },
-      {    0.000197e-6,      533.623118358,  1.048982898 },
-      {    0.000205e-6,    -6279.485421340,  1.829362730 },
-      {    0.000209e-6,   -10988.808157535,  2.636140084 },
-      {    0.000208e-6,     -227.526189440,  4.127883842 },
-      {    0.000191e-6,      415.552490612,  4.401165650 },
-   /* 361, 370 */
-      {    0.000190e-6,    29296.615389579,  4.175658539 },
-      {    0.000264e-6,    66567.485864652,  4.601102551 },
-      {    0.000256e-6,    -3646.350377354,  0.506364778 },
-      {    0.000188e-6,    13119.721102825,  2.032195842 },
-      {    0.000185e-6,     -209.366942175,  4.694756586 },
-      {    0.000198e-6,    25934.124331089,  3.832703118 },
-      {    0.000195e-6,     4061.219215394,  3.308463427 },
-      {    0.000234e-6,     5113.487598583,  1.716090661 },
-      {    0.000188e-6,     1478.866574064,  5.686865780 },
-      {    0.000222e-6,    11823.161639450,  1.942386641 },
-   /* 371, 380 */
-      {    0.000181e-6,    10770.893256262,  1.999482059 },
-      {    0.000171e-6,     6546.159773364,  1.182807992 },
-      {    0.000206e-6,       70.328180442,  5.934076062 },
-      {    0.000169e-6,    20995.392966449,  2.169080622 },
-      {    0.000191e-6,    10660.686935042,  5.405515999 },
-      {    0.000228e-6,    33019.021112205,  4.656985514 },
-      {    0.000184e-6,    -4933.208440333,  3.327476868 },
-      {    0.000220e-6,     -135.625325010,  1.765430262 },
-      {    0.000166e-6,    23141.558382925,  3.454132746 },
-      {    0.000191e-6,     6144.558353121,  5.020393445 },
-   /* 381, 390 */
-      {    0.000180e-6,     6084.003848555,  0.602182191 },
-      {    0.000163e-6,    17782.732072784,  4.960593133 },
-      {    0.000225e-6,    16460.333529525,  2.596451817 },
-      {    0.000222e-6,     5905.702242076,  3.731990323 },
-      {    0.000204e-6,      227.476132789,  5.636192701 },
-      {    0.000159e-6,    16737.577236597,  3.600691544 },
-      {    0.000200e-6,     6805.653268085,  0.868220961 },
-      {    0.000187e-6,    11919.140866668,  2.629456641 },
-      {    0.000161e-6,      127.471796607,  2.862574720 },
-      {    0.000205e-6,     6286.666278643,  1.742882331 },
-   /* 391, 400 */
-      {    0.000189e-6,      153.778810485,  4.812372643 },
-      {    0.000168e-6,    16723.350142595,  0.027860588 },
-      {    0.000149e-6,    11720.068865232,  0.659721876 },
-      {    0.000189e-6,     5237.921013804,  5.245313000 },
-      {    0.000143e-6,     6709.674040867,  4.317625647 },
-      {    0.000146e-6,     4487.817406270,  4.815297007 },
-      {    0.000144e-6,     -664.756045130,  5.381366880 },
-      {    0.000175e-6,     5127.714692584,  4.728443327 },
-      {    0.000162e-6,     6254.626662524,  1.435132069 },
-      {    0.000187e-6,    47162.516354635,  1.354371923 },
-   /* 401, 410 */
-      {    0.000146e-6,    11080.171578918,  3.369695406 },
-      {    0.000180e-6,     -348.924420448,  2.490902145 },
-      {    0.000148e-6,      151.047669843,  3.799109588 },
-      {    0.000157e-6,     6197.248551160,  1.284375887 },
-      {    0.000167e-6,      146.594251718,  0.759969109 },
-      {    0.000133e-6,    -5331.357443741,  5.409701889 },
-      {    0.000154e-6,       95.979227218,  3.366890614 },
-      {    0.000148e-6,    -6418.140930027,  3.384104996 },
-      {    0.000128e-6,    -6525.804453965,  3.803419985 },
-      {    0.000130e-6,    11293.470674356,  0.939039445 },
-   /* 411, 420 */
-      {    0.000152e-6,    -5729.506447149,  0.734117523 },
-      {    0.000138e-6,      210.117701700,  2.564216078 },
-      {    0.000123e-6,     6066.595360816,  4.517099537 },
-      {    0.000140e-6,    18451.078546566,  0.642049130 },
-      {    0.000126e-6,    11300.584221356,  3.485280663 },
-      {    0.000119e-6,    10027.903195729,  3.217431161 },
-      {    0.000151e-6,     4274.518310832,  4.404359108 },
-      {    0.000117e-6,     6072.958148291,  0.366324650 },
-      {    0.000165e-6,    -7668.637425143,  4.298212528 },
-      {    0.000117e-6,    -6245.048177356,  5.379518958 },
-   /* 421, 430 */
-      {    0.000130e-6,    -5888.449964932,  4.527681115 },
-      {    0.000121e-6,     -543.918059096,  6.109429504 },
-      {    0.000162e-6,     9683.594581116,  5.720092446 },
-      {    0.000141e-6,     6219.339951688,  0.679068671 },
-      {    0.000118e-6,    22743.409379516,  4.881123092 },
-      {    0.000129e-6,     1692.165669502,  0.351407289 },
-      {    0.000126e-6,     5657.405657679,  5.146592349 },
-      {    0.000114e-6,      728.762966531,  0.520791814 },
-      {    0.000120e-6,       52.596639600,  0.948516300 },
-      {    0.000115e-6,       65.220371012,  3.504914846 },
-   /* 431, 440 */
-      {    0.000126e-6,     5881.403728234,  5.577502482 },
-      {    0.000158e-6,   163096.180360983,  2.957128968 },
-      {    0.000134e-6,    12341.806904281,  2.598576764 },
-      {    0.000151e-6,    16627.370915377,  3.985702050 },
-      {    0.000109e-6,     1368.660252845,  0.014730471 },
-      {    0.000131e-6,     6211.263196841,  0.085077024 },
-      {    0.000146e-6,     5792.741760812,  0.708426604 },
-      {    0.000146e-6,      -77.750543984,  3.121576600 },
-      {    0.000107e-6,     5341.013788022,  0.288231904 },
-      {    0.000138e-6,     6281.591377283,  2.797450317 },
-   /* 441, 450 */
-      {    0.000113e-6,    -6277.552925684,  2.788904128 },
-      {    0.000115e-6,     -525.758811831,  5.895222200 },
-      {    0.000138e-6,     6016.468808270,  6.096188999 },
-      {    0.000139e-6,    23539.707386333,  2.028195445 },
-      {    0.000146e-6,    -4176.041342449,  4.660008502 },
-      {    0.000107e-6,    16062.184526117,  4.066520001 },
-      {    0.000142e-6,    83783.548222473,  2.936315115 },
-      {    0.000128e-6,     9380.959672717,  3.223844306 },
-      {    0.000135e-6,     6205.325306007,  1.638054048 },
-      {    0.000101e-6,     2699.734819318,  5.481603249 },
-   /* 451, 460 */
-      {    0.000104e-6,     -568.821874027,  2.205734493 },
-      {    0.000103e-6,     6321.103522627,  2.440421099 },
-      {    0.000119e-6,     6321.208885629,  2.547496264 },
-      {    0.000138e-6,     1975.492545856,  2.314608466 },
-      {    0.000121e-6,      137.033024162,  4.539108237 },
-      {    0.000123e-6,    19402.796952817,  4.538074405 },
-      {    0.000119e-6,    22805.735565994,  2.869040566 },
-      {    0.000133e-6,    64471.991241142,  6.056405489 },
-      {    0.000129e-6,      -85.827298831,  2.540635083 },
-      {    0.000131e-6,    13613.804277336,  4.005732868 },
-   /* 461, 470 */
-      {    0.000104e-6,     9814.604100291,  1.959967212 },
-      {    0.000112e-6,    16097.679950283,  3.589026260 },
-      {    0.000123e-6,     2107.034507542,  1.728627253 },
-      {    0.000121e-6,    36949.230808424,  6.072332087 },
-      {    0.000108e-6,   -12539.853380183,  3.716133846 },
-      {    0.000113e-6,    -7875.671863624,  2.725771122 },
-      {    0.000109e-6,     4171.425536614,  4.033338079 },
-      {    0.000101e-6,     6247.911759770,  3.441347021 },
-      {    0.000113e-6,     7330.728427345,  0.656372122 },
-      {    0.000113e-6,    51092.726050855,  2.791483066 },
-   /* 471, 480 */
-      {    0.000106e-6,     5621.842923210,  1.815323326 },
-      {    0.000101e-6,      111.430161497,  5.711033677 },
-      {    0.000103e-6,      909.818733055,  2.812745443 },
-      {    0.000101e-6,     1790.642637886,  1.965746028 },
-
-   /* T */
-      {  102.156724e-6,     6283.075849991,  4.249032005 },
-      {    1.706807e-6,    12566.151699983,  4.205904248 },
-      {    0.269668e-6,      213.299095438,  3.400290479 },
-      {    0.265919e-6,      529.690965095,  5.836047367 },
-      {    0.210568e-6,       -3.523118349,  6.262738348 },
-      {    0.077996e-6,     5223.693919802,  4.670344204 },
-   /* 481, 490 */
-      {    0.054764e-6,     1577.343542448,  4.534800170 },
-      {    0.059146e-6,       26.298319800,  1.083044735 },
-      {    0.034420e-6,     -398.149003408,  5.980077351 },
-      {    0.032088e-6,    18849.227549974,  4.162913471 },
-      {    0.033595e-6,     5507.553238667,  5.980162321 },
-      {    0.029198e-6,     5856.477659115,  0.623811863 },
-      {    0.027764e-6,      155.420399434,  3.745318113 },
-      {    0.025190e-6,     5746.271337896,  2.980330535 },
-      {    0.022997e-6,     -796.298006816,  1.174411803 },
-      {    0.024976e-6,     5760.498431898,  2.467913690 },
-   /* 491, 500 */
-      {    0.021774e-6,      206.185548437,  3.854787540 },
-      {    0.017925e-6,     -775.522611324,  1.092065955 },
-      {    0.013794e-6,      426.598190876,  2.699831988 },
-      {    0.013276e-6,     6062.663207553,  5.845801920 },
-      {    0.011774e-6,    12036.460734888,  2.292832062 },
-      {    0.012869e-6,     6076.890301554,  5.333425680 },
-      {    0.012152e-6,     1059.381930189,  6.222874454 },
-      {    0.011081e-6,       -7.113547001,  5.154724984 },
-      {    0.010143e-6,     4694.002954708,  4.044013795 },
-      {    0.009357e-6,     5486.777843175,  3.416081409 },
-   /* 501, 510 */
-      {    0.010084e-6,      522.577418094,  0.749320262 },
-      {    0.008587e-6,    10977.078804699,  2.777152598 },
-      {    0.008628e-6,     6275.962302991,  4.562060226 },
-      {    0.008158e-6,     -220.412642439,  5.806891533 },
-      {    0.007746e-6,     2544.314419883,  1.603197066 },
-      {    0.007670e-6,     2146.165416475,  3.000200440 },
-      {    0.007098e-6,       74.781598567,  0.443725817 },
-      {    0.006180e-6,     -536.804512095,  1.302642751 },
-      {    0.005818e-6,     5088.628839767,  4.827723531 },
-      {    0.004945e-6,    -6286.598968340,  0.268305170 },
-   /* 511, 520 */
-      {    0.004774e-6,     1349.867409659,  5.808636673 },
-      {    0.004687e-6,     -242.728603974,  5.154890570 },
-      {    0.006089e-6,     1748.016413067,  4.403765209 },
-      {    0.005975e-6,    -1194.447010225,  2.583472591 },
-      {    0.004229e-6,      951.718406251,  0.931172179 },
-      {    0.005264e-6,      553.569402842,  2.336107252 },
-      {    0.003049e-6,     5643.178563677,  1.362634430 },
-      {    0.002974e-6,     6812.766815086,  1.583012668 },
-      {    0.003403e-6,    -2352.866153772,  2.552189886 },
-      {    0.003030e-6,      419.484643875,  5.286473844 },
-   /* 521, 530 */
-      {    0.003210e-6,       -7.046236698,  1.863796539 },
-      {    0.003058e-6,     9437.762934887,  4.226420633 },
-      {    0.002589e-6,    12352.852604545,  1.991935820 },
-      {    0.002927e-6,     5216.580372801,  2.319951253 },
-      {    0.002425e-6,     5230.807466803,  3.084752833 },
-      {    0.002656e-6,     3154.687084896,  2.487447866 },
-      {    0.002445e-6,    10447.387839604,  2.347139160 },
-      {    0.002990e-6,     4690.479836359,  6.235872050 },
-      {    0.002890e-6,     5863.591206116,  0.095197563 },
-      {    0.002498e-6,     6438.496249426,  2.994779800 },
-   /* 531, 540 */
-      {    0.001889e-6,     8031.092263058,  3.569003717 },
-      {    0.002567e-6,      801.820931124,  3.425611498 },
-      {    0.001803e-6,   -71430.695617928,  2.192295512 },
-      {    0.001782e-6,        3.932153263,  5.180433689 },
-      {    0.001694e-6,    -4705.732307544,  4.641779174 },
-      {    0.001704e-6,    -1592.596013633,  3.997097652 },
-      {    0.001735e-6,     5849.364112115,  0.417558428 },
-      {    0.001643e-6,     8429.241266467,  2.180619584 },
-      {    0.001680e-6,       38.133035638,  4.164529426 },
-      {    0.002045e-6,     7084.896781115,  0.526323854 },
-   /* 541, 550 */
-      {    0.001458e-6,     4292.330832950,  1.356098141 },
-      {    0.001437e-6,       20.355319399,  3.895439360 },
-      {    0.001738e-6,     6279.552731642,  0.087484036 },
-      {    0.001367e-6,    14143.495242431,  3.987576591 },
-      {    0.001344e-6,     7234.794256242,  0.090454338 },
-      {    0.001438e-6,    11499.656222793,  0.974387904 },
-      {    0.001257e-6,     6836.645252834,  1.509069366 },
-      {    0.001358e-6,    11513.883316794,  0.495572260 },
-      {    0.001628e-6,     7632.943259650,  4.968445721 },
-      {    0.001169e-6,      103.092774219,  2.838496795 },
-   /* 551, 560 */
-      {    0.001162e-6,     4164.311989613,  3.408387778 },
-      {    0.001092e-6,     6069.776754553,  3.617942651 },
-      {    0.001008e-6,    17789.845619785,  0.286350174 },
-      {    0.001008e-6,      639.897286314,  1.610762073 },
-      {    0.000918e-6,    10213.285546211,  5.532798067 },
-      {    0.001011e-6,    -6256.777530192,  0.661826484 },
-      {    0.000753e-6,    16730.463689596,  3.905030235 },
-      {    0.000737e-6,    11926.254413669,  4.641956361 },
-      {    0.000694e-6,     3340.612426700,  2.111120332 },
-      {    0.000701e-6,     3894.181829542,  2.760823491 },
-   /* 561, 570 */
-      {    0.000689e-6,     -135.065080035,  4.768800780 },
-      {    0.000700e-6,    13367.972631107,  5.760439898 },
-      {    0.000664e-6,     6040.347246017,  1.051215840 },
-      {    0.000654e-6,     5650.292110678,  4.911332503 },
-      {    0.000788e-6,     6681.224853400,  4.699648011 },
-      {    0.000628e-6,     5333.900241022,  5.024608847 },
-      {    0.000755e-6,     -110.206321219,  4.370971253 },
-      {    0.000628e-6,     6290.189396992,  3.660478857 },
-      {    0.000635e-6,    25132.303399966,  4.121051532 },
-      {    0.000534e-6,     5966.683980335,  1.173284524 },
-   /* 571, 580 */
-      {    0.000543e-6,     -433.711737877,  0.345585464 },
-      {    0.000517e-6,    -1990.745017041,  5.414571768 },
-      {    0.000504e-6,     5767.611978898,  2.328281115 },
-      {    0.000485e-6,     5753.384884897,  1.685874771 },
-      {    0.000463e-6,     7860.419392439,  5.297703006 },
-      {    0.000604e-6,      515.463871093,  0.591998446 },
-      {    0.000443e-6,    12168.002696575,  4.830881244 },
-      {    0.000570e-6,      199.072001436,  3.899190272 },
-      {    0.000465e-6,    10969.965257698,  0.476681802 },
-      {    0.000424e-6,    -7079.373856808,  1.112242763 },
-   /* 581, 590 */
-      {    0.000427e-6,      735.876513532,  1.994214480 },
-      {    0.000478e-6,    -6127.655450557,  3.778025483 },
-      {    0.000414e-6,    10973.555686350,  5.441088327 },
-      {    0.000512e-6,     1589.072895284,  0.107123853 },
-      {    0.000378e-6,    10984.192351700,  0.915087231 },
-      {    0.000402e-6,    11371.704689758,  4.107281715 },
-      {    0.000453e-6,     9917.696874510,  1.917490952 },
-      {    0.000395e-6,      149.563197135,  2.763124165 },
-      {    0.000371e-6,     5739.157790895,  3.112111866 },
-      {    0.000350e-6,    11790.629088659,  0.440639857 },
-   /* 591, 600 */
-      {    0.000356e-6,     6133.512652857,  5.444568842 },
-      {    0.000344e-6,      412.371096874,  5.676832684 },
-      {    0.000383e-6,      955.599741609,  5.559734846 },
-      {    0.000333e-6,     6496.374945429,  0.261537984 },
-      {    0.000340e-6,     6055.549660552,  5.975534987 },
-      {    0.000334e-6,     1066.495477190,  2.335063907 },
-      {    0.000399e-6,    11506.769769794,  5.321230910 },
-      {    0.000314e-6,    18319.536584880,  2.313312404 },
-      {    0.000424e-6,     1052.268383188,  1.211961766 },
-      {    0.000307e-6,       63.735898303,  3.169551388 },
-   /* 601, 610 */
-      {    0.000329e-6,       29.821438149,  6.106912080 },
-      {    0.000357e-6,     6309.374169791,  4.223760346 },
-      {    0.000312e-6,    -3738.761430108,  2.180556645 },
-      {    0.000301e-6,      309.278322656,  1.499984572 },
-      {    0.000268e-6,    12043.574281889,  2.447520648 },
-      {    0.000257e-6,    12491.370101415,  3.662331761 },
-      {    0.000290e-6,      625.670192312,  1.272834584 },
-      {    0.000256e-6,     5429.879468239,  1.913426912 },
-      {    0.000339e-6,     3496.032826134,  4.165930011 },
-      {    0.000283e-6,     3930.209696220,  4.325565754 },
-   /* 611, 620 */
-      {    0.000241e-6,    12528.018664345,  3.832324536 },
-      {    0.000304e-6,     4686.889407707,  1.612348468 },
-      {    0.000259e-6,    16200.772724501,  3.470173146 },
-      {    0.000238e-6,    12139.553509107,  1.147977842 },
-      {    0.000236e-6,     6172.869528772,  3.776271728 },
-      {    0.000296e-6,    -7058.598461315,  0.460368852 },
-      {    0.000306e-6,    10575.406682942,  0.554749016 },
-      {    0.000251e-6,    17298.182327326,  0.834332510 },
-      {    0.000290e-6,     4732.030627343,  4.759564091 },
-      {    0.000261e-6,     5884.926846583,  0.298259862 },
-   /* 621, 630 */
-      {    0.000249e-6,     5547.199336460,  3.749366406 },
-      {    0.000213e-6,    11712.955318231,  5.415666119 },
-      {    0.000223e-6,     4701.116501708,  2.703203558 },
-      {    0.000268e-6,     -640.877607382,  0.283670793 },
-      {    0.000209e-6,     5636.065016677,  1.238477199 },
-      {    0.000193e-6,    10177.257679534,  1.943251340 },
-      {    0.000182e-6,     6283.143160294,  2.456157599 },
-      {    0.000184e-6,     -227.526189440,  5.888038582 },
-      {    0.000182e-6,    -6283.008539689,  0.241332086 },
-      {    0.000228e-6,    -6284.056171060,  2.657323816 },
-   /* 631, 640 */
-      {    0.000166e-6,     7238.675591600,  5.930629110 },
-      {    0.000167e-6,     3097.883822726,  5.570955333 },
-      {    0.000159e-6,     -323.505416657,  5.786670700 },
-      {    0.000154e-6,    -4136.910433516,  1.517805532 },
-      {    0.000176e-6,    12029.347187887,  3.139266834 },
-      {    0.000167e-6,    12132.439962106,  3.556352289 },
-      {    0.000153e-6,      202.253395174,  1.463313961 },
-      {    0.000157e-6,    17267.268201691,  1.586837396 },
-      {    0.000142e-6,    83996.847317911,  0.022670115 },
-      {    0.000152e-6,    17260.154654690,  0.708528947 },
-   /* 641, 650 */
-      {    0.000144e-6,     6084.003848555,  5.187075177 },
-      {    0.000135e-6,     5756.566278634,  1.993229262 },
-      {    0.000134e-6,     5750.203491159,  3.457197134 },
-      {    0.000144e-6,     5326.786694021,  6.066193291 },
-      {    0.000160e-6,    11015.106477335,  1.710431974 },
-      {    0.000133e-6,     3634.621024518,  2.836451652 },
-      {    0.000134e-6,    18073.704938650,  5.453106665 },
-      {    0.000134e-6,     1162.474704408,  5.326898811 },
-      {    0.000128e-6,     5642.198242609,  2.511652591 },
-      {    0.000160e-6,      632.783739313,  5.628785365 },
-   /* 651, 660 */
-      {    0.000132e-6,    13916.019109642,  0.819294053 },
-      {    0.000122e-6,    14314.168113050,  5.677408071 },
-      {    0.000125e-6,    12359.966151546,  5.251984735 },
-      {    0.000121e-6,     5749.452731634,  2.210924603 },
-      {    0.000136e-6,     -245.831646229,  1.646502367 },
-      {    0.000120e-6,     5757.317038160,  3.240883049 },
-      {    0.000134e-6,    12146.667056108,  3.059480037 },
-      {    0.000137e-6,     6206.809778716,  1.867105418 },
-      {    0.000141e-6,    17253.041107690,  2.069217456 },
-      {    0.000129e-6,    -7477.522860216,  2.781469314 },
-   /* 661, 670 */
-      {    0.000116e-6,     5540.085789459,  4.281176991 },
-      {    0.000116e-6,     9779.108676125,  3.320925381 },
-      {    0.000129e-6,     5237.921013804,  3.497704076 },
-      {    0.000113e-6,     5959.570433334,  0.983210840 },
-      {    0.000122e-6,     6282.095528923,  2.674938860 },
-      {    0.000140e-6,      -11.045700264,  4.957936982 },
-      {    0.000108e-6,    23543.230504682,  1.390113589 },
-      {    0.000106e-6,   -12569.674818332,  0.429631317 },
-      {    0.000110e-6,     -266.607041722,  5.501340197 },
-      {    0.000115e-6,    12559.038152982,  4.691456618 },
-   /* 671, 680 */
-      {    0.000134e-6,    -2388.894020449,  0.577313584 },
-      {    0.000109e-6,    10440.274292604,  6.218148717 },
-      {    0.000102e-6,     -543.918059096,  1.477842615 },
-      {    0.000108e-6,    21228.392023546,  2.237753948 },
-      {    0.000101e-6,    -4535.059436924,  3.100492232 },
-      {    0.000103e-6,       76.266071276,  5.594294322 },
-      {    0.000104e-6,      949.175608970,  5.674287810 },
-      {    0.000101e-6,    13517.870106233,  2.196632348 },
-      {    0.000100e-6,    11933.367960670,  4.056084160 },
-
-   /* T^2 */
-      {    4.322990e-6,     6283.075849991,  2.642893748 },
-   /* 681, 690 */
-      {    0.406495e-6,        0.000000000,  4.712388980 },
-      {    0.122605e-6,    12566.151699983,  2.438140634 },
-      {    0.019476e-6,      213.299095438,  1.642186981 },
-      {    0.016916e-6,      529.690965095,  4.510959344 },
-      {    0.013374e-6,       -3.523118349,  1.502210314 },
-      {    0.008042e-6,       26.298319800,  0.478549024 },
-      {    0.007824e-6,      155.420399434,  5.254710405 },
-      {    0.004894e-6,     5746.271337896,  4.683210850 },
-      {    0.004875e-6,     5760.498431898,  0.759507698 },
-      {    0.004416e-6,     5223.693919802,  6.028853166 },
-   /* 691, 700 */
-      {    0.004088e-6,       -7.113547001,  0.060926389 },
-      {    0.004433e-6,    77713.771467920,  3.627734103 },
-      {    0.003277e-6,    18849.227549974,  2.327912542 },
-      {    0.002703e-6,     6062.663207553,  1.271941729 },
-      {    0.003435e-6,     -775.522611324,  0.747446224 },
-      {    0.002618e-6,     6076.890301554,  3.633715689 },
-      {    0.003146e-6,      206.185548437,  5.647874613 },
-      {    0.002544e-6,     1577.343542448,  6.232904270 },
-      {    0.002218e-6,     -220.412642439,  1.309509946 },
-      {    0.002197e-6,     5856.477659115,  2.407212349 },
-   /* 701, 710 */
-      {    0.002897e-6,     5753.384884897,  5.863842246 },
-      {    0.001766e-6,      426.598190876,  0.754113147 },
-      {    0.001738e-6,     -796.298006816,  2.714942671 },
-      {    0.001695e-6,      522.577418094,  2.629369842 },
-      {    0.001584e-6,     5507.553238667,  1.341138229 },
-      {    0.001503e-6,     -242.728603974,  0.377699736 },
-      {    0.001552e-6,     -536.804512095,  2.904684667 },
-      {    0.001370e-6,     -398.149003408,  1.265599125 },
-      {    0.001889e-6,    -5573.142801634,  4.413514859 },
-      {    0.001722e-6,     6069.776754553,  2.445966339 },
-   /* 711, 720 */
-      {    0.001124e-6,     1059.381930189,  5.041799657 },
-      {    0.001258e-6,      553.569402842,  3.849557278 },
-      {    0.000831e-6,      951.718406251,  2.471094709 },
-      {    0.000767e-6,     4694.002954708,  5.363125422 },
-      {    0.000756e-6,     1349.867409659,  1.046195744 },
-      {    0.000775e-6,      -11.045700264,  0.245548001 },
-      {    0.000597e-6,     2146.165416475,  4.543268798 },
-      {    0.000568e-6,     5216.580372801,  4.178853144 },
-      {    0.000711e-6,     1748.016413067,  5.934271972 },
-      {    0.000499e-6,    12036.460734888,  0.624434410 },
-   /* 721, 730 */
-      {    0.000671e-6,    -1194.447010225,  4.136047594 },
-      {    0.000488e-6,     5849.364112115,  2.209679987 },
-      {    0.000621e-6,     6438.496249426,  4.518860804 },
-      {    0.000495e-6,    -6286.598968340,  1.868201275 },
-      {    0.000456e-6,     5230.807466803,  1.271231591 },
-      {    0.000451e-6,     5088.628839767,  0.084060889 },
-      {    0.000435e-6,     5643.178563677,  3.324456609 },
-      {    0.000387e-6,    10977.078804699,  4.052488477 },
-      {    0.000547e-6,   161000.685737473,  2.841633844 },
-      {    0.000522e-6,     3154.687084896,  2.171979966 },
-   /* 731, 740 */
-      {    0.000375e-6,     5486.777843175,  4.983027306 },
-      {    0.000421e-6,     5863.591206116,  4.546432249 },
-      {    0.000439e-6,     7084.896781115,  0.522967921 },
-      {    0.000309e-6,     2544.314419883,  3.172606705 },
-      {    0.000347e-6,     4690.479836359,  1.479586566 },
-      {    0.000317e-6,      801.820931124,  3.553088096 },
-      {    0.000262e-6,      419.484643875,  0.606635550 },
-      {    0.000248e-6,     6836.645252834,  3.014082064 },
-      {    0.000245e-6,    -1592.596013633,  5.519526220 },
-      {    0.000225e-6,     4292.330832950,  2.877956536 },
-   /* 741, 750 */
-      {    0.000214e-6,     7234.794256242,  1.605227587 },
-      {    0.000205e-6,     5767.611978898,  0.625804796 },
-      {    0.000180e-6,    10447.387839604,  3.499954526 },
-      {    0.000229e-6,      199.072001436,  5.632304604 },
-      {    0.000214e-6,      639.897286314,  5.960227667 },
-      {    0.000175e-6,     -433.711737877,  2.162417992 },
-      {    0.000209e-6,      515.463871093,  2.322150893 },
-      {    0.000173e-6,     6040.347246017,  2.556183691 },
-      {    0.000184e-6,     6309.374169791,  4.732296790 },
-      {    0.000227e-6,   149854.400134205,  5.385812217 },
-   /* 751, 760 */
-      {    0.000154e-6,     8031.092263058,  5.120720920 },
-      {    0.000151e-6,     5739.157790895,  4.815000443 },
-      {    0.000197e-6,     7632.943259650,  0.222827271 },
-      {    0.000197e-6,       74.781598567,  3.910456770 },
-      {    0.000138e-6,     6055.549660552,  1.397484253 },
-      {    0.000149e-6,    -6127.655450557,  5.333727496 },
-      {    0.000137e-6,     3894.181829542,  4.281749907 },
-      {    0.000135e-6,     9437.762934887,  5.979971885 },
-      {    0.000139e-6,    -2352.866153772,  4.715630782 },
-      {    0.000142e-6,     6812.766815086,  0.513330157 },
-   /* 761, 770 */
-      {    0.000120e-6,    -4705.732307544,  0.194160689 },
-      {    0.000131e-6,   -71430.695617928,  0.000379226 },
-      {    0.000124e-6,     6279.552731642,  2.122264908 },
-      {    0.000108e-6,    -6256.777530192,  0.883445696 },
-
-   /* T^3 */
-      {    0.143388e-6,     6283.075849991,  1.131453581 },
-      {    0.006671e-6,    12566.151699983,  0.775148887 },
-      {    0.001480e-6,      155.420399434,  0.480016880 },
-      {    0.000934e-6,      213.299095438,  6.144453084 },
-      {    0.000795e-6,      529.690965095,  2.941595619 },
-      {    0.000673e-6,     5746.271337896,  0.120415406 },
-   /* 771, 780 */
-      {    0.000672e-6,     5760.498431898,  5.317009738 },
-      {    0.000389e-6,     -220.412642439,  3.090323467 },
-      {    0.000373e-6,     6062.663207553,  3.003551964 },
-      {    0.000360e-6,     6076.890301554,  1.918913041 },
-      {    0.000316e-6,      -21.340641002,  5.545798121 },
-      {    0.000315e-6,     -242.728603974,  1.884932563 },
-      {    0.000278e-6,      206.185548437,  1.266254859 },
-      {    0.000238e-6,     -536.804512095,  4.532664830 },
-      {    0.000185e-6,      522.577418094,  4.578313856 },
-      {    0.000245e-6,    18849.227549974,  0.587467082 },
-   /* 781, 787 */
-      {    0.000180e-6,      426.598190876,  5.151178553 },
-      {    0.000200e-6,      553.569402842,  5.355983739 },
-      {    0.000141e-6,     5223.693919802,  1.336556009 },
-      {    0.000104e-6,     5856.477659115,  4.239842759 },
-
-   /* T^4 */
-      {    0.003826e-6,     6283.075849991,  5.705257275 },
-      {    0.000303e-6,    12566.151699983,  5.407132842 },
-      {    0.000209e-6,      155.420399434,  1.989815753 }
-   };
-
-
-/* Time since J2000.0 in Julian millennia. */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM;
-
-/* ================= */
-/* Topocentric terms */
-/* ================= */
-
-/* Convert UT to local solar time in radians. */
-   tsol = fmod(ut, 1.0) * ERFA_D2PI + elong;
-
-/* FUNDAMENTAL ARGUMENTS:  Simon et al. 1994. */
-
-/* Combine time argument (millennia) with deg/arcsec factor. */
-   w = t / 3600.0;
-
-/* Sun Mean Longitude. */
-   elsun = fmod(280.46645683 + 1296027711.03429 * w, 360.0) * ERFA_DD2R;
-
-/* Sun Mean Anomaly. */
-   emsun = fmod(357.52910918 + 1295965810.481 * w, 360.0) * ERFA_DD2R;
-
-/* Mean Elongation of Moon from Sun. */
-   d = fmod(297.85019547 + 16029616012.090 * w, 360.0) * ERFA_DD2R;
-
-/* Mean Longitude of Jupiter. */
-   elj = fmod(34.35151874 + 109306899.89453 * w, 360.0) * ERFA_DD2R;
-
-/* Mean Longitude of Saturn. */
-   els = fmod(50.07744430 + 44046398.47038 * w, 360.0) * ERFA_DD2R;
-
-/* TOPOCENTRIC TERMS:  Moyer 1981 and Murray 1983. */
-   wt =   +  0.00029e-10 * u * sin(tsol + elsun - els)
-          +  0.00100e-10 * u * sin(tsol - 2.0 * emsun)
-          +  0.00133e-10 * u * sin(tsol - d)
-          +  0.00133e-10 * u * sin(tsol + elsun - elj)
-          -  0.00229e-10 * u * sin(tsol + 2.0 * elsun + emsun)
-          -  0.02200e-10 * v * cos(elsun + emsun)
-          +  0.05312e-10 * u * sin(tsol - emsun)
-          -  0.13677e-10 * u * sin(tsol + 2.0 * elsun)
-          -  1.31840e-10 * v * cos(elsun)
-          +  3.17679e-10 * u * sin(tsol);
-
-/* ===================== */
-/* Fairhead et al. model */
-/* ===================== */
-
-/* T**0 */
-   w0 = 0;
-   for (j = 473; j >= 0; j--) {
-      w0 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
-   }
-
-/* T**1 */
-   w1 = 0;
-   for (j = 678; j >= 474; j--) {
-      w1 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
-   }
-
-/* T**2 */
-   w2 = 0;
-   for (j = 763; j >= 679; j--) {
-      w2 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
-   }
-
-/* T**3 */
-   w3 = 0;
-   for (j = 783; j >= 764; j--) {
-      w3 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
-   }
-
-/* T**4 */
-   w4 = 0;
-   for (j = 786; j >= 784; j--) {
-      w4 += fairhd[j][0] * sin(fairhd[j][1] * t + fairhd[j][2]);
-   }
-
-/* Multiply by powers of T and combine. */
-   wf = t * (t * (t * (t * w4 + w3) + w2) + w1) + w0;
-
-/* Adjustments to use JPL planetary masses instead of IAU. */
-   wj =   0.00065e-6 * sin(6069.776754 * t + 4.021194) +
-          0.00033e-6 * sin( 213.299095 * t + 5.543132) +
-        (-0.00196e-6 * sin(6208.294251 * t + 5.696701)) +
-        (-0.00173e-6 * sin(  74.781599 * t + 2.435900)) +
-          0.03638e-6 * t * t;
-
-/* ============ */
-/* Final result */
-/* ============ */
-
-/* TDB-TT in seconds. */
-   w = wt + wf + wj;
-
-   return w;
-
-}
-
-int eraDtf2d(const char *scale, int iy, int im, int id,
-             int ihr, int imn, double sec, double *d1, double *d2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int js, iy2, im2, id2;
-   double dj, w, day, seclim, dat0, dat12, dat24, dleap, time;
-
-
-/* Today's Julian Day Number. */
-   js = eraCal2jd(iy, im, id, &dj, &w);
-   if ( js ) return js;
-   dj += w;
-
-/* Day length and final minute length in seconds (provisional). */
-   day = ERFA_DAYSEC;
-   seclim = 60.0;
-
-/* Deal with the UTC leap second case. */
-   if ( ! strcmp(scale,"UTC") ) {
-
-   /* TAI-UTC at 0h today. */
-      js = eraDat(iy, im, id, 0.0, &dat0);
-      if ( js < 0 ) return js;
-
-   /* TAI-UTC at 12h today (to detect drift). */
-      js = eraDat(iy, im, id, 0.5, &dat12);
-      if ( js < 0 ) return js;
-
-   /* TAI-UTC at 0h tomorrow (to detect jumps). */
-      js = eraJd2cal ( dj, 1.5, &iy2, &im2, &id2, &w);
-      if ( js ) return js;
-      js = eraDat(iy2, im2, id2, 0.0, &dat24);
-      if ( js < 0 ) return js;
-
-   /* Any sudden change in TAI-UTC between today and tomorrow. */
-      dleap = dat24 - (2.0*dat12 - dat0);
-
-   /* If leap second day, correct the day and final minute lengths. */
-      day += dleap;
-      if ( ihr == 23 && imn == 59 ) seclim += dleap;
-
-   /* End of UTC-specific actions. */
-   }
-
-/* Validate the time. */
-   if ( ihr >= 0 && ihr <= 23 ) {
-      if ( imn >= 0 && imn <= 59 ) {
-         if ( sec >= 0 ) {
-            if ( sec >= seclim ) {
-               js += 2;
-            }
-         } else {
-            js = -6;
-         }
-      } else {
-         js = -5;
-      }
-   } else {
-      js = -4;
-   }
-   if ( js < 0 ) return js;
-
-/* The time in days. */
-   time  = ( 60.0 * ( (double) ( 60 * ihr + imn ) ) + sec ) / day;
-
-/* Return the date and time. */
-   *d1 = dj;
-   *d2 = time;
-
-/* Status. */
-   return js;
-
-}
-
-double eraEe00(double date1, double date2, double epsa, double dpsi)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double ee;
-
-
-/* Equation of the equinoxes. */
-   ee = dpsi * cos(epsa) + eraEect00(date1, date2);
-
-   return ee;
-
-}
-
-double eraEe00a(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsipr, depspr, epsa, dpsi, deps, ee;
-
-
-/* IAU 2000 precession-rate adjustments. */
-   eraPr00(date1, date2, &dpsipr, &depspr);
-
-/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
-   epsa = eraObl80(date1, date2) + depspr;
-
-/* Nutation in longitude. */
-   eraNut00a(date1, date2, &dpsi, &deps);
-
-/* Equation of the equinoxes. */
-   ee = eraEe00(date1, date2, epsa, dpsi);
-
-   return ee;
-
-}
-
-double eraEe00b(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsipr, depspr, epsa, dpsi, deps, ee;
-
-
-/* IAU 2000 precession-rate adjustments. */
-   eraPr00(date1, date2, &dpsipr, &depspr);
-
-/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
-   epsa = eraObl80(date1, date2) + depspr;
-
-/* Nutation in longitude. */
-   eraNut00b(date1, date2, &dpsi, &deps);
-
-/* Equation of the equinoxes. */
-   ee = eraEe00(date1, date2, epsa, dpsi);
-
-   return ee;
-
-}
-
-double eraEe06a(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gst06a, gmst06, ee;
-
-
-/* Apparent and mean sidereal times. */
-   gst06a = eraGst06a(0.0, 0.0, date1, date2);
-   gmst06 = eraGmst06(0.0, 0.0, date1, date2);
-
-/* Equation of the equinoxes. */
-   ee  = eraAnpm(gst06a - gmst06);
-
-   return ee;
-
-}
-
-double eraEect00(double date1, double date2)
-/*
-**  - - - - - - - - - -
-**   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", Astronomy &
-**     Astrophysics, 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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Time since J2000.0, in Julian centuries */
-   double t;
-
-/* Miscellaneous */
-   int i, j;
-   double a, s0, s1;
-
-/* Fundamental arguments */
-   double fa[14];
-
-/* Returned value. */
-   double eect;
-
-/* ----------------------------------------- */
-/* The series for the EE complementary terms */
-/* ----------------------------------------- */
-
-   typedef struct {
-      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
-      double s, c;     /* sine and cosine coefficients */
-   } TERM;
-
-/* Terms of order t^0 */
-   static const TERM e0[] = {
-
-   /* 1-10 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0}, 2640.96e-6, -0.39e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},   63.52e-6, -0.02e-6 },
-      {{ 0,  0,  2, -2,  3,  0,  0,  0},   11.75e-6,  0.01e-6 },
-      {{ 0,  0,  2, -2,  1,  0,  0,  0},   11.21e-6,  0.01e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},   -4.55e-6,  0.00e-6 },
-      {{ 0,  0,  2,  0,  3,  0,  0,  0},    2.02e-6,  0.00e-6 },
-      {{ 0,  0,  2,  0,  1,  0,  0,  0},    1.98e-6,  0.00e-6 },
-      {{ 0,  0,  0,  0,  3,  0,  0,  0},   -1.72e-6,  0.00e-6 },
-      {{ 0,  1,  0,  0,  1,  0,  0,  0},   -1.41e-6, -0.01e-6 },
-      {{ 0,  1,  0,  0, -1,  0,  0,  0},   -1.26e-6, -0.01e-6 },
-
-   /* 11-20 */
-      {{ 1,  0,  0,  0, -1,  0,  0,  0},   -0.63e-6,  0.00e-6 },
-      {{ 1,  0,  0,  0,  1,  0,  0,  0},   -0.63e-6,  0.00e-6 },
-      {{ 0,  1,  2, -2,  3,  0,  0,  0},    0.46e-6,  0.00e-6 },
-      {{ 0,  1,  2, -2,  1,  0,  0,  0},    0.45e-6,  0.00e-6 },
-      {{ 0,  0,  4, -4,  4,  0,  0,  0},    0.36e-6,  0.00e-6 },
-      {{ 0,  0,  1, -1,  1, -8, 12,  0},   -0.24e-6, -0.12e-6 },
-      {{ 0,  0,  2,  0,  0,  0,  0,  0},    0.32e-6,  0.00e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},    0.28e-6,  0.00e-6 },
-      {{ 1,  0,  2,  0,  3,  0,  0,  0},    0.27e-6,  0.00e-6 },
-      {{ 1,  0,  2,  0,  1,  0,  0,  0},    0.26e-6,  0.00e-6 },
-
-   /* 21-30 */
-      {{ 0,  0,  2, -2,  0,  0,  0,  0},   -0.21e-6,  0.00e-6 },
-      {{ 0,  1, -2,  2, -3,  0,  0,  0},    0.19e-6,  0.00e-6 },
-      {{ 0,  1, -2,  2, -1,  0,  0,  0},    0.18e-6,  0.00e-6 },
-      {{ 0,  0,  0,  0,  0,  8,-13, -1},   -0.10e-6,  0.05e-6 },
-      {{ 0,  0,  0,  2,  0,  0,  0,  0},    0.15e-6,  0.00e-6 },
-      {{ 2,  0, -2,  0, -1,  0,  0,  0},   -0.14e-6,  0.00e-6 },
-      {{ 1,  0,  0, -2,  1,  0,  0,  0},    0.14e-6,  0.00e-6 },
-      {{ 0,  1,  2, -2,  2,  0,  0,  0},   -0.14e-6,  0.00e-6 },
-      {{ 1,  0,  0, -2, -1,  0,  0,  0},    0.14e-6,  0.00e-6 },
-      {{ 0,  0,  4, -2,  4,  0,  0,  0},    0.13e-6,  0.00e-6 },
-
-   /* 31-33 */
-      {{ 0,  0,  2, -2,  4,  0,  0,  0},   -0.11e-6,  0.00e-6 },
-      {{ 1,  0, -2,  0, -3,  0,  0,  0},    0.11e-6,  0.00e-6 },
-      {{ 1,  0, -2,  0, -1,  0,  0,  0},    0.11e-6,  0.00e-6 }
-   };
-
-/* Terms of order t^1 */
-   static const TERM e1[] = {
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.87e-6,  0.00e-6 }
-   };
-
-/* Number of terms in the series */
-   const int NE0 = (int) (sizeof e0 / sizeof (TERM));
-   const int NE1 = (int) (sizeof e1 / sizeof (TERM));
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental epoch J2000.0 and current date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Fundamental Arguments (from IERS Conventions 2003) */
-
-/* Mean anomaly of the Moon. */
-   fa[0] = eraFal03(t);
-
-/* Mean anomaly of the Sun. */
-   fa[1] = eraFalp03(t);
-
-/* Mean longitude of the Moon minus that of the ascending node. */
-   fa[2] = eraFaf03(t);
-
-/* Mean elongation of the Moon from the Sun. */
-   fa[3] = eraFad03(t);
-
-/* Mean longitude of the ascending node of the Moon. */
-   fa[4] = eraFaom03(t);
-
-/* Mean longitude of Venus. */
-   fa[5] = eraFave03(t);
-
-/* Mean longitude of Earth. */
-   fa[6] = eraFae03(t);
-
-/* General precession in longitude. */
-   fa[7] = eraFapa03(t);
-
-/* Evaluate the EE complementary terms. */
-   s0 = 0.0;
-   s1 = 0.0;
-
-   for (i = NE0-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)(e0[i].nfa[j]) * fa[j];
-      }
-      s0 += e0[i].s * sin(a) + e0[i].c * cos(a);
-   }
-
-   for (i = NE1-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)(e1[i].nfa[j]) * fa[j];
-      }
-      s1 += e1[i].s * sin(a) + e1[i].c * cos(a);
-   }
-
-   eect = (s0 + s1 * t ) * ERFA_DAS2R;
-
-   return eect;
-
-}
-
-int eraEform ( int n, double *a, double *f )
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Look up a and f for the specified reference ellipsoid. */
-   switch ( n ) {
-
-   case ERFA_WGS84:
-      *a = 6378137.0;
-      *f = 1.0 / 298.257223563;
-      break;
-
-   case ERFA_GRS80:
-      *a = 6378137.0;
-      *f = 1.0 / 298.257222101;
-      break;
-
-   case ERFA_WGS72:
-      *a = 6378135.0;
-      *f = 1.0 / 298.26;
-      break;
-
-   default:
-
-   /* Invalid identifier. */
-      *a = 0.0;
-      *f = 0.0;
-      return -1;
-
-   }
-
-/* OK status. */
-   return 0;
-
-}
-
-double eraEo06a(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r[3][3], x, y, s, eo;
-
-
-/* Classical nutation x precession x bias matrix. */
-   eraPnm06a(date1, date2, r);
-
-/* Extract CIP coordinates. */
-   eraBpn2xy(r, &x, &y);
-
-/* The CIO locator, s. */
-   s = eraS06(date1, date2, x, y);
-
-/* Solve for the EO. */
-   eo = eraEors(r, s);
-
-   return eo;
-
-}
-
-double eraEors(double rnpb[3][3], double s)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, ax, xs, ys, zs, p, q, eo;
-
-
-/* Evaluate Wallace & Capitaine (2006) expression (16). */
-   x = rnpb[2][0];
-   ax = x / (1.0 + rnpb[2][2]);
-   xs = 1.0 - ax * x;
-   ys = -ax * rnpb[2][1];
-   zs = -x;
-   p = rnpb[0][0] * xs + rnpb[0][1] * ys + rnpb[0][2] * zs;
-   q = rnpb[1][0] * xs + rnpb[1][1] * ys + rnpb[1][2] * zs;
-   eo = ((p != 0) || (q != 0)) ? s - atan2(q, p) : s;
-
-   return eo;
-
-}
-
-double eraEpb(double dj1, double dj2)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* J2000.0-B1900.0 (2415019.81352) in days */
-   const double D1900 = 36524.68648;
-
-   return 1900.0 + ((dj1 - ERFA_DJ00) + (dj2 + D1900)) / ERFA_DTY;
-
-}
-
-void eraEpb2jd(double epb, double *djm0, double *djm)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   *djm0 = ERFA_DJM0;
-   *djm  =   15019.81352 + (epb - 1900.0) * ERFA_DTY;
-
-   return;
-
-}
-
-double eraEpj(double dj1, double dj2)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double epj;
-
-
-   epj = 2000.0 + ((dj1 - ERFA_DJ00) + dj2) / ERFA_DJY;
-
-   return epj;
-
-}
-
-void eraEpj2jd(double epj, double *djm0, double *djm)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   *djm0 = ERFA_DJM0;
-   *djm  = ERFA_DJM00 + (epj - 2000.0) * 365.25;
-
-   return;
-
-}
-
-int eraEpv00(double date1, double date2,
-             double pvh[2][3], double pvb[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/*
-** Matrix elements for orienting the analytical model to DE405.
-**
-** The corresponding Euler angles are:
-**
-**                       d  '  "
-**   1st rotation    -  23 26 21.4091 about the x-axis  (obliquity)
-**   2nd rotation    +         0.0475 about the z-axis  (RA offset)
-**
-** These were obtained empirically, by comparisons with DE405 over
-** 1900-2100.
-*/
-   static const double am12 =  0.000000211284,
-                       am13 = -0.000000091603,
-                       am21 = -0.000000230286,
-                       am22 =  0.917482137087,
-                       am23 = -0.397776982902,
-                       am32 =  0.397776982902,
-                       am33 =  0.917482137087;
-
-/*
-** ----------------------
-** Ephemeris Coefficients
-** ----------------------
-**
-** The ephemeris consists of harmonic terms for predicting (i) the Sun
-** to Earth vector and (ii) the Solar-System-barycenter to Sun vector
-** respectively.  The coefficients are stored in arrays which, although
-** 1-demensional, contain groups of three.  Each triplet of
-** coefficients is the amplitude, phase and frequency for one term in
-** the model, and each array contains the number of terms called for by
-** the model.
-**
-** There are eighteen such arrays, named as follows:
-**
-**     array         model      power of T      component
-**
-**      e0x      Sun-to-Earth        0              x
-**      e0y      Sun-to-Earth        0              y
-**      e0z      Sun-to-Earth        0              z
-**
-**      e1x      Sun-to-Earth        1              x
-**      e1y      Sun-to-Earth        1              y
-**      e1z      Sun-to-Earth        1              z
-**
-**      e2x      Sun-to-Earth        2              x
-**      e2y      Sun-to-Earth        2              y
-**      e2z      Sun-to-Earth        2              z
-**
-**      s0x      SSB-to-Sun          0              x
-**      s0y      SSB-to-Sun          0              y
-**      s0z      SSB-to-Sun          0              z
-**
-**      s1x      SSB-to-Sun          1              x
-**      s1y      SSB-to-Sun          1              y
-**      s1z      SSB-to-Sun          1              z
-**
-**      s2x      SSB-to-Sun          2              x
-**      s2y      SSB-to-Sun          2              y
-**      s2z      SSB-to-Sun          2              z
-*/
-
-/* Sun-to-Earth, T^0, X */
-   static const double e0x[] = {
-      0.9998292878132e+00, 0.1753485171504e+01, 0.6283075850446e+01,
-      0.8352579567414e-02, 0.1710344404582e+01, 0.1256615170089e+02,
-      0.5611445335148e-02, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.1046664295572e-03, 0.1667225416770e+01, 0.1884922755134e+02,
-      0.3110842534677e-04, 0.6687513390251e+00, 0.8399684731857e+02,
-      0.2552413503550e-04, 0.5830637358413e+00, 0.5296909721118e+00,
-      0.2137207845781e-04, 0.1092330954011e+01, 0.1577343543434e+01,
-      0.1680240182951e-04, 0.4955366134987e+00, 0.6279552690824e+01,
-      0.1679012370795e-04, 0.6153014091901e+01, 0.6286599010068e+01,
-      0.1445526946777e-04, 0.3472744100492e+01, 0.2352866153506e+01,
-
-      0.1091038246184e-04, 0.3689845786119e+01, 0.5223693906222e+01,
-      0.9344399733932e-05, 0.6073934645672e+01, 0.1203646072878e+02,
-      0.8993182910652e-05, 0.3175705249069e+01, 0.1021328554739e+02,
-      0.5665546034116e-05, 0.2152484672246e+01, 0.1059381944224e+01,
-      0.6844146703035e-05, 0.1306964099750e+01, 0.5753384878334e+01,
-      0.7346610905565e-05, 0.4354980070466e+01, 0.3981490189893e+00,
-      0.6815396474414e-05, 0.2218229211267e+01, 0.4705732307012e+01,
-      0.6112787253053e-05, 0.5384788425458e+01, 0.6812766822558e+01,
-      0.4518120711239e-05, 0.6087604012291e+01, 0.5884926831456e+01,
-      0.4521963430706e-05, 0.1279424524906e+01, 0.6256777527156e+01,
-
-      0.4497426764085e-05, 0.5369129144266e+01, 0.6309374173736e+01,
-      0.4062190566959e-05, 0.5436473303367e+00, 0.6681224869435e+01,
-      0.5412193480192e-05, 0.7867838528395e+00, 0.7755226100720e+00,
-      0.5469839049386e-05, 0.1461440311134e+01, 0.1414349524433e+02,
-      0.5205264083477e-05, 0.4432944696116e+01, 0.7860419393880e+01,
-      0.2149759935455e-05, 0.4502237496846e+01, 0.1150676975667e+02,
-      0.2279109618501e-05, 0.1239441308815e+01, 0.7058598460518e+01,
-      0.2259282939683e-05, 0.3272430985331e+01, 0.4694002934110e+01,
-      0.2558950271319e-05, 0.2265471086404e+01, 0.1216800268190e+02,
-      0.2561581447555e-05, 0.1454740653245e+01, 0.7099330490126e+00,
-
-      0.1781441115440e-05, 0.2962068630206e+01, 0.7962980379786e+00,
-      0.1612005874644e-05, 0.1473255041006e+01, 0.5486777812467e+01,
-      0.1818630667105e-05, 0.3743903293447e+00, 0.6283008715021e+01,
-      0.1818601377529e-05, 0.6274174354554e+01, 0.6283142985870e+01,
-      0.1554475925257e-05, 0.1624110906816e+01, 0.2513230340178e+02,
-      0.2090948029241e-05, 0.5852052276256e+01, 0.1179062909082e+02,
-      0.2000176345460e-05, 0.4072093298513e+01, 0.1778984560711e+02,
-      0.1289535917759e-05, 0.5217019331069e+01, 0.7079373888424e+01,
-      0.1281135307881e-05, 0.4802054538934e+01, 0.3738761453707e+01,
-      0.1518229005692e-05, 0.8691914742502e+00, 0.2132990797783e+00,
-
-      0.9450128579027e-06, 0.4601859529950e+01, 0.1097707878456e+02,
-      0.7781119494996e-06, 0.1844352816694e+01, 0.8827390247185e+01,
-      0.7733407759912e-06, 0.3582790154750e+01, 0.5507553240374e+01,
-      0.7350644318120e-06, 0.2695277788230e+01, 0.1589072916335e+01,
-      0.6535928827023e-06, 0.3651327986142e+01, 0.1176985366291e+02,
-      0.6324624183656e-06, 0.2241302375862e+01, 0.6262300422539e+01,
-      0.6298565300557e-06, 0.4407122406081e+01, 0.6303851278352e+01,
-      0.8587037089179e-06, 0.3024307223119e+01, 0.1672837615881e+03,
-      0.8299954491035e-06, 0.6192539428237e+01, 0.3340612434717e+01,
-      0.6311263503401e-06, 0.2014758795416e+01, 0.7113454667900e-02,
-
-      0.6005646745452e-06, 0.3399500503397e+01, 0.4136910472696e+01,
-      0.7917715109929e-06, 0.2493386877837e+01, 0.6069776770667e+01,
-      0.7556958099685e-06, 0.4159491740143e+01, 0.6496374930224e+01,
-      0.6773228244949e-06, 0.4034162934230e+01, 0.9437762937313e+01,
-      0.5370708577847e-06, 0.1562219163734e+01, 0.1194447056968e+01,
-      0.5710804266203e-06, 0.2662730803386e+01, 0.6282095334605e+01,
-      0.5709824583726e-06, 0.3985828430833e+01, 0.6284056366286e+01,
-      0.5143950896447e-06, 0.1308144688689e+01, 0.6290189305114e+01,
-      0.5088010604546e-06, 0.5352817214804e+01, 0.6275962395778e+01,
-      0.4960369085172e-06, 0.2644267922349e+01, 0.6127655567643e+01,
-
-      0.4803137891183e-06, 0.4008844192080e+01, 0.6438496133249e+01,
-      0.5731747768225e-06, 0.3794550174597e+01, 0.3154687086868e+01,
-      0.4735947960579e-06, 0.6107118308982e+01, 0.3128388763578e+01,
-      0.4808348796625e-06, 0.4771458618163e+01, 0.8018209333619e+00,
-      0.4115073743137e-06, 0.3327111335159e+01, 0.8429241228195e+01,
-      0.5230575889287e-06, 0.5305708551694e+01, 0.1336797263425e+02,
-      0.5133977889215e-06, 0.5784230738814e+01, 0.1235285262111e+02,
-      0.5065815825327e-06, 0.2052064793679e+01, 0.1185621865188e+02,
-      0.4339831593868e-06, 0.3644994195830e+01, 0.1726015463500e+02,
-      0.3952928638953e-06, 0.4930376436758e+01, 0.5481254917084e+01,
-
-      0.4898498111942e-06, 0.4542084219731e+00, 0.9225539266174e+01,
-      0.4757490209328e-06, 0.3161126388878e+01, 0.5856477690889e+01,
-      0.4727701669749e-06, 0.6214993845446e+00, 0.2544314396739e+01,
-      0.3800966681863e-06, 0.3040132339297e+01, 0.4265981595566e+00,
-      0.3257301077939e-06, 0.8064977360087e+00, 0.3930209696940e+01,
-      0.3255810528674e-06, 0.1974147981034e+01, 0.2146165377750e+01,
-      0.3252029748187e-06, 0.2845924913135e+01, 0.4164311961999e+01,
-      0.3255505635308e-06, 0.3017900824120e+01, 0.5088628793478e+01,
-      0.2801345211990e-06, 0.6109717793179e+01, 0.1256967486051e+02,
-      0.3688987740970e-06, 0.2911550235289e+01, 0.1807370494127e+02,
-
-      0.2475153429458e-06, 0.2179146025856e+01, 0.2629832328990e-01,
-      0.3033457749150e-06, 0.1994161050744e+01, 0.4535059491685e+01,
-      0.2186743763110e-06, 0.5125687237936e+01, 0.1137170464392e+02,
-      0.2764777032774e-06, 0.4822646860252e+00, 0.1256262854127e+02,
-      0.2199028768592e-06, 0.4637633293831e+01, 0.1255903824622e+02,
-      0.2046482824760e-06, 0.1467038733093e+01, 0.7084896783808e+01,
-      0.2611209147507e-06, 0.3044718783485e+00, 0.7143069561767e+02,
-      0.2286079656818e-06, 0.4764220356805e+01, 0.8031092209206e+01,
-      0.1855071202587e-06, 0.3383637774428e+01, 0.1748016358760e+01,
-      0.2324669506784e-06, 0.6189088449251e+01, 0.1831953657923e+02,
-
-      0.1709528015688e-06, 0.5874966729774e+00, 0.4933208510675e+01,
-      0.2168156875828e-06, 0.4302994009132e+01, 0.1044738781244e+02,
-      0.2106675556535e-06, 0.3800475419891e+01, 0.7477522907414e+01,
-      0.1430213830465e-06, 0.1294660846502e+01, 0.2942463415728e+01,
-      0.1388396901944e-06, 0.4594797202114e+01, 0.8635942003952e+01,
-      0.1922258844190e-06, 0.4943044543591e+00, 0.1729818233119e+02,
-      0.1888460058292e-06, 0.2426943912028e+01, 0.1561374759853e+03,
-      0.1789449386107e-06, 0.1582973303499e+00, 0.1592596075957e+01,
-      0.1360803685374e-06, 0.5197240440504e+01, 0.1309584267300e+02,
-      0.1504038014709e-06, 0.3120360916217e+01, 0.1649636139783e+02,
-
-      0.1382769533389e-06, 0.6164702888205e+01, 0.7632943190217e+01,
-      0.1438059769079e-06, 0.1437423770979e+01, 0.2042657109477e+02,
-      0.1326303260037e-06, 0.3609688799679e+01, 0.1213955354133e+02,
-      0.1159244950540e-06, 0.5463018167225e+01, 0.5331357529664e+01,
-      0.1433118149136e-06, 0.6028909912097e+01, 0.7342457794669e+01,
-      0.1234623148594e-06, 0.3109645574997e+01, 0.6279485555400e+01,
-      0.1233949875344e-06, 0.3539359332866e+01, 0.6286666145492e+01,
-      0.9927196061299e-07, 0.1259321569772e+01, 0.7234794171227e+01,
-      0.1242302191316e-06, 0.1065949392609e+01, 0.1511046609763e+02,
-      0.1098402195201e-06, 0.2192508743837e+01, 0.1098880815746e+02,
-
-      0.1158191395315e-06, 0.4054411278650e+01, 0.5729506548653e+01,
-      0.9048475596241e-07, 0.5429764748518e+01, 0.9623688285163e+01,
-      0.8889853269023e-07, 0.5046586206575e+01, 0.6148010737701e+01,
-      0.1048694242164e-06, 0.2628858030806e+01, 0.6836645152238e+01,
-      0.1112308378646e-06, 0.4177292719907e+01, 0.1572083878776e+02,
-      0.8631729709901e-07, 0.1601345232557e+01, 0.6418140963190e+01,
-      0.8527816951664e-07, 0.2463888997513e+01, 0.1471231707864e+02,
-      0.7892139456991e-07, 0.3154022088718e+01, 0.2118763888447e+01,
-      0.1051782905236e-06, 0.4795035816088e+01, 0.1349867339771e+01,
-      0.1048219943164e-06, 0.2952983395230e+01, 0.5999216516294e+01,
-
-      0.7435760775143e-07, 0.5420547991464e+01, 0.6040347114260e+01,
-      0.9869574106949e-07, 0.3695646753667e+01, 0.6566935184597e+01,
-      0.9156886364226e-07, 0.3922675306609e+01, 0.5643178611111e+01,
-      0.7006834356188e-07, 0.1233968624861e+01, 0.6525804586632e+01,
-      0.9806170182601e-07, 0.1919542280684e+01, 0.2122839202813e+02,
-      0.9052289673607e-07, 0.4615902724369e+01, 0.4690479774488e+01,
-      0.7554200867893e-07, 0.1236863719072e+01, 0.1253985337760e+02,
-      0.8215741286498e-07, 0.3286800101559e+00, 0.1097355562493e+02,
-      0.7185178575397e-07, 0.5880942158367e+01, 0.6245048154254e+01,
-      0.7130726476180e-07, 0.7674871987661e+00, 0.6321103546637e+01,
-
-      0.6650894461162e-07, 0.6987129150116e+00, 0.5327476111629e+01,
-      0.7396888823688e-07, 0.3576824794443e+01, 0.5368044267797e+00,
-      0.7420588884775e-07, 0.5033615245369e+01, 0.2354323048545e+02,
-      0.6141181642908e-07, 0.9449927045673e+00, 0.1296430071988e+02,
-      0.6373557924058e-07, 0.6206342280341e+01, 0.9517183207817e+00,
-      0.6359474329261e-07, 0.5036079095757e+01, 0.1990745094947e+01,
-      0.5740173582646e-07, 0.6105106371350e+01, 0.9555997388169e+00,
-      0.7019864084602e-07, 0.7237747359018e+00, 0.5225775174439e+00,
-      0.6398054487042e-07, 0.3976367969666e+01, 0.2407292145756e+02,
-      0.7797092650498e-07, 0.4305423910623e+01, 0.2200391463820e+02,
-
-      0.6466760000900e-07, 0.3500136825200e+01, 0.5230807360890e+01,
-      0.7529417043890e-07, 0.3514779246100e+01, 0.1842262939178e+02,
-      0.6924571140892e-07, 0.2743457928679e+01, 0.1554202828031e+00,
-      0.6220798650222e-07, 0.2242598118209e+01, 0.1845107853235e+02,
-      0.5870209391853e-07, 0.2332832707527e+01, 0.6398972393349e+00,
-      0.6263953473888e-07, 0.2191105358956e+01, 0.6277552955062e+01,
-      0.6257781390012e-07, 0.4457559396698e+01, 0.6288598745829e+01,
-      0.5697304945123e-07, 0.3499234761404e+01, 0.1551045220144e+01,
-      0.6335438746791e-07, 0.6441691079251e+00, 0.5216580451554e+01,
-      0.6377258441152e-07, 0.2252599151092e+01, 0.5650292065779e+01,
-
-      0.6484841818165e-07, 0.1992812417646e+01, 0.1030928125552e+00,
-      0.4735551485250e-07, 0.3744672082942e+01, 0.1431416805965e+02,
-      0.4628595996170e-07, 0.1334226211745e+01, 0.5535693017924e+00,
-      0.6258152336933e-07, 0.4395836159154e+01, 0.2608790314060e+02,
-      0.6196171366594e-07, 0.2587043007997e+01, 0.8467247584405e+02,
-      0.6159556952126e-07, 0.4782499769128e+01, 0.2394243902548e+03,
-      0.4987741172394e-07, 0.7312257619924e+00, 0.7771377146812e+02,
-      0.5459280703142e-07, 0.3001376372532e+01, 0.6179983037890e+01,
-      0.4863461189999e-07, 0.3767222128541e+01, 0.9027992316901e+02,
-      0.5349912093158e-07, 0.3663594450273e+01, 0.6386168663001e+01,
-
-      0.5673725607806e-07, 0.4331187919049e+01, 0.6915859635113e+01,
-      0.4745485060512e-07, 0.5816195745518e+01, 0.6282970628506e+01,
-      0.4745379005326e-07, 0.8323672435672e+00, 0.6283181072386e+01,
-      0.4049002796321e-07, 0.3785023976293e+01, 0.6254626709878e+01,
-      0.4247084014515e-07, 0.2378220728783e+01, 0.7875671926403e+01,
-      0.4026912363055e-07, 0.2864103423269e+01, 0.6311524991013e+01,
-      0.4062935011774e-07, 0.2415408595975e+01, 0.3634620989887e+01,
-      0.5347771048509e-07, 0.3343479309801e+01, 0.2515860172507e+02,
-      0.4829494136505e-07, 0.2821742398262e+01, 0.5760498333002e+01,
-      0.4342554404599e-07, 0.5624662458712e+01, 0.7238675589263e+01,
-
-      0.4021599184361e-07, 0.5557250275009e+00, 0.1101510648075e+02,
-      0.4104900474558e-07, 0.3296691780005e+01, 0.6709674010002e+01,
-      0.4376532905131e-07, 0.3814443999443e+01, 0.6805653367890e+01,
-      0.3314590480650e-07, 0.3560229189250e+01, 0.1259245002418e+02,
-      0.3232421839643e-07, 0.5185389180568e+01, 0.1066495398892e+01,
-      0.3541176318876e-07, 0.3921381909679e+01, 0.9917696840332e+01,
-      0.3689831242681e-07, 0.4190658955386e+01, 0.1192625446156e+02,
-      0.3890605376774e-07, 0.5546023371097e+01, 0.7478166569050e-01,
-      0.3038559339780e-07, 0.6231032794494e+01, 0.1256621883632e+02,
-      0.3137083969782e-07, 0.6207063419190e+01, 0.4292330755499e+01,
-
-      0.4024004081854e-07, 0.1195257375713e+01, 0.1334167431096e+02,
-      0.3300234879283e-07, 0.1804694240998e+01, 0.1057540660594e+02,
-      0.3635399155575e-07, 0.5597811343500e+01, 0.6208294184755e+01,
-      0.3032668691356e-07, 0.3191059366530e+01, 0.1805292951336e+02,
-      0.2809652069058e-07, 0.4094348032570e+01, 0.3523159621801e-02,
-      0.3696955383823e-07, 0.5219282738794e+01, 0.5966683958112e+01,
-      0.3562894142503e-07, 0.1037247544554e+01, 0.6357857516136e+01,
-      0.3510598524148e-07, 0.1430020816116e+01, 0.6599467742779e+01,
-      0.3617736142953e-07, 0.3002911403677e+01, 0.6019991944201e+01,
-      0.2624524910730e-07, 0.2437046757292e+01, 0.6702560555334e+01,
-
-      0.2535824204490e-07, 0.1581594689647e+01, 0.3141537925223e+02,
-      0.3519787226257e-07, 0.5379863121521e+01, 0.2505706758577e+03,
-      0.2578406709982e-07, 0.4904222639329e+01, 0.1673046366289e+02,
-      0.3423887981473e-07, 0.3646448997315e+01, 0.6546159756691e+01,
-      0.2776083886467e-07, 0.3307829300144e+01, 0.1272157198369e+02,
-      0.3379592818379e-07, 0.1747541251125e+01, 0.1494531617769e+02,
-      0.3050255426284e-07, 0.1784689432607e-01, 0.4732030630302e+01,
-      0.2652378350236e-07, 0.4420055276260e+01, 0.5863591145557e+01,
-      0.2374498173768e-07, 0.3629773929208e+01, 0.2388894113936e+01,
-      0.2716451255140e-07, 0.3079623706780e+01, 0.1202934727411e+02,
-
-      0.3038583699229e-07, 0.3312487903507e+00, 0.1256608456547e+02,
-      0.2220681228760e-07, 0.5265520401774e+01, 0.1336244973887e+02,
-      0.3044156540912e-07, 0.4766664081250e+01, 0.2908881142201e+02,
-      0.2731859923561e-07, 0.5069146530691e+01, 0.1391601904066e+02,
-      0.2285603018171e-07, 0.5954935112271e+01, 0.6076890225335e+01,
-      0.2025006454555e-07, 0.4061789589267e+01, 0.4701116388778e+01,
-      0.2012597519804e-07, 0.2485047705241e+01, 0.6262720680387e+01,
-      0.2003406962258e-07, 0.4163779209320e+01, 0.6303431020504e+01,
-      0.2207863441371e-07, 0.6923839133828e+00, 0.6489261475556e+01,
-      0.2481374305624e-07, 0.5944173595676e+01, 0.1204357418345e+02,
-
-      0.2130923288870e-07, 0.4641013671967e+01, 0.5746271423666e+01,
-      0.2446370543391e-07, 0.6125796518757e+01, 0.1495633313810e+00,
-      0.1932492759052e-07, 0.2234572324504e+00, 0.1352175143971e+02,
-      0.2600122568049e-07, 0.4281012405440e+01, 0.4590910121555e+01,
-      0.2431754047488e-07, 0.1429943874870e+00, 0.1162474756779e+01,
-      0.1875902869209e-07, 0.9781803816948e+00, 0.6279194432410e+01,
-      0.1874381139426e-07, 0.5670368130173e+01, 0.6286957268481e+01,
-      0.2156696047173e-07, 0.2008985006833e+01, 0.1813929450232e+02,
-      0.1965076182484e-07, 0.2566186202453e+00, 0.4686889479442e+01,
-      0.2334816372359e-07, 0.4408121891493e+01, 0.1002183730415e+02,
-
-      0.1869937408802e-07, 0.5272745038656e+01, 0.2427287361862e+00,
-      0.2436236460883e-07, 0.4407720479029e+01, 0.9514313292143e+02,
-      0.1761365216611e-07, 0.1943892315074e+00, 0.1351787002167e+02,
-      0.2156289480503e-07, 0.1418570924545e+01, 0.6037244212485e+01,
-      0.2164748979255e-07, 0.4724603439430e+01, 0.2301353951334e+02,
-      0.2222286670853e-07, 0.2400266874598e+01, 0.1266924451345e+02,
-      0.2070901414929e-07, 0.5230348028732e+01, 0.6528907488406e+01,
-      0.1792745177020e-07, 0.2099190328945e+01, 0.6819880277225e+01,
-      0.1841802068445e-07, 0.3467527844848e+00, 0.6514761976723e+02,
-      0.1578401631718e-07, 0.7098642356340e+00, 0.2077542790660e-01,
-
-      0.1561690152531e-07, 0.5943349620372e+01, 0.6272439236156e+01,
-      0.1558591045463e-07, 0.7040653478980e+00, 0.6293712464735e+01,
-      0.1737356469576e-07, 0.4487064760345e+01, 0.1765478049437e+02,
-      0.1434755619991e-07, 0.2993391570995e+01, 0.1102062672231e+00,
-      0.1482187806654e-07, 0.2278049198251e+01, 0.1052268489556e+01,
-      0.1424812827089e-07, 0.1682114725827e+01, 0.1311972100268e+02,
-      0.1380282448623e-07, 0.3262668602579e+01, 0.1017725758696e+02,
-      0.1811481244566e-07, 0.3187771221777e+01, 0.1887552587463e+02,
-      0.1504446185696e-07, 0.5650162308647e+01, 0.7626583626240e-01,
-      0.1740776154137e-07, 0.5487068607507e+01, 0.1965104848470e+02,
-
-      0.1374339536251e-07, 0.5745688172201e+01, 0.6016468784579e+01,
-      0.1761377477704e-07, 0.5748060203659e+01, 0.2593412433514e+02,
-      0.1535138225795e-07, 0.6226848505790e+01, 0.9411464614024e+01,
-      0.1788140543676e-07, 0.6189318878563e+01, 0.3301902111895e+02,
-      0.1375002807996e-07, 0.5371812884394e+01, 0.6327837846670e+00,
-      0.1242115758632e-07, 0.1471687569712e+01, 0.3894181736510e+01,
-      0.1450977333938e-07, 0.4143836662127e+01, 0.1277945078067e+02,
-      0.1297579575023e-07, 0.9003477661957e+00, 0.6549682916313e+01,
-      0.1462667934821e-07, 0.5760505536428e+01, 0.1863592847156e+02,
-      0.1381774374799e-07, 0.1085471729463e+01, 0.2379164476796e+01,
-
-      0.1682333169307e-07, 0.5409870870133e+01, 0.1620077269078e+02,
-      0.1190812918837e-07, 0.1397205174601e+01, 0.1149965630200e+02,
-      0.1221434762106e-07, 0.9001804809095e+00, 0.1257326515556e+02,
-      0.1549934644860e-07, 0.4262528275544e+01, 0.1820933031200e+02,
-      0.1252138953050e-07, 0.1411642012027e+01, 0.6993008899458e+01,
-      0.1237078905387e-07, 0.2844472403615e+01, 0.2435678079171e+02,
-      0.1446953389615e-07, 0.5295835522223e+01, 0.3813291813120e-01,
-      0.1388446457170e-07, 0.4969428135497e+01, 0.2458316379602e+00,
-      0.1019339179228e-07, 0.2491369561806e+01, 0.6112403035119e+01,
-      0.1258880815343e-07, 0.4679426248976e+01, 0.5429879531333e+01,
-
-      0.1297768238261e-07, 0.1074509953328e+01, 0.1249137003520e+02,
-      0.9913505718094e-08, 0.4735097918224e+01, 0.6247047890016e+01,
-      0.9830453155969e-08, 0.4158649187338e+01, 0.6453748665772e+01,
-      0.1192615865309e-07, 0.3438208613699e+01, 0.6290122169689e+01,
-      0.9835874798277e-08, 0.1913300781229e+01, 0.6319103810876e+01,
-      0.9639087569277e-08, 0.9487683644125e+00, 0.8273820945392e+01,
-      0.1175716107001e-07, 0.3228141664287e+01, 0.6276029531202e+01,
-      0.1018926508678e-07, 0.2216607854300e+01, 0.1254537627298e+02,
-      0.9500087869225e-08, 0.2625116459733e+01, 0.1256517118505e+02,
-      0.9664192916575e-08, 0.5860562449214e+01, 0.6259197520765e+01,
-
-      0.9612858712203e-08, 0.7885682917381e+00, 0.6306954180126e+01,
-      0.1117645675413e-07, 0.3932148831189e+01, 0.1779695906178e+02,
-      0.1158864052160e-07, 0.9995605521691e+00, 0.1778273215245e+02,
-      0.9021043467028e-08, 0.5263769742673e+01, 0.6172869583223e+01,
-      0.8836134773563e-08, 0.1496843220365e+01, 0.1692165728891e+01,
-      0.1045872200691e-07, 0.7009039517214e+00, 0.2204125344462e+00,
-      0.1211463487798e-07, 0.4041544938511e+01, 0.8257698122054e+02,
-      0.8541990804094e-08, 0.1447586692316e+01, 0.6393282117669e+01,
-      0.1038720703636e-07, 0.4594249718112e+00, 0.1550861511662e+02,
-      0.1126722351445e-07, 0.3925550579036e+01, 0.2061856251104e+00,
-
-      0.8697373859631e-08, 0.4411341856037e+01, 0.9491756770005e+00,
-      0.8869380028441e-08, 0.2402659724813e+01, 0.3903911373650e+01,
-      0.9247014693258e-08, 0.1401579743423e+01, 0.6267823317922e+01,
-      0.9205062930950e-08, 0.5245978000814e+01, 0.6298328382969e+01,
-      0.8000745038049e-08, 0.3590803356945e+01, 0.2648454860559e+01,
-      0.9168973650819e-08, 0.2470150501679e+01, 0.1498544001348e+03,
-      0.1075444949238e-07, 0.1328606161230e+01, 0.3694923081589e+02,
-      0.7817298525817e-08, 0.6162256225998e+01, 0.4804209201333e+01,
-      0.9541469226356e-08, 0.3942568967039e+01, 0.1256713221673e+02,
-      0.9821910122027e-08, 0.2360246287233e+00, 0.1140367694411e+02,
-
-      0.9897822023777e-08, 0.4619805634280e+01, 0.2280573557157e+02,
-      0.7737289283765e-08, 0.3784727847451e+01, 0.7834121070590e+01,
-      0.9260204034710e-08, 0.2223352487601e+01, 0.2787043132925e+01,
-      0.7320252888486e-08, 0.1288694636874e+01, 0.6282655592598e+01,
-      0.7319785780946e-08, 0.5359869567774e+01, 0.6283496108294e+01,
-      0.7147219933778e-08, 0.5516616675856e+01, 0.1725663147538e+02,
-      0.7946502829878e-08, 0.2630459984567e+01, 0.1241073141809e+02,
-      0.9001711808932e-08, 0.2849815827227e+01, 0.6281591679874e+01,
-      0.8994041507257e-08, 0.3795244450750e+01, 0.6284560021018e+01,
-      0.8298582787358e-08, 0.5236413127363e+00, 0.1241658836951e+02,
-
-      0.8526596520710e-08, 0.4794605424426e+01, 0.1098419223922e+02,
-      0.8209822103197e-08, 0.1578752370328e+01, 0.1096996532989e+02,
-      0.6357049861094e-08, 0.5708926113761e+01, 0.1596186371003e+01,
-      0.7370473179049e-08, 0.3842402530241e+01, 0.4061219149443e+01,
-      0.7232154664726e-08, 0.3067548981535e+01, 0.1610006857377e+03,
-      0.6328765494903e-08, 0.1313930030069e+01, 0.1193336791622e+02,
-      0.8030064908595e-08, 0.3488500408886e+01, 0.8460828644453e+00,
-      0.6275464259232e-08, 0.1532061626198e+01, 0.8531963191132e+00,
-      0.7051897446325e-08, 0.3285859929993e+01, 0.5849364236221e+01,
-      0.6161593705428e-08, 0.1477341999464e+01, 0.5573142801433e+01,
-
-      0.7754683957278e-08, 0.1586118663096e+01, 0.8662240327241e+01,
-      0.5889928990701e-08, 0.1304887868803e+01, 0.1232342296471e+02,
-      0.5705756047075e-08, 0.4555333589350e+01, 0.1258692712880e+02,
-      0.5964178808332e-08, 0.3001762842062e+01, 0.5333900173445e+01,
-      0.6712446027467e-08, 0.4886780007595e+01, 0.1171295538178e+02,
-      0.5941809275464e-08, 0.4701509603824e+01, 0.9779108567966e+01,
-      0.5466993627395e-08, 0.4588357817278e+01, 0.1884211409667e+02,
-      0.6340512090980e-08, 0.1164543038893e+01, 0.5217580628120e+02,
-      0.6325505710045e-08, 0.3919171259645e+01, 0.1041998632314e+02,
-      0.6164789509685e-08, 0.2143828253542e+01, 0.6151533897323e+01,
-
-      0.5263330812430e-08, 0.6066564434241e+01, 0.1885275071096e+02,
-      0.5597087780221e-08, 0.2926316429472e+01, 0.4337116142245e+00,
-      0.5396556236817e-08, 0.3244303591505e+01, 0.6286362197481e+01,
-      0.5396615148223e-08, 0.3404304703662e+01, 0.6279789503410e+01,
-      0.7091832443341e-08, 0.8532377803192e+00, 0.4907302013889e+01,
-      0.6572352589782e-08, 0.4901966774419e+01, 0.1176433076753e+02,
-      0.5960236060795e-08, 0.1874672315797e+01, 0.1422690933580e-01,
-      0.5125480043511e-08, 0.3735726064334e+01, 0.1245594543367e+02,
-      0.5928241866410e-08, 0.4502033899935e+01, 0.6414617803568e+01,
-      0.5249600357424e-08, 0.4372334799878e+01, 0.1151388321134e+02,
-
-      0.6059171276087e-08, 0.2581617302908e+01, 0.6062663316000e+01,
-      0.5295235081662e-08, 0.2974811513158e+01, 0.3496032717521e+01,
-      0.5820561875933e-08, 0.1796073748244e+00, 0.2838593341516e+00,
-      0.4754696606440e-08, 0.1981998136973e+01, 0.3104930017775e+01,
-      0.6385053548955e-08, 0.2559174171605e+00, 0.6133512519065e+01,
-      0.6589828273941e-08, 0.2750967106776e+01, 0.4087944051283e+02,
-      0.5383376567189e-08, 0.6325947523578e+00, 0.2248384854122e+02,
-      0.5928941683538e-08, 0.1672304519067e+01, 0.1581959461667e+01,
-      0.4816060709794e-08, 0.3512566172575e+01, 0.9388005868221e+01,
-      0.6003381586512e-08, 0.5610932219189e+01, 0.5326786718777e+01,
-
-      0.5504225393105e-08, 0.4037501131256e+01, 0.6503488384892e+01,
-      0.5353772620129e-08, 0.6122774968240e+01, 0.1735668374386e+03,
-      0.5786253768544e-08, 0.5527984999515e+01, 0.1350651127443e+00,
-      0.5065706702002e-08, 0.9980765573624e+00, 0.1248988586463e+02,
-      0.5972838885276e-08, 0.6044489493203e+01, 0.2673594526851e+02,
-      0.5323585877961e-08, 0.3924265998147e+01, 0.4171425416666e+01,
-      0.5210772682858e-08, 0.6220111376901e+01, 0.2460261242967e+02,
-      0.4726549040535e-08, 0.3716043206862e+01, 0.7232251527446e+01,
-      0.6029425105059e-08, 0.8548704071116e+00, 0.3227113045244e+03,
-      0.4481542826513e-08, 0.1426925072829e+01, 0.5547199253223e+01,
-
-      0.5836024505068e-08, 0.7135651752625e-01, 0.7285056171570e+02,
-      0.4137046613272e-08, 0.5330767643283e+01, 0.1087398597200e+02,
-      0.5171977473924e-08, 0.4494262335353e+00, 0.1884570439172e+02,
-      0.5694429833732e-08, 0.2952369582215e+01, 0.9723862754494e+02,
-      0.4009158925298e-08, 0.3500003416535e+01, 0.6244942932314e+01,
-      0.4784939596873e-08, 0.6196709413181e+01, 0.2929661536378e+02,
-      0.3983725022610e-08, 0.5103690031897e+01, 0.4274518229222e+01,
-      0.3870535232462e-08, 0.3187569587401e+01, 0.6321208768577e+01,
-      0.5140501213951e-08, 0.1668924357457e+01, 0.1232032006293e+02,
-      0.3849034819355e-08, 0.4445722510309e+01, 0.1726726808967e+02,
-
-      0.4002383075060e-08, 0.5226224152423e+01, 0.7018952447668e+01,
-      0.3890719543549e-08, 0.4371166550274e+01, 0.1491901785440e+02,
-      0.4887084607881e-08, 0.5973556689693e+01, 0.1478866649112e+01,
-      0.3739939287592e-08, 0.2089084714600e+01, 0.6922973089781e+01,
-      0.5031925918209e-08, 0.4658371936827e+01, 0.1715706182245e+02,
-      0.4387748764954e-08, 0.4825580552819e+01, 0.2331413144044e+03,
-      0.4147398098865e-08, 0.3739003524998e+01, 0.1376059875786e+02,
-      0.3719089993586e-08, 0.1148941386536e+01, 0.6297302759782e+01,
-      0.3934238461056e-08, 0.1559893008343e+01, 0.7872148766781e+01,
-      0.3672471375622e-08, 0.5516145383612e+01, 0.6268848941110e+01,
-
-      0.3768911277583e-08, 0.6116053700563e+01, 0.4157198507331e+01,
-      0.4033388417295e-08, 0.5076821746017e+01, 0.1567108171867e+02,
-      0.3764194617832e-08, 0.8164676232075e+00, 0.3185192151914e+01,
-      0.4840628226284e-08, 0.1360479453671e+01, 0.1252801878276e+02,
-      0.4949443923785e-08, 0.2725622229926e+01, 0.1617106187867e+03,
-      0.4117393089971e-08, 0.6054459628492e+00, 0.5642198095270e+01,
-      0.3925754020428e-08, 0.8570462135210e+00, 0.2139354194808e+02,
-      0.3630551757923e-08, 0.3552067338279e+01, 0.6294805223347e+01,
-      0.3627274802357e-08, 0.3096565085313e+01, 0.6271346477544e+01,
-      0.3806143885093e-08, 0.6367751709777e+00, 0.1725304118033e+02,
-
-      0.4433254641565e-08, 0.4848461503937e+01, 0.7445550607224e+01,
-      0.3712319846576e-08, 0.1331950643655e+01, 0.4194847048887e+00,
-      0.3849847534783e-08, 0.4958368297746e+00, 0.9562891316684e+00,
-      0.3483955430165e-08, 0.2237215515707e+01, 0.1161697602389e+02,
-      0.3961912730982e-08, 0.3332402188575e+01, 0.2277943724828e+02,
-      0.3419978244481e-08, 0.5785600576016e+01, 0.1362553364512e+02,
-      0.3329417758177e-08, 0.9812676559709e-01, 0.1685848245639e+02,
-      0.4207206893193e-08, 0.9494780468236e+00, 0.2986433403208e+02,
-      0.3268548976410e-08, 0.1739332095686e+00, 0.5749861718712e+01,
-      0.3321880082685e-08, 0.1423354800666e+01, 0.6279143387820e+01,
-
-      0.4503173010852e-08, 0.2314972675293e+00, 0.1385561574497e+01,
-      0.4316599090954e-08, 0.1012646782616e+00, 0.4176041334900e+01,
-      0.3283493323850e-08, 0.5233306881265e+01, 0.6287008313071e+01,
-      0.3164033542343e-08, 0.4005597257511e+01, 0.2099539292909e+02,
-      0.4159720956725e-08, 0.5365676242020e+01, 0.5905702259363e+01,
-      0.3565176892217e-08, 0.4284440620612e+01, 0.3932462625300e-02,
-      0.3514440950221e-08, 0.4270562636575e+01, 0.7335344340001e+01,
-      0.3540596871909e-08, 0.5953553201060e+01, 0.1234573916645e+02,
-      0.2960769905118e-08, 0.1115180417718e+01, 0.2670964694522e+02,
-      0.2962213739684e-08, 0.3863811918186e+01, 0.6408777551755e+00,
-
-      0.3883556700251e-08, 0.1268617928302e+01, 0.6660449441528e+01,
-      0.2919225516346e-08, 0.4908605223265e+01, 0.1375773836557e+01,
-      0.3115158863370e-08, 0.3744519976885e+01, 0.3802769619140e-01,
-      0.4099438144212e-08, 0.4173244670532e+01, 0.4480965020977e+02,
-      0.2899531858964e-08, 0.5910601428850e+01, 0.2059724391010e+02,
-      0.3289733429855e-08, 0.2488050078239e+01, 0.1081813534213e+02,
-      0.3933075612875e-08, 0.1122363652883e+01, 0.3773735910827e+00,
-      0.3021403764467e-08, 0.4951973724904e+01, 0.2982630633589e+02,
-      0.2798598949757e-08, 0.5117057845513e+01, 0.1937891852345e+02,
-      0.3397421302707e-08, 0.6104159180476e+01, 0.6923953605621e+01,
-
-      0.3720398002179e-08, 0.1184933429829e+01, 0.3066615496545e+02,
-      0.3598484186267e-08, 0.3505282086105e+01, 0.6147450479709e+01,
-      0.3694594027310e-08, 0.2286651088141e+01, 0.2636725487657e+01,
-      0.2680444152969e-08, 0.1871816775482e+00, 0.6816289982179e+01,
-      0.3497574865641e-08, 0.3143251755431e+01, 0.6418701221183e+01,
-      0.3130274129494e-08, 0.2462167316018e+01, 0.1235996607578e+02,
-      0.3241119069551e-08, 0.4256374004686e+01, 0.1652265972112e+02,
-      0.2601960842061e-08, 0.4970362941425e+01, 0.1045450126711e+02,
-      0.2690601527504e-08, 0.2372657824898e+01, 0.3163918923335e+00,
-      0.2908688152664e-08, 0.4232652627721e+01, 0.2828699048865e+02,
-
-      0.3120456131875e-08, 0.3925747001137e+00, 0.2195415756911e+02,
-      0.3148855423384e-08, 0.3093478330445e+01, 0.1172006883645e+02,
-      0.3051044261017e-08, 0.5560948248212e+01, 0.6055599646783e+01,
-      0.2826006876660e-08, 0.5072790310072e+01, 0.5120601093667e+01,
-      0.3100034191711e-08, 0.4998530231096e+01, 0.1799603123222e+02,
-      0.2398771640101e-08, 0.2561739802176e+01, 0.6255674361143e+01,
-      0.2384002842728e-08, 0.4087420284111e+01, 0.6310477339748e+01,
-      0.2842146517568e-08, 0.2515048217955e+01, 0.5469525544182e+01,
-      0.2847674371340e-08, 0.5235326497443e+01, 0.1034429499989e+02,
-      0.2903722140764e-08, 0.1088200795797e+01, 0.6510552054109e+01,
-
-      0.3187610710605e-08, 0.4710624424816e+01, 0.1693792562116e+03,
-      0.3048869992813e-08, 0.2857975896445e+00, 0.8390110365991e+01,
-      0.2860216950984e-08, 0.2241619020815e+01, 0.2243449970715e+00,
-      0.2701117683113e-08, 0.6651573305272e-01, 0.6129297044991e+01,
-      0.2509891590152e-08, 0.1285135324585e+01, 0.1044027435778e+02,
-      0.2623200252223e-08, 0.2981229834530e+00, 0.6436854655901e+01,
-      0.2622541669202e-08, 0.6122470726189e+01, 0.9380959548977e+01,
-      0.2818435667099e-08, 0.4251087148947e+01, 0.5934151399930e+01,
-      0.2365196797465e-08, 0.3465070460790e+01, 0.2470570524223e+02,
-      0.2358704646143e-08, 0.5791603815350e+01, 0.8671969964381e+01,
-
-      0.2388299481390e-08, 0.4142483772941e+01, 0.7096626156709e+01,
-      0.1996041217224e-08, 0.2101901889496e+01, 0.1727188400790e+02,
-      0.2687593060336e-08, 0.1526689456959e+01, 0.7075506709219e+02,
-      0.2618913670810e-08, 0.2397684236095e+01, 0.6632000300961e+01,
-      0.2571523050364e-08, 0.5751929456787e+00, 0.6206810014183e+01,
-      0.2582135006946e-08, 0.5595464352926e+01, 0.4873985990671e+02,
-      0.2372530190361e-08, 0.5092689490655e+01, 0.1590676413561e+02,
-      0.2357178484712e-08, 0.4444363527851e+01, 0.3097883698531e+01,
-      0.2451590394723e-08, 0.3108251687661e+01, 0.6612329252343e+00,
-      0.2370045949608e-08, 0.2608133861079e+01, 0.3459636466239e+02,
-
-      0.2268997267358e-08, 0.3639717753384e+01, 0.2844914056730e-01,
-      0.1731432137906e-08, 0.1741898445707e+00, 0.2019909489111e+02,
-      0.1629869741622e-08, 0.3902225646724e+01, 0.3035599730800e+02,
-      0.2206215801974e-08, 0.4971131250731e+01, 0.6281667977667e+01,
-      0.2205469554680e-08, 0.1677462357110e+01, 0.6284483723224e+01,
-      0.2148792362509e-08, 0.4236259604006e+01, 0.1980482729015e+02,
-      0.1873733657847e-08, 0.5926814998687e+01, 0.2876692439167e+02,
-      0.2026573758959e-08, 0.4349643351962e+01, 0.2449240616245e+02,
-      0.1807770325110e-08, 0.5700940482701e+01, 0.2045286941806e+02,
-      0.1881174408581e-08, 0.6601286363430e+00, 0.2358125818164e+02,
-
-      0.1368023671690e-08, 0.2211098592752e+01, 0.2473415438279e+02,
-      0.1720017916280e-08, 0.4942488551129e+01, 0.1679593901136e+03,
-      0.1702427665131e-08, 0.1452233856386e+01, 0.3338575901272e+03,
-      0.1414032510054e-08, 0.5525357721439e+01, 0.1624205518357e+03,
-      0.1652626045364e-08, 0.4108794283624e+01, 0.8956999012000e+02,
-      0.1642957769686e-08, 0.7344335209984e+00, 0.5267006960365e+02,
-      0.1614952403624e-08, 0.3541213951363e+01, 0.3332657872986e+02,
-      0.1535988291188e-08, 0.4031094072151e+01, 0.3852657435933e+02,
-      0.1593193738177e-08, 0.4185136203609e+01, 0.2282781046519e+03,
-      0.1074569126382e-08, 0.1720485636868e+01, 0.8397383534231e+02,
-
-      0.1074408214509e-08, 0.2758613420318e+01, 0.8401985929482e+02,
-      0.9700199670465e-09, 0.4216686842097e+01, 0.7826370942180e+02,
-      0.1258433517061e-08, 0.2575068876639e+00, 0.3115650189215e+03,
-      0.1240303229539e-08, 0.4800844956756e+00, 0.1784300471910e+03,
-      0.9018345948127e-09, 0.3896756361552e+00, 0.5886454391678e+02,
-      0.1135301432805e-08, 0.3700805023550e+00, 0.7842370451713e+02,
-      0.9215887951370e-09, 0.4364579276638e+01, 0.1014262087719e+03,
-      0.1055401054147e-08, 0.2156564222111e+01, 0.5660027930059e+02,
-      0.1008725979831e-08, 0.5454015785234e+01, 0.4245678405627e+02,
-      0.7217398104321e-09, 0.1597772562175e+01, 0.2457074661053e+03,
-
-      0.6912033134447e-09, 0.5824090621461e+01, 0.1679936946371e+03,
-      0.6833881523549e-09, 0.3578778482835e+01, 0.6053048899753e+02,
-      0.4887304205142e-09, 0.3724362812423e+01, 0.9656299901946e+02,
-      0.5173709754788e-09, 0.5422427507933e+01, 0.2442876000072e+03,
-      0.4671353097145e-09, 0.2396106924439e+01, 0.1435713242844e+03,
-      0.5652608439480e-09, 0.2804028838685e+01, 0.8365903305582e+02,
-      0.5604061331253e-09, 0.1638816006247e+01, 0.8433466158131e+02,
-      0.4712723365400e-09, 0.8979003224474e+00, 0.3164282286739e+03,
-      0.4909967465112e-09, 0.3210426725516e+01, 0.4059982187939e+03,
-      0.4771358267658e-09, 0.5308027211629e+01, 0.1805255418145e+03,
-
-      0.3943451445989e-09, 0.2195145341074e+01, 0.2568537517081e+03,
-      0.3952109120244e-09, 0.5081189491586e+01, 0.2449975330562e+03,
-      0.3788134594789e-09, 0.4345171264441e+01, 0.1568131045107e+03,
-      0.3738330190479e-09, 0.2613062847997e+01, 0.3948519331910e+03,
-      0.3099866678136e-09, 0.2846760817689e+01, 0.1547176098872e+03,
-      0.2002962716768e-09, 0.4921360989412e+01, 0.2268582385539e+03,
-      0.2198291338754e-09, 0.1130360117454e+00, 0.1658638954901e+03,
-      0.1491958330784e-09, 0.4228195232278e+01, 0.2219950288015e+03,
-      0.1475384076173e-09, 0.3005721811604e+00, 0.3052819430710e+03,
-      0.1661626624624e-09, 0.7830125621203e+00, 0.2526661704812e+03,
-
-      0.9015823460025e-10, 0.3807792942715e+01, 0.4171445043968e+03 };
-
-/* Sun-to-Earth, T^0, Y */
-   static const double e0y[] = {
-      0.9998921098898e+00, 0.1826583913846e+00, 0.6283075850446e+01,
-     -0.2442700893735e-01, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.8352929742915e-02, 0.1395277998680e+00, 0.1256615170089e+02,
-      0.1046697300177e-03, 0.9641423109763e-01, 0.1884922755134e+02,
-      0.3110841876663e-04, 0.5381140401712e+01, 0.8399684731857e+02,
-      0.2570269094593e-04, 0.5301016407128e+01, 0.5296909721118e+00,
-      0.2147389623610e-04, 0.2662510869850e+01, 0.1577343543434e+01,
-      0.1680344384050e-04, 0.5207904119704e+01, 0.6279552690824e+01,
-      0.1679117312193e-04, 0.4582187486968e+01, 0.6286599010068e+01,
-      0.1440512068440e-04, 0.1900688517726e+01, 0.2352866153506e+01,
-
-      0.1135139664999e-04, 0.5273108538556e+01, 0.5223693906222e+01,
-      0.9345482571018e-05, 0.4503047687738e+01, 0.1203646072878e+02,
-      0.9007418719568e-05, 0.1605621059637e+01, 0.1021328554739e+02,
-      0.5671536712314e-05, 0.5812849070861e+00, 0.1059381944224e+01,
-      0.7451401861666e-05, 0.2807346794836e+01, 0.3981490189893e+00,
-      0.6393470057114e-05, 0.6029224133855e+01, 0.5753384878334e+01,
-      0.6814275881697e-05, 0.6472990145974e+00, 0.4705732307012e+01,
-      0.6113705628887e-05, 0.3813843419700e+01, 0.6812766822558e+01,
-      0.4503851367273e-05, 0.4527804370996e+01, 0.5884926831456e+01,
-      0.4522249141926e-05, 0.5991783029224e+01, 0.6256777527156e+01,
-
-      0.4501794307018e-05, 0.3798703844397e+01, 0.6309374173736e+01,
-      0.5514927480180e-05, 0.3961257833388e+01, 0.5507553240374e+01,
-      0.4062862799995e-05, 0.5256247296369e+01, 0.6681224869435e+01,
-      0.5414900429712e-05, 0.5499032014097e+01, 0.7755226100720e+00,
-      0.5463153987424e-05, 0.6173092454097e+01, 0.1414349524433e+02,
-      0.5071611859329e-05, 0.2870244247651e+01, 0.7860419393880e+01,
-      0.2195112094455e-05, 0.2952338617201e+01, 0.1150676975667e+02,
-      0.2279139233919e-05, 0.5951775132933e+01, 0.7058598460518e+01,
-      0.2278386100876e-05, 0.4845456398785e+01, 0.4694002934110e+01,
-      0.2559088003308e-05, 0.6945321117311e+00, 0.1216800268190e+02,
-
-      0.2561079286856e-05, 0.6167224608301e+01, 0.7099330490126e+00,
-      0.1792755796387e-05, 0.1400122509632e+01, 0.7962980379786e+00,
-      0.1818715656502e-05, 0.4703347611830e+01, 0.6283142985870e+01,
-      0.1818744924791e-05, 0.5086748900237e+01, 0.6283008715021e+01,
-      0.1554518791390e-05, 0.5331008042713e-01, 0.2513230340178e+02,
-      0.2063265737239e-05, 0.4283680484178e+01, 0.1179062909082e+02,
-      0.1497613520041e-05, 0.6074207826073e+01, 0.5486777812467e+01,
-      0.2000617940427e-05, 0.2501426281450e+01, 0.1778984560711e+02,
-      0.1289731195580e-05, 0.3646340599536e+01, 0.7079373888424e+01,
-      0.1282657998934e-05, 0.3232864804902e+01, 0.3738761453707e+01,
-
-      0.1528915968658e-05, 0.5581433416669e+01, 0.2132990797783e+00,
-      0.1187304098432e-05, 0.5453576453694e+01, 0.9437762937313e+01,
-      0.7842782928118e-06, 0.2823953922273e+00, 0.8827390247185e+01,
-      0.7352892280868e-06, 0.1124369580175e+01, 0.1589072916335e+01,
-      0.6570189360797e-06, 0.2089154042840e+01, 0.1176985366291e+02,
-      0.6324967590410e-06, 0.6704855581230e+00, 0.6262300422539e+01,
-      0.6298289872283e-06, 0.2836414855840e+01, 0.6303851278352e+01,
-      0.6476686465855e-06, 0.4852433866467e+00, 0.7113454667900e-02,
-      0.8587034651234e-06, 0.1453511005668e+01, 0.1672837615881e+03,
-      0.8068948788113e-06, 0.9224087798609e+00, 0.6069776770667e+01,
-
-      0.8353786011661e-06, 0.4631707184895e+01, 0.3340612434717e+01,
-      0.6009324532132e-06, 0.1829498827726e+01, 0.4136910472696e+01,
-      0.7558158559566e-06, 0.2588596800317e+01, 0.6496374930224e+01,
-      0.5809279504503e-06, 0.5516818853476e+00, 0.1097707878456e+02,
-      0.5374131950254e-06, 0.6275674734960e+01, 0.1194447056968e+01,
-      0.5711160507326e-06, 0.1091905956872e+01, 0.6282095334605e+01,
-      0.5710183170746e-06, 0.2415001635090e+01, 0.6284056366286e+01,
-      0.5144373590610e-06, 0.6020336443438e+01, 0.6290189305114e+01,
-      0.5103108927267e-06, 0.3775634564605e+01, 0.6275962395778e+01,
-      0.4960654697891e-06, 0.1073450946756e+01, 0.6127655567643e+01,
-
-      0.4786385689280e-06, 0.2431178012310e+01, 0.6438496133249e+01,
-      0.6109911263665e-06, 0.5343356157914e+01, 0.3154687086868e+01,
-      0.4839898944024e-06, 0.5830833594047e-01, 0.8018209333619e+00,
-      0.4734822623919e-06, 0.4536080134821e+01, 0.3128388763578e+01,
-      0.4834741473290e-06, 0.2585090489754e+00, 0.7084896783808e+01,
-      0.5134858581156e-06, 0.4213317172603e+01, 0.1235285262111e+02,
-      0.5064004264978e-06, 0.4814418806478e+00, 0.1185621865188e+02,
-      0.3753476772761e-06, 0.1599953399788e+01, 0.8429241228195e+01,
-      0.4935264014283e-06, 0.2157417556873e+01, 0.2544314396739e+01,
-      0.3950929600897e-06, 0.3359394184254e+01, 0.5481254917084e+01,
-
-      0.4895849789777e-06, 0.5165704376558e+01, 0.9225539266174e+01,
-      0.4215241688886e-06, 0.2065368800993e+01, 0.1726015463500e+02,
-      0.3796773731132e-06, 0.1468606346612e+01, 0.4265981595566e+00,
-      0.3114178142515e-06, 0.3615638079474e+01, 0.2146165377750e+01,
-      0.3260664220838e-06, 0.4417134922435e+01, 0.4164311961999e+01,
-      0.3976996123008e-06, 0.4700866883004e+01, 0.5856477690889e+01,
-      0.2801459672924e-06, 0.4538902060922e+01, 0.1256967486051e+02,
-      0.3638931868861e-06, 0.1334197991475e+01, 0.1807370494127e+02,
-      0.2487013269476e-06, 0.3749275558275e+01, 0.2629832328990e-01,
-      0.3034165481994e-06, 0.4236622030873e+00, 0.4535059491685e+01,
-
-      0.2676278825586e-06, 0.5970848007811e+01, 0.3930209696940e+01,
-      0.2764903818918e-06, 0.5194636754501e+01, 0.1256262854127e+02,
-      0.2485149930507e-06, 0.1002434207846e+01, 0.5088628793478e+01,
-      0.2199305540941e-06, 0.3066773098403e+01, 0.1255903824622e+02,
-      0.2571106500435e-06, 0.7588312459063e+00, 0.1336797263425e+02,
-      0.2049751817158e-06, 0.3444977434856e+01, 0.1137170464392e+02,
-      0.2599707296297e-06, 0.1873128542205e+01, 0.7143069561767e+02,
-      0.1785018072217e-06, 0.5015891306615e+01, 0.1748016358760e+01,
-      0.2324833891115e-06, 0.4618271239730e+01, 0.1831953657923e+02,
-      0.1709711119545e-06, 0.5300003455669e+01, 0.4933208510675e+01,
-
-      0.2107159351716e-06, 0.2229819815115e+01, 0.7477522907414e+01,
-      0.1750333080295e-06, 0.6161485880008e+01, 0.1044738781244e+02,
-      0.2000598210339e-06, 0.2967357299999e+01, 0.8031092209206e+01,
-      0.1380920248681e-06, 0.3027007923917e+01, 0.8635942003952e+01,
-      0.1412460470299e-06, 0.6037597163798e+01, 0.2942463415728e+01,
-      0.1888459803001e-06, 0.8561476243374e+00, 0.1561374759853e+03,
-      0.1788370542585e-06, 0.4869736290209e+01, 0.1592596075957e+01,
-      0.1360893296167e-06, 0.3626411886436e+01, 0.1309584267300e+02,
-      0.1506846530160e-06, 0.1550975377427e+01, 0.1649636139783e+02,
-      0.1800913376176e-06, 0.2075826033190e+01, 0.1729818233119e+02,
-
-      0.1436261390649e-06, 0.6148876420255e+01, 0.2042657109477e+02,
-      0.1220227114151e-06, 0.4382583879906e+01, 0.7632943190217e+01,
-      0.1337883603592e-06, 0.2036644327361e+01, 0.1213955354133e+02,
-      0.1159326650738e-06, 0.3892276994687e+01, 0.5331357529664e+01,
-      0.1352853128569e-06, 0.1447950649744e+01, 0.1673046366289e+02,
-      0.1433408296083e-06, 0.4457854692961e+01, 0.7342457794669e+01,
-      0.1234701666518e-06, 0.1538818147151e+01, 0.6279485555400e+01,
-      0.1234027192007e-06, 0.1968523220760e+01, 0.6286666145492e+01,
-      0.1244024091797e-06, 0.5779803499985e+01, 0.1511046609763e+02,
-      0.1097934945516e-06, 0.6210975221388e+00, 0.1098880815746e+02,
-
-      0.1254611329856e-06, 0.2591963807998e+01, 0.1572083878776e+02,
-      0.1158247286784e-06, 0.2483612812670e+01, 0.5729506548653e+01,
-      0.9039078252960e-07, 0.3857554579796e+01, 0.9623688285163e+01,
-      0.9108024978836e-07, 0.5826368512984e+01, 0.7234794171227e+01,
-      0.8887068108436e-07, 0.3475694573987e+01, 0.6148010737701e+01,
-      0.8632374035438e-07, 0.3059070488983e-01, 0.6418140963190e+01,
-      0.7893186992967e-07, 0.1583194837728e+01, 0.2118763888447e+01,
-      0.8297650201172e-07, 0.8519770534637e+00, 0.1471231707864e+02,
-      0.1019759578988e-06, 0.1319598738732e+00, 0.1349867339771e+01,
-      0.1010037696236e-06, 0.9937860115618e+00, 0.6836645152238e+01,
-
-      0.1047727548266e-06, 0.1382138405399e+01, 0.5999216516294e+01,
-      0.7351993881086e-07, 0.3833397851735e+01, 0.6040347114260e+01,
-      0.9868771092341e-07, 0.2124913814390e+01, 0.6566935184597e+01,
-      0.7007321959390e-07, 0.5946305343763e+01, 0.6525804586632e+01,
-      0.6861411679709e-07, 0.4574654977089e+01, 0.7238675589263e+01,
-      0.7554519809614e-07, 0.5949232686844e+01, 0.1253985337760e+02,
-      0.9541880448335e-07, 0.3495242990564e+01, 0.2122839202813e+02,
-      0.7185606722155e-07, 0.4310113471661e+01, 0.6245048154254e+01,
-      0.7131360871710e-07, 0.5480309323650e+01, 0.6321103546637e+01,
-      0.6651142021039e-07, 0.5411097713654e+01, 0.5327476111629e+01,
-
-      0.8538618213667e-07, 0.1827849973951e+01, 0.1101510648075e+02,
-      0.8634954288044e-07, 0.5443584943349e+01, 0.5643178611111e+01,
-      0.7449415051484e-07, 0.2011535459060e+01, 0.5368044267797e+00,
-      0.7421047599169e-07, 0.3464562529249e+01, 0.2354323048545e+02,
-      0.6140694354424e-07, 0.5657556228815e+01, 0.1296430071988e+02,
-      0.6353525143033e-07, 0.3463816593821e+01, 0.1990745094947e+01,
-      0.6221964013447e-07, 0.1532259498697e+01, 0.9517183207817e+00,
-      0.5852480257244e-07, 0.1375396598875e+01, 0.9555997388169e+00,
-      0.6398637498911e-07, 0.2405645801972e+01, 0.2407292145756e+02,
-      0.7039744069878e-07, 0.5397541799027e+01, 0.5225775174439e+00,
-
-      0.6977997694382e-07, 0.4762347105419e+01, 0.1097355562493e+02,
-      0.7460629558396e-07, 0.2711944692164e+01, 0.2200391463820e+02,
-      0.5376577536101e-07, 0.2352980430239e+01, 0.1431416805965e+02,
-      0.7530607893556e-07, 0.1943940180699e+01, 0.1842262939178e+02,
-      0.6822928971605e-07, 0.4337651846959e+01, 0.1554202828031e+00,
-      0.6220772380094e-07, 0.6716871369278e+00, 0.1845107853235e+02,
-      0.6586950799043e-07, 0.2229714460505e+01, 0.5216580451554e+01,
-      0.5873800565771e-07, 0.7627013920580e+00, 0.6398972393349e+00,
-      0.6264346929745e-07, 0.6202785478961e+00, 0.6277552955062e+01,
-      0.6257929115669e-07, 0.2886775596668e+01, 0.6288598745829e+01,
-
-      0.5343536033409e-07, 0.1977241012051e+01, 0.4690479774488e+01,
-      0.5587849781714e-07, 0.1922923484825e+01, 0.1551045220144e+01,
-      0.6905100845603e-07, 0.3570757164631e+01, 0.1030928125552e+00,
-      0.6178957066649e-07, 0.5197558947765e+01, 0.5230807360890e+01,
-      0.6187270224331e-07, 0.8193497368922e+00, 0.5650292065779e+01,
-      0.5385664291426e-07, 0.5406336665586e+01, 0.7771377146812e+02,
-      0.6329363917926e-07, 0.2837760654536e+01, 0.2608790314060e+02,
-      0.4546018761604e-07, 0.2933580297050e+01, 0.5535693017924e+00,
-      0.6196091049375e-07, 0.4157871494377e+01, 0.8467247584405e+02,
-      0.6159555108218e-07, 0.3211703561703e+01, 0.2394243902548e+03,
-
-      0.4995340539317e-07, 0.1459098102922e+01, 0.4732030630302e+01,
-      0.5457031243572e-07, 0.1430457676136e+01, 0.6179983037890e+01,
-      0.4863461418397e-07, 0.2196425916730e+01, 0.9027992316901e+02,
-      0.5342947626870e-07, 0.2086612890268e+01, 0.6386168663001e+01,
-      0.5674296648439e-07, 0.2760204966535e+01, 0.6915859635113e+01,
-      0.4745783120161e-07, 0.4245368971862e+01, 0.6282970628506e+01,
-      0.4745676961198e-07, 0.5544725787016e+01, 0.6283181072386e+01,
-      0.4049796869973e-07, 0.2213984363586e+01, 0.6254626709878e+01,
-      0.4248333596940e-07, 0.8075781952896e+00, 0.7875671926403e+01,
-      0.4027178070205e-07, 0.1293268540378e+01, 0.6311524991013e+01,
-
-      0.4066543943476e-07, 0.3986141175804e+01, 0.3634620989887e+01,
-      0.4858863787880e-07, 0.1276112738231e+01, 0.5760498333002e+01,
-      0.5277398263530e-07, 0.4916111741527e+01, 0.2515860172507e+02,
-      0.4105635656559e-07, 0.1725805864426e+01, 0.6709674010002e+01,
-      0.4376781925772e-07, 0.2243642442106e+01, 0.6805653367890e+01,
-      0.3235827894693e-07, 0.3614135118271e+01, 0.1066495398892e+01,
-      0.3073244740308e-07, 0.2460873393460e+01, 0.5863591145557e+01,
-      0.3088609271373e-07, 0.5678431771790e+01, 0.9917696840332e+01,
-      0.3393022279836e-07, 0.3814017477291e+01, 0.1391601904066e+02,
-      0.3038686508802e-07, 0.4660216229171e+01, 0.1256621883632e+02,
-
-      0.4019677752497e-07, 0.5906906243735e+01, 0.1334167431096e+02,
-      0.3288834998232e-07, 0.9536146445882e+00, 0.1620077269078e+02,
-      0.3889973794631e-07, 0.3942205097644e+01, 0.7478166569050e-01,
-      0.3050438987141e-07, 0.1624810271286e+01, 0.1805292951336e+02,
-      0.3601142564638e-07, 0.4030467142575e+01, 0.6208294184755e+01,
-      0.3689015557141e-07, 0.3648878818694e+01, 0.5966683958112e+01,
-      0.3563471893565e-07, 0.5749584017096e+01, 0.6357857516136e+01,
-      0.2776183170667e-07, 0.2630124187070e+01, 0.3523159621801e-02,
-      0.2922350530341e-07, 0.1790346403629e+01, 0.1272157198369e+02,
-      0.3511076917302e-07, 0.6142198301611e+01, 0.6599467742779e+01,
-
-      0.3619351007632e-07, 0.1432421386492e+01, 0.6019991944201e+01,
-      0.2561254711098e-07, 0.2302822475792e+01, 0.1259245002418e+02,
-      0.2626903942920e-07, 0.8660470994571e+00, 0.6702560555334e+01,
-      0.2550187397083e-07, 0.6069721995383e+01, 0.1057540660594e+02,
-      0.2535873526138e-07, 0.1079020331795e-01, 0.3141537925223e+02,
-      0.3519786153847e-07, 0.3809066902283e+01, 0.2505706758577e+03,
-      0.3424651492873e-07, 0.2075435114417e+01, 0.6546159756691e+01,
-      0.2372676630861e-07, 0.2057803120154e+01, 0.2388894113936e+01,
-      0.2710980779541e-07, 0.1510068488010e+01, 0.1202934727411e+02,
-      0.3038710889704e-07, 0.5043617528901e+01, 0.1256608456547e+02,
-
-      0.2220364130585e-07, 0.3694793218205e+01, 0.1336244973887e+02,
-      0.3025880825460e-07, 0.5450618999049e-01, 0.2908881142201e+02,
-      0.2784493486864e-07, 0.3381164084502e+01, 0.1494531617769e+02,
-      0.2294414142438e-07, 0.4382309025210e+01, 0.6076890225335e+01,
-      0.2012723294724e-07, 0.9142212256518e+00, 0.6262720680387e+01,
-      0.2036357831958e-07, 0.5676172293154e+01, 0.4701116388778e+01,
-      0.2003474823288e-07, 0.2592767977625e+01, 0.6303431020504e+01,
-      0.2207144900109e-07, 0.5404976271180e+01, 0.6489261475556e+01,
-      0.2481664905135e-07, 0.4373284587027e+01, 0.1204357418345e+02,
-      0.2674949182295e-07, 0.5859182188482e+01, 0.4590910121555e+01,
-
-      0.2450554720322e-07, 0.4555381557451e+01, 0.1495633313810e+00,
-      0.2601975986457e-07, 0.3933165584959e+01, 0.1965104848470e+02,
-      0.2199860022848e-07, 0.5227977189087e+01, 0.1351787002167e+02,
-      0.2448121172316e-07, 0.4858060353949e+01, 0.1162474756779e+01,
-      0.1876014864049e-07, 0.5690546553605e+01, 0.6279194432410e+01,
-      0.1874513219396e-07, 0.4099539297446e+01, 0.6286957268481e+01,
-      0.2156380842559e-07, 0.4382594769913e+00, 0.1813929450232e+02,
-      0.1981691240061e-07, 0.1829784152444e+01, 0.4686889479442e+01,
-      0.2329992648539e-07, 0.2836254278973e+01, 0.1002183730415e+02,
-      0.1765184135302e-07, 0.2803494925833e+01, 0.4292330755499e+01,
-
-      0.2436368366085e-07, 0.2836897959677e+01, 0.9514313292143e+02,
-      0.2164089203889e-07, 0.6127522446024e+01, 0.6037244212485e+01,
-      0.1847755034221e-07, 0.3683163635008e+01, 0.2427287361862e+00,
-      0.1674798769966e-07, 0.3316993867246e+00, 0.1311972100268e+02,
-      0.2222542124356e-07, 0.8294097805480e+00, 0.1266924451345e+02,
-      0.2071074505925e-07, 0.3659492220261e+01, 0.6528907488406e+01,
-      0.1608224471835e-07, 0.4774492067182e+01, 0.1352175143971e+02,
-      0.1857583439071e-07, 0.2873120597682e+01, 0.8662240327241e+01,
-      0.1793018836159e-07, 0.5282441177929e+00, 0.6819880277225e+01,
-      0.1575391221692e-07, 0.1320789654258e+01, 0.1102062672231e+00,
-
-      0.1840132009557e-07, 0.1917110916256e+01, 0.6514761976723e+02,
-      0.1760917288281e-07, 0.2972635937132e+01, 0.5746271423666e+01,
-      0.1561779518516e-07, 0.4372569261981e+01, 0.6272439236156e+01,
-      0.1558687885205e-07, 0.5416424926425e+01, 0.6293712464735e+01,
-      0.1951359382579e-07, 0.3094448898752e+01, 0.2301353951334e+02,
-      0.1569144275614e-07, 0.2802103689808e+01, 0.1765478049437e+02,
-      0.1479130389462e-07, 0.2136435020467e+01, 0.2077542790660e-01,
-      0.1467828510764e-07, 0.7072627435674e+00, 0.1052268489556e+01,
-      0.1627627337440e-07, 0.3947607143237e+01, 0.6327837846670e+00,
-      0.1503498479758e-07, 0.4079248909190e+01, 0.7626583626240e-01,
-
-      0.1297967708237e-07, 0.6269637122840e+01, 0.1149965630200e+02,
-      0.1374416896634e-07, 0.4175657970702e+01, 0.6016468784579e+01,
-      0.1783812325219e-07, 0.1476540547560e+01, 0.3301902111895e+02,
-      0.1525884228756e-07, 0.4653477715241e+01, 0.9411464614024e+01,
-      0.1451067396763e-07, 0.2573001128225e+01, 0.1277945078067e+02,
-      0.1297713111950e-07, 0.5612799618771e+01, 0.6549682916313e+01,
-      0.1462784012820e-07, 0.4189661623870e+01, 0.1863592847156e+02,
-      0.1384185980007e-07, 0.2656915472196e+01, 0.2379164476796e+01,
-      0.1221497599801e-07, 0.5612515760138e+01, 0.1257326515556e+02,
-      0.1560574525896e-07, 0.4783414317919e+01, 0.1887552587463e+02,
-
-      0.1544598372036e-07, 0.2694431138063e+01, 0.1820933031200e+02,
-      0.1531678928696e-07, 0.4105103489666e+01, 0.2593412433514e+02,
-      0.1349321503795e-07, 0.3082437194015e+00, 0.5120601093667e+01,
-      0.1252030290917e-07, 0.6124072334087e+01, 0.6993008899458e+01,
-      0.1459243816687e-07, 0.3733103981697e+01, 0.3813291813120e-01,
-      0.1226103625262e-07, 0.1267127706817e+01, 0.2435678079171e+02,
-      0.1019449641504e-07, 0.4367790112269e+01, 0.1725663147538e+02,
-      0.1380789433607e-07, 0.3387201768700e+01, 0.2458316379602e+00,
-      0.1019453421658e-07, 0.9204143073737e+00, 0.6112403035119e+01,
-      0.1297929434405e-07, 0.5786874896426e+01, 0.1249137003520e+02,
-
-      0.9912677786097e-08, 0.3164232870746e+01, 0.6247047890016e+01,
-      0.9829386098599e-08, 0.2586762413351e+01, 0.6453748665772e+01,
-      0.1226807746104e-07, 0.6239068436607e+01, 0.5429879531333e+01,
-      0.1192691755997e-07, 0.1867380051424e+01, 0.6290122169689e+01,
-      0.9836499227081e-08, 0.3424716293727e+00, 0.6319103810876e+01,
-      0.9642862564285e-08, 0.5661372990657e+01, 0.8273820945392e+01,
-      0.1165184404862e-07, 0.5768367239093e+01, 0.1778273215245e+02,
-      0.1175794418818e-07, 0.1657351222943e+01, 0.6276029531202e+01,
-      0.1018948635601e-07, 0.6458292350865e+00, 0.1254537627298e+02,
-      0.9500383606676e-08, 0.1054306140741e+01, 0.1256517118505e+02,
-
-      0.1227512202906e-07, 0.2505278379114e+01, 0.2248384854122e+02,
-      0.9664792009993e-08, 0.4289737277000e+01, 0.6259197520765e+01,
-      0.9613285666331e-08, 0.5500597673141e+01, 0.6306954180126e+01,
-      0.1117906736211e-07, 0.2361405953468e+01, 0.1779695906178e+02,
-      0.9611378640782e-08, 0.2851310576269e+01, 0.2061856251104e+00,
-      0.8845354852370e-08, 0.6208777705343e+01, 0.1692165728891e+01,
-      0.1054046966600e-07, 0.5413091423934e+01, 0.2204125344462e+00,
-      0.1215539124483e-07, 0.5613969479755e+01, 0.8257698122054e+02,
-      0.9932460955209e-08, 0.1106124877015e+01, 0.1017725758696e+02,
-      0.8785804715043e-08, 0.2869224476477e+01, 0.9491756770005e+00,
-
-      0.8538084097562e-08, 0.6159640899344e+01, 0.6393282117669e+01,
-      0.8648994369529e-08, 0.1374901198784e+01, 0.4804209201333e+01,
-      0.1039063219067e-07, 0.5171080641327e+01, 0.1550861511662e+02,
-      0.8867983926439e-08, 0.8317320304902e+00, 0.3903911373650e+01,
-      0.8327495955244e-08, 0.3605591969180e+01, 0.6172869583223e+01,
-      0.9243088356133e-08, 0.6114299196843e+01, 0.6267823317922e+01,
-      0.9205657357835e-08, 0.3675153683737e+01, 0.6298328382969e+01,
-      0.1033269714606e-07, 0.3313328813024e+01, 0.5573142801433e+01,
-      0.8001706275552e-08, 0.2019980960053e+01, 0.2648454860559e+01,
-      0.9171858254191e-08, 0.8992015524177e+00, 0.1498544001348e+03,
-
-      0.1075327150242e-07, 0.2898669963648e+01, 0.3694923081589e+02,
-      0.9884866689828e-08, 0.4946715904478e+01, 0.1140367694411e+02,
-      0.9541835576677e-08, 0.2371787888469e+01, 0.1256713221673e+02,
-      0.7739903376237e-08, 0.2213775190612e+01, 0.7834121070590e+01,
-      0.7311962684106e-08, 0.3429378787739e+01, 0.1192625446156e+02,
-      0.9724904869624e-08, 0.6195878564404e+01, 0.2280573557157e+02,
-      0.9251628983612e-08, 0.6511509527390e+00, 0.2787043132925e+01,
-      0.7320763787842e-08, 0.6001083639421e+01, 0.6282655592598e+01,
-      0.7320296650962e-08, 0.3789073265087e+01, 0.6283496108294e+01,
-      0.7947032271039e-08, 0.1059659582204e+01, 0.1241073141809e+02,
-
-      0.9005277053115e-08, 0.1280315624361e+01, 0.6281591679874e+01,
-      0.8995601652048e-08, 0.2224439106766e+01, 0.6284560021018e+01,
-      0.8288040568796e-08, 0.5234914433867e+01, 0.1241658836951e+02,
-      0.6359381347255e-08, 0.4137989441490e+01, 0.1596186371003e+01,
-      0.8699572228626e-08, 0.1758411009497e+01, 0.6133512519065e+01,
-      0.6456797542736e-08, 0.5919285089994e+01, 0.1685848245639e+02,
-      0.7424573475452e-08, 0.5414616938827e+01, 0.4061219149443e+01,
-      0.7235671196168e-08, 0.1496516557134e+01, 0.1610006857377e+03,
-      0.8104015182733e-08, 0.1919918242764e+01, 0.8460828644453e+00,
-      0.8098576535937e-08, 0.3819615855458e+01, 0.3894181736510e+01,
-
-      0.6275292346625e-08, 0.6244264115141e+01, 0.8531963191132e+00,
-      0.6052432989112e-08, 0.5037731872610e+00, 0.1567108171867e+02,
-      0.5705651535817e-08, 0.2984557271995e+01, 0.1258692712880e+02,
-      0.5789650115138e-08, 0.6087038140697e+01, 0.1193336791622e+02,
-      0.5512132153377e-08, 0.5855668994076e+01, 0.1232342296471e+02,
-      0.7388890819102e-08, 0.2443128574740e+01, 0.4907302013889e+01,
-      0.5467593991798e-08, 0.3017561234194e+01, 0.1884211409667e+02,
-      0.6388519802999e-08, 0.5887386712935e+01, 0.5217580628120e+02,
-      0.6106777149944e-08, 0.3483461059895e+00, 0.1422690933580e-01,
-      0.7383420275489e-08, 0.5417387056707e+01, 0.2358125818164e+02,
-
-      0.5505208141738e-08, 0.2848193644783e+01, 0.1151388321134e+02,
-      0.6310757462877e-08, 0.2349882520828e+01, 0.1041998632314e+02,
-      0.6166904929691e-08, 0.5728575944077e+00, 0.6151533897323e+01,
-      0.5263442042754e-08, 0.4495796125937e+01, 0.1885275071096e+02,
-      0.5591828082629e-08, 0.1355441967677e+01, 0.4337116142245e+00,
-      0.5397051680497e-08, 0.1673422864307e+01, 0.6286362197481e+01,
-      0.5396992745159e-08, 0.1833502206373e+01, 0.6279789503410e+01,
-      0.6572913000726e-08, 0.3331122065824e+01, 0.1176433076753e+02,
-      0.5123421866413e-08, 0.2165327142679e+01, 0.1245594543367e+02,
-      0.5930495725999e-08, 0.2931146089284e+01, 0.6414617803568e+01,
-
-      0.6431797403933e-08, 0.4134407994088e+01, 0.1350651127443e+00,
-      0.5003182207604e-08, 0.3805420303749e+01, 0.1096996532989e+02,
-      0.5587731032504e-08, 0.1082469260599e+01, 0.6062663316000e+01,
-      0.5935263407816e-08, 0.8384333678401e+00, 0.5326786718777e+01,
-      0.4756019827760e-08, 0.3552588749309e+01, 0.3104930017775e+01,
-      0.6599951172637e-08, 0.4320826409528e+01, 0.4087944051283e+02,
-      0.5902606868464e-08, 0.4811879454445e+01, 0.5849364236221e+01,
-      0.5921147809031e-08, 0.9942628922396e-01, 0.1581959461667e+01,
-      0.5505382581266e-08, 0.2466557607764e+01, 0.6503488384892e+01,
-      0.5353771071862e-08, 0.4551978748683e+01, 0.1735668374386e+03,
-
-      0.5063282210946e-08, 0.5710812312425e+01, 0.1248988586463e+02,
-      0.5926120403383e-08, 0.1333998428358e+01, 0.2673594526851e+02,
-      0.5211016176149e-08, 0.4649315360760e+01, 0.2460261242967e+02,
-      0.5347075084894e-08, 0.5512754081205e+01, 0.4171425416666e+01,
-      0.4872609773574e-08, 0.1308025299938e+01, 0.5333900173445e+01,
-      0.4727711321420e-08, 0.2144908368062e+01, 0.7232251527446e+01,
-      0.6029426018652e-08, 0.5567259412084e+01, 0.3227113045244e+03,
-      0.4321485284369e-08, 0.5230667156451e+01, 0.9388005868221e+01,
-      0.4476406760553e-08, 0.6134081115303e+01, 0.5547199253223e+01,
-      0.5835268277420e-08, 0.4783808492071e+01, 0.7285056171570e+02,
-
-      0.5172183602748e-08, 0.5161817911099e+01, 0.1884570439172e+02,
-      0.5693571465184e-08, 0.1381646203111e+01, 0.9723862754494e+02,
-      0.4060634965349e-08, 0.3876705259495e+00, 0.4274518229222e+01,
-      0.3967398770473e-08, 0.5029491776223e+01, 0.3496032717521e+01,
-      0.3943754005255e-08, 0.1923162955490e+01, 0.6244942932314e+01,
-      0.4781323427824e-08, 0.4633332586423e+01, 0.2929661536378e+02,
-      0.3871483781204e-08, 0.1616650009743e+01, 0.6321208768577e+01,
-      0.5141741733997e-08, 0.9817316704659e-01, 0.1232032006293e+02,
-      0.4002385978497e-08, 0.3656161212139e+01, 0.7018952447668e+01,
-      0.4901092604097e-08, 0.4404098713092e+01, 0.1478866649112e+01,
-
-      0.3740932630345e-08, 0.5181188732639e+00, 0.6922973089781e+01,
-      0.4387283718538e-08, 0.3254859566869e+01, 0.2331413144044e+03,
-      0.5019197802033e-08, 0.3086773224677e+01, 0.1715706182245e+02,
-      0.3834931695175e-08, 0.2797882673542e+01, 0.1491901785440e+02,
-      0.3760413942497e-08, 0.2892676280217e+01, 0.1726726808967e+02,
-      0.3719717204628e-08, 0.5861046025739e+01, 0.6297302759782e+01,
-      0.4145623530149e-08, 0.2168239627033e+01, 0.1376059875786e+02,
-      0.3932788425380e-08, 0.6271811124181e+01, 0.7872148766781e+01,
-      0.3686377476857e-08, 0.3936853151404e+01, 0.6268848941110e+01,
-      0.3779077950339e-08, 0.1404148734043e+01, 0.4157198507331e+01,
-
-      0.4091334550598e-08, 0.2452436180854e+01, 0.9779108567966e+01,
-      0.3926694536146e-08, 0.6102292739040e+01, 0.1098419223922e+02,
-      0.4841000253289e-08, 0.6072760457276e+01, 0.1252801878276e+02,
-      0.4949340130240e-08, 0.1154832815171e+01, 0.1617106187867e+03,
-      0.3761557737360e-08, 0.5527545321897e+01, 0.3185192151914e+01,
-      0.3647396268188e-08, 0.1525035688629e+01, 0.6271346477544e+01,
-      0.3932405074189e-08, 0.5570681040569e+01, 0.2139354194808e+02,
-      0.3631322501141e-08, 0.1981240601160e+01, 0.6294805223347e+01,
-      0.4130007425139e-08, 0.2050060880201e+01, 0.2195415756911e+02,
-      0.4433905965176e-08, 0.3277477970321e+01, 0.7445550607224e+01,
-
-      0.3851814176947e-08, 0.5210690074886e+01, 0.9562891316684e+00,
-      0.3485807052785e-08, 0.6653274904611e+00, 0.1161697602389e+02,
-      0.3979772816991e-08, 0.1767941436148e+01, 0.2277943724828e+02,
-      0.3402607460500e-08, 0.3421746306465e+01, 0.1087398597200e+02,
-      0.4049993000926e-08, 0.1127144787547e+01, 0.3163918923335e+00,
-      0.3420511182382e-08, 0.4214794779161e+01, 0.1362553364512e+02,
-      0.3640772365012e-08, 0.5324905497687e+01, 0.1725304118033e+02,
-      0.3323037987501e-08, 0.6135761838271e+01, 0.6279143387820e+01,
-      0.4503141663637e-08, 0.1802305450666e+01, 0.1385561574497e+01,
-      0.4314560055588e-08, 0.4812299731574e+01, 0.4176041334900e+01,
-
-      0.3294226949110e-08, 0.3657547059723e+01, 0.6287008313071e+01,
-      0.3215657197281e-08, 0.4866676894425e+01, 0.5749861718712e+01,
-      0.4129362656266e-08, 0.3809342558906e+01, 0.5905702259363e+01,
-      0.3137762976388e-08, 0.2494635174443e+01, 0.2099539292909e+02,
-      0.3514010952384e-08, 0.2699961831678e+01, 0.7335344340001e+01,
-      0.3327607571530e-08, 0.3318457714816e+01, 0.5436992986000e+01,
-      0.3541066946675e-08, 0.4382703582466e+01, 0.1234573916645e+02,
-      0.3216179847052e-08, 0.5271066317054e+01, 0.3802769619140e-01,
-      0.2959045059570e-08, 0.5819591585302e+01, 0.2670964694522e+02,
-      0.3884040326665e-08, 0.5980934960428e+01, 0.6660449441528e+01,
-
-      0.2922027539886e-08, 0.3337290282483e+01, 0.1375773836557e+01,
-      0.4110846382042e-08, 0.5742978187327e+01, 0.4480965020977e+02,
-      0.2934508411032e-08, 0.2278075804200e+01, 0.6408777551755e+00,
-      0.3966896193000e-08, 0.5835747858477e+01, 0.3773735910827e+00,
-      0.3286695827610e-08, 0.5838898193902e+01, 0.3932462625300e-02,
-      0.3720643094196e-08, 0.1122212337858e+01, 0.1646033343740e+02,
-      0.3285508906174e-08, 0.9182250996416e+00, 0.1081813534213e+02,
-      0.3753880575973e-08, 0.5174761973266e+01, 0.5642198095270e+01,
-      0.3022129385587e-08, 0.3381611020639e+01, 0.2982630633589e+02,
-      0.2798569205621e-08, 0.3546193723922e+01, 0.1937891852345e+02,
-
-      0.3397872070505e-08, 0.4533203197934e+01, 0.6923953605621e+01,
-      0.3708099772977e-08, 0.2756168198616e+01, 0.3066615496545e+02,
-      0.3599283541510e-08, 0.1934395469918e+01, 0.6147450479709e+01,
-      0.3688702753059e-08, 0.7149920971109e+00, 0.2636725487657e+01,
-      0.2681084724003e-08, 0.4899819493154e+01, 0.6816289982179e+01,
-      0.3495993460759e-08, 0.1572418915115e+01, 0.6418701221183e+01,
-      0.3130770324995e-08, 0.8912190180489e+00, 0.1235996607578e+02,
-      0.2744353821941e-08, 0.3800821940055e+01, 0.2059724391010e+02,
-      0.2842732906341e-08, 0.2644717440029e+01, 0.2828699048865e+02,
-      0.3046882682154e-08, 0.3987793020179e+01, 0.6055599646783e+01,
-
-      0.2399072455143e-08, 0.9908826440764e+00, 0.6255674361143e+01,
-      0.2384306274204e-08, 0.2516149752220e+01, 0.6310477339748e+01,
-      0.2977324500559e-08, 0.5849195642118e+01, 0.1652265972112e+02,
-      0.3062835258972e-08, 0.1681660100162e+01, 0.1172006883645e+02,
-      0.3109682589231e-08, 0.5804143987737e+00, 0.2751146787858e+02,
-      0.2903920355299e-08, 0.5800768280123e+01, 0.6510552054109e+01,
-      0.2823221989212e-08, 0.9241118370216e+00, 0.5469525544182e+01,
-      0.3187949696649e-08, 0.3139776445735e+01, 0.1693792562116e+03,
-      0.2922559771655e-08, 0.3549440782984e+01, 0.2630839062450e+00,
-      0.2436302066603e-08, 0.4735540696319e+01, 0.3946258593675e+00,
-
-      0.3049473043606e-08, 0.4998289124561e+01, 0.8390110365991e+01,
-      0.2863682575784e-08, 0.6709515671102e+00, 0.2243449970715e+00,
-      0.2641750517966e-08, 0.5410978257284e+01, 0.2986433403208e+02,
-      0.2704093466243e-08, 0.4778317207821e+01, 0.6129297044991e+01,
-      0.2445522177011e-08, 0.6009020662222e+01, 0.1171295538178e+02,
-      0.2623608810230e-08, 0.5010449777147e+01, 0.6436854655901e+01,
-      0.2079259704053e-08, 0.5980943768809e+01, 0.2019909489111e+02,
-      0.2820225596771e-08, 0.2679965110468e+01, 0.5934151399930e+01,
-      0.2365221950927e-08, 0.1894231148810e+01, 0.2470570524223e+02,
-      0.2359682077149e-08, 0.4220752950780e+01, 0.8671969964381e+01,
-
-      0.2387577137206e-08, 0.2571783940617e+01, 0.7096626156709e+01,
-      0.1982102089816e-08, 0.5169765997119e+00, 0.1727188400790e+02,
-      0.2687502389925e-08, 0.6239078264579e+01, 0.7075506709219e+02,
-      0.2207751669135e-08, 0.2031184412677e+01, 0.4377611041777e+01,
-      0.2618370214274e-08, 0.8266079985979e+00, 0.6632000300961e+01,
-      0.2591951887361e-08, 0.8819350522008e+00, 0.4873985990671e+02,
-      0.2375055656248e-08, 0.3520944177789e+01, 0.1590676413561e+02,
-      0.2472019978911e-08, 0.1551431908671e+01, 0.6612329252343e+00,
-      0.2368157127199e-08, 0.4178610147412e+01, 0.3459636466239e+02,
-      0.1764846605693e-08, 0.1506764000157e+01, 0.1980094587212e+02,
-
-      0.2291769608798e-08, 0.2118250611782e+01, 0.2844914056730e-01,
-      0.2209997316943e-08, 0.3363255261678e+01, 0.2666070658668e+00,
-      0.2292699097923e-08, 0.4200423956460e+00, 0.1484170571900e-02,
-      0.1629683015329e-08, 0.2331362582487e+01, 0.3035599730800e+02,
-      0.2206492862426e-08, 0.3400274026992e+01, 0.6281667977667e+01,
-      0.2205746568257e-08, 0.1066051230724e+00, 0.6284483723224e+01,
-      0.2026310767991e-08, 0.2779066487979e+01, 0.2449240616245e+02,
-      0.1762977622163e-08, 0.9951450691840e+00, 0.2045286941806e+02,
-      0.1368535049606e-08, 0.6402447365817e+00, 0.2473415438279e+02,
-      0.1720598775450e-08, 0.2303524214705e+00, 0.1679593901136e+03,
-
-      0.1702429015449e-08, 0.6164622655048e+01, 0.3338575901272e+03,
-      0.1414033197685e-08, 0.3954561185580e+01, 0.1624205518357e+03,
-      0.1573768958043e-08, 0.2028286308984e+01, 0.3144167757552e+02,
-      0.1650705184447e-08, 0.2304040666128e+01, 0.5267006960365e+02,
-      0.1651087618855e-08, 0.2538461057280e+01, 0.8956999012000e+02,
-      0.1616409518983e-08, 0.5111054348152e+01, 0.3332657872986e+02,
-      0.1537175173581e-08, 0.5601130666603e+01, 0.3852657435933e+02,
-      0.1593191980553e-08, 0.2614340453411e+01, 0.2282781046519e+03,
-      0.1499480170643e-08, 0.3624721577264e+01, 0.2823723341956e+02,
-      0.1493807843235e-08, 0.4214569879008e+01, 0.2876692439167e+02,
-
-      0.1074571199328e-08, 0.1496911744704e+00, 0.8397383534231e+02,
-      0.1074406983417e-08, 0.1187817671922e+01, 0.8401985929482e+02,
-      0.9757576855851e-09, 0.2655703035858e+01, 0.7826370942180e+02,
-      0.1258432887565e-08, 0.4969896184844e+01, 0.3115650189215e+03,
-      0.1240336343282e-08, 0.5192460776926e+01, 0.1784300471910e+03,
-      0.9016107005164e-09, 0.1960356923057e+01, 0.5886454391678e+02,
-      0.1135392360918e-08, 0.5082427809068e+01, 0.7842370451713e+02,
-      0.9216046089565e-09, 0.2793775037273e+01, 0.1014262087719e+03,
-      0.1061276615030e-08, 0.3726144311409e+01, 0.5660027930059e+02,
-      0.1010110596263e-08, 0.7404080708937e+00, 0.4245678405627e+02,
-
-      0.7217424756199e-09, 0.2697449980577e-01, 0.2457074661053e+03,
-      0.6912003846756e-09, 0.4253296276335e+01, 0.1679936946371e+03,
-      0.6871814664847e-09, 0.5148072412354e+01, 0.6053048899753e+02,
-      0.4887158016343e-09, 0.2153581148294e+01, 0.9656299901946e+02,
-      0.5161802866314e-09, 0.3852750634351e+01, 0.2442876000072e+03,
-      0.5652599559057e-09, 0.1233233356270e+01, 0.8365903305582e+02,
-      0.4710812608586e-09, 0.5610486976767e+01, 0.3164282286739e+03,
-      0.4909977500324e-09, 0.1639629524123e+01, 0.4059982187939e+03,
-      0.4772641839378e-09, 0.3737100368583e+01, 0.1805255418145e+03,
-      0.4487562567153e-09, 0.1158417054478e+00, 0.8433466158131e+02,
-
-      0.3943441230497e-09, 0.6243502862796e+00, 0.2568537517081e+03,
-      0.3952236913598e-09, 0.3510377382385e+01, 0.2449975330562e+03,
-      0.3788898363417e-09, 0.5916128302299e+01, 0.1568131045107e+03,
-      0.3738329328831e-09, 0.1042266763456e+01, 0.3948519331910e+03,
-      0.2451199165151e-09, 0.1166788435700e+01, 0.1435713242844e+03,
-      0.2436734402904e-09, 0.3254726114901e+01, 0.2268582385539e+03,
-      0.2213605274325e-09, 0.1687210598530e+01, 0.1658638954901e+03,
-      0.1491521204829e-09, 0.2657541786794e+01, 0.2219950288015e+03,
-      0.1474995329744e-09, 0.5013089805819e+01, 0.3052819430710e+03,
-      0.1661939475656e-09, 0.5495315428418e+01, 0.2526661704812e+03,
-
-      0.9015946748003e-10, 0.2236989966505e+01, 0.4171445043968e+03 };
-
-/* Sun-to-Earth, T^0, Z */
-   static const double e0z[] = {
-      0.2796207639075e-05, 0.3198701560209e+01, 0.8433466158131e+02,
-      0.1016042198142e-05, 0.5422360395913e+01, 0.5507553240374e+01,
-      0.8044305033647e-06, 0.3880222866652e+01, 0.5223693906222e+01,
-      0.4385347909274e-06, 0.3704369937468e+01, 0.2352866153506e+01,
-      0.3186156414906e-06, 0.3999639363235e+01, 0.1577343543434e+01,
-      0.2272412285792e-06, 0.3984738315952e+01, 0.1047747311755e+01,
-      0.1645620103007e-06, 0.3565412516841e+01, 0.5856477690889e+01,
-      0.1815836921166e-06, 0.4984507059020e+01, 0.6283075850446e+01,
-      0.1447461676364e-06, 0.3702753570108e+01, 0.9437762937313e+01,
-      0.1430760876382e-06, 0.3409658712357e+01, 0.1021328554739e+02,
-
-      0.1120445753226e-06, 0.4829561570246e+01, 0.1414349524433e+02,
-      0.1090232840797e-06, 0.2080729178066e+01, 0.6812766822558e+01,
-      0.9715727346551e-07, 0.3476295881948e+01, 0.4694002934110e+01,
-      0.1036267136217e-06, 0.4056639536648e+01, 0.7109288135493e+02,
-      0.8752665271340e-07, 0.4448159519911e+01, 0.5753384878334e+01,
-      0.8331864956004e-07, 0.4991704044208e+01, 0.7084896783808e+01,
-      0.6901658670245e-07, 0.4325358994219e+01, 0.6275962395778e+01,
-      0.9144536848998e-07, 0.1141826375363e+01, 0.6620890113188e+01,
-      0.7205085037435e-07, 0.3624344170143e+01, 0.5296909721118e+00,
-      0.7697874654176e-07, 0.5554257458998e+01, 0.1676215758509e+03,
-
-      0.5197545738384e-07, 0.6251760961735e+01, 0.1807370494127e+02,
-      0.5031345378608e-07, 0.2497341091913e+01, 0.4705732307012e+01,
-      0.4527110205840e-07, 0.2335079920992e+01, 0.6309374173736e+01,
-      0.4753355798089e-07, 0.7094148987474e+00, 0.5884926831456e+01,
-      0.4296951977516e-07, 0.1101916352091e+01, 0.6681224869435e+01,
-      0.3855341568387e-07, 0.1825495405486e+01, 0.5486777812467e+01,
-      0.5253930970990e-07, 0.4424740687208e+01, 0.7860419393880e+01,
-      0.4024630496471e-07, 0.5120498157053e+01, 0.1336797263425e+02,
-      0.4061069791453e-07, 0.6029771435451e+01, 0.3930209696940e+01,
-      0.3797883804205e-07, 0.4435193600836e+00, 0.3154687086868e+01,
-
-      0.2933033225587e-07, 0.5124157356507e+01, 0.1059381944224e+01,
-      0.3503000930426e-07, 0.5421830162065e+01, 0.6069776770667e+01,
-      0.3670096214050e-07, 0.4582101667297e+01, 0.1219403291462e+02,
-      0.2905609437008e-07, 0.1926566420072e+01, 0.1097707878456e+02,
-      0.2466827821713e-07, 0.6090174539834e+00, 0.6496374930224e+01,
-      0.2691647295332e-07, 0.1393432595077e+01, 0.2200391463820e+02,
-      0.2150554667946e-07, 0.4308671715951e+01, 0.5643178611111e+01,
-      0.2237481922680e-07, 0.8133968269414e+00, 0.8635942003952e+01,
-      0.1817741038157e-07, 0.3755205127454e+01, 0.3340612434717e+01,
-      0.2227820762132e-07, 0.2759558596664e+01, 0.1203646072878e+02,
-
-      0.1944713772307e-07, 0.5699645869121e+01, 0.1179062909082e+02,
-      0.1527340520662e-07, 0.1986749091746e+01, 0.3981490189893e+00,
-      0.1577282574914e-07, 0.3205017217983e+01, 0.5088628793478e+01,
-      0.1424738825424e-07, 0.6256747903666e+01, 0.2544314396739e+01,
-      0.1616563121701e-07, 0.2601671259394e+00, 0.1729818233119e+02,
-      0.1401210391692e-07, 0.4686939173506e+01, 0.7058598460518e+01,
-      0.1488726974214e-07, 0.2815862451372e+01, 0.2593412433514e+02,
-      0.1692626442388e-07, 0.4956894109797e+01, 0.1564752902480e+03,
-      0.1123571582910e-07, 0.2381192697696e+01, 0.3738761453707e+01,
-      0.9903308606317e-08, 0.4294851657684e+01, 0.9225539266174e+01,
-
-      0.9174533187191e-08, 0.3075171510642e+01, 0.4164311961999e+01,
-      0.8645985631457e-08, 0.5477534821633e+00, 0.8429241228195e+01,
-     -0.1085876492688e-07, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.9264309077815e-08, 0.5968571670097e+01, 0.7079373888424e+01,
-      0.8243116984954e-08, 0.1489098777643e+01, 0.1044738781244e+02,
-      0.8268102113708e-08, 0.3512977691983e+01, 0.1150676975667e+02,
-      0.9043613988227e-08, 0.1290704408221e+00, 0.1101510648075e+02,
-      0.7432912038789e-08, 0.1991086893337e+01, 0.2608790314060e+02,
-      0.8586233727285e-08, 0.4238357924414e+01, 0.2986433403208e+02,
-      0.7612230060131e-08, 0.2911090150166e+01, 0.4732030630302e+01,
-
-      0.7097787751408e-08, 0.1908938392390e+01, 0.8031092209206e+01,
-      0.7640237040175e-08, 0.6129219000168e+00, 0.7962980379786e+00,
-      0.7070445688081e-08, 0.1380417036651e+01, 0.2146165377750e+01,
-      0.7690770957702e-08, 0.1680504249084e+01, 0.2122839202813e+02,
-      0.8051292542594e-08, 0.5127423484511e+01, 0.2942463415728e+01,
-      0.5902709104515e-08, 0.2020274190917e+01, 0.7755226100720e+00,
-      0.5134567496462e-08, 0.2606778676418e+01, 0.1256615170089e+02,
-      0.5525802046102e-08, 0.1613011769663e+01, 0.8018209333619e+00,
-      0.5880724784221e-08, 0.4604483417236e+01, 0.4690479774488e+01,
-      0.5211699081370e-08, 0.5718964114193e+01, 0.8827390247185e+01,
-
-      0.4891849573562e-08, 0.3689658932196e+01, 0.2132990797783e+00,
-      0.5150246069997e-08, 0.4099769855122e+01, 0.6480980550449e+02,
-      0.5102434319633e-08, 0.5660834602509e+01, 0.3379454372902e+02,
-      0.5083405254252e-08, 0.9842221218974e+00, 0.4136910472696e+01,
-      0.4206562585682e-08, 0.1341363634163e+00, 0.3128388763578e+01,
-      0.4663249683579e-08, 0.8130132735866e+00, 0.5216580451554e+01,
-      0.4099474416530e-08, 0.5791497770644e+01, 0.4265981595566e+00,
-      0.4628251220767e-08, 0.1249802769331e+01, 0.1572083878776e+02,
-      0.5024068728142e-08, 0.4795684802743e+01, 0.6290189305114e+01,
-      0.5120234327758e-08, 0.3810420387208e+01, 0.5230807360890e+01,
-
-      0.5524029815280e-08, 0.1029264714351e+01, 0.2397622045175e+03,
-      0.4757415718860e-08, 0.3528044781779e+01, 0.1649636139783e+02,
-      0.3915786131127e-08, 0.5593889282646e+01, 0.1589072916335e+01,
-      0.4869053149991e-08, 0.3299636454433e+01, 0.7632943190217e+01,
-      0.3649365703729e-08, 0.1286049002584e+01, 0.6206810014183e+01,
-      0.3992493949002e-08, 0.3100307589464e+01, 0.2515860172507e+02,
-      0.3320247477418e-08, 0.6212683940807e+01, 0.1216800268190e+02,
-      0.3287123739696e-08, 0.4699118445928e+01, 0.7234794171227e+01,
-      0.3472776811103e-08, 0.2630507142004e+01, 0.7342457794669e+01,
-      0.3423253294767e-08, 0.2946432844305e+01, 0.9623688285163e+01,
-
-      0.3896173898244e-08, 0.1224834179264e+01, 0.6438496133249e+01,
-      0.3388455337924e-08, 0.1543807616351e+01, 0.1494531617769e+02,
-      0.3062704716523e-08, 0.1191777572310e+01, 0.8662240327241e+01,
-      0.3270075600400e-08, 0.5483498767737e+01, 0.1194447056968e+01,
-      0.3101209215259e-08, 0.8000833804348e+00, 0.3772475342596e+02,
-      0.2780883347311e-08, 0.4077980721888e+00, 0.5863591145557e+01,
-      0.2903605931824e-08, 0.2617490302147e+01, 0.1965104848470e+02,
-      0.2682014743119e-08, 0.2634703158290e+01, 0.7238675589263e+01,
-      0.2534360108492e-08, 0.6102446114873e+01, 0.6836645152238e+01,
-      0.2392564882509e-08, 0.3681820208691e+01, 0.5849364236221e+01,
-
-      0.2656667254856e-08, 0.6216045388886e+01, 0.6133512519065e+01,
-      0.2331242096773e-08, 0.5864949777744e+01, 0.4535059491685e+01,
-      0.2287898363668e-08, 0.4566628532802e+01, 0.7477522907414e+01,
-      0.2336944521306e-08, 0.2442722126930e+01, 0.1137170464392e+02,
-      0.3156632236269e-08, 0.1626628050682e+01, 0.2509084901204e+03,
-      0.2982612402766e-08, 0.2803604512609e+01, 0.1748016358760e+01,
-      0.2774031674807e-08, 0.4654002897158e+01, 0.8223916695780e+02,
-      0.2295236548638e-08, 0.4326518333253e+01, 0.3378142627421e+00,
-      0.2190714699873e-08, 0.4519614578328e+01, 0.2908881142201e+02,
-      0.2191495845045e-08, 0.3012626912549e+01, 0.1673046366289e+02,
-
-      0.2492901628386e-08, 0.1290101424052e+00, 0.1543797956245e+03,
-      0.1993778064319e-08, 0.3864046799414e+01, 0.1778984560711e+02,
-      0.1898146479022e-08, 0.5053777235891e+01, 0.2042657109477e+02,
-      0.1918280127634e-08, 0.2222470192548e+01, 0.4165496312290e+02,
-      0.1916351061607e-08, 0.8719067257774e+00, 0.7737595720538e+02,
-      0.1834720181466e-08, 0.4031491098040e+01, 0.2358125818164e+02,
-      0.1249201523806e-08, 0.5938379466835e+01, 0.3301902111895e+02,
-      0.1477304050539e-08, 0.6544722606797e+00, 0.9548094718417e+02,
-      0.1264316431249e-08, 0.2059072853236e+01, 0.8399684731857e+02,
-      0.1203526495039e-08, 0.3644813532605e+01, 0.4558517281984e+02,
-
-      0.9221681059831e-09, 0.3241815055602e+01, 0.7805158573086e+02,
-      0.7849278367646e-09, 0.5043812342457e+01, 0.5217580628120e+02,
-      0.7983392077387e-09, 0.5000024502753e+01, 0.1501922143975e+03,
-      0.7925395431654e-09, 0.1398734871821e-01, 0.9061773743175e+02,
-      0.7640473285886e-09, 0.5067111723130e+01, 0.4951538251678e+02,
-      0.5398937754482e-09, 0.5597382200075e+01, 0.1613385000004e+03,
-      0.5626247550193e-09, 0.2601338209422e+01, 0.7318837597844e+02,
-      0.5525197197855e-09, 0.5814832109256e+01, 0.1432335100216e+03,
-      0.5407629837898e-09, 0.3384820609076e+01, 0.3230491187871e+03,
-      0.3856739119801e-09, 0.1072391840473e+01, 0.2334791286671e+03,
-
-      0.3856425239987e-09, 0.2369540393327e+01, 0.1739046517013e+03,
-      0.4350867755983e-09, 0.5255575751082e+01, 0.1620484330494e+03,
-      0.3844113924996e-09, 0.5482356246182e+01, 0.9757644180768e+02,
-      0.2854869155431e-09, 0.9573634763143e+00, 0.1697170704744e+03,
-      0.1719227671416e-09, 0.1887203025202e+01, 0.2265204242912e+03,
-      0.1527846879755e-09, 0.3982183931157e+01, 0.3341954043900e+03,
-      0.1128229264847e-09, 0.2787457156298e+01, 0.3119028331842e+03 };
-
-/* Sun-to-Earth, T^1, X */
-   static const double e1x[] = {
-      0.1234046326004e-05, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.5150068824701e-06, 0.6002664557501e+01, 0.1256615170089e+02,
-      0.1290743923245e-07, 0.5959437664199e+01, 0.1884922755134e+02,
-      0.1068615564952e-07, 0.2015529654209e+01, 0.6283075850446e+01,
-      0.2079619142538e-08, 0.1732960531432e+01, 0.6279552690824e+01,
-      0.2078009243969e-08, 0.4915604476996e+01, 0.6286599010068e+01,
-      0.6206330058856e-09, 0.3616457953824e+00, 0.4705732307012e+01,
-      0.5989335313746e-09, 0.3802607304474e+01, 0.6256777527156e+01,
-      0.5958495663840e-09, 0.2845866560031e+01, 0.6309374173736e+01,
-      0.4866923261539e-09, 0.5213203771824e+01, 0.7755226100720e+00,
-
-      0.4267785823142e-09, 0.4368189727818e+00, 0.1059381944224e+01,
-      0.4610675141648e-09, 0.1837249181372e-01, 0.7860419393880e+01,
-      0.3626989993973e-09, 0.2161590545326e+01, 0.5753384878334e+01,
-      0.3563071194389e-09, 0.1452631954746e+01, 0.5884926831456e+01,
-      0.3557015642807e-09, 0.4470593393054e+01, 0.6812766822558e+01,
-      0.3210412089122e-09, 0.5195926078314e+01, 0.6681224869435e+01,
-      0.2875473577986e-09, 0.5916256610193e+01, 0.2513230340178e+02,
-      0.2842913681629e-09, 0.1149902426047e+01, 0.6127655567643e+01,
-      0.2751248215916e-09, 0.5502088574662e+01, 0.6438496133249e+01,
-      0.2481432881127e-09, 0.2921989846637e+01, 0.5486777812467e+01,
-
-      0.2059885976560e-09, 0.3718070376585e+01, 0.7079373888424e+01,
-      0.2015522342591e-09, 0.5979395259740e+01, 0.6290189305114e+01,
-      0.1995364084253e-09, 0.6772087985494e+00, 0.6275962395778e+01,
-      0.1957436436943e-09, 0.2899210654665e+01, 0.5507553240374e+01,
-      0.1651609818948e-09, 0.6228206482192e+01, 0.1150676975667e+02,
-      0.1822980550699e-09, 0.1469348746179e+01, 0.1179062909082e+02,
-      0.1675223159760e-09, 0.3813910555688e+01, 0.7058598460518e+01,
-      0.1706491764745e-09, 0.3004380506684e+00, 0.7113454667900e-02,
-      0.1392952362615e-09, 0.1440393973406e+01, 0.7962980379786e+00,
-      0.1209868266342e-09, 0.4150425791727e+01, 0.4694002934110e+01,
-
-      0.1009827202611e-09, 0.3290040429843e+01, 0.3738761453707e+01,
-      0.1047261388602e-09, 0.4229590090227e+01, 0.6282095334605e+01,
-      0.1047006652004e-09, 0.2418967680575e+01, 0.6284056366286e+01,
-      0.9609993143095e-10, 0.4627943659201e+01, 0.6069776770667e+01,
-      0.9590900593873e-10, 0.1894393939924e+01, 0.4136910472696e+01,
-      0.9146249188071e-10, 0.2010647519562e+01, 0.6496374930224e+01,
-      0.8545274480290e-10, 0.5529846956226e-01, 0.1194447056968e+01,
-      0.8224377881194e-10, 0.1254304102174e+01, 0.1589072916335e+01,
-      0.6183529510410e-10, 0.3360862168815e+01, 0.8827390247185e+01,
-      0.6259255147141e-10, 0.4755628243179e+01, 0.8429241228195e+01,
-
-      0.5539291694151e-10, 0.5371746955142e+01, 0.4933208510675e+01,
-      0.7328259466314e-10, 0.4927699613906e+00, 0.4535059491685e+01,
-      0.6017835843560e-10, 0.5776682001734e-01, 0.1255903824622e+02,
-      0.7079827775243e-10, 0.4395059432251e+01, 0.5088628793478e+01,
-      0.5170358878213e-10, 0.5154062619954e+01, 0.1176985366291e+02,
-      0.4872301838682e-10, 0.6289611648973e+00, 0.6040347114260e+01,
-      0.5249869411058e-10, 0.5617272046949e+01, 0.3154687086868e+01,
-      0.4716172354411e-10, 0.3965901800877e+01, 0.5331357529664e+01,
-      0.4871214940964e-10, 0.4627507050093e+01, 0.1256967486051e+02,
-      0.4598076850751e-10, 0.6023631226459e+01, 0.6525804586632e+01,
-
-      0.4562196089485e-10, 0.4138562084068e+01, 0.3930209696940e+01,
-      0.4325493872224e-10, 0.1330845906564e+01, 0.7632943190217e+01,
-      0.5673781176748e-10, 0.2558752615657e+01, 0.5729506548653e+01,
-      0.3961436642503e-10, 0.2728071734630e+01, 0.7234794171227e+01,
-      0.5101868209058e-10, 0.4113444965144e+01, 0.6836645152238e+01,
-      0.5257043167676e-10, 0.6195089830590e+01, 0.8031092209206e+01,
-      0.5076613989393e-10, 0.2305124132918e+01, 0.7477522907414e+01,
-      0.3342169352778e-10, 0.5415998155071e+01, 0.1097707878456e+02,
-      0.3545881983591e-10, 0.3727160564574e+01, 0.4164311961999e+01,
-      0.3364063738599e-10, 0.2901121049204e+00, 0.1137170464392e+02,
-
-      0.3357039670776e-10, 0.1652229354331e+01, 0.5223693906222e+01,
-      0.4307412268687e-10, 0.4938909587445e+01, 0.1592596075957e+01,
-      0.3405769115435e-10, 0.2408890766511e+01, 0.3128388763578e+01,
-      0.3001926198480e-10, 0.4862239006386e+01, 0.1748016358760e+01,
-      0.2778264787325e-10, 0.5241168661353e+01, 0.7342457794669e+01,
-      0.2676159480666e-10, 0.3423593942199e+01, 0.2146165377750e+01,
-      0.2954273399939e-10, 0.1881721265406e+01, 0.5368044267797e+00,
-      0.3309362888795e-10, 0.1931525677349e+01, 0.8018209333619e+00,
-      0.2810283608438e-10, 0.2414659495050e+01, 0.5225775174439e+00,
-      0.3378045637764e-10, 0.4238019163430e+01, 0.1554202828031e+00,
-
-      0.2558134979840e-10, 0.1828225235805e+01, 0.5230807360890e+01,
-      0.2273755578447e-10, 0.5858184283998e+01, 0.7084896783808e+01,
-      0.2294176037690e-10, 0.4514589779057e+01, 0.1726015463500e+02,
-      0.2533506099435e-10, 0.2355717851551e+01, 0.5216580451554e+01,
-      0.2716685375812e-10, 0.2221003625100e+01, 0.8635942003952e+01,
-      0.2419043435198e-10, 0.5955704951635e+01, 0.4690479774488e+01,
-      0.2521232544812e-10, 0.1395676848521e+01, 0.5481254917084e+01,
-      0.2630195021491e-10, 0.5727468918743e+01, 0.2629832328990e-01,
-      0.2548395840944e-10, 0.2628351859400e-03, 0.1349867339771e+01 };
-
-/* Sun-to-Earth, T^1, Y */
-   static const double e1y[] = {
-      0.9304690546528e-06, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.5150715570663e-06, 0.4431807116294e+01, 0.1256615170089e+02,
-      0.1290825411056e-07, 0.4388610039678e+01, 0.1884922755134e+02,
-      0.4645466665386e-08, 0.5827263376034e+01, 0.6283075850446e+01,
-      0.2079625310718e-08, 0.1621698662282e+00, 0.6279552690824e+01,
-      0.2078189850907e-08, 0.3344713435140e+01, 0.6286599010068e+01,
-      0.6207190138027e-09, 0.5074049319576e+01, 0.4705732307012e+01,
-      0.5989826532569e-09, 0.2231842216620e+01, 0.6256777527156e+01,
-      0.5961360812618e-09, 0.1274975769045e+01, 0.6309374173736e+01,
-      0.4874165471016e-09, 0.3642277426779e+01, 0.7755226100720e+00,
-
-      0.4283834034360e-09, 0.5148765510106e+01, 0.1059381944224e+01,
-      0.4652389287529e-09, 0.4715794792175e+01, 0.7860419393880e+01,
-      0.3751707476401e-09, 0.6617207370325e+00, 0.5753384878334e+01,
-      0.3559998806198e-09, 0.6155548875404e+01, 0.5884926831456e+01,
-      0.3558447558857e-09, 0.2898827297664e+01, 0.6812766822558e+01,
-      0.3211116927106e-09, 0.3625813502509e+01, 0.6681224869435e+01,
-      0.2875609914672e-09, 0.4345435813134e+01, 0.2513230340178e+02,
-      0.2843109704069e-09, 0.5862263940038e+01, 0.6127655567643e+01,
-      0.2744676468427e-09, 0.3926419475089e+01, 0.6438496133249e+01,
-      0.2481285237789e-09, 0.1351976572828e+01, 0.5486777812467e+01,
-
-      0.2060338481033e-09, 0.2147556998591e+01, 0.7079373888424e+01,
-      0.2015822358331e-09, 0.4408358972216e+01, 0.6290189305114e+01,
-      0.2001195944195e-09, 0.5385829822531e+01, 0.6275962395778e+01,
-      0.1953667642377e-09, 0.1304933746120e+01, 0.5507553240374e+01,
-      0.1839744078713e-09, 0.6173567228835e+01, 0.1179062909082e+02,
-      0.1643334294845e-09, 0.4635942997523e+01, 0.1150676975667e+02,
-      0.1768051018652e-09, 0.5086283558874e+01, 0.7113454667900e-02,
-      0.1674874205489e-09, 0.2243332137241e+01, 0.7058598460518e+01,
-      0.1421445397609e-09, 0.6186899771515e+01, 0.7962980379786e+00,
-      0.1255163958267e-09, 0.5730238465658e+01, 0.4694002934110e+01,
-
-      0.1013945281961e-09, 0.1726055228402e+01, 0.3738761453707e+01,
-      0.1047294335852e-09, 0.2658801228129e+01, 0.6282095334605e+01,
-      0.1047103879392e-09, 0.8481047835035e+00, 0.6284056366286e+01,
-      0.9530343962826e-10, 0.3079267149859e+01, 0.6069776770667e+01,
-      0.9604637611690e-10, 0.3258679792918e+00, 0.4136910472696e+01,
-      0.9153518537177e-10, 0.4398599886584e+00, 0.6496374930224e+01,
-      0.8562458214922e-10, 0.4772686794145e+01, 0.1194447056968e+01,
-      0.8232525360654e-10, 0.5966220721679e+01, 0.1589072916335e+01,
-      0.6150223411438e-10, 0.1780985591923e+01, 0.8827390247185e+01,
-      0.6272087858000e-10, 0.3184305429012e+01, 0.8429241228195e+01,
-
-      0.5540476311040e-10, 0.3801260595433e+01, 0.4933208510675e+01,
-      0.7331901699361e-10, 0.5205948591865e+01, 0.4535059491685e+01,
-      0.6018528702791e-10, 0.4770139083623e+01, 0.1255903824622e+02,
-      0.5150530724804e-10, 0.3574796899585e+01, 0.1176985366291e+02,
-      0.6471933741811e-10, 0.2679787266521e+01, 0.5088628793478e+01,
-      0.5317460644174e-10, 0.9528763345494e+00, 0.3154687086868e+01,
-      0.4832187748783e-10, 0.5329322498232e+01, 0.6040347114260e+01,
-      0.4716763555110e-10, 0.2395235316466e+01, 0.5331357529664e+01,
-      0.4871509139861e-10, 0.3056663648823e+01, 0.1256967486051e+02,
-      0.4598417696768e-10, 0.4452762609019e+01, 0.6525804586632e+01,
-
-      0.5674189533175e-10, 0.9879680872193e+00, 0.5729506548653e+01,
-      0.4073560328195e-10, 0.5939127696986e+01, 0.7632943190217e+01,
-      0.5040994945359e-10, 0.4549875824510e+01, 0.8031092209206e+01,
-      0.5078185134679e-10, 0.7346659893982e+00, 0.7477522907414e+01,
-      0.3769343537061e-10, 0.1071317188367e+01, 0.7234794171227e+01,
-      0.4980331365299e-10, 0.2500345341784e+01, 0.6836645152238e+01,
-      0.3458236594757e-10, 0.3825159450711e+01, 0.1097707878456e+02,
-      0.3578859493602e-10, 0.5299664791549e+01, 0.4164311961999e+01,
-      0.3370504646419e-10, 0.5002316301593e+01, 0.1137170464392e+02,
-      0.3299873338428e-10, 0.2526123275282e+01, 0.3930209696940e+01,
-
-      0.4304917318409e-10, 0.3368078557132e+01, 0.1592596075957e+01,
-      0.3402418753455e-10, 0.8385495425800e+00, 0.3128388763578e+01,
-      0.2778460572146e-10, 0.3669905203240e+01, 0.7342457794669e+01,
-      0.2782710128902e-10, 0.2691664812170e+00, 0.1748016358760e+01,
-      0.2711725179646e-10, 0.4707487217718e+01, 0.5296909721118e+00,
-      0.2981760946340e-10, 0.3190260867816e+00, 0.5368044267797e+00,
-      0.2811672977772e-10, 0.3196532315372e+01, 0.7084896783808e+01,
-      0.2863454474467e-10, 0.2263240324780e+00, 0.5223693906222e+01,
-      0.3333464634051e-10, 0.3498451685065e+01, 0.8018209333619e+00,
-      0.3312991747609e-10, 0.5839154477412e+01, 0.1554202828031e+00,
-
-      0.2813255564006e-10, 0.8268044346621e+00, 0.5225775174439e+00,
-      0.2665098083966e-10, 0.3934021725360e+01, 0.5216580451554e+01,
-      0.2349795705216e-10, 0.5197620913779e+01, 0.2146165377750e+01,
-      0.2330352293961e-10, 0.2984999231807e+01, 0.1726015463500e+02,
-      0.2728001683419e-10, 0.6521679638544e+00, 0.8635942003952e+01,
-      0.2484061007669e-10, 0.3468955561097e+01, 0.5230807360890e+01,
-      0.2646328768427e-10, 0.1013724533516e+01, 0.2629832328990e-01,
-      0.2518630264831e-10, 0.6108081057122e+01, 0.5481254917084e+01,
-      0.2421901455384e-10, 0.1651097776260e+01, 0.1349867339771e+01,
-      0.6348533267831e-11, 0.3220226560321e+01, 0.8433466158131e+02 };
-
-/* Sun-to-Earth, T^1, Z */
-   static const double e1z[] = {
-      0.2278290449966e-05, 0.3413716033863e+01, 0.6283075850446e+01,
-      0.5429458209830e-07, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.1903240492525e-07, 0.3370592358297e+01, 0.1256615170089e+02,
-      0.2385409276743e-09, 0.3327914718416e+01, 0.1884922755134e+02,
-      0.8676928342573e-10, 0.1824006811264e+01, 0.5223693906222e+01,
-      0.7765442593544e-10, 0.3888564279247e+01, 0.5507553240374e+01,
-      0.7066158332715e-10, 0.5194267231944e+01, 0.2352866153506e+01,
-      0.7092175288657e-10, 0.2333246960021e+01, 0.8399684731857e+02,
-      0.5357582213535e-10, 0.2224031176619e+01, 0.5296909721118e+00,
-      0.3828035865021e-10, 0.2156710933584e+01, 0.6279552690824e+01,
-
-      0.3824857220427e-10, 0.1529755219915e+01, 0.6286599010068e+01,
-      0.3286995181628e-10, 0.4879512900483e+01, 0.1021328554739e+02 };
-
-/* Sun-to-Earth, T^2, X */
-   static const double e2x[] = {
-     -0.4143818297913e-10, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.2171497694435e-10, 0.4398225628264e+01, 0.1256615170089e+02,
-      0.9845398442516e-11, 0.2079720838384e+00, 0.6283075850446e+01,
-      0.9256833552682e-12, 0.4191264694361e+01, 0.1884922755134e+02,
-      0.1022049384115e-12, 0.5381133195658e+01, 0.8399684731857e+02 };
-
-/* Sun-to-Earth, T^2, Y */
-   static const double e2y[] = {
-      0.5063375872532e-10, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.2173815785980e-10, 0.2827805833053e+01, 0.1256615170089e+02,
-      0.1010231999920e-10, 0.4634612377133e+01, 0.6283075850446e+01,
-      0.9259745317636e-12, 0.2620612076189e+01, 0.1884922755134e+02,
-      0.1022202095812e-12, 0.3809562326066e+01, 0.8399684731857e+02 };
-
-/* Sun-to-Earth, T^2, Z */
-   static const double e2z[] = {
-      0.9722666114891e-10, 0.5152219582658e+01, 0.6283075850446e+01,
-     -0.3494819171909e-11, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.6713034376076e-12, 0.6440188750495e+00, 0.1256615170089e+02 };
-
-/* SSB-to-Sun, T^0, X */
-   static const double s0x[] = {
-      0.4956757536410e-02, 0.3741073751789e+01, 0.5296909721118e+00,
-      0.2718490072522e-02, 0.4016011511425e+01, 0.2132990797783e+00,
-      0.1546493974344e-02, 0.2170528330642e+01, 0.3813291813120e-01,
-      0.8366855276341e-03, 0.2339614075294e+01, 0.7478166569050e-01,
-      0.2936777942117e-03, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.1201317439469e-03, 0.4090736353305e+01, 0.1059381944224e+01,
-      0.7578550887230e-04, 0.3241518088140e+01, 0.4265981595566e+00,
-      0.1941787367773e-04, 0.1012202064330e+01, 0.2061856251104e+00,
-      0.1889227765991e-04, 0.3892520416440e+01, 0.2204125344462e+00,
-      0.1937896968613e-04, 0.4797779441161e+01, 0.1495633313810e+00,
-
-      0.1434506110873e-04, 0.3868960697933e+01, 0.5225775174439e+00,
-      0.1406659911580e-04, 0.4759766557397e+00, 0.5368044267797e+00,
-      0.1179022300202e-04, 0.7774961520598e+00, 0.7626583626240e-01,
-      0.8085864460959e-05, 0.3254654471465e+01, 0.3664874755930e-01,
-      0.7622752967615e-05, 0.4227633103489e+01, 0.3961708870310e-01,
-      0.6209171139066e-05, 0.2791828325711e+00, 0.7329749511860e-01,
-      0.4366435633970e-05, 0.4440454875925e+01, 0.1589072916335e+01,
-      0.3792124889348e-05, 0.5156393842356e+01, 0.7113454667900e-02,
-      0.3154548963402e-05, 0.6157005730093e+01, 0.4194847048887e+00,
-      0.3088359882942e-05, 0.2494567553163e+01, 0.6398972393349e+00,
-
-      0.2788440902136e-05, 0.4934318747989e+01, 0.1102062672231e+00,
-      0.3039928456376e-05, 0.4895077702640e+01, 0.6283075850446e+01,
-      0.2272258457679e-05, 0.5278394064764e+01, 0.1030928125552e+00,
-      0.2162007057957e-05, 0.5802978019099e+01, 0.3163918923335e+00,
-      0.1767632855737e-05, 0.3415346595193e-01, 0.1021328554739e+02,
-      0.1349413459362e-05, 0.2001643230755e+01, 0.1484170571900e-02,
-      0.1170141900476e-05, 0.2424750491620e+01, 0.6327837846670e+00,
-      0.1054355266820e-05, 0.3123311487576e+01, 0.4337116142245e+00,
-      0.9800822461610e-06, 0.3026258088130e+01, 0.1052268489556e+01,
-      0.1091203749931e-05, 0.3157811670347e+01, 0.1162474756779e+01,
-
-      0.6960236715913e-06, 0.8219570542313e+00, 0.1066495398892e+01,
-      0.5689257296909e-06, 0.1323052375236e+01, 0.9491756770005e+00,
-      0.6613172135802e-06, 0.2765348881598e+00, 0.8460828644453e+00,
-      0.6277702517571e-06, 0.5794064466382e+01, 0.1480791608091e+00,
-      0.6304884066699e-06, 0.7323555380787e+00, 0.2243449970715e+00,
-      0.4897850467382e-06, 0.3062464235399e+01, 0.3340612434717e+01,
-      0.3759148598786e-06, 0.4588290469664e+01, 0.3516457698740e-01,
-      0.3110520548195e-06, 0.1374299536572e+01, 0.6373574839730e-01,
-      0.3064708359780e-06, 0.4222267485047e+01, 0.1104591729320e-01,
-      0.2856347168241e-06, 0.3714202944973e+01, 0.1510475019529e+00,
-
-      0.2840945514288e-06, 0.2847972875882e+01, 0.4110125927500e-01,
-      0.2378951599405e-06, 0.3762072563388e+01, 0.2275259891141e+00,
-      0.2714229481417e-06, 0.1036049980031e+01, 0.2535050500000e-01,
-      0.2323551717307e-06, 0.4682388599076e+00, 0.8582758298370e-01,
-      0.1881790512219e-06, 0.4790565425418e+01, 0.2118763888447e+01,
-      0.2261353968371e-06, 0.1669144912212e+01, 0.7181332454670e-01,
-      0.2214546389848e-06, 0.3937717281614e+01, 0.2968341143800e-02,
-      0.2184915594933e-06, 0.1129169845099e+00, 0.7775000683430e-01,
-      0.2000164937936e-06, 0.4030009638488e+01, 0.2093666171530e+00,
-      0.1966105136719e-06, 0.8745955786834e+00, 0.2172315424036e+00,
-
-      0.1904742332624e-06, 0.5919743598964e+01, 0.2022531624851e+00,
-      0.1657399705031e-06, 0.2549141484884e+01, 0.7358765972222e+00,
-      0.1574070533987e-06, 0.5277533020230e+01, 0.7429900518901e+00,
-      0.1832261651039e-06, 0.3064688127777e+01, 0.3235053470014e+00,
-      0.1733615346569e-06, 0.3011432799094e+01, 0.1385174140878e+00,
-      0.1549124014496e-06, 0.4005569132359e+01, 0.5154640627760e+00,
-      0.1637044713838e-06, 0.1831375966632e+01, 0.8531963191132e+00,
-      0.1123420082383e-06, 0.1180270407578e+01, 0.1990721704425e+00,
-      0.1083754165740e-06, 0.3414101320863e+00, 0.5439178814476e+00,
-      0.1156638012655e-06, 0.6130479452594e+00, 0.5257585094865e+00,
-
-      0.1142548785134e-06, 0.3724761948846e+01, 0.5336234347371e+00,
-      0.7921463895965e-07, 0.2435425589361e+01, 0.1478866649112e+01,
-      0.7428600285231e-07, 0.3542144398753e+01, 0.2164800718209e+00,
-      0.8323211246747e-07, 0.3525058072354e+01, 0.1692165728891e+01,
-      0.7257595116312e-07, 0.1364299431982e+01, 0.2101180877357e+00,
-      0.7111185833236e-07, 0.2460478875808e+01, 0.4155522422634e+00,
-      0.6868090383716e-07, 0.4397327670704e+01, 0.1173197218910e+00,
-      0.7226419974175e-07, 0.4042647308905e+01, 0.1265567569334e+01,
-      0.6955642383177e-07, 0.2865047906085e+01, 0.9562891316684e+00,
-      0.7492139296331e-07, 0.5014278994215e+01, 0.1422690933580e-01,
-
-      0.6598363128857e-07, 0.2376730020492e+01, 0.6470106940028e+00,
-      0.7381147293385e-07, 0.3272990384244e+01, 0.1581959461667e+01,
-      0.6402909624032e-07, 0.5302290955138e+01, 0.9597935788730e-01,
-      0.6237454263857e-07, 0.5444144425332e+01, 0.7084920306520e-01,
-      0.5241198544016e-07, 0.4215359579205e+01, 0.5265099800692e+00,
-      0.5144463853918e-07, 0.1218916689916e+00, 0.5328719641544e+00,
-      0.5868164772299e-07, 0.2369402002213e+01, 0.7871412831580e-01,
-      0.6233195669151e-07, 0.1254922242403e+01, 0.2608790314060e+02,
-      0.6068463791422e-07, 0.5679713760431e+01, 0.1114304132498e+00,
-      0.4359361135065e-07, 0.6097219641646e+00, 0.1375773836557e+01,
-
-      0.4686510366826e-07, 0.4786231041431e+01, 0.1143987543936e+00,
-      0.3758977287225e-07, 0.1167368068139e+01, 0.1596186371003e+01,
-      0.4282051974778e-07, 0.1519471064319e+01, 0.2770348281756e+00,
-      0.5153765386113e-07, 0.1860532322984e+01, 0.2228608264996e+00,
-      0.4575129387188e-07, 0.7632857887158e+00, 0.1465949902372e+00,
-      0.3326844933286e-07, 0.1298219485285e+01, 0.5070101000000e-01,
-      0.3748617450984e-07, 0.1046510321062e+01, 0.4903339079539e+00,
-      0.2816756661499e-07, 0.3434522346190e+01, 0.2991266627620e+00,
-      0.3412750405039e-07, 0.2523766270318e+01, 0.3518164938661e+00,
-      0.2655796761776e-07, 0.2904422260194e+01, 0.6256703299991e+00,
-
-      0.2963597929458e-07, 0.5923900431149e+00, 0.1099462426779e+00,
-      0.2539523734781e-07, 0.4851947722567e+01, 0.1256615170089e+02,
-      0.2283087914139e-07, 0.3400498595496e+01, 0.6681224869435e+01,
-      0.2321309799331e-07, 0.5789099148673e+01, 0.3368040641550e-01,
-      0.2549657649750e-07, 0.3991856479792e-01, 0.1169588211447e+01,
-      0.2290462303977e-07, 0.2788567577052e+01, 0.1045155034888e+01,
-      0.1945398522914e-07, 0.3290896998176e+01, 0.1155361302111e+01,
-      0.1849171512638e-07, 0.2698060129367e+01, 0.4452511715700e-02,
-      0.1647199834254e-07, 0.3016735644085e+01, 0.4408250688924e+00,
-      0.1529530765273e-07, 0.5573043116178e+01, 0.6521991896920e-01,
-
-      0.1433199339978e-07, 0.1481192356147e+01, 0.9420622223326e+00,
-      0.1729134193602e-07, 0.1422817538933e+01, 0.2108507877249e+00,
-      0.1716463931346e-07, 0.3469468901855e+01, 0.2157473718317e+00,
-      0.1391206061378e-07, 0.6122436220547e+01, 0.4123712502208e+00,
-      0.1404746661924e-07, 0.1647765641936e+01, 0.4258542984690e-01,
-      0.1410452399455e-07, 0.5989729161964e+01, 0.2258291676434e+00,
-      0.1089828772168e-07, 0.2833705509371e+01, 0.4226656969313e+00,
-      0.1047374564948e-07, 0.5090690007331e+00, 0.3092784376656e+00,
-      0.1358279126532e-07, 0.5128990262836e+01, 0.7923417740620e-01,
-      0.1020456476148e-07, 0.9632772880808e+00, 0.1456308687557e+00,
-
-      0.1033428735328e-07, 0.3223779318418e+01, 0.1795258541446e+01,
-      0.1412435841540e-07, 0.2410271572721e+01, 0.1525316725248e+00,
-      0.9722759371574e-08, 0.2333531395690e+01, 0.8434341241180e-01,
-      0.9657334084704e-08, 0.6199270974168e+01, 0.1272681024002e+01,
-      0.1083641148690e-07, 0.2864222292929e+01, 0.7032915397480e-01,
-      0.1067318403838e-07, 0.5833458866568e+00, 0.2123349582968e+00,
-      0.1062366201976e-07, 0.4307753989494e+01, 0.2142632012598e+00,
-      0.1236364149266e-07, 0.2873917870593e+01, 0.1847279083684e+00,
-      0.1092759489593e-07, 0.2959887266733e+01, 0.1370332435159e+00,
-      0.8912069362899e-08, 0.5141213702562e+01, 0.2648454860559e+01,
-
-      0.9656467707970e-08, 0.4532182462323e+01, 0.4376440768498e+00,
-      0.8098386150135e-08, 0.2268906338379e+01, 0.2880807454688e+00,
-      0.7857714675000e-08, 0.4055544260745e+01, 0.2037373330570e+00,
-      0.7288455940646e-08, 0.5357901655142e+01, 0.1129145838217e+00,
-      0.9450595950552e-08, 0.4264926963939e+01, 0.5272426800584e+00,
-      0.9381718247537e-08, 0.7489366976576e-01, 0.5321392641652e+00,
-      0.7079052646038e-08, 0.1923311052874e+01, 0.6288513220417e+00,
-      0.9259004415344e-08, 0.2970256853438e+01, 0.1606092486742e+00,
-      0.8259801499742e-08, 0.3327056314697e+01, 0.8389694097774e+00,
-      0.6476334355779e-08, 0.2954925505727e+01, 0.2008557621224e+01,
-
-      0.5984021492007e-08, 0.9138753105829e+00, 0.2042657109477e+02,
-      0.5989546863181e-08, 0.3244464082031e+01, 0.2111650433779e+01,
-      0.6233108606023e-08, 0.4995232638403e+00, 0.4305306221819e+00,
-      0.6877299149965e-08, 0.2834987233449e+01, 0.9561746721300e-02,
-      0.8311234227190e-08, 0.2202951835758e+01, 0.3801276407308e+00,
-      0.6599472832414e-08, 0.4478581462618e+01, 0.1063314406849e+01,
-      0.6160491096549e-08, 0.5145858696411e+01, 0.1368660381889e+01,
-      0.6164772043891e-08, 0.3762976697911e+00, 0.4234171675140e+00,
-      0.6363248684450e-08, 0.3162246718685e+01, 0.1253008786510e-01,
-      0.6448587520999e-08, 0.3442693302119e+01, 0.5287268506303e+00,
-
-      0.6431662283977e-08, 0.8977549136606e+00, 0.5306550935933e+00,
-      0.6351223158474e-08, 0.4306447410369e+01, 0.5217580628120e+02,
-      0.5476721393451e-08, 0.3888529177855e+01, 0.2221856701002e+01,
-      0.5341772572619e-08, 0.2655560662512e+01, 0.7466759693650e-01,
-      0.5337055758302e-08, 0.5164990735946e+01, 0.7489573444450e-01,
-      0.5373120816787e-08, 0.6041214553456e+01, 0.1274714967946e+00,
-      0.5392351705426e-08, 0.9177763485932e+00, 0.1055449481598e+01,
-      0.6688495850205e-08, 0.3089608126937e+01, 0.2213766559277e+00,
-      0.5072003660362e-08, 0.4311316541553e+01, 0.2132517061319e+00,
-      0.5070726650455e-08, 0.5790675464444e+00, 0.2133464534247e+00,
-
-      0.5658012950032e-08, 0.2703945510675e+01, 0.7287631425543e+00,
-      0.4835509924854e-08, 0.2975422976065e+01, 0.7160067364790e-01,
-      0.6479821978012e-08, 0.1324168733114e+01, 0.2209183458640e-01,
-      0.6230636494980e-08, 0.2860103632836e+01, 0.3306188016693e+00,
-      0.4649239516213e-08, 0.4832259763403e+01, 0.7796265773310e-01,
-      0.6487325792700e-08, 0.2726165825042e+01, 0.3884652414254e+00,
-      0.4682823682770e-08, 0.6966602455408e+00, 0.1073608853559e+01,
-      0.5704230804976e-08, 0.5669634104606e+01, 0.8731175355560e-01,
-      0.6125413585489e-08, 0.1513386538915e+01, 0.7605151500000e-01,
-      0.6035825038187e-08, 0.1983509168227e+01, 0.9846002785331e+00,
-
-      0.4331123462303e-08, 0.2782892992807e+01, 0.4297791515992e+00,
-      0.4681107685143e-08, 0.5337232886836e+01, 0.2127790306879e+00,
-      0.4669105829655e-08, 0.5837133792160e+01, 0.2138191288687e+00,
-      0.5138823602365e-08, 0.3080560200507e+01, 0.7233337363710e-01,
-      0.4615856664534e-08, 0.1661747897471e+01, 0.8603097737811e+00,
-      0.4496916702197e-08, 0.2112508027068e+01, 0.7381754420900e-01,
-      0.4278479042945e-08, 0.5716528462627e+01, 0.7574578717200e-01,
-      0.3840525503932e-08, 0.6424172726492e+00, 0.3407705765729e+00,
-      0.4866636509685e-08, 0.4919244697715e+01, 0.7722995774390e-01,
-      0.3526100639296e-08, 0.2550821052734e+01, 0.6225157782540e-01,
-
-      0.3939558488075e-08, 0.3939331491710e+01, 0.5268983110410e-01,
-      0.4041268772576e-08, 0.2275337571218e+01, 0.3503323232942e+00,
-      0.3948761842853e-08, 0.1999324200790e+01, 0.1451108196653e+00,
-      0.3258394550029e-08, 0.9121001378200e+00, 0.5296435984654e+00,
-      0.3257897048761e-08, 0.3428428660869e+01, 0.5297383457582e+00,
-      0.3842559031298e-08, 0.6132927720035e+01, 0.9098186128426e+00,
-      0.3109920095448e-08, 0.7693650193003e+00, 0.3932462625300e-02,
-      0.3132237775119e-08, 0.3621293854908e+01, 0.2346394437820e+00,
-      0.3942189421510e-08, 0.4841863659733e+01, 0.3180992042600e-02,
-      0.3796972285340e-08, 0.1814174994268e+01, 0.1862120789403e+00,
-
-      0.3995640233688e-08, 0.1386990406091e+01, 0.4549093064213e+00,
-      0.2875013727414e-08, 0.9178318587177e+00, 0.1905464808669e+01,
-      0.3073719932844e-08, 0.2688923811835e+01, 0.3628624111593e+00,
-      0.2731016580075e-08, 0.1188259127584e+01, 0.2131850110243e+00,
-      0.2729549896546e-08, 0.3702160634273e+01, 0.2134131485323e+00,
-      0.3339372892449e-08, 0.7199163960331e+00, 0.2007689919132e+00,
-      0.2898833764204e-08, 0.1916709364999e+01, 0.5291709230214e+00,
-      0.2894536549362e-08, 0.2424043195547e+01, 0.5302110212022e+00,
-      0.3096872473843e-08, 0.4445894977497e+01, 0.2976424921901e+00,
-      0.2635672326810e-08, 0.3814366984117e+01, 0.1485980103780e+01,
-
-      0.3649302697001e-08, 0.2924200596084e+01, 0.6044726378023e+00,
-      0.3127954585895e-08, 0.1842251648327e+01, 0.1084620721060e+00,
-      0.2616040173947e-08, 0.4155841921984e+01, 0.1258454114666e+01,
-      0.2597395859860e-08, 0.1158045978874e+00, 0.2103781122809e+00,
-      0.2593286172210e-08, 0.4771850408691e+01, 0.2162200472757e+00,
-      0.2481823585747e-08, 0.4608842558889e+00, 0.1062562936266e+01,
-      0.2742219550725e-08, 0.1538781127028e+01, 0.5651155736444e+00,
-      0.3199558469610e-08, 0.3226647822878e+00, 0.7036329877322e+00,
-      0.2666088542957e-08, 0.1967991731219e+00, 0.1400015846597e+00,
-      0.2397067430580e-08, 0.3707036669873e+01, 0.2125476091956e+00,
-
-      0.2376570772738e-08, 0.1182086628042e+01, 0.2140505503610e+00,
-      0.2547228007887e-08, 0.4906256820629e+01, 0.1534957940063e+00,
-      0.2265575594114e-08, 0.3414949866857e+01, 0.2235935264888e+00,
-      0.2464381430585e-08, 0.4599122275378e+01, 0.2091065926078e+00,
-      0.2433408527044e-08, 0.2830751145445e+00, 0.2174915669488e+00,
-      0.2443605509076e-08, 0.4212046432538e+01, 0.1739420156204e+00,
-      0.2319779262465e-08, 0.9881978408630e+00, 0.7530171478090e-01,
-      0.2284622835465e-08, 0.5565347331588e+00, 0.7426161660010e-01,
-      0.2467268750783e-08, 0.5655708150766e+00, 0.2526561439362e+00,
-      0.2808513492782e-08, 0.1418405053408e+01, 0.5636314030725e+00,
-
-      0.2329528932532e-08, 0.4069557545675e+01, 0.1056200952181e+01,
-      0.9698639532817e-09, 0.1074134313634e+01, 0.7826370942180e+02 };
-
-/* SSB-to-Sun, T^0, Y */
-   static const double s0y[] = {
-      0.4955392320126e-02, 0.2170467313679e+01, 0.5296909721118e+00,
-      0.2722325167392e-02, 0.2444433682196e+01, 0.2132990797783e+00,
-      0.1546579925346e-02, 0.5992779281546e+00, 0.3813291813120e-01,
-      0.8363140252966e-03, 0.7687356310801e+00, 0.7478166569050e-01,
-      0.3385792683603e-03, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.1201192221613e-03, 0.2520035601514e+01, 0.1059381944224e+01,
-      0.7587125720554e-04, 0.1669954006449e+01, 0.4265981595566e+00,
-      0.1964155361250e-04, 0.5707743963343e+01, 0.2061856251104e+00,
-      0.1891900364909e-04, 0.2320960679937e+01, 0.2204125344462e+00,
-      0.1937373433356e-04, 0.3226940689555e+01, 0.1495633313810e+00,
-
-      0.1437139941351e-04, 0.2301626908096e+01, 0.5225775174439e+00,
-      0.1406267683099e-04, 0.5188579265542e+01, 0.5368044267797e+00,
-      0.1178703080346e-04, 0.5489483248476e+01, 0.7626583626240e-01,
-      0.8079835186041e-05, 0.1683751835264e+01, 0.3664874755930e-01,
-      0.7623253594652e-05, 0.2656400462961e+01, 0.3961708870310e-01,
-      0.6248667483971e-05, 0.4992775362055e+01, 0.7329749511860e-01,
-      0.4366353695038e-05, 0.2869706279678e+01, 0.1589072916335e+01,
-      0.3829101568895e-05, 0.3572131359950e+01, 0.7113454667900e-02,
-      0.3175733773908e-05, 0.4535372530045e+01, 0.4194847048887e+00,
-      0.3092437902159e-05, 0.9230153317909e+00, 0.6398972393349e+00,
-
-      0.2874168812154e-05, 0.3363143761101e+01, 0.1102062672231e+00,
-      0.3040119321826e-05, 0.3324250895675e+01, 0.6283075850446e+01,
-      0.2699723308006e-05, 0.2917882441928e+00, 0.1030928125552e+00,
-      0.2134832683534e-05, 0.4220997202487e+01, 0.3163918923335e+00,
-      0.1770412139433e-05, 0.4747318496462e+01, 0.1021328554739e+02,
-      0.1377264209373e-05, 0.4305058462401e+00, 0.1484170571900e-02,
-      0.1127814538960e-05, 0.8538177240740e+00, 0.6327837846670e+00,
-      0.1055608090130e-05, 0.1551800742580e+01, 0.4337116142245e+00,
-      0.9802673861420e-06, 0.1459646735377e+01, 0.1052268489556e+01,
-      0.1090329461951e-05, 0.1587351228711e+01, 0.1162474756779e+01,
-
-      0.6959590025090e-06, 0.5534442628766e+01, 0.1066495398892e+01,
-      0.5664914529542e-06, 0.6030673003297e+01, 0.9491756770005e+00,
-      0.6607787763599e-06, 0.4989507233927e+01, 0.8460828644453e+00,
-      0.6269725742838e-06, 0.4222951804572e+01, 0.1480791608091e+00,
-      0.6301889697863e-06, 0.5444316669126e+01, 0.2243449970715e+00,
-      0.4891042662861e-06, 0.1490552839784e+01, 0.3340612434717e+01,
-      0.3457083123290e-06, 0.3030475486049e+01, 0.3516457698740e-01,
-      0.3032559967314e-06, 0.2652038793632e+01, 0.1104591729320e-01,
-      0.2841133988903e-06, 0.1276744786829e+01, 0.4110125927500e-01,
-      0.2855564444432e-06, 0.2143368674733e+01, 0.1510475019529e+00,
-
-      0.2765157135038e-06, 0.5444186109077e+01, 0.6373574839730e-01,
-      0.2382312465034e-06, 0.2190521137593e+01, 0.2275259891141e+00,
-      0.2808060365077e-06, 0.5735195064841e+01, 0.2535050500000e-01,
-      0.2332175234405e-06, 0.9481985524859e-01, 0.7181332454670e-01,
-      0.2322488199659e-06, 0.5180499361533e+01, 0.8582758298370e-01,
-      0.1881850258423e-06, 0.3219788273885e+01, 0.2118763888447e+01,
-      0.2196111392808e-06, 0.2366941159761e+01, 0.2968341143800e-02,
-      0.2183810335519e-06, 0.4825445110915e+01, 0.7775000683430e-01,
-      0.2002733093326e-06, 0.2457148995307e+01, 0.2093666171530e+00,
-      0.1967111767229e-06, 0.5586291545459e+01, 0.2172315424036e+00,
-
-      0.1568473250543e-06, 0.3708003123320e+01, 0.7429900518901e+00,
-      0.1852528314300e-06, 0.4310638151560e+01, 0.2022531624851e+00,
-      0.1832111226447e-06, 0.1494665322656e+01, 0.3235053470014e+00,
-      0.1746805502310e-06, 0.1451378500784e+01, 0.1385174140878e+00,
-      0.1555730966650e-06, 0.1068040418198e+01, 0.7358765972222e+00,
-      0.1554883462559e-06, 0.2442579035461e+01, 0.5154640627760e+00,
-      0.1638380568746e-06, 0.2597913420625e+00, 0.8531963191132e+00,
-      0.1159938593640e-06, 0.5834512021280e+01, 0.1990721704425e+00,
-      0.1083427965695e-06, 0.5054033177950e+01, 0.5439178814476e+00,
-      0.1156480369431e-06, 0.5325677432457e+01, 0.5257585094865e+00,
-
-      0.1141308860095e-06, 0.2153403923857e+01, 0.5336234347371e+00,
-      0.7913146470946e-07, 0.8642846847027e+00, 0.1478866649112e+01,
-      0.7439752463733e-07, 0.1970628496213e+01, 0.2164800718209e+00,
-      0.7280277104079e-07, 0.6073307250609e+01, 0.2101180877357e+00,
-      0.8319567719136e-07, 0.1954371928334e+01, 0.1692165728891e+01,
-      0.7137705549290e-07, 0.8904989440909e+00, 0.4155522422634e+00,
-      0.6900825396225e-07, 0.2825717714977e+01, 0.1173197218910e+00,
-      0.7245757216635e-07, 0.2481677513331e+01, 0.1265567569334e+01,
-      0.6961165696255e-07, 0.1292955312978e+01, 0.9562891316684e+00,
-      0.7571804456890e-07, 0.3427517575069e+01, 0.1422690933580e-01,
-
-      0.6605425721904e-07, 0.8052192701492e+00, 0.6470106940028e+00,
-      0.7375477357248e-07, 0.1705076390088e+01, 0.1581959461667e+01,
-      0.7041664951470e-07, 0.4848356967891e+00, 0.9597935788730e-01,
-      0.6322199535763e-07, 0.3878069473909e+01, 0.7084920306520e-01,
-      0.5244380279191e-07, 0.2645560544125e+01, 0.5265099800692e+00,
-      0.5143125704988e-07, 0.4834486101370e+01, 0.5328719641544e+00,
-      0.5871866319373e-07, 0.7981472548900e+00, 0.7871412831580e-01,
-      0.6300822573871e-07, 0.5979398788281e+01, 0.2608790314060e+02,
-      0.6062154271548e-07, 0.4108655402756e+01, 0.1114304132498e+00,
-      0.4361912339976e-07, 0.5322624319280e+01, 0.1375773836557e+01,
-
-      0.4417005920067e-07, 0.6240817359284e+01, 0.2770348281756e+00,
-      0.4686806749936e-07, 0.3214977301156e+01, 0.1143987543936e+00,
-      0.3758892132305e-07, 0.5879809634765e+01, 0.1596186371003e+01,
-      0.5151351332319e-07, 0.2893377688007e+00, 0.2228608264996e+00,
-      0.4554683578572e-07, 0.5475427144122e+01, 0.1465949902372e+00,
-      0.3442381385338e-07, 0.5992034796640e+01, 0.5070101000000e-01,
-      0.2831093954933e-07, 0.5367350273914e+01, 0.3092784376656e+00,
-      0.3756267090084e-07, 0.5758171285420e+01, 0.4903339079539e+00,
-      0.2816374679892e-07, 0.1863718700923e+01, 0.2991266627620e+00,
-      0.3419307025569e-07, 0.9524347534130e+00, 0.3518164938661e+00,
-
-      0.2904250494239e-07, 0.5304471615602e+01, 0.1099462426779e+00,
-      0.2471734511206e-07, 0.1297069793530e+01, 0.6256703299991e+00,
-      0.2539620831872e-07, 0.3281126083375e+01, 0.1256615170089e+02,
-      0.2281017868007e-07, 0.1829122133165e+01, 0.6681224869435e+01,
-      0.2275319473335e-07, 0.5797198160181e+01, 0.3932462625300e-02,
-      0.2547755368442e-07, 0.4752697708330e+01, 0.1169588211447e+01,
-      0.2285979669317e-07, 0.1223205292886e+01, 0.1045155034888e+01,
-      0.1913386560994e-07, 0.1757532993389e+01, 0.1155361302111e+01,
-      0.1809020525147e-07, 0.4246116108791e+01, 0.3368040641550e-01,
-      0.1649213300201e-07, 0.1445162890627e+01, 0.4408250688924e+00,
-
-      0.1834972793932e-07, 0.1126917567225e+01, 0.4452511715700e-02,
-      0.1439550648138e-07, 0.6160756834764e+01, 0.9420622223326e+00,
-      0.1487645457041e-07, 0.4358761931792e+01, 0.4123712502208e+00,
-      0.1731729516660e-07, 0.6134456753344e+01, 0.2108507877249e+00,
-      0.1717747163567e-07, 0.1898186084455e+01, 0.2157473718317e+00,
-      0.1418190430374e-07, 0.4180286741266e+01, 0.6521991896920e-01,
-      0.1404844134873e-07, 0.7654053565412e-01, 0.4258542984690e-01,
-      0.1409842846538e-07, 0.4418612420312e+01, 0.2258291676434e+00,
-      0.1090948346291e-07, 0.1260615686131e+01, 0.4226656969313e+00,
-      0.1357577323612e-07, 0.3558248818690e+01, 0.7923417740620e-01,
-
-      0.1018154061960e-07, 0.5676087241256e+01, 0.1456308687557e+00,
-      0.1412073972109e-07, 0.8394392632422e+00, 0.1525316725248e+00,
-      0.1030938326496e-07, 0.1653593274064e+01, 0.1795258541446e+01,
-      0.1180081567104e-07, 0.1285802592036e+01, 0.7032915397480e-01,
-      0.9708510575650e-08, 0.7631889488106e+00, 0.8434341241180e-01,
-      0.9637689663447e-08, 0.4630642649176e+01, 0.1272681024002e+01,
-      0.1068910429389e-07, 0.5294934032165e+01, 0.2123349582968e+00,
-      0.1063716179336e-07, 0.2736266800832e+01, 0.2142632012598e+00,
-      0.1234858713814e-07, 0.1302891146570e+01, 0.1847279083684e+00,
-      0.8912631189738e-08, 0.3570415993621e+01, 0.2648454860559e+01,
-
-      0.1036378285534e-07, 0.4236693440949e+01, 0.1370332435159e+00,
-      0.9667798501561e-08, 0.2960768892398e+01, 0.4376440768498e+00,
-      0.8108314201902e-08, 0.6987781646841e+00, 0.2880807454688e+00,
-      0.7648364324628e-08, 0.2499017863863e+01, 0.2037373330570e+00,
-      0.7286136828406e-08, 0.3787426951665e+01, 0.1129145838217e+00,
-      0.9448237743913e-08, 0.2694354332983e+01, 0.5272426800584e+00,
-      0.9374276106428e-08, 0.4787121277064e+01, 0.5321392641652e+00,
-      0.7100226287462e-08, 0.3530238792101e+00, 0.6288513220417e+00,
-      0.9253056659571e-08, 0.1399478925664e+01, 0.1606092486742e+00,
-      0.6636432145504e-08, 0.3479575438447e+01, 0.1368660381889e+01,
-
-      0.6469975312932e-08, 0.1383669964800e+01, 0.2008557621224e+01,
-      0.7335849729765e-08, 0.1243698166898e+01, 0.9561746721300e-02,
-      0.8743421205855e-08, 0.3776164289301e+01, 0.3801276407308e+00,
-      0.5993635744494e-08, 0.5627122113596e+01, 0.2042657109477e+02,
-      0.5981008479693e-08, 0.1674336636752e+01, 0.2111650433779e+01,
-      0.6188535145838e-08, 0.5214925208672e+01, 0.4305306221819e+00,
-      0.6596074017566e-08, 0.2907653268124e+01, 0.1063314406849e+01,
-      0.6630815126226e-08, 0.2127643669658e+01, 0.8389694097774e+00,
-      0.6156772830040e-08, 0.5082160803295e+01, 0.4234171675140e+00,
-      0.6446960563014e-08, 0.1872100916905e+01, 0.5287268506303e+00,
-
-      0.6429324424668e-08, 0.5610276103577e+01, 0.5306550935933e+00,
-      0.6302232396465e-08, 0.1592152049607e+01, 0.1253008786510e-01,
-      0.6399244436159e-08, 0.2746214421532e+01, 0.5217580628120e+02,
-      0.5474965172558e-08, 0.2317666374383e+01, 0.2221856701002e+01,
-      0.5339293190692e-08, 0.1084724961156e+01, 0.7466759693650e-01,
-      0.5334733683389e-08, 0.3594106067745e+01, 0.7489573444450e-01,
-      0.5392665782110e-08, 0.5630254365606e+01, 0.1055449481598e+01,
-      0.6682075673789e-08, 0.1518480041732e+01, 0.2213766559277e+00,
-      0.5079130495960e-08, 0.2739765115711e+01, 0.2132517061319e+00,
-      0.5077759793261e-08, 0.5290711290094e+01, 0.2133464534247e+00,
-
-      0.4832037368310e-08, 0.1404473217200e+01, 0.7160067364790e-01,
-      0.6463279674802e-08, 0.6038381695210e+01, 0.2209183458640e-01,
-      0.6240592771560e-08, 0.1290170653666e+01, 0.3306188016693e+00,
-      0.4672013521493e-08, 0.3261895939677e+01, 0.7796265773310e-01,
-      0.6500650750348e-08, 0.1154522312095e+01, 0.3884652414254e+00,
-      0.6344161389053e-08, 0.6206111545062e+01, 0.7605151500000e-01,
-      0.4682518370646e-08, 0.5409118796685e+01, 0.1073608853559e+01,
-      0.5329460015591e-08, 0.1202985784864e+01, 0.7287631425543e+00,
-      0.5701588675898e-08, 0.4098715257064e+01, 0.8731175355560e-01,
-      0.6030690867211e-08, 0.4132033218460e+00, 0.9846002785331e+00,
-
-      0.4336256312655e-08, 0.1211415991827e+01, 0.4297791515992e+00,
-      0.4688498808975e-08, 0.3765479072409e+01, 0.2127790306879e+00,
-      0.4675578609335e-08, 0.4265540037226e+01, 0.2138191288687e+00,
-      0.4225578112158e-08, 0.5237566010676e+01, 0.3407705765729e+00,
-      0.5139422230028e-08, 0.1507173079513e+01, 0.7233337363710e-01,
-      0.4619995093571e-08, 0.9023957449848e-01, 0.8603097737811e+00,
-      0.4494776255461e-08, 0.5414930552139e+00, 0.7381754420900e-01,
-      0.4274026276788e-08, 0.4145735303659e+01, 0.7574578717200e-01,
-      0.5018141789353e-08, 0.3344408829055e+01, 0.3180992042600e-02,
-      0.4866163952181e-08, 0.3348534657607e+01, 0.7722995774390e-01,
-
-      0.4111986020501e-08, 0.4198823597220e+00, 0.1451108196653e+00,
-      0.3356142784950e-08, 0.5609144747180e+01, 0.1274714967946e+00,
-      0.4070575554551e-08, 0.7028411059224e+00, 0.3503323232942e+00,
-      0.3257451857278e-08, 0.5624697983086e+01, 0.5296435984654e+00,
-      0.3256973703026e-08, 0.1857842076707e+01, 0.5297383457582e+00,
-      0.3830771508640e-08, 0.4562887279931e+01, 0.9098186128426e+00,
-      0.3725024005962e-08, 0.2358058692652e+00, 0.1084620721060e+00,
-      0.3136763921756e-08, 0.2049731526845e+01, 0.2346394437820e+00,
-      0.3795147256194e-08, 0.2432356296933e+00, 0.1862120789403e+00,
-      0.2877342229911e-08, 0.5631101279387e+01, 0.1905464808669e+01,
-
-      0.3076931798805e-08, 0.1117615737392e+01, 0.3628624111593e+00,
-      0.2734765945273e-08, 0.5899826516955e+01, 0.2131850110243e+00,
-      0.2733405296885e-08, 0.2130562964070e+01, 0.2134131485323e+00,
-      0.2898552353410e-08, 0.3462387048225e+00, 0.5291709230214e+00,
-      0.2893736103681e-08, 0.8534352781543e+00, 0.5302110212022e+00,
-      0.3095717734137e-08, 0.2875061429041e+01, 0.2976424921901e+00,
-      0.2636190425832e-08, 0.2242512846659e+01, 0.1485980103780e+01,
-      0.3645512095537e-08, 0.1354016903958e+01, 0.6044726378023e+00,
-      0.2808173547723e-08, 0.6705114365631e-01, 0.6225157782540e-01,
-      0.2625012866888e-08, 0.4775705748482e+01, 0.5268983110410e-01,
-
-      0.2572233995651e-08, 0.2638924216139e+01, 0.1258454114666e+01,
-      0.2604238824792e-08, 0.4826358927373e+01, 0.2103781122809e+00,
-      0.2596886385239e-08, 0.3200388483118e+01, 0.2162200472757e+00,
-      0.3228057304264e-08, 0.5384848409563e+01, 0.2007689919132e+00,
-      0.2481601798252e-08, 0.5173373487744e+01, 0.1062562936266e+01,
-      0.2745977498864e-08, 0.6250966149853e+01, 0.5651155736444e+00,
-      0.2669878833811e-08, 0.4906001352499e+01, 0.1400015846597e+00,
-      0.3203986611711e-08, 0.5034333010005e+01, 0.7036329877322e+00,
-      0.3354961227212e-08, 0.6108262423137e+01, 0.4549093064213e+00,
-      0.2400407324558e-08, 0.2135399294955e+01, 0.2125476091956e+00,
-
-      0.2379905859802e-08, 0.5893721933961e+01, 0.2140505503610e+00,
-      0.2550844302187e-08, 0.3331940762063e+01, 0.1534957940063e+00,
-      0.2268824211001e-08, 0.1843418461035e+01, 0.2235935264888e+00,
-      0.2464700891204e-08, 0.3029548547230e+01, 0.2091065926078e+00,
-      0.2436814726024e-08, 0.4994717970364e+01, 0.2174915669488e+00,
-      0.2443623894745e-08, 0.2645102591375e+01, 0.1739420156204e+00,
-      0.2318701783838e-08, 0.5700547397897e+01, 0.7530171478090e-01,
-      0.2284448700256e-08, 0.5268898905872e+01, 0.7426161660010e-01,
-      0.2468848123510e-08, 0.5276280575078e+01, 0.2526561439362e+00,
-      0.2814052350303e-08, 0.6130168623475e+01, 0.5636314030725e+00,
-
-      0.2243662755220e-08, 0.6631692457995e+00, 0.8886590321940e-01,
-      0.2330795855941e-08, 0.2499435487702e+01, 0.1056200952181e+01,
-      0.9757679038404e-09, 0.5796846023126e+01, 0.7826370942180e+02 };
-
-/* SSB-to-Sun, T^0, Z */
-   static const double s0z[] = {
-      0.1181255122986e-03, 0.4607918989164e+00, 0.2132990797783e+00,
-      0.1127777651095e-03, 0.4169146331296e+00, 0.5296909721118e+00,
-      0.4777754401806e-04, 0.4582657007130e+01, 0.3813291813120e-01,
-      0.1129354285772e-04, 0.5758735142480e+01, 0.7478166569050e-01,
-     -0.1149543637123e-04, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.3298730512306e-05, 0.5978801994625e+01, 0.4265981595566e+00,
-      0.2733376706079e-05, 0.7665413691040e+00, 0.1059381944224e+01,
-      0.9426389657270e-06, 0.3710201265838e+01, 0.2061856251104e+00,
-      0.8187517749552e-06, 0.3390675605802e+00, 0.2204125344462e+00,
-      0.4080447871819e-06, 0.4552296640088e+00, 0.5225775174439e+00,
-
-      0.3169973017028e-06, 0.3445455899321e+01, 0.5368044267797e+00,
-      0.2438098615549e-06, 0.5664675150648e+01, 0.3664874755930e-01,
-      0.2601897517235e-06, 0.1931894095697e+01, 0.1495633313810e+00,
-      0.2314558080079e-06, 0.3666319115574e+00, 0.3961708870310e-01,
-      0.1962549548002e-06, 0.3167411699020e+01, 0.7626583626240e-01,
-      0.2180518287925e-06, 0.1544420746580e+01, 0.7113454667900e-02,
-      0.1451382442868e-06, 0.1583756740070e+01, 0.1102062672231e+00,
-      0.1358439007389e-06, 0.5239941758280e+01, 0.6398972393349e+00,
-      0.1050585898028e-06, 0.2266958352859e+01, 0.3163918923335e+00,
-      0.1050029870186e-06, 0.2711495250354e+01, 0.4194847048887e+00,
-
-      0.9934920679800e-07, 0.1116208151396e+01, 0.1589072916335e+01,
-      0.1048395331560e-06, 0.3408619600206e+01, 0.1021328554739e+02,
-      0.8370147196668e-07, 0.3810459401087e+01, 0.2535050500000e-01,
-      0.7989856510998e-07, 0.3769910473647e+01, 0.7329749511860e-01,
-      0.5441221655233e-07, 0.2416994903374e+01, 0.1030928125552e+00,
-      0.4610812906784e-07, 0.5858503336994e+01, 0.4337116142245e+00,
-      0.3923022803444e-07, 0.3354170010125e+00, 0.1484170571900e-02,
-      0.2610725582128e-07, 0.5410600646324e+01, 0.6327837846670e+00,
-      0.2455279767721e-07, 0.6120216681403e+01, 0.1162474756779e+01,
-      0.2375530706525e-07, 0.6055443426143e+01, 0.1052268489556e+01,
-
-      0.1782967577553e-07, 0.3146108708004e+01, 0.8460828644453e+00,
-      0.1581687095238e-07, 0.6255496089819e+00, 0.3340612434717e+01,
-      0.1594657672461e-07, 0.3782604300261e+01, 0.1066495398892e+01,
-      0.1563448615040e-07, 0.1997775733196e+01, 0.2022531624851e+00,
-      0.1463624258525e-07, 0.1736316792088e+00, 0.3516457698740e-01,
-      0.1331585056673e-07, 0.4331941830747e+01, 0.9491756770005e+00,
-      0.1130634557637e-07, 0.6152017751825e+01, 0.2968341143800e-02,
-      0.1028949607145e-07, 0.2101792614637e+00, 0.2275259891141e+00,
-      0.1024074971618e-07, 0.4071833211074e+01, 0.5070101000000e-01,
-      0.8826956060303e-08, 0.4861633688145e+00, 0.2093666171530e+00,
-
-      0.8572230171541e-08, 0.5268190724302e+01, 0.4110125927500e-01,
-      0.7649332643544e-08, 0.5134543417106e+01, 0.2608790314060e+02,
-      0.8581673291033e-08, 0.2920218146681e+01, 0.1480791608091e+00,
-      0.8430589300938e-08, 0.3604576619108e+01, 0.2172315424036e+00,
-      0.7776165501012e-08, 0.3772942249792e+01, 0.6373574839730e-01,
-      0.8311070234408e-08, 0.6200412329888e+01, 0.3235053470014e+00,
-      0.6927365212582e-08, 0.4543353113437e+01, 0.8531963191132e+00,
-      0.6791574208598e-08, 0.2882188406238e+01, 0.7181332454670e-01,
-      0.5593100811839e-08, 0.1776646892780e+01, 0.7429900518901e+00,
-      0.4553381853021e-08, 0.3949617611240e+01, 0.7775000683430e-01,
-
-      0.5758000450068e-08, 0.3859251775075e+01, 0.1990721704425e+00,
-      0.4281283457133e-08, 0.1466294631206e+01, 0.2118763888447e+01,
-      0.4206935661097e-08, 0.5421776011706e+01, 0.1104591729320e-01,
-      0.4213751641837e-08, 0.3412048993322e+01, 0.2243449970715e+00,
-      0.5310506239878e-08, 0.5421641370995e+00, 0.5154640627760e+00,
-      0.3827450341320e-08, 0.8887314524995e+00, 0.1510475019529e+00,
-      0.4292435241187e-08, 0.1405043757194e+01, 0.1422690933580e-01,
-      0.3189780702289e-08, 0.1060049293445e+01, 0.1173197218910e+00,
-      0.3226611928069e-08, 0.6270858897442e+01, 0.2164800718209e+00,
-      0.2893897608830e-08, 0.5117563223301e+01, 0.6470106940028e+00,
-
-      0.3239852024578e-08, 0.4079092237983e+01, 0.2101180877357e+00,
-      0.2956892222200e-08, 0.1594917021704e+01, 0.3092784376656e+00,
-      0.2980177912437e-08, 0.5258787667564e+01, 0.4155522422634e+00,
-      0.3163725690776e-08, 0.3854589225479e+01, 0.8582758298370e-01,
-      0.2662262399118e-08, 0.3561326430187e+01, 0.5257585094865e+00,
-      0.2766689135729e-08, 0.3180732086830e+00, 0.1385174140878e+00,
-      0.2411600278464e-08, 0.3324798335058e+01, 0.5439178814476e+00,
-      0.2483527695131e-08, 0.4169069291947e+00, 0.5336234347371e+00,
-      0.7788777276590e-09, 0.1900569908215e+01, 0.5217580628120e+02 };
-
-/* SSB-to-Sun, T^1, X */
-   static const double s1x[] = {
-     -0.1296310361520e-07, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.8975769009438e-08, 0.1128891609250e+01, 0.4265981595566e+00,
-      0.7771113441307e-08, 0.2706039877077e+01, 0.2061856251104e+00,
-      0.7538303866642e-08, 0.2191281289498e+01, 0.2204125344462e+00,
-      0.6061384579336e-08, 0.3248167319958e+01, 0.1059381944224e+01,
-      0.5726994235594e-08, 0.5569981398610e+01, 0.5225775174439e+00,
-      0.5616492836424e-08, 0.5057386614909e+01, 0.5368044267797e+00,
-      0.1010881584769e-08, 0.3473577116095e+01, 0.7113454667900e-02,
-      0.7259606157626e-09, 0.3651858593665e+00, 0.6398972393349e+00,
-      0.8755095026935e-09, 0.1662835408338e+01, 0.4194847048887e+00,
-
-      0.5370491182812e-09, 0.1327673878077e+01, 0.4337116142245e+00,
-      0.5743773887665e-09, 0.4250200846687e+01, 0.2132990797783e+00,
-      0.4408103140300e-09, 0.3598752574277e+01, 0.1589072916335e+01,
-      0.3101892374445e-09, 0.4887822983319e+01, 0.1052268489556e+01,
-      0.3209453713578e-09, 0.9702272295114e+00, 0.5296909721118e+00,
-      0.3017228286064e-09, 0.5484462275949e+01, 0.1066495398892e+01,
-      0.3200700038601e-09, 0.2846613338643e+01, 0.1495633313810e+00,
-      0.2137637279911e-09, 0.5692163292729e+00, 0.3163918923335e+00,
-      0.1899686386727e-09, 0.2061077157189e+01, 0.2275259891141e+00,
-      0.1401994545308e-09, 0.4177771136967e+01, 0.1102062672231e+00,
-
-      0.1578057810499e-09, 0.5782460597335e+01, 0.7626583626240e-01,
-      0.1237713253351e-09, 0.5705900866881e+01, 0.5154640627760e+00,
-      0.1313076837395e-09, 0.5163438179576e+01, 0.3664874755930e-01,
-      0.1184963304860e-09, 0.3054804427242e+01, 0.6327837846670e+00,
-      0.1238130878565e-09, 0.2317292575962e+01, 0.3961708870310e-01,
-      0.1015959527736e-09, 0.2194643645526e+01, 0.7329749511860e-01,
-      0.9017954423714e-10, 0.2868603545435e+01, 0.1990721704425e+00,
-      0.8668024955603e-10, 0.4923849675082e+01, 0.5439178814476e+00,
-      0.7756083930103e-10, 0.3014334135200e+01, 0.9491756770005e+00,
-      0.7536503401741e-10, 0.2704886279769e+01, 0.1030928125552e+00,
-
-      0.5483308679332e-10, 0.6010983673799e+01, 0.8531963191132e+00,
-      0.5184339620428e-10, 0.1952704573291e+01, 0.2093666171530e+00,
-      0.5108658712030e-10, 0.2958575786649e+01, 0.2172315424036e+00,
-      0.5019424524650e-10, 0.1736317621318e+01, 0.2164800718209e+00,
-      0.4909312625978e-10, 0.3167216416257e+01, 0.2101180877357e+00,
-      0.4456638901107e-10, 0.7697579923471e+00, 0.3235053470014e+00,
-      0.4227030350925e-10, 0.3490910137928e+01, 0.6373574839730e-01,
-      0.4095456040093e-10, 0.5178888984491e+00, 0.6470106940028e+00,
-      0.4990537041422e-10, 0.3323887668974e+01, 0.1422690933580e-01,
-      0.4321170010845e-10, 0.4288484987118e+01, 0.7358765972222e+00,
-
-      0.3544072091802e-10, 0.6021051579251e+01, 0.5265099800692e+00,
-      0.3480198638687e-10, 0.4600027054714e+01, 0.5328719641544e+00,
-      0.3440287244435e-10, 0.4349525970742e+01, 0.8582758298370e-01,
-      0.3330628322713e-10, 0.2347391505082e+01, 0.1104591729320e-01,
-      0.2973060707184e-10, 0.4789409286400e+01, 0.5257585094865e+00,
-      0.2932606766089e-10, 0.5831693799927e+01, 0.5336234347371e+00,
-      0.2876972310953e-10, 0.2692638514771e+01, 0.1173197218910e+00,
-      0.2827488278556e-10, 0.2056052487960e+01, 0.2022531624851e+00,
-      0.2515028239756e-10, 0.7411863262449e+00, 0.9597935788730e-01,
-      0.2853033744415e-10, 0.3948481024894e+01, 0.2118763888447e+01 };
-
-/* SSB-to-Sun, T^1, Y */
-   static const double s1y[] = {
-      0.8989047573576e-08, 0.5840593672122e+01, 0.4265981595566e+00,
-      0.7815938401048e-08, 0.1129664707133e+01, 0.2061856251104e+00,
-      0.7550926713280e-08, 0.6196589104845e+00, 0.2204125344462e+00,
-      0.6056556925895e-08, 0.1677494667846e+01, 0.1059381944224e+01,
-      0.5734142698204e-08, 0.4000920852962e+01, 0.5225775174439e+00,
-      0.5614341822459e-08, 0.3486722577328e+01, 0.5368044267797e+00,
-      0.1028678147656e-08, 0.1877141024787e+01, 0.7113454667900e-02,
-      0.7270792075266e-09, 0.5077167301739e+01, 0.6398972393349e+00,
-      0.8734141726040e-09, 0.9069550282609e-01, 0.4194847048887e+00,
-      0.5377371402113e-09, 0.6039381844671e+01, 0.4337116142245e+00,
-
-      0.4729719431571e-09, 0.2153086311760e+01, 0.2132990797783e+00,
-      0.4458052820973e-09, 0.5059830025565e+01, 0.5296909721118e+00,
-      0.4406855467908e-09, 0.2027971692630e+01, 0.1589072916335e+01,
-      0.3101659310977e-09, 0.3317677981860e+01, 0.1052268489556e+01,
-      0.3016749232545e-09, 0.3913703482532e+01, 0.1066495398892e+01,
-      0.3198541352656e-09, 0.1275513098525e+01, 0.1495633313810e+00,
-      0.2142065389871e-09, 0.5301351614597e+01, 0.3163918923335e+00,
-      0.1902615247592e-09, 0.4894943352736e+00, 0.2275259891141e+00,
-      0.1613410990871e-09, 0.2449891130437e+01, 0.1102062672231e+00,
-      0.1576992165097e-09, 0.4211421447633e+01, 0.7626583626240e-01,
-
-      0.1241637259894e-09, 0.4140803368133e+01, 0.5154640627760e+00,
-      0.1313974830355e-09, 0.3591920305503e+01, 0.3664874755930e-01,
-      0.1181697118258e-09, 0.1506314382788e+01, 0.6327837846670e+00,
-      0.1238239742779e-09, 0.7461405378404e+00, 0.3961708870310e-01,
-      0.1010107068241e-09, 0.6271010795475e+00, 0.7329749511860e-01,
-      0.9226316616509e-10, 0.1259158839583e+01, 0.1990721704425e+00,
-      0.8664946419555e-10, 0.3353244696934e+01, 0.5439178814476e+00,
-      0.7757230468978e-10, 0.1447677295196e+01, 0.9491756770005e+00,
-      0.7693168628139e-10, 0.1120509896721e+01, 0.1030928125552e+00,
-      0.5487897454612e-10, 0.4439380426795e+01, 0.8531963191132e+00,
-
-      0.5196118677218e-10, 0.3788856619137e+00, 0.2093666171530e+00,
-      0.5110853339935e-10, 0.1386879372016e+01, 0.2172315424036e+00,
-      0.5027804534813e-10, 0.1647881805466e+00, 0.2164800718209e+00,
-      0.4922485922674e-10, 0.1594315079862e+01, 0.2101180877357e+00,
-      0.6155599524400e-10, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.4447147832161e-10, 0.5480720918976e+01, 0.3235053470014e+00,
-      0.4144691276422e-10, 0.1931371033660e+01, 0.6373574839730e-01,
-      0.4099950625452e-10, 0.5229611294335e+01, 0.6470106940028e+00,
-      0.5060541682953e-10, 0.1731112486298e+01, 0.1422690933580e-01,
-      0.4293615946300e-10, 0.2714571038925e+01, 0.7358765972222e+00,
-
-      0.3545659845763e-10, 0.4451041444634e+01, 0.5265099800692e+00,
-      0.3479112041196e-10, 0.3029385448081e+01, 0.5328719641544e+00,
-      0.3438516493570e-10, 0.2778507143731e+01, 0.8582758298370e-01,
-      0.3297341285033e-10, 0.7898709807584e+00, 0.1104591729320e-01,
-      0.2972585818015e-10, 0.3218785316973e+01, 0.5257585094865e+00,
-      0.2931707295017e-10, 0.4260731012098e+01, 0.5336234347371e+00,
-      0.2897198149403e-10, 0.1120753978101e+01, 0.1173197218910e+00,
-      0.2832293240878e-10, 0.4597682717827e+00, 0.2022531624851e+00,
-      0.2864348326612e-10, 0.2169939928448e+01, 0.9597935788730e-01,
-      0.2852714675471e-10, 0.2377659870578e+01, 0.2118763888447e+01 };
-
-/* SSB-to-Sun, T^1, Z */
-   static const double s1z[] = {
-      0.5444220475678e-08, 0.1803825509310e+01, 0.2132990797783e+00,
-      0.3883412695596e-08, 0.4668616389392e+01, 0.5296909721118e+00,
-      0.1334341434551e-08, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.3730001266883e-09, 0.5401405918943e+01, 0.2061856251104e+00,
-      0.2894929197956e-09, 0.4932415609852e+01, 0.2204125344462e+00,
-      0.2857950357701e-09, 0.3154625362131e+01, 0.7478166569050e-01,
-      0.2499226432292e-09, 0.3657486128988e+01, 0.4265981595566e+00,
-      0.1937705443593e-09, 0.5740434679002e+01, 0.1059381944224e+01,
-      0.1374894396320e-09, 0.1712857366891e+01, 0.5368044267797e+00,
-      0.1217248678408e-09, 0.2312090870932e+01, 0.5225775174439e+00,
-
-      0.7961052740870e-10, 0.5283368554163e+01, 0.3813291813120e-01,
-      0.4979225949689e-10, 0.4298290471860e+01, 0.4194847048887e+00,
-      0.4388552286597e-10, 0.6145515047406e+01, 0.7113454667900e-02,
-      0.2586835212560e-10, 0.3019448001809e+01, 0.6398972393349e+00 };
-
-/* SSB-to-Sun, T^2, X */
-   static const double s2x[] = {
-      0.1603551636587e-11, 0.4404109410481e+01, 0.2061856251104e+00,
-      0.1556935889384e-11, 0.4818040873603e+00, 0.2204125344462e+00,
-      0.1182594414915e-11, 0.9935762734472e+00, 0.5225775174439e+00,
-      0.1158794583180e-11, 0.3353180966450e+01, 0.5368044267797e+00,
-      0.9597358943932e-12, 0.5567045358298e+01, 0.2132990797783e+00,
-      0.6511516579605e-12, 0.5630872420788e+01, 0.4265981595566e+00,
-      0.7419792747688e-12, 0.2156188581957e+01, 0.5296909721118e+00,
-      0.3951972655848e-12, 0.1981022541805e+01, 0.1059381944224e+01,
-      0.4478223877045e-12, 0.0000000000000e+00, 0.0000000000000e+00 };
-
-/* SSB-to-Sun, T^2, Y */
-   static const double s2y[] = {
-      0.1609114495091e-11, 0.2831096993481e+01, 0.2061856251104e+00,
-      0.1560330784946e-11, 0.5193058213906e+01, 0.2204125344462e+00,
-      0.1183535479202e-11, 0.5707003443890e+01, 0.5225775174439e+00,
-      0.1158183066182e-11, 0.1782400404928e+01, 0.5368044267797e+00,
-      0.1032868027407e-11, 0.4036925452011e+01, 0.2132990797783e+00,
-      0.6540142847741e-12, 0.4058241056717e+01, 0.4265981595566e+00,
-      0.7305236491596e-12, 0.6175401942957e+00, 0.5296909721118e+00,
-     -0.5580725052968e-12, 0.0000000000000e+00, 0.0000000000000e+00,
-      0.3946122651015e-12, 0.4108265279171e+00, 0.1059381944224e+01 };
-
-/* SSB-to-Sun, T^2, Z */
-   static const double s2z[] = {
-      0.3749920358054e-12, 0.3230285558668e+01, 0.2132990797783e+00,
-      0.2735037220939e-12, 0.6154322683046e+01, 0.5296909721118e+00 };
-
-/* Pointers to coefficient arrays, in x,y,z sets */
-   static const double *ce0[] = { e0x, e0y, e0z },
-                       *ce1[] = { e1x, e1y, e1z },
-                       *ce2[] = { e2x, e2y, e2z },
-                       *cs0[] = { s0x, s0y, s0z },
-                       *cs1[] = { s1x, s1y, s1z },
-                       *cs2[] = { s2x, s2y, s2z };
-   const double *coeffs;
-
-/* Numbers of terms for each component of the model, in x,y,z sets */
-   static const int ne0[3] = {(int)(sizeof e0x / sizeof (double) / 3),
-                              (int)(sizeof e0y / sizeof (double) / 3),
-                              (int)(sizeof e0z / sizeof (double) / 3) },
-                    ne1[3] = {(int)(sizeof e1x / sizeof (double) / 3),
-                              (int)(sizeof e1y / sizeof (double) / 3),
-                              (int)(sizeof e1z / sizeof (double) / 3) },
-                    ne2[3] = {(int)(sizeof e2x / sizeof (double) / 3),
-                              (int)(sizeof e2y / sizeof (double) / 3),
-                              (int)(sizeof e2z / sizeof (double) / 3) },
-                    ns0[3] = {(int)(sizeof s0x / sizeof (double) / 3),
-                              (int)(sizeof s0y / sizeof (double) / 3),
-                              (int)(sizeof s0z / sizeof (double) / 3) },
-                    ns1[3] = {(int)(sizeof s1x / sizeof (double) / 3),
-                              (int)(sizeof s1y / sizeof (double) / 3),
-                              (int)(sizeof s1z / sizeof (double) / 3) },
-                    ns2[3] = {(int)(sizeof s2x / sizeof (double) / 3),
-                              (int)(sizeof s2y / sizeof (double) / 3),
-                              (int)(sizeof s2z / sizeof (double) / 3) };
-   int nterms;
-
-/* Miscellaneous */
-   int jstat, i, j;
-   double t, t2, xyz, xyzd, a, b, c, ct, p, cp,
-          ph[3], vh[3], pb[3], vb[3], x, y, z;
-
-/*--------------------------------------------------------------------*/
-
-/* Time since reference epoch, Julian years. */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
-   t2 = t*t;
-
-/* Set status. */
-   jstat = fabs(t) <= 100.0 ? 0 : 1;
-
-/* X then Y then Z. */
-   for (i = 0; i < 3; i++) {
-
-   /* Initialize position and velocity component. */
-      xyz = 0.0;
-      xyzd = 0.0;
-
-   /* ------------------------------------------------ */
-   /* Obtain component of Sun to Earth ecliptic vector */
-   /* ------------------------------------------------ */
-
-   /* Sun to Earth, T^0 terms. */
-      coeffs = ce0[i];
-      nterms = ne0[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         p = b + c*t;
-         xyz  += a*cos(p);
-         xyzd -= a*c*sin(p);
-      }
-
-   /* Sun to Earth, T^1 terms. */
-      coeffs = ce1[i];
-      nterms = ne1[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         ct = c*t;
-         p = b + ct;
-         cp = cos(p);
-         xyz  += a*t*cp;
-         xyzd += a*( cp - ct*sin(p) );
-      }
-
-   /* Sun to Earth, T^2 terms. */
-      coeffs = ce2[i];
-      nterms = ne2[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         ct = c*t;
-         p = b + ct;
-         cp = cos(p);
-         xyz  += a*t2*cp;
-         xyzd += a*t*( 2.0*cp - ct*sin(p) );
-      }
-
-   /* Heliocentric Earth position and velocity component. */
-      ph[i] = xyz;
-      vh[i] = xyzd / ERFA_DJY;
-
-   /* ------------------------------------------------ */
-   /* Obtain component of SSB to Earth ecliptic vector */
-   /* ------------------------------------------------ */
-
-   /* SSB to Sun, T^0 terms. */
-      coeffs = cs0[i];
-      nterms = ns0[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         p = b + c*t;
-         xyz  += a*cos(p);
-         xyzd -= a*c*sin(p);
-      }
-
-   /* SSB to Sun, T^1 terms. */
-      coeffs = cs1[i];
-      nterms = ns1[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         ct = c*t;
-         p = b + ct;
-         cp = cos(p);
-         xyz  += a*t*cp;
-         xyzd += a*(cp - ct*sin(p));
-      }
-
-   /* SSB to Sun, T^2 terms. */
-      coeffs = cs2[i];
-      nterms = ns2[i];
-      for (j = 0; j < nterms; j++) {
-         a = *coeffs++;
-         b = *coeffs++;
-         c = *coeffs++;
-         ct = c*t;
-         p = b + ct;
-         cp = cos(p);
-         xyz  += a*t2*cp;
-         xyzd += a*t*(2.0*cp - ct*sin(p));
-     }
-
-   /* Barycentric Earth position and velocity component. */
-     pb[i] = xyz;
-     vb[i] = xyzd / ERFA_DJY;
-
-   /* Next Cartesian component. */
-   }
-
-/* Rotate from ecliptic to BCRS coordinates. */
-
-   x = ph[0];
-   y = ph[1];
-   z = ph[2];
-   pvh[0][0] =      x + am12*y + am13*z;
-   pvh[0][1] = am21*x + am22*y + am23*z;
-   pvh[0][2] =          am32*y + am33*z;
-
-   x = vh[0];
-   y = vh[1];
-   z = vh[2];
-   pvh[1][0] =      x + am12*y + am13*z;
-   pvh[1][1] = am21*x + am22*y + am23*z;
-   pvh[1][2] =          am32*y + am33*z;
-
-   x = pb[0];
-   y = pb[1];
-   z = pb[2];
-   pvb[0][0] =      x + am12*y + am13*z;
-   pvb[0][1] = am21*x + am22*y + am23*z;
-   pvb[0][2] =          am32*y + am33*z;
-
-   x = vb[0];
-   y = vb[1];
-   z = vb[2];
-   pvb[1][0] =      x + am12*y + am13*z;
-   pvb[1][1] = am21*x + am22*y + am23*z;
-   pvb[1][2] =          am32*y + am33*z;
-
-/* Return the status. */
-   return jstat;
-
-}
-
-double eraEqeq94(double date1, double date2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t,  om,  dpsi,  deps,  eps0, ee;
-
-
-/* Interval between fundamental epoch J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Longitude of the mean ascending node of the lunar orbit on the */
-/* ecliptic, measured from the mean equinox of date. */
-   om = eraAnpm((450160.280 + (-482890.539
-           + (7.455 + 0.008 * t) * t) * t) * ERFA_DAS2R
-           + fmod(-5.0 * t, 1.0) * ERFA_D2PI);
-
-/* Nutation components and mean obliquity. */
-   eraNut80(date1, date2, &dpsi, &deps);
-   eps0 = eraObl80(date1, date2);
-
-/* Equation of the equinoxes. */
-   ee = dpsi*cos(eps0) + ERFA_DAS2R*(0.00264*sin(om) + 0.000063*sin(om+om));
-
-   return ee;
-
-}
-
-double eraEra00(double dj1, double dj2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double d1, d2, t, f, theta;
-
-
-/* Days since fundamental epoch. */
-   if (dj1 < dj2) {
-      d1 = dj1;
-      d2 = dj2;
-   } else {
-      d1 = dj2;
-      d2 = dj1;
-   }
-   t = d1 + (d2- ERFA_DJ00);
-
-/* Fractional part of T (days). */
-   f = fmod(d1, 1.0) + fmod(d2, 1.0);
-
-/* Earth rotation angle at this UT1. */
-   theta = eraAnp(ERFA_D2PI * (f + 0.7790572732640
-                            + 0.00273781191135448 * t));
-
-   return theta;
-
-}
-
-double eraFad03(double t)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean elongation of the Moon from the Sun (IERS Conventions 2003). */
-   a = fmod(          1072260.703692 +
-             t * ( 1602961601.2090 +
-             t * (        - 6.3706 +
-             t * (          0.006593 +
-             t * (        - 0.00003169 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
-
-   return a;
-
-}
-
-double eraFae03(double t)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Earth (IERS Conventions 2003). */
-   a = fmod(1.753470314 + 628.3075849991 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFaf03(double t)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of the Moon minus that of the ascending node */
-/* (IERS Conventions 2003).                                    */
-   a = fmod(           335779.526232 +
-             t * ( 1739527262.8478 +
-             t * (       - 12.7512 +
-             t * (        - 0.001037 +
-             t * (          0.00000417 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
-
-   return a;
-
-
-}
-
-double eraFaju03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Jupiter (IERS Conventions 2003). */
-   a = fmod(0.599546497 + 52.9690962641 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFal03(double t)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean anomaly of the Moon (IERS Conventions 2003). */
-   a = fmod(           485868.249036  +
-             t * ( 1717915923.2178 +
-             t * (         31.8792 +
-             t * (          0.051635 +
-             t * (        - 0.00024470 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
-
-   return a;
-
-}
-
-double eraFalp03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean anomaly of the Sun (IERS Conventions 2003). */
-   a = fmod(         1287104.793048 +
-             t * ( 129596581.0481 +
-             t * (       - 0.5532 +
-             t * (         0.000136 +
-             t * (       - 0.00001149 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
-
-   return a;
-
-}
-
-double eraFama03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Mars (IERS Conventions 2003). */
-   a = fmod(6.203480913 + 334.0612426700 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFame03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Mercury (IERS Conventions 2003). */
-   a = fmod(4.402608842 + 2608.7903141574 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFane03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Neptune (IERS Conventions 2003). */
-   a = fmod(5.311886287 + 3.8133035638 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFaom03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of the Moon's ascending node */
-/* (IERS Conventions 2003).                    */
-   a = fmod(          450160.398036 +
-             t * ( - 6962890.5431 +
-             t * (         7.4722 +
-             t * (         0.007702 +
-             t * (       - 0.00005939 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
-
-   return a;
-
-}
-
-double eraFapa03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* General accumulated precession in longitude. */
-   a = (0.024381750 + 0.00000538691 * t) * t;
-
-   return a;
-
-}
-
-double eraFasa03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Saturn (IERS Conventions 2003). */
-   a = fmod(0.874016757 + 21.3299104960 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFaur03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Uranus (IERS Conventions 2003). */
-   a = fmod(5.481293872 + 7.4781598567 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-double eraFave03(double t)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double a;
-
-
-/* Mean longitude of Venus (IERS Conventions 2003). */
-   a = fmod(3.176146697 + 1021.3285546211 * t, ERFA_D2PI);
-
-   return a;
-
-}
-
-void eraFk52h(double r5, double d5,
-              double dr5, double dd5, double px5, double rv5,
-              double *rh, double *dh,
-              double *drh, double *ddh, double *pxh, double *rvh)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i;
-   double pv5[2][3], r5h[3][3], s5h[3], wxp[3], vv[3], pvh[2][3];
-
-
-/* FK5 barycentric position/velocity pv-vector (normalized). */
-   eraStarpv(r5, d5, dr5, dd5, px5, rv5, pv5);
-
-/* FK5 to Hipparcos orientation matrix and spin vector. */
-   eraFk5hip(r5h, s5h);
-
-/* Make spin units per day instead of per year. */
-   for ( i = 0; i < 3; s5h[i++] /= 365.25 );
-
-/* Orient the FK5 position into the Hipparcos system. */
-   eraRxp(r5h, pv5[0], pvh[0]);
-
-/* Apply spin to the position giving an extra space motion component. */
-   eraPxp(pv5[0], s5h, wxp);
-
-/* Add this component to the FK5 space motion. */
-   eraPpp(wxp, pv5[1], vv);
-
-/* Orient the FK5 space motion into the Hipparcos system. */
-   eraRxp(r5h, vv, pvh[1]);
-
-/* Hipparcos pv-vector to spherical. */
-   eraPvstar(pvh, rh, dh, drh, ddh, pxh, rvh);
-
-   return;
-
-}
-
-void eraFk5hip(double r5h[3][3], double s5h[3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double v[3];
-
-/* FK5 wrt Hipparcos orientation and spin (radians, radians/year) */
-   double epx, epy, epz;
-   double omx, omy, omz;
-
-
-   epx = -19.9e-3 * ERFA_DAS2R;
-   epy =  -9.1e-3 * ERFA_DAS2R;
-   epz =  22.9e-3 * ERFA_DAS2R;
-
-   omx = -0.30e-3 * ERFA_DAS2R;
-   omy =  0.60e-3 * ERFA_DAS2R;
-   omz =  0.70e-3 * ERFA_DAS2R;
-
-/* FK5 to Hipparcos orientation expressed as an r-vector. */
-   v[0] = epx;
-   v[1] = epy;
-   v[2] = epz;
-
-/* Re-express as an r-matrix. */
-   eraRv2m(v, r5h);
-
-/* Hipparcos wrt FK5 spin expressed as an r-vector. */
-   s5h[0] = omx;
-   s5h[1] = omy;
-   s5h[2] = omz;
-
-   return;
-
-}
-
-void eraFk5hz(double r5, double d5, double date1, double date2,
-              double *rh, double *dh)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, p5e[3], r5h[3][3], s5h[3], vst[3], rst[3][3], p5[3],
-          ph[3], w;
-
-
-/* Interval from given date to fundamental epoch J2000.0 (JY). */
-   t = - ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
-
-/* FK5 barycentric position vector. */
-   eraS2c(r5, d5, p5e);
-
-/* FK5 to Hipparcos orientation matrix and spin vector. */
-   eraFk5hip(r5h, s5h);
-
-/* Accumulated Hipparcos wrt FK5 spin over that interval. */
-   eraSxp(t, s5h, vst);
-
-/* Express the accumulated spin as a rotation matrix. */
-   eraRv2m(vst, rst);
-
-/* Derotate the vector's FK5 axes back to date. */
-   eraTrxp(rst, p5e, p5);
-
-/* Rotate the vector into the Hipparcos system. */
-   eraRxp(r5h, p5, ph);
-
-/* Hipparcos vector to spherical. */
-   eraC2s(ph, &w, dh);
-   *rh = eraAnp(w);
-
-   return;
-
-}
-
-void eraFw2m(double gamb, double phib, double psi, double eps,
-             double r[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Construct the matrix. */
-   eraIr(r);
-   eraRz(gamb, r);
-   eraRx(phib, r);
-   eraRz(-psi, r);
-   eraRx(-eps, r);
-
-   return;
-
-}
-
-void eraFw2xy(double gamb, double phib, double psi, double eps,
-              double *x, double *y)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r[3][3];
-
-
-/* Form NxPxB matrix. */
-   eraFw2m(gamb, phib, psi, eps, r);
-
-/* Extract CIP X,Y. */
-   eraBpn2xy(r, x, y);
-
-   return;
-
-}
-
-int eraGc2gd ( int n, double xyz[3],
-               double *elong, double *phi, double *height )
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   double a, f;
-
-
-/* Obtain reference ellipsoid parameters. */
-   j = eraEform ( n, &a, &f );
-
-/* If OK, transform x,y,z to longitude, geodetic latitude, height. */
-   if ( j == 0 ) {
-      j = eraGc2gde ( a, f, xyz, elong, phi, height );
-      if ( j < 0 ) j = -2;
-   }
-
-/* Deal with any errors. */
-   if ( j < 0 ) {
-      *elong = -1e9;
-      *phi = -1e9;
-      *height = -1e9;
-   }
-
-/* Return the status. */
-   return j;
-
-}
-
-int eraGc2gde ( double a, double f, double xyz[3],
-                double *elong, double *phi, double *height )
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double aeps2, e2, e4t, ec2, ec, b, x, y, z, p2, absz, p, s0, pn, zc,
-                 c0, c02, c03, s02, s03, a02, a0, a03, d0, f0, b0, s1,
-                 cc, s12, cc2;
-
-
-/* ------------- */
-/* Preliminaries */
-/* ------------- */
-
-/* Validate ellipsoid parameters. */
-   if ( f < 0.0 || f >= 1.0 ) return -1;
-   if ( a <= 0.0 ) return -2;
-
-/* Functions of ellipsoid parameters (with further validation of f). */
-   aeps2 = a*a * 1e-32;
-   e2 = (2.0 - f) * f;
-   e4t = e2*e2 * 1.5;
-   ec2 = 1.0 - e2;
-   if ( ec2 <= 0.0 ) return -1;
-   ec = sqrt(ec2);
-   b = a * ec;
-
-/* Cartesian components. */
-   x = xyz[0];
-   y = xyz[1];
-   z = xyz[2];
-
-/* Distance from polar axis squared. */
-   p2 = x*x + y*y;
-
-/* Longitude. */
-   *elong = p2 != 0.0 ? atan2(y, x) : 0.0;
-
-/* Unsigned z-coordinate. */
-   absz = fabs(z);
-
-/* Proceed unless polar case. */
-   if ( p2 > aeps2 ) {
-
-   /* Distance from polar axis. */
-      p = sqrt(p2);
-
-   /* Normalization. */
-      s0 = absz / a;
-      pn = p / a;
-      zc = ec * s0;
-
-   /* Prepare Newton correction factors. */
-      c0 = ec * pn;
-      c02 = c0 * c0;
-      c03 = c02 * c0;
-      s02 = s0 * s0;
-      s03 = s02 * s0;
-      a02 = c02 + s02;
-      a0 = sqrt(a02);
-      a03 = a02 * a0;
-      d0 = zc*a03 + e2*s03;
-      f0 = pn*a03 - e2*c03;
-
-   /* Prepare Halley correction factor. */
-      b0 = e4t * s02 * c02 * pn * (a0 - ec);
-      s1 = d0*f0 - b0*s0;
-      cc = ec * (f0*f0 - b0*c0);
-
-   /* Evaluate latitude and height. */
-      *phi = atan(s1/cc);
-      s12 = s1 * s1;
-      cc2 = cc * cc;
-      *height = (p*cc + absz*s1 - a * sqrt(ec2*s12 + cc2)) /
-                                                        sqrt(s12 + cc2);
-   } else {
-
-   /* Exception: pole. */
-      *phi = ERFA_DPI / 2.0;
-      *height = absz - b;
-   }
-
-/* Restore sign of latitude. */
-   if ( z < 0 ) *phi = -*phi;
-
-/* OK status. */
-   return 0;
-
-}
-
-int eraGd2gc ( int n, double elong, double phi, double height,
-               double xyz[3] )
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j;
-   double a, f;
-
-
-/* Obtain reference ellipsoid parameters. */
-   j = eraEform ( n, &a, &f );
-
-/* If OK, transform longitude, geodetic latitude, height to x,y,z. */
-   if ( j == 0 ) {
-      j = eraGd2gce ( a, f, elong, phi, height, xyz );
-      if ( j != 0 ) j = -2;
-   }
-
-/* Deal with any errors. */
-   if ( j != 0 ) eraZp ( xyz );
-
-/* Return the status. */
-   return j;
-
-}
-
-int eraGd2gce ( double a, double f, double elong, double phi,
-                double height, double xyz[3] )
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double sp, cp, w, d, ac, as, r;
-
-
-/* Functions of geodetic latitude. */
-   sp = sin(phi);
-   cp = cos(phi);
-   w = 1.0 - f;
-   w = w * w;
-   d = cp*cp + w*sp*sp;
-   if ( d <= 0.0 ) return -1;
-   ac = a / sqrt(d);
-   as = w * ac;
-
-/* Geocentric vector. */
-   r = (ac + height) * cp;
-   xyz[0] = r * cos(elong);
-   xyz[1] = r * sin(elong);
-   xyz[2] = (as + height) * sp;
-
-/* Success. */
-   return 0;
-
-}
-
-double eraGmst00(double uta, double utb, double tta, double ttb)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, gmst;
-
-
-/* TT Julian centuries since J2000.0. */
-   t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
-
-/* Greenwich Mean Sidereal Time, IAU 2000. */
-   gmst = eraAnp(eraEra00(uta, utb) +
-                   (     0.014506   +
-                   (  4612.15739966 +
-                   (     1.39667721 +
-                   (    -0.00009344 +
-                   (     0.00001882 )
-          * t) * t) * t) * t) * ERFA_DAS2R);
-
-   return gmst;
-
-}
-
-double eraGmst06(double uta, double utb, double tta, double ttb)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, gmst;
-
-
-/* TT Julian centuries since J2000.0. */
-   t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
-
-/* Greenwich mean sidereal time, IAU 2006. */
-   gmst = eraAnp(eraEra00(uta, utb) +
-                  (    0.014506     +
-                  (  4612.156534    +
-                  (     1.3915817   +
-                  (    -0.00000044  +
-                  (    -0.000029956 +
-                  (    -0.0000000368 )
-          * t) * t) * t) * t) * t) * ERFA_DAS2R);
-
-   return gmst;
-
-}
-
-double eraGmst82(double dj1, double dj2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Coefficients of IAU 1982 GMST-UT1 model */
-   double A = 24110.54841  -  ERFA_DAYSEC / 2.0;
-   double B = 8640184.812866;
-   double C = 0.093104;
-   double D =  -6.2e-6;
-
-/* Note: the first constant, A, has to be adjusted by 12 hours */
-/* because the UT1 is supplied as a Julian date, which begins  */
-/* at noon.                                                    */
-
-   double d1, d2, t, f, gmst;
-
-
-/* Julian centuries since fundamental epoch. */
-   if (dj1 < dj2) {
-      d1 = dj1;
-      d2 = dj2;
-   } else {
-      d1 = dj2;
-      d2 = dj1;
-   }
-   t = (d1 + (d2 - ERFA_DJ00)) / ERFA_DJC;
-
-/* Fractional part of JD(UT1), in seconds. */
-   f = ERFA_DAYSEC * (fmod(d1, 1.0) + fmod(d2, 1.0));
-
-/* GMST at this UT1. */
-   gmst = eraAnp(ERFA_DS2R * ((A + (B + (C + D * t) * t) * t) + f));
-
-   return gmst;
-
-}
-
-double eraGst00a(double uta, double utb, double tta, double ttb)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gmst00, ee00a, gst;
-
-
-   gmst00 = eraGmst00(uta, utb, tta, ttb);
-   ee00a = eraEe00a(tta, ttb);
-   gst = eraAnp(gmst00 + ee00a);
-
-   return gst;
-
-}
-
-double eraGst00b(double uta, double utb)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gmst00, ee00b, gst;
-
-
-   gmst00 = eraGmst00(uta, utb, uta, utb);
-   ee00b = eraEe00b(uta, utb);
-   gst = eraAnp(gmst00 + ee00b);
-
-   return gst;
-
-}
-
-double eraGst06(double uta, double utb, double tta, double ttb,
-                double rnpb[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y, s, era, eors, gst;
-
-
-/* Extract CIP coordinates. */
-   eraBpn2xy(rnpb, &x, &y);
-
-/* The CIO locator, s. */
-   s = eraS06(tta, ttb, x, y);
-
-/* Greenwich apparent sidereal time. */
-   era = eraEra00(uta, utb);
-   eors = eraEors(rnpb, s);
-   gst = eraAnp(era - eors);
-
-   return gst;
-
-}
-
-double eraGst06a(double uta, double utb, double tta, double ttb)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rnpb[3][3], gst;
-
-
-/* Classical nutation x precession x bias matrix, IAU 2000A. */
-   eraPnm06a(tta, ttb, rnpb);
-
-/* Greenwich apparent sidereal time. */
-   gst = eraGst06(uta, utb, tta, ttb, rnpb);
-
-   return gst;
-
-}
-
-double eraGst94(double uta, double utb)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gmst82, eqeq94, gst;
-
-
-   gmst82 = eraGmst82(uta, utb);
-   eqeq94 = eraEqeq94(uta, utb);
-   gst = eraAnp(gmst82  + eqeq94);
-
-   return gst;
-
-}
-
-void eraH2fk5(double rh, double dh,
-              double drh, double ddh, double pxh, double rvh,
-              double *r5, double *d5,
-              double *dr5, double *dd5, double *px5, double *rv5)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i;
-   double pvh[2][3], r5h[3][3], s5h[3], sh[3], wxp[3], vv[3], pv5[2][3];
-
-
-/* Hipparcos barycentric position/velocity pv-vector (normalized). */
-   eraStarpv(rh, dh, drh, ddh, pxh, rvh, pvh);
-
-/* FK5 to Hipparcos orientation matrix and spin vector. */
-   eraFk5hip(r5h, s5h);
-
-/* Make spin units per day instead of per year. */
-   for ( i = 0; i < 3; s5h[i++] /= 365.25 );
-
-/* Orient the spin into the Hipparcos system. */
-   eraRxp(r5h, s5h, sh);
-
-/* De-orient the Hipparcos position into the FK5 system. */
-   eraTrxp(r5h, pvh[0], pv5[0]);
-
-/* Apply spin to the position giving an extra space motion component. */
-   eraPxp(pvh[0], sh, wxp);
-
-/* Subtract this component from the Hipparcos space motion. */
-   eraPmp(pvh[1], wxp, vv);
-
-/* De-orient the Hipparcos space motion into the FK5 system. */
-   eraTrxp(r5h, vv, pv5[1]);
-
-/* FK5 pv-vector to spherical. */
-   eraPvstar(pv5, r5, d5, dr5, dd5, px5, rv5);
-
-   return;
-
-}
-
-void eraHfk5z(double rh, double dh, double date1, double date2,
-              double *r5, double *d5, double *dr5, double *dd5)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, ph[3], r5h[3][3], s5h[3], sh[3], vst[3],
-   rst[3][3], r5ht[3][3], pv5e[2][3], vv[3],
-   w, r, v;
-
-
-/* Time interval from fundamental epoch J2000.0 to given date (JY). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
-
-/* Hipparcos barycentric position vector (normalized). */
-   eraS2c(rh, dh, ph);
-
-/* FK5 to Hipparcos orientation matrix and spin vector. */
-   eraFk5hip(r5h, s5h);
-
-/* Rotate the spin into the Hipparcos system. */
-   eraRxp(r5h, s5h, sh);
-
-/* Accumulated Hipparcos wrt FK5 spin over that interval. */
-   eraSxp(t, s5h, vst);
-
-/* Express the accumulated spin as a rotation matrix. */
-   eraRv2m(vst, rst);
-
-/* Rotation matrix:  accumulated spin, then FK5 to Hipparcos. */
-   eraRxr(r5h, rst, r5ht);
-
-/* De-orient & de-spin the Hipparcos position into FK5 J2000.0. */
-   eraTrxp(r5ht, ph, pv5e[0]);
-
-/* Apply spin to the position giving a space motion. */
-   eraPxp(sh, ph, vv);
-
-/* De-orient & de-spin the Hipparcos space motion into FK5 J2000.0. */
-   eraTrxp(r5ht, vv, pv5e[1]);
-
-/* FK5 position/velocity pv-vector to spherical. */
-   eraPv2s(pv5e, &w, d5, &r, dr5, dd5, &v);
-   *r5 = eraAnp(w);
-
-   return;
-
-}
-
-void eraIr(double r[3][3])
-/*
-**  - - - - - -
-**   e r a I r
-**  - - - - - -
-**
-**  Initialize an r-matrix to the identity matrix.
-**
-**  Returned:
-**     r       double[3][3]    r-matrix
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   r[0][0] = 1.0;
-   r[0][1] = 0.0;
-   r[0][2] = 0.0;
-   r[1][0] = 0.0;
-   r[1][1] = 1.0;
-   r[1][2] = 0.0;
-   r[2][0] = 0.0;
-   r[2][1] = 0.0;
-   r[2][2] = 1.0;
-
-   return;
-
-}
-
-int eraJd2cal(double dj1, double dj2,
-              int *iy, int *im, int *id, double *fd)
-/*
-**  - - - - - - - - - -
-**   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 3)
-**
-**  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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Minimum and maximum allowed JD */
-   const double DJMIN = -68569.5;
-   const double DJMAX = 1e9;
-
-   long jd, l, n, i, k;
-   double dj, d1, d2, f1, f2, f, d;
-
-
-/* Verify date is acceptable. */
-   dj = dj1 + dj2;
-   if (dj < DJMIN || dj > DJMAX) return -1;
-
-/* Copy the date, big then small, and re-align to midnight. */
-   if (dj1 >= dj2) {
-      d1 = dj1;
-      d2 = dj2;
-   } else {
-      d1 = dj2;
-      d2 = dj1;
-   }
-   d2 -= 0.5;
-
-/* Separate day and fraction. */
-   f1 = fmod(d1, 1.0);
-   f2 = fmod(d2, 1.0);
-   f = fmod(f1 + f2, 1.0);
-   if (f < 0.0) f += 1.0;
-   d = floor(d1 - f1) + floor(d2 - f2) + floor(f1 + f2 - f);
-   jd = (long) floor(d) + 1L;
-
-/* Express day in Gregorian calendar. */
-   l = jd + 68569L;
-   n = (4L * l) / 146097L;
-   l -= (146097L * n + 3L) / 4L;
-   i = (4000L * (l + 1L)) / 1461001L;
-   l -= (1461L * i) / 4L - 31L;
-   k = (80L * l) / 2447L;
-   *id = (int) (l - (2447L * k) / 80L);
-   l = k / 11L;
-   *im = (int) (k + 2L - 12L * l);
-   *iy = (int) (100L * (n - 49L) + i + l);
-   *fd = f;
-
-   return 0;
-
-}
-
-int eraJdcalf(int ndp, double dj1, double dj2, int iymdf[4])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int j, js;
-   double denom, d1, d2, f1, f2, f;
-
-
-/* Denominator of fraction (e.g. 100 for 2 decimal places). */
-   if ((ndp >= 0) && (ndp <= 9)) {
-      j = 0;
-      denom = pow(10.0, ndp);
-   } else {
-      j = 1;
-      denom = 1.0;
-   }
-
-/* Copy the date, big then small, and realign to midnight. */
-   if (dj1 >= dj2) {
-      d1 = dj1;
-      d2 = dj2;
-   } else {
-      d1 = dj2;
-      d2 = dj1;
-   }
-   d2 -= 0.5;
-
-/* Separate days and fractions. */
-   f1 = fmod(d1, 1.0);
-   f2 = fmod(d2, 1.0);
-   d1 = floor(d1 - f1);
-   d2 = floor(d2 - f2);
-
-/* Round the total fraction to the specified number of places. */
-   f = floor((f1+f2)*denom + 0.5) / denom;
-
-/* Re-assemble the rounded date and re-align to noon. */
-   d2 += f + 0.5;
-
-/* Convert to Gregorian calendar. */
-   js = eraJd2cal(d1, d2, &iymdf[0], &iymdf[1], &iymdf[2], &f);
-   if (js == 0) {
-      iymdf[3] = (int) (f * denom);
-   } else {
-      j = js;
-   }
-
-/* Return the status. */
-   return j;
-
-}
-
-void eraLd(double bm, double p[3], double q[3], double e[3],
-           double em, double dlim, double p1[3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i;
-   double qpe[3], qdqpe, w, eq[3], peq[3];
-
-
-/* q . (q + e). */
-   for (i = 0; i < 3; i++) {
-      qpe[i] = q[i] + e[i];
-   }
-   qdqpe = eraPdp(q, qpe);
-
-/* 2 x G x bm / ( em x c^2 x ( q . (q + e) ) ). */
-   w = bm * ERFA_SRS / em / ERFA_GMAX(qdqpe,dlim);
-
-/* p x (e x q). */
-   eraPxp(e, q, eq);
-   eraPxp(p, eq, peq);
-
-/* Apply the deflection. */
-   for (i = 0; i < 3; i++) {
-      p1[i] = p[i] + w*peq[i];
-   }
-
-/* Finished. */
-
-}
-
-void eraLdn(int n, eraLDBODY b[], double ob[3], double sc[3],
-            double sn[3])
-/*+
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Light time for 1 AU (days) */
-   const double CR = ERFA_AULT/ERFA_DAYSEC;
-
-   int i;
-   double  v[3], dt, ev[3], em, e[3];
-
-
-/* Star direction prior to deflection. */
-   eraCp(sc, sn);
-
-/* Body by body. */
-   for ( i = 0; i < n; i++ ) {
-
-   /* Body to observer vector at epoch of observation (au). */
-      eraPmp ( ob, b[i].pv[0], v );
-
-   /* Minus the time since the light passed the body (days). */
-      dt = eraPdp(sn,v) * CR;
-
-   /* Neutralize if the star is "behind" the observer. */
-      dt = ERFA_GMIN(dt, 0.0);
-
-   /* Backtrack the body to the time the light was passing the body. */
-      eraPpsp(v, -dt, b[i].pv[1], ev);
-
-   /* Body to observer vector as magnitude and direction. */
-      eraPn(ev, &em, e);
-
-   /* Apply light deflection for this body. */
-      eraLd ( b[i].bm, sn, sn, e, em, b[i].dl, sn );
-
-   /* Next body. */
-   }
-
-/* Finished. */
-
-}
-
-void eraLdsun(double p[3], double e[3], double em, double p1[3])
-/*
-**  - - - - - - - - -
-**   e r a L d s u n
-**  - - - - - - - - -
-**
-**  Light deflection by the Sun.
-**
-**  Given:
-**     p      double[3]  direction from observer to source (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 source (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 about 9 arcsec, falling to
-**     zero for zero separation. (The chosen threshold is within the
-**     solar limb for all solar-system applications.)
-**
-**  3) The arguments p and p1 can be the same array.
-**
-**  Called:
-**     eraLd        light deflection by a solar-system body
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraLd(1.0, p, p, e, em, 1e-9, p1);
-
-/* Finished. */
-
-}
-
-void eraNum00a(double date1, double date2, double rmatn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3];
-
-
-/* Obtain the required matrix (discarding other results). */
-   eraPn00a(date1, date2,
-            &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn);
-
-   return;
-
-}
-
-void eraNum00b(double date1, double date2, double rmatn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3];
-
-
-/* Obtain the required matrix (discarding other results). */
-   eraPn00b(date1, date2,
-            &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn);
-
-   return;
-
-}
-
-void eraNum06a(double date1, double date2, double rmatn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double eps, dp, de;
-
-
-/* Mean obliquity. */
-   eps = eraObl06(date1, date2);
-
-/* Nutation components. */
-   eraNut06a(date1, date2, &dp, &de);
-
-/* Nutation matrix. */
-   eraNumat(eps, dp, de, rmatn);
-
-   return;
-
-}
-
-void eraNumat(double epsa, double dpsi, double deps, double rmatn[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Build the rotation matrix. */
-   eraIr(rmatn);
-   eraRx(epsa, rmatn);
-   eraRz(-dpsi, rmatn);
-   eraRx(-(epsa + deps), rmatn);
-
-   return;
-
-}
-
-void eraNut00a(double date1, double date2, double *dpsi, double *deps)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i;
-   double t, el, elp, f, d, om, arg, dp, de, sarg, carg,
-          al, af, ad, aom, alme, alve, alea, alma,
-          alju, alsa, alur, alne, apa, dpsils, depsls,
-          dpsipl, depspl;
-
-/* Units of 0.1 microarcsecond to radians */
-   const double U2R = ERFA_DAS2R / 1e7;
-
-/* ------------------------- */
-/* Luni-Solar nutation model */
-/* ------------------------- */
-
-/* The units for the sine and cosine coefficients are */
-/* 0.1 microarcsecond and the same per Julian century */
-
-   static const struct {
-      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
-      double sp,spt,cp;     /* longitude sin, t*sin, cos coefficients */
-      double ce,cet,se;     /* obliquity cos, t*cos, sin coefficients */
-   } xls[] = {
-
-   /* 1- 10 */
-      { 0, 0, 0, 0, 1,
-         -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0},
-      { 0, 0, 2,-2, 2,
-           -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0},
-      { 0, 0, 2, 0, 2,-2276413.0,-234.0,2796.0,978459.0,-485.0, 1374.0},
-      { 0, 0, 0, 0, 2,2074554.0, 207.0, -698.0,-897492.0,470.0, -291.0},
-      { 0, 1, 0, 0, 0,1475877.0,-3633.0,11817.0,73871.0,-184.0,-1924.0},
-      { 0, 1, 2,-2, 2,-516821.0,1226.0, -524.0,224386.0,-677.0, -174.0},
-      { 1, 0, 0, 0, 0, 711159.0,  73.0, -872.0,  -6750.0,  0.0,  358.0},
-      { 0, 0, 2, 0, 1,-387298.0,-367.0,  380.0, 200728.0, 18.0,  318.0},
-      { 1, 0, 2, 0, 2,-301461.0, -36.0,  816.0, 129025.0,-63.0,  367.0},
-      { 0,-1, 2,-2, 2, 215829.0,-494.0,  111.0, -95929.0,299.0,  132.0},
-
-   /* 11-20 */
-      { 0, 0, 2,-2, 1, 128227.0, 137.0,  181.0, -68982.0, -9.0,   39.0},
-      {-1, 0, 2, 0, 2, 123457.0,  11.0,   19.0, -53311.0, 32.0,   -4.0},
-      {-1, 0, 0, 2, 0, 156994.0,  10.0, -168.0,  -1235.0,  0.0,   82.0},
-      { 1, 0, 0, 0, 1,  63110.0,  63.0,   27.0, -33228.0,  0.0,   -9.0},
-      {-1, 0, 0, 0, 1, -57976.0, -63.0, -189.0,  31429.0,  0.0,  -75.0},
-      {-1, 0, 2, 2, 2, -59641.0, -11.0,  149.0,  25543.0,-11.0,   66.0},
-      { 1, 0, 2, 0, 1, -51613.0, -42.0,  129.0,  26366.0,  0.0,   78.0},
-      {-2, 0, 2, 0, 1,  45893.0,  50.0,   31.0, -24236.0,-10.0,   20.0},
-      { 0, 0, 0, 2, 0,  63384.0,  11.0, -150.0,  -1220.0,  0.0,   29.0},
-      { 0, 0, 2, 2, 2, -38571.0,  -1.0,  158.0,  16452.0,-11.0,   68.0},
-
-   /* 21-30 */
-      { 0,-2, 2,-2, 2,  32481.0,   0.0,    0.0, -13870.0,  0.0,    0.0},
-      {-2, 0, 0, 2, 0, -47722.0,   0.0,  -18.0,    477.0,  0.0,  -25.0},
-      { 2, 0, 2, 0, 2, -31046.0,  -1.0,  131.0,  13238.0,-11.0,   59.0},
-      { 1, 0, 2,-2, 2,  28593.0,   0.0,   -1.0, -12338.0, 10.0,   -3.0},
-      {-1, 0, 2, 0, 1,  20441.0,  21.0,   10.0, -10758.0,  0.0,   -3.0},
-      { 2, 0, 0, 0, 0,  29243.0,   0.0,  -74.0,   -609.0,  0.0,   13.0},
-      { 0, 0, 2, 0, 0,  25887.0,   0.0,  -66.0,   -550.0,  0.0,   11.0},
-      { 0, 1, 0, 0, 1, -14053.0, -25.0,   79.0,   8551.0, -2.0,  -45.0},
-      {-1, 0, 0, 2, 1,  15164.0,  10.0,   11.0,  -8001.0,  0.0,   -1.0},
-      { 0, 2, 2,-2, 2, -15794.0,  72.0,  -16.0,   6850.0,-42.0,   -5.0},
-
-   /* 31-40 */
-      { 0, 0,-2, 2, 0,  21783.0,   0.0,   13.0,   -167.0,  0.0,   13.0},
-      { 1, 0, 0,-2, 1, -12873.0, -10.0,  -37.0,   6953.0,  0.0,  -14.0},
-      { 0,-1, 0, 0, 1, -12654.0,  11.0,   63.0,   6415.0,  0.0,   26.0},
-      {-1, 0, 2, 2, 1, -10204.0,   0.0,   25.0,   5222.0,  0.0,   15.0},
-      { 0, 2, 0, 0, 0,  16707.0, -85.0,  -10.0,    168.0, -1.0,   10.0},
-      { 1, 0, 2, 2, 2,  -7691.0,   0.0,   44.0,   3268.0,  0.0,   19.0},
-      {-2, 0, 2, 0, 0, -11024.0,   0.0,  -14.0,    104.0,  0.0,    2.0},
-      { 0, 1, 2, 0, 2,   7566.0, -21.0,  -11.0,  -3250.0,  0.0,   -5.0},
-      { 0, 0, 2, 2, 1,  -6637.0, -11.0,   25.0,   3353.0,  0.0,   14.0},
-      { 0,-1, 2, 0, 2,  -7141.0,  21.0,    8.0,   3070.0,  0.0,    4.0},
-
-   /* 41-50 */
-      { 0, 0, 0, 2, 1,  -6302.0, -11.0,    2.0,   3272.0,  0.0,    4.0},
-      { 1, 0, 2,-2, 1,   5800.0,  10.0,    2.0,  -3045.0,  0.0,   -1.0},
-      { 2, 0, 2,-2, 2,   6443.0,   0.0,   -7.0,  -2768.0,  0.0,   -4.0},
-      {-2, 0, 0, 2, 1,  -5774.0, -11.0,  -15.0,   3041.0,  0.0,   -5.0},
-      { 2, 0, 2, 0, 1,  -5350.0,   0.0,   21.0,   2695.0,  0.0,   12.0},
-      { 0,-1, 2,-2, 1,  -4752.0, -11.0,   -3.0,   2719.0,  0.0,   -3.0},
-      { 0, 0, 0,-2, 1,  -4940.0, -11.0,  -21.0,   2720.0,  0.0,   -9.0},
-      {-1,-1, 0, 2, 0,   7350.0,   0.0,   -8.0,    -51.0,  0.0,    4.0},
-      { 2, 0, 0,-2, 1,   4065.0,   0.0,    6.0,  -2206.0,  0.0,    1.0},
-      { 1, 0, 0, 2, 0,   6579.0,   0.0,  -24.0,   -199.0,  0.0,    2.0},
-
-   /* 51-60 */
-      { 0, 1, 2,-2, 1,   3579.0,   0.0,    5.0,  -1900.0,  0.0,    1.0},
-      { 1,-1, 0, 0, 0,   4725.0,   0.0,   -6.0,    -41.0,  0.0,    3.0},
-      {-2, 0, 2, 0, 2,  -3075.0,   0.0,   -2.0,   1313.0,  0.0,   -1.0},
-      { 3, 0, 2, 0, 2,  -2904.0,   0.0,   15.0,   1233.0,  0.0,    7.0},
-      { 0,-1, 0, 2, 0,   4348.0,   0.0,  -10.0,    -81.0,  0.0,    2.0},
-      { 1,-1, 2, 0, 2,  -2878.0,   0.0,    8.0,   1232.0,  0.0,    4.0},
-      { 0, 0, 0, 1, 0,  -4230.0,   0.0,    5.0,    -20.0,  0.0,   -2.0},
-      {-1,-1, 2, 2, 2,  -2819.0,   0.0,    7.0,   1207.0,  0.0,    3.0},
-      {-1, 0, 2, 0, 0,  -4056.0,   0.0,    5.0,     40.0,  0.0,   -2.0},
-      { 0,-1, 2, 2, 2,  -2647.0,   0.0,   11.0,   1129.0,  0.0,    5.0},
-
-   /* 61-70 */
-      {-2, 0, 0, 0, 1,  -2294.0,   0.0,  -10.0,   1266.0,  0.0,   -4.0},
-      { 1, 1, 2, 0, 2,   2481.0,   0.0,   -7.0,  -1062.0,  0.0,   -3.0},
-      { 2, 0, 0, 0, 1,   2179.0,   0.0,   -2.0,  -1129.0,  0.0,   -2.0},
-      {-1, 1, 0, 1, 0,   3276.0,   0.0,    1.0,     -9.0,  0.0,    0.0},
-      { 1, 1, 0, 0, 0,  -3389.0,   0.0,    5.0,     35.0,  0.0,   -2.0},
-      { 1, 0, 2, 0, 0,   3339.0,   0.0,  -13.0,   -107.0,  0.0,    1.0},
-      {-1, 0, 2,-2, 1,  -1987.0,   0.0,   -6.0,   1073.0,  0.0,   -2.0},
-      { 1, 0, 0, 0, 2,  -1981.0,   0.0,    0.0,    854.0,  0.0,    0.0},
-      {-1, 0, 0, 1, 0,   4026.0,   0.0, -353.0,   -553.0,  0.0, -139.0},
-      { 0, 0, 2, 1, 2,   1660.0,   0.0,   -5.0,   -710.0,  0.0,   -2.0},
-
-   /* 71-80 */
-      {-1, 0, 2, 4, 2,  -1521.0,   0.0,    9.0,    647.0,  0.0,    4.0},
-      {-1, 1, 0, 1, 1,   1314.0,   0.0,    0.0,   -700.0,  0.0,    0.0},
-      { 0,-2, 2,-2, 1,  -1283.0,   0.0,    0.0,    672.0,  0.0,    0.0},
-      { 1, 0, 2, 2, 1,  -1331.0,   0.0,    8.0,    663.0,  0.0,    4.0},
-      {-2, 0, 2, 2, 2,   1383.0,   0.0,   -2.0,   -594.0,  0.0,   -2.0},
-      {-1, 0, 0, 0, 2,   1405.0,   0.0,    4.0,   -610.0,  0.0,    2.0},
-      { 1, 1, 2,-2, 2,   1290.0,   0.0,    0.0,   -556.0,  0.0,    0.0},
-      {-2, 0, 2, 4, 2,  -1214.0,   0.0,    5.0,    518.0,  0.0,    2.0},
-      {-1, 0, 4, 0, 2,   1146.0,   0.0,   -3.0,   -490.0,  0.0,   -1.0},
-      { 2, 0, 2,-2, 1,   1019.0,   0.0,   -1.0,   -527.0,  0.0,   -1.0},
-
-   /* 81-90 */
-      { 2, 0, 2, 2, 2,  -1100.0,   0.0,    9.0,    465.0,  0.0,    4.0},
-      { 1, 0, 0, 2, 1,   -970.0,   0.0,    2.0,    496.0,  0.0,    1.0},
-      { 3, 0, 0, 0, 0,   1575.0,   0.0,   -6.0,    -50.0,  0.0,    0.0},
-      { 3, 0, 2,-2, 2,    934.0,   0.0,   -3.0,   -399.0,  0.0,   -1.0},
-      { 0, 0, 4,-2, 2,    922.0,   0.0,   -1.0,   -395.0,  0.0,   -1.0},
-      { 0, 1, 2, 0, 1,    815.0,   0.0,   -1.0,   -422.0,  0.0,   -1.0},
-      { 0, 0,-2, 2, 1,    834.0,   0.0,    2.0,   -440.0,  0.0,    1.0},
-      { 0, 0, 2,-2, 3,   1248.0,   0.0,    0.0,   -170.0,  0.0,    1.0},
-      {-1, 0, 0, 4, 0,   1338.0,   0.0,   -5.0,    -39.0,  0.0,    0.0},
-      { 2, 0,-2, 0, 1,    716.0,   0.0,   -2.0,   -389.0,  0.0,   -1.0},
-
-   /* 91-100 */
-      {-2, 0, 0, 4, 0,   1282.0,   0.0,   -3.0,    -23.0,  0.0,    1.0},
-      {-1,-1, 0, 2, 1,    742.0,   0.0,    1.0,   -391.0,  0.0,    0.0},
-      {-1, 0, 0, 1, 1,   1020.0,   0.0,  -25.0,   -495.0,  0.0,  -10.0},
-      { 0, 1, 0, 0, 2,    715.0,   0.0,   -4.0,   -326.0,  0.0,    2.0},
-      { 0, 0,-2, 0, 1,   -666.0,   0.0,   -3.0,    369.0,  0.0,   -1.0},
-      { 0,-1, 2, 0, 1,   -667.0,   0.0,    1.0,    346.0,  0.0,    1.0},
-      { 0, 0, 2,-1, 2,   -704.0,   0.0,    0.0,    304.0,  0.0,    0.0},
-      { 0, 0, 2, 4, 2,   -694.0,   0.0,    5.0,    294.0,  0.0,    2.0},
-      {-2,-1, 0, 2, 0,  -1014.0,   0.0,   -1.0,      4.0,  0.0,   -1.0},
-      { 1, 1, 0,-2, 1,   -585.0,   0.0,   -2.0,    316.0,  0.0,   -1.0},
-
-   /* 101-110 */
-      {-1, 1, 0, 2, 0,   -949.0,   0.0,    1.0,      8.0,  0.0,   -1.0},
-      {-1, 1, 0, 1, 2,   -595.0,   0.0,    0.0,    258.0,  0.0,    0.0},
-      { 1,-1, 0, 0, 1,    528.0,   0.0,    0.0,   -279.0,  0.0,    0.0},
-      { 1,-1, 2, 2, 2,   -590.0,   0.0,    4.0,    252.0,  0.0,    2.0},
-      {-1, 1, 2, 2, 2,    570.0,   0.0,   -2.0,   -244.0,  0.0,   -1.0},
-      { 3, 0, 2, 0, 1,   -502.0,   0.0,    3.0,    250.0,  0.0,    2.0},
-      { 0, 1,-2, 2, 0,   -875.0,   0.0,    1.0,     29.0,  0.0,    0.0},
-      {-1, 0, 0,-2, 1,   -492.0,   0.0,   -3.0,    275.0,  0.0,   -1.0},
-      { 0, 1, 2, 2, 2,    535.0,   0.0,   -2.0,   -228.0,  0.0,   -1.0},
-      {-1,-1, 2, 2, 1,   -467.0,   0.0,    1.0,    240.0,  0.0,    1.0},
-
-   /* 111-120 */
-      { 0,-1, 0, 0, 2,    591.0,   0.0,    0.0,   -253.0,  0.0,    0.0},
-      { 1, 0, 2,-4, 1,   -453.0,   0.0,   -1.0,    244.0,  0.0,   -1.0},
-      {-1, 0,-2, 2, 0,    766.0,   0.0,    1.0,      9.0,  0.0,    0.0},
-      { 0,-1, 2, 2, 1,   -446.0,   0.0,    2.0,    225.0,  0.0,    1.0},
-      { 2,-1, 2, 0, 2,   -488.0,   0.0,    2.0,    207.0,  0.0,    1.0},
-      { 0, 0, 0, 2, 2,   -468.0,   0.0,    0.0,    201.0,  0.0,    0.0},
-      { 1,-1, 2, 0, 1,   -421.0,   0.0,    1.0,    216.0,  0.0,    1.0},
-      {-1, 1, 2, 0, 2,    463.0,   0.0,    0.0,   -200.0,  0.0,    0.0},
-      { 0, 1, 0, 2, 0,   -673.0,   0.0,    2.0,     14.0,  0.0,    0.0},
-      { 0,-1,-2, 2, 0,    658.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 121-130 */
-      { 0, 3, 2,-2, 2,   -438.0,   0.0,    0.0,    188.0,  0.0,    0.0},
-      { 0, 0, 0, 1, 1,   -390.0,   0.0,    0.0,    205.0,  0.0,    0.0},
-      {-1, 0, 2, 2, 0,    639.0, -11.0,   -2.0,    -19.0,  0.0,    0.0},
-      { 2, 1, 2, 0, 2,    412.0,   0.0,   -2.0,   -176.0,  0.0,   -1.0},
-      { 1, 1, 0, 0, 1,   -361.0,   0.0,    0.0,    189.0,  0.0,    0.0},
-      { 1, 1, 2, 0, 1,    360.0,   0.0,   -1.0,   -185.0,  0.0,   -1.0},
-      { 2, 0, 0, 2, 0,    588.0,   0.0,   -3.0,    -24.0,  0.0,    0.0},
-      { 1, 0,-2, 2, 0,   -578.0,   0.0,    1.0,      5.0,  0.0,    0.0},
-      {-1, 0, 0, 2, 2,   -396.0,   0.0,    0.0,    171.0,  0.0,    0.0},
-      { 0, 1, 0, 1, 0,    565.0,   0.0,   -1.0,     -6.0,  0.0,    0.0},
-
-   /* 131-140 */
-      { 0, 1, 0,-2, 1,   -335.0,   0.0,   -1.0,    184.0,  0.0,   -1.0},
-      {-1, 0, 2,-2, 2,    357.0,   0.0,    1.0,   -154.0,  0.0,    0.0},
-      { 0, 0, 0,-1, 1,    321.0,   0.0,    1.0,   -174.0,  0.0,    0.0},
-      {-1, 1, 0, 0, 1,   -301.0,   0.0,   -1.0,    162.0,  0.0,    0.0},
-      { 1, 0, 2,-1, 2,   -334.0,   0.0,    0.0,    144.0,  0.0,    0.0},
-      { 1,-1, 0, 2, 0,    493.0,   0.0,   -2.0,    -15.0,  0.0,    0.0},
-      { 0, 0, 0, 4, 0,    494.0,   0.0,   -2.0,    -19.0,  0.0,    0.0},
-      { 1, 0, 2, 1, 2,    337.0,   0.0,   -1.0,   -143.0,  0.0,   -1.0},
-      { 0, 0, 2, 1, 1,    280.0,   0.0,   -1.0,   -144.0,  0.0,    0.0},
-      { 1, 0, 0,-2, 2,    309.0,   0.0,    1.0,   -134.0,  0.0,    0.0},
-
-   /* 141-150 */
-      {-1, 0, 2, 4, 1,   -263.0,   0.0,    2.0,    131.0,  0.0,    1.0},
-      { 1, 0,-2, 0, 1,    253.0,   0.0,    1.0,   -138.0,  0.0,    0.0},
-      { 1, 1, 2,-2, 1,    245.0,   0.0,    0.0,   -128.0,  0.0,    0.0},
-      { 0, 0, 2, 2, 0,    416.0,   0.0,   -2.0,    -17.0,  0.0,    0.0},
-      {-1, 0, 2,-1, 1,   -229.0,   0.0,    0.0,    128.0,  0.0,    0.0},
-      {-2, 0, 2, 2, 1,    231.0,   0.0,    0.0,   -120.0,  0.0,    0.0},
-      { 4, 0, 2, 0, 2,   -259.0,   0.0,    2.0,    109.0,  0.0,    1.0},
-      { 2,-1, 0, 0, 0,    375.0,   0.0,   -1.0,     -8.0,  0.0,    0.0},
-      { 2, 1, 2,-2, 2,    252.0,   0.0,    0.0,   -108.0,  0.0,    0.0},
-      { 0, 1, 2, 1, 2,   -245.0,   0.0,    1.0,    104.0,  0.0,    0.0},
-
-   /* 151-160 */
-      { 1, 0, 4,-2, 2,    243.0,   0.0,   -1.0,   -104.0,  0.0,    0.0},
-      {-1,-1, 0, 0, 1,    208.0,   0.0,    1.0,   -112.0,  0.0,    0.0},
-      { 0, 1, 0, 2, 1,    199.0,   0.0,    0.0,   -102.0,  0.0,    0.0},
-      {-2, 0, 2, 4, 1,   -208.0,   0.0,    1.0,    105.0,  0.0,    0.0},
-      { 2, 0, 2, 0, 0,    335.0,   0.0,   -2.0,    -14.0,  0.0,    0.0},
-      { 1, 0, 0, 1, 0,   -325.0,   0.0,    1.0,      7.0,  0.0,    0.0},
-      {-1, 0, 0, 4, 1,   -187.0,   0.0,    0.0,     96.0,  0.0,    0.0},
-      {-1, 0, 4, 0, 1,    197.0,   0.0,   -1.0,   -100.0,  0.0,    0.0},
-      { 2, 0, 2, 2, 1,   -192.0,   0.0,    2.0,     94.0,  0.0,    1.0},
-      { 0, 0, 2,-3, 2,   -188.0,   0.0,    0.0,     83.0,  0.0,    0.0},
-
-   /* 161-170 */
-      {-1,-2, 0, 2, 0,    276.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 1, 0, 0, 0,   -286.0,   0.0,    1.0,      6.0,  0.0,    0.0},
-      { 0, 0, 4, 0, 2,    186.0,   0.0,   -1.0,    -79.0,  0.0,    0.0},
-      { 0, 0, 0, 0, 3,   -219.0,   0.0,    0.0,     43.0,  0.0,    0.0},
-      { 0, 3, 0, 0, 0,    276.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 2,-4, 1,   -153.0,   0.0,   -1.0,     84.0,  0.0,    0.0},
-      { 0,-1, 0, 2, 1,   -156.0,   0.0,    0.0,     81.0,  0.0,    0.0},
-      { 0, 0, 0, 4, 1,   -154.0,   0.0,    1.0,     78.0,  0.0,    0.0},
-      {-1,-1, 2, 4, 2,   -174.0,   0.0,    1.0,     75.0,  0.0,    0.0},
-      { 1, 0, 2, 4, 2,   -163.0,   0.0,    2.0,     69.0,  0.0,    1.0},
-
-   /* 171-180 */
-      {-2, 2, 0, 2, 0,   -228.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-2,-1, 2, 0, 1,     91.0,   0.0,   -4.0,    -54.0,  0.0,   -2.0},
-      {-2, 0, 0, 2, 2,    175.0,   0.0,    0.0,    -75.0,  0.0,    0.0},
-      {-1,-1, 2, 0, 2,   -159.0,   0.0,    0.0,     69.0,  0.0,    0.0},
-      { 0, 0, 4,-2, 1,    141.0,   0.0,    0.0,    -72.0,  0.0,    0.0},
-      { 3, 0, 2,-2, 1,    147.0,   0.0,    0.0,    -75.0,  0.0,    0.0},
-      {-2,-1, 0, 2, 1,   -132.0,   0.0,    0.0,     69.0,  0.0,    0.0},
-      { 1, 0, 0,-1, 1,    159.0,   0.0,  -28.0,    -54.0,  0.0,   11.0},
-      { 0,-2, 0, 2, 0,    213.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      {-2, 0, 0, 4, 1,    123.0,   0.0,    0.0,    -64.0,  0.0,    0.0},
-
-   /* 181-190 */
-      {-3, 0, 0, 0, 1,   -118.0,   0.0,   -1.0,     66.0,  0.0,    0.0},
-      { 1, 1, 2, 2, 2,    144.0,   0.0,   -1.0,    -61.0,  0.0,    0.0},
-      { 0, 0, 2, 4, 1,   -121.0,   0.0,    1.0,     60.0,  0.0,    0.0},
-      { 3, 0, 2, 2, 2,   -134.0,   0.0,    1.0,     56.0,  0.0,    1.0},
-      {-1, 1, 2,-2, 1,   -105.0,   0.0,    0.0,     57.0,  0.0,    0.0},
-      { 2, 0, 0,-4, 1,   -102.0,   0.0,    0.0,     56.0,  0.0,    0.0},
-      { 0, 0, 0,-2, 2,    120.0,   0.0,    0.0,    -52.0,  0.0,    0.0},
-      { 2, 0, 2,-4, 1,    101.0,   0.0,    0.0,    -54.0,  0.0,    0.0},
-      {-1, 1, 0, 2, 1,   -113.0,   0.0,    0.0,     59.0,  0.0,    0.0},
-      { 0, 0, 2,-1, 1,   -106.0,   0.0,    0.0,     61.0,  0.0,    0.0},
-
-   /* 191-200 */
-      { 0,-2, 2, 2, 2,   -129.0,   0.0,    1.0,     55.0,  0.0,    0.0},
-      { 2, 0, 0, 2, 1,   -114.0,   0.0,    0.0,     57.0,  0.0,    0.0},
-      { 4, 0, 2,-2, 2,    113.0,   0.0,   -1.0,    -49.0,  0.0,    0.0},
-      { 2, 0, 0,-2, 2,   -102.0,   0.0,    0.0,     44.0,  0.0,    0.0},
-      { 0, 2, 0, 0, 1,    -94.0,   0.0,    0.0,     51.0,  0.0,    0.0},
-      { 1, 0, 0,-4, 1,   -100.0,   0.0,   -1.0,     56.0,  0.0,    0.0},
-      { 0, 2, 2,-2, 1,     87.0,   0.0,    0.0,    -47.0,  0.0,    0.0},
-      {-3, 0, 0, 4, 0,    161.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-1, 1, 2, 0, 1,     96.0,   0.0,    0.0,    -50.0,  0.0,    0.0},
-      {-1,-1, 0, 4, 0,    151.0,   0.0,   -1.0,     -5.0,  0.0,    0.0},
-
-   /* 201-210 */
-      {-1,-2, 2, 2, 2,   -104.0,   0.0,    0.0,     44.0,  0.0,    0.0},
-      {-2,-1, 2, 4, 2,   -110.0,   0.0,    0.0,     48.0,  0.0,    0.0},
-      { 1,-1, 2, 2, 1,   -100.0,   0.0,    1.0,     50.0,  0.0,    0.0},
-      {-2, 1, 0, 2, 0,     92.0,   0.0,   -5.0,     12.0,  0.0,   -2.0},
-      {-2, 1, 2, 0, 1,     82.0,   0.0,    0.0,    -45.0,  0.0,    0.0},
-      { 2, 1, 0,-2, 1,     82.0,   0.0,    0.0,    -45.0,  0.0,    0.0},
-      {-3, 0, 2, 0, 1,    -78.0,   0.0,    0.0,     41.0,  0.0,    0.0},
-      {-2, 0, 2,-2, 1,    -77.0,   0.0,    0.0,     43.0,  0.0,    0.0},
-      {-1, 1, 0, 2, 2,      2.0,   0.0,    0.0,     54.0,  0.0,    0.0},
-      { 0,-1, 2,-1, 2,     94.0,   0.0,    0.0,    -40.0,  0.0,    0.0},
-
-   /* 211-220 */
-      {-1, 0, 4,-2, 2,    -93.0,   0.0,    0.0,     40.0,  0.0,    0.0},
-      { 0,-2, 2, 0, 2,    -83.0,   0.0,   10.0,     40.0,  0.0,   -2.0},
-      {-1, 0, 2, 1, 2,     83.0,   0.0,    0.0,    -36.0,  0.0,    0.0},
-      { 2, 0, 0, 0, 2,    -91.0,   0.0,    0.0,     39.0,  0.0,    0.0},
-      { 0, 0, 2, 0, 3,    128.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-2, 0, 4, 0, 2,    -79.0,   0.0,    0.0,     34.0,  0.0,    0.0},
-      {-1, 0,-2, 0, 1,    -83.0,   0.0,    0.0,     47.0,  0.0,    0.0},
-      {-1, 1, 2, 2, 1,     84.0,   0.0,    0.0,    -44.0,  0.0,    0.0},
-      { 3, 0, 0, 0, 1,     83.0,   0.0,    0.0,    -43.0,  0.0,    0.0},
-      {-1, 0, 2, 3, 2,     91.0,   0.0,    0.0,    -39.0,  0.0,    0.0},
-
-   /* 221-230 */
-      { 2,-1, 2, 0, 1,    -77.0,   0.0,    0.0,     39.0,  0.0,    0.0},
-      { 0, 1, 2, 2, 1,     84.0,   0.0,    0.0,    -43.0,  0.0,    0.0},
-      { 0,-1, 2, 4, 2,    -92.0,   0.0,    1.0,     39.0,  0.0,    0.0},
-      { 2,-1, 2, 2, 2,    -92.0,   0.0,    1.0,     39.0,  0.0,    0.0},
-      { 0, 2,-2, 2, 0,    -94.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 2,-1, 1,     68.0,   0.0,    0.0,    -36.0,  0.0,    0.0},
-      { 0,-2, 0, 0, 1,    -61.0,   0.0,    0.0,     32.0,  0.0,    0.0},
-      { 1, 0, 2,-4, 2,     71.0,   0.0,    0.0,    -31.0,  0.0,    0.0},
-      { 1,-1, 0,-2, 1,     62.0,   0.0,    0.0,    -34.0,  0.0,    0.0},
-      {-1,-1, 2, 0, 1,    -63.0,   0.0,    0.0,     33.0,  0.0,    0.0},
-
-   /* 231-240 */
-      { 1,-1, 2,-2, 2,    -73.0,   0.0,    0.0,     32.0,  0.0,    0.0},
-      {-2,-1, 0, 4, 0,    115.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 0, 0, 3, 0,   -103.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2,-1, 2, 2, 2,     63.0,   0.0,    0.0,    -28.0,  0.0,    0.0},
-      { 0, 2, 2, 0, 2,     74.0,   0.0,    0.0,    -32.0,  0.0,    0.0},
-      { 1, 1, 0, 2, 0,   -103.0,   0.0,   -3.0,      3.0,  0.0,   -1.0},
-      { 2, 0, 2,-1, 2,    -69.0,   0.0,    0.0,     30.0,  0.0,    0.0},
-      { 1, 0, 2, 1, 1,     57.0,   0.0,    0.0,    -29.0,  0.0,    0.0},
-      { 4, 0, 0, 0, 0,     94.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 2, 1, 2, 0, 1,     64.0,   0.0,    0.0,    -33.0,  0.0,    0.0},
-
-   /* 241-250 */
-      { 3,-1, 2, 0, 2,    -63.0,   0.0,    0.0,     26.0,  0.0,    0.0},
-      {-2, 2, 0, 2, 1,    -38.0,   0.0,    0.0,     20.0,  0.0,    0.0},
-      { 1, 0, 2,-3, 1,    -43.0,   0.0,    0.0,     24.0,  0.0,    0.0},
-      { 1, 1, 2,-4, 1,    -45.0,   0.0,    0.0,     23.0,  0.0,    0.0},
-      {-1,-1, 2,-2, 1,     47.0,   0.0,    0.0,    -24.0,  0.0,    0.0},
-      { 0,-1, 0,-1, 1,    -48.0,   0.0,    0.0,     25.0,  0.0,    0.0},
-      { 0,-1, 0,-2, 1,     45.0,   0.0,    0.0,    -26.0,  0.0,    0.0},
-      {-2, 0, 0, 0, 2,     56.0,   0.0,    0.0,    -25.0,  0.0,    0.0},
-      {-2, 0,-2, 2, 0,     88.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 0,-2, 4, 0,    -75.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 251-260 */
-      { 1,-2, 0, 0, 0,     85.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 0, 1, 1,     49.0,   0.0,    0.0,    -26.0,  0.0,    0.0},
-      {-1, 2, 0, 2, 0,    -74.0,   0.0,   -3.0,     -1.0,  0.0,   -1.0},
-      { 1,-1, 2,-2, 1,    -39.0,   0.0,    0.0,     21.0,  0.0,    0.0},
-      { 1, 2, 2,-2, 2,     45.0,   0.0,    0.0,    -20.0,  0.0,    0.0},
-      { 2,-1, 2,-2, 2,     51.0,   0.0,    0.0,    -22.0,  0.0,    0.0},
-      { 1, 0, 2,-1, 1,    -40.0,   0.0,    0.0,     21.0,  0.0,    0.0},
-      { 2, 1, 2,-2, 1,     41.0,   0.0,    0.0,    -21.0,  0.0,    0.0},
-      {-2, 0, 0,-2, 1,    -42.0,   0.0,    0.0,     24.0,  0.0,    0.0},
-      { 1,-2, 2, 0, 2,    -51.0,   0.0,    0.0,     22.0,  0.0,    0.0},
-
-   /* 261-270 */
-      { 0, 1, 2, 1, 1,    -42.0,   0.0,    0.0,     22.0,  0.0,    0.0},
-      { 1, 0, 4,-2, 1,     39.0,   0.0,    0.0,    -21.0,  0.0,    0.0},
-      {-2, 0, 4, 2, 2,     46.0,   0.0,    0.0,    -18.0,  0.0,    0.0},
-      { 1, 1, 2, 1, 2,    -53.0,   0.0,    0.0,     22.0,  0.0,    0.0},
-      { 1, 0, 0, 4, 0,     82.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 1, 0, 2, 2, 0,     81.0,   0.0,   -1.0,     -4.0,  0.0,    0.0},
-      { 2, 0, 2, 1, 2,     47.0,   0.0,    0.0,    -19.0,  0.0,    0.0},
-      { 3, 1, 2, 0, 2,     53.0,   0.0,    0.0,    -23.0,  0.0,    0.0},
-      { 4, 0, 2, 0, 1,    -45.0,   0.0,    0.0,     22.0,  0.0,    0.0},
-      {-2,-1, 2, 0, 0,    -44.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 271-280 */
-      { 0, 1,-2, 2, 1,    -33.0,   0.0,    0.0,     16.0,  0.0,    0.0},
-      { 1, 0,-2, 1, 0,    -61.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 0,-1,-2, 2, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
-      { 2,-1, 0,-2, 1,    -38.0,   0.0,    0.0,     19.0,  0.0,    0.0},
-      {-1, 0, 2,-1, 2,    -33.0,   0.0,    0.0,     21.0,  0.0,    0.0},
-      { 1, 0, 2,-3, 2,    -60.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 2,-2, 3,     48.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
-      { 0, 0, 2,-3, 1,     27.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
-      {-1, 0,-2, 2, 1,     38.0,   0.0,    0.0,    -20.0,  0.0,    0.0},
-      { 0, 0, 2,-4, 2,     31.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
-
-   /* 281-290 */
-      {-2, 1, 0, 0, 1,    -29.0,   0.0,    0.0,     15.0,  0.0,    0.0},
-      {-1, 0, 0,-1, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
-      { 2, 0, 2,-4, 2,    -32.0,   0.0,    0.0,     15.0,  0.0,    0.0},
-      { 0, 0, 4,-4, 4,     45.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
-      { 0, 0, 4,-4, 2,    -44.0,   0.0,    0.0,     19.0,  0.0,    0.0},
-      {-1,-2, 0, 2, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
-      {-2, 0, 0, 3, 0,    -51.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0,-2, 2, 1,    -36.0,   0.0,    0.0,     20.0,  0.0,    0.0},
-      {-3, 0, 2, 2, 2,     44.0,   0.0,    0.0,    -19.0,  0.0,    0.0},
-      {-3, 0, 2, 2, 1,     26.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
-
-   /* 291-300 */
-      {-2, 0, 2, 2, 0,    -60.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2,-1, 0, 0, 1,     35.0,   0.0,    0.0,    -18.0,  0.0,    0.0},
-      {-2, 1, 2, 2, 2,    -27.0,   0.0,    0.0,     11.0,  0.0,    0.0},
-      { 1, 1, 0, 1, 0,     47.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0, 1, 4,-2, 2,     36.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
-      {-1, 1, 0,-2, 1,    -36.0,   0.0,    0.0,     20.0,  0.0,    0.0},
-      { 0, 0, 0,-4, 1,    -35.0,   0.0,    0.0,     19.0,  0.0,    0.0},
-      { 1,-1, 0, 2, 1,    -37.0,   0.0,    0.0,     19.0,  0.0,    0.0},
-      { 1, 1, 0, 2, 1,     32.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
-      {-1, 2, 2, 2, 2,     35.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
-
-   /* 301-310 */
-      { 3, 1, 2,-2, 2,     32.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
-      { 0,-1, 0, 4, 0,     65.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2,-1, 0, 2, 0,     47.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0, 0, 4, 0, 1,     32.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
-      { 2, 0, 4,-2, 2,     37.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
-      {-1,-1, 2, 4, 1,    -30.0,   0.0,    0.0,     15.0,  0.0,    0.0},
-      { 1, 0, 0, 4, 1,    -32.0,   0.0,    0.0,     16.0,  0.0,    0.0},
-      { 1,-2, 2, 2, 2,    -31.0,   0.0,    0.0,     13.0,  0.0,    0.0},
-      { 0, 0, 2, 3, 2,     37.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
-      {-1, 1, 2, 4, 2,     31.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
-
-   /* 311-320 */
-      { 3, 0, 0, 2, 0,     49.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 0, 4, 2, 2,     32.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
-      { 1, 1, 2, 2, 1,     23.0,   0.0,    0.0,    -12.0,  0.0,    0.0},
-      {-2, 0, 2, 6, 2,    -43.0,   0.0,    0.0,     18.0,  0.0,    0.0},
-      { 2, 1, 2, 2, 2,     26.0,   0.0,    0.0,    -11.0,  0.0,    0.0},
-      {-1, 0, 2, 6, 2,    -32.0,   0.0,    0.0,     14.0,  0.0,    0.0},
-      { 1, 0, 2, 4, 1,    -29.0,   0.0,    0.0,     14.0,  0.0,    0.0},
-      { 2, 0, 2, 4, 2,    -27.0,   0.0,    0.0,     12.0,  0.0,    0.0},
-      { 1, 1,-2, 1, 0,     30.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3, 1, 2, 1, 2,    -11.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-
-   /* 321-330 */
-      { 2, 0,-2, 0, 2,    -21.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      {-1, 0, 0, 1, 2,    -34.0,   0.0,    0.0,     15.0,  0.0,    0.0},
-      {-4, 0, 2, 2, 1,    -10.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      {-1,-1, 0, 1, 0,    -36.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0,-2, 2, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 1, 0, 0,-1, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 0,-1, 2,-2, 3,    -21.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      {-2, 1, 2, 0, 0,    -29.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0, 0, 2,-2, 4,    -15.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-2,-2, 0, 2, 0,    -20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 331-340 */
-      {-2, 0,-2, 4, 0,     28.0,   0.0,    0.0,      0.0,  0.0,   -2.0},
-      { 0,-2,-2, 2, 0,     17.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 2, 0,-2, 1,    -22.0,   0.0,    0.0,     12.0,  0.0,    0.0},
-      { 3, 0, 0,-4, 1,    -14.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-      {-1, 1, 2,-2, 2,     24.0,   0.0,    0.0,    -11.0,  0.0,    0.0},
-      { 1,-1, 2,-4, 1,     11.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      { 1, 1, 0,-2, 2,     14.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      {-3, 0, 2, 0, 0,     24.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3, 0, 2, 0, 2,     18.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
-      {-2, 0, 0, 1, 0,    -38.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 341-350 */
-      { 0, 0,-2, 1, 0,    -31.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3, 0, 0, 2, 1,    -16.0,   0.0,    0.0,      8.0,  0.0,    0.0},
-      {-1,-1,-2, 2, 0,     29.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 2,-4, 1,    -18.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      { 2, 1, 0,-4, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 0, 2, 0,-2, 1,    -17.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      { 1, 0, 0,-3, 1,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      {-2, 0, 2,-2, 2,     16.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      {-2,-1, 0, 0, 1,     22.0,   0.0,    0.0,    -12.0,  0.0,    0.0},
-      {-4, 0, 0, 2, 0,     20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 351-360 */
-      { 1, 1, 0,-4, 1,    -13.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      {-1, 0, 2,-4, 1,    -17.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      { 0, 0, 4,-4, 1,    -14.0,   0.0,    0.0,      8.0,  0.0,    0.0},
-      { 0, 3, 2,-2, 2,      0.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
-      {-3,-1, 0, 4, 0,     14.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3, 0, 0, 4, 1,     19.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
-      { 1,-1,-2, 2, 0,    -34.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 0, 2, 2,    -20.0,   0.0,    0.0,      8.0,  0.0,    0.0},
-      { 1,-2, 0, 0, 1,      9.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-      { 1,-1, 0, 0, 2,    -18.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-
-   /* 361-370 */
-      { 0, 0, 0, 1, 2,     13.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      {-1,-1, 2, 0, 0,     17.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1,-2, 2,-2, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 0,-1, 2,-1, 1,     15.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
-      {-1, 0, 2, 0, 3,    -11.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 1, 1, 0, 0, 2,     13.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-      {-1, 1, 2, 0, 0,    -18.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 2, 0, 0, 0,    -35.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 2, 2, 0, 2,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      {-1, 0, 4,-2, 1,    -19.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-
-   /* 371-380 */
-      { 3, 0, 2,-4, 2,    -26.0,   0.0,    0.0,     11.0,  0.0,    0.0},
-      { 1, 2, 2,-2, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 1, 0, 4,-4, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      {-2,-1, 0, 4, 1,     10.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      { 0,-1, 0, 2, 2,    -21.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      {-2, 1, 0, 4, 0,    -15.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2,-1, 2, 2, 1,      9.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-      { 2, 0,-2, 2, 0,    -29.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 0, 1, 1,    -19.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      { 0, 1, 0, 2, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-
-   /* 381-390 */
-      { 1,-1, 2,-1, 2,     22.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
-      {-2, 0, 4, 0, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 2, 1, 0, 0, 1,    -20.0,   0.0,    0.0,     11.0,  0.0,    0.0},
-      { 0, 1, 2, 0, 0,    -20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0,-1, 4,-2, 2,    -17.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-      { 0, 0, 4,-2, 4,     15.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 0, 2, 2, 0, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      {-3, 0, 0, 6, 0,     14.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 0, 4, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      { 1,-2, 0, 2, 0,     25.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 391-400 */
-      {-1, 0, 0, 4, 2,    -13.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      {-1,-2, 2, 2, 1,    -14.0,   0.0,    0.0,      8.0,  0.0,    0.0},
-      {-1, 0, 0,-2, 2,     13.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-      { 1, 0,-2,-2, 1,    -17.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      { 0, 0,-2,-2, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      {-2, 0,-2, 0, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 0, 0, 0, 3, 1,     10.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
-      { 0, 0, 0, 3, 0,    -15.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 1, 0, 4, 0,    -22.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 2, 2, 0,     28.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-
-   /* 401-410 */
-      {-2, 0, 2, 3, 2,     15.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
-      { 1, 0, 0, 2, 2,     23.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
-      { 0,-1, 2, 1, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-      { 3,-1, 0, 0, 0,     29.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 2, 0, 0, 1, 0,    -25.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 1,-1, 2, 0, 0,     22.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0, 2, 1, 0,    -18.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 2, 0, 3,     15.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 3, 1, 0, 0, 0,    -23.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 3,-1, 2,-2, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
-
-   /* 411-420 */
-      { 2, 0, 2,-1, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 1, 1, 2, 0, 0,    -19.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0, 4,-1, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 1, 2, 2, 0, 2,     21.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
-      {-2, 0, 0, 6, 0,     23.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0,-1, 0, 4, 1,    -16.0,   0.0,    0.0,      8.0,  0.0,    0.0},
-      {-2,-1, 2, 4, 1,    -19.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      { 0,-2, 2, 2, 1,    -22.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      { 0,-1, 2, 2, 0,     27.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-1, 0, 2, 3, 1,     16.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
-
-   /* 421-430 */
-      {-2, 1, 2, 4, 2,     19.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
-      { 2, 0, 0, 2, 2,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 2,-2, 2, 0, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      {-1, 1, 2, 3, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 3, 0, 2,-1, 2,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 4, 0, 2,-2, 1,     18.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
-      {-1, 0, 0, 6, 0,     16.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-1,-2, 2, 4, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      {-3, 0, 2, 6, 2,    -23.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      {-1, 0, 2, 4, 0,     16.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-
-   /* 431-440 */
-      { 3, 0, 0, 2, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
-      { 3,-1, 2, 0, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 3, 0, 2, 0, 0,     30.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 1, 0, 4, 0, 2,     24.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
-      { 5, 0, 2,-2, 2,     10.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 0,-1, 2, 4, 1,    -16.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-      { 2,-1, 2, 2, 1,    -16.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-      { 0, 1, 2, 4, 2,     17.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
-      { 1,-1, 2, 4, 2,    -24.0,   0.0,    0.0,     10.0,  0.0,    0.0},
-      { 3,-1, 2, 2, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-
-   /* 441-450 */
-      { 3, 0, 2, 2, 1,    -24.0,   0.0,    0.0,     11.0,  0.0,    0.0},
-      { 5, 0, 2, 0, 2,    -23.0,   0.0,    0.0,      9.0,  0.0,    0.0},
-      { 0, 0, 2, 6, 2,    -13.0,   0.0,    0.0,      5.0,  0.0,    0.0},
-      { 4, 0, 2, 2, 2,    -15.0,   0.0,    0.0,      7.0,  0.0,    0.0},
-      { 0,-1, 1,-1, 1,      0.0,   0.0,-1988.0,      0.0,  0.0,-1679.0},
-      {-1, 0, 1, 0, 3,      0.0,   0.0,  -63.0,      0.0,  0.0,  -27.0},
-      { 0,-2, 2,-2, 3,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0,-1, 0, 1,      0.0,   0.0,    5.0,      0.0,  0.0,    4.0},
-      { 2,-2, 0,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-1, 0, 1, 0, 2,      0.0,   0.0,  364.0,      0.0,  0.0,  176.0},
-
-   /* 451-460 */
-      {-1, 0, 1, 0, 1,      0.0,   0.0,-1044.0,      0.0,  0.0, -891.0},
-      {-1,-1, 2,-1, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-2, 2, 0, 2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 0, 1, 0, 0,      0.0,   0.0,  330.0,      0.0,  0.0,    0.0},
-      {-4, 1, 2, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-3, 0, 2, 1, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-2,-1, 2, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 1, 0,-2, 1, 1,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2,-1,-2, 0, 1,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-4, 0, 2, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 461-470 */
-      {-3, 1, 0, 3, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 0,-1, 2, 0,      0.0,   0.0,    5.0,      0.0,  0.0,    0.0},
-      { 0,-2, 0, 0, 2,      0.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 0,-2, 0, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-3, 0, 0, 3, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2,-1, 0, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 0,-2, 3, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-4, 0, 0, 4, 0,    -12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 1,-2, 0, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 2,-1, 0,-2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-
-   /* 471-480 */
-      { 0, 0, 1,-1, 0,     -5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 2, 0, 1, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 1, 2, 0, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 1, 1, 0,-1, 1,      7.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 1, 0, 1,-2, 1,      0.0,   0.0,  -12.0,      0.0,  0.0,  -10.0},
-      { 0, 2, 0, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 1,-1, 2,-3, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 1, 2,-1, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2, 0, 4,-2, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-2, 0, 4,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-
-   /* 481-490 */
-      {-2,-2, 0, 2, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-2, 0,-2, 4, 0,      0.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 2, 2,-4, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 1, 1, 2,-4, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-1, 2, 2,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2, 0, 0,-3, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 2, 0, 0, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 0, 0, 0,-2, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 2,-2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 1, 0, 0, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 491-500 */
-      { 0, 0, 0,-1, 2,     -8.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-2, 1, 0, 1, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1,-2, 0,-2, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 1, 0,-2, 0, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-3, 1, 0, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 1,-2, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 0, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-3, 0, 0, 2, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3,-1, 0, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 0, 2,-6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-
-   /* 501-510 */
-      { 0, 1, 2,-4, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 0, 0,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-2, 1, 2,-2, 1,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0,-1, 2,-4, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 0, 1, 0,-2, 2,      9.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-1, 0, 0,-2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 0,-2,-2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-4, 0, 2, 0, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1,-1, 0,-1, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0,-2, 0, 2,      9.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-
-   /* 511-520 */
-      {-3, 0, 0, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 0,-2, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 0,-2, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 0, 0,-4, 2, 0,      8.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2,-1,-2, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 2,-6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 0, 2,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 1, 0, 0,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 2, 1, 2,-4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 2, 1, 2,-4, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-
-   /* 521-530 */
-      { 0, 1, 4,-4, 4,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 4,-4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-1,-1,-2, 4, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-3, 0, 2, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 0,-2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2,-1, 0, 3, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0,-2, 3, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 0, 0, 3, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 0,-1, 0, 1, 0,    -13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3, 0, 2, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 531-540 */
-      { 1, 1,-2, 2, 0,     10.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 1, 0, 2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 1,-2, 2,-2, 1,     10.0,   0.0,   13.0,      6.0,  0.0,   -5.0},
-      { 0, 0, 1, 0, 2,      0.0,   0.0,   30.0,      0.0,  0.0,   14.0},
-      { 0, 0, 1, 0, 1,      0.0,   0.0, -162.0,      0.0,  0.0, -138.0},
-      { 0, 0, 1, 0, 0,      0.0,   0.0,   75.0,      0.0,  0.0,    0.0},
-      {-1, 2, 0, 2, 1,     -7.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      { 0, 0, 2, 0, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2, 0, 2, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 0, 0,-1, 1,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 541-550 */
-      { 3, 0, 0,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 1, 0, 2,-2, 3,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 2, 0, 0, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2, 0, 2,-3, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 1, 4,-2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2,-2, 0, 4, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0,-3, 0, 2, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0,-2, 4, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 0, 3, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 0, 0, 4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-
-   /* 551-560 */
-      {-1, 0, 0, 3, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2,-2, 0, 0, 0,      7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1,-1, 0, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 0, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0,-2, 2, 0, 1,     -6.0,   0.0,   -3.0,      3.0,  0.0,    1.0},
-      {-1, 0, 1, 2, 1,      0.0,   0.0,   -3.0,      0.0,  0.0,   -2.0},
-      {-1, 1, 0, 3, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-1, 2, 1, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0,-1, 2, 0, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 1, 2, 2, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-
-   /* 561-570 */
-      { 2,-2, 2,-2, 2,     -1.0,   0.0,    3.0,      3.0,  0.0,   -1.0},
-      { 1, 1, 0, 1, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 1, 0, 1, 0, 1,      0.0,   0.0,  -13.0,      0.0,  0.0,  -11.0},
-      { 1, 0, 1, 0, 0,      3.0,   0.0,    6.0,      0.0,  0.0,    0.0},
-      { 0, 2, 0, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2,-1, 2,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 0,-1, 4,-2, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 0, 0, 4,-2, 3,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 4,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 4, 0, 2,-4, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-
-   /* 571-580 */
-      { 2, 2, 2,-2, 2,      8.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 2, 0, 4,-4, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1,-2, 0, 4, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1,-3, 2, 2, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-3, 0, 2, 4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-3, 0, 2,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1,-1, 0,-2, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      {-3, 0, 0, 0, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-3, 0,-2, 2, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 0,-4, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-
-   /* 581-590 */
-      {-2, 1, 0,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-4, 0, 0, 0, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-      {-1, 0, 0,-4, 1,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-3, 0, 0,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 0, 3, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-1, 1, 0, 4, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 1,-2, 2, 0, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 0, 1, 0, 3, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-1, 0, 2, 2, 3,      6.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 0, 0, 2, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 591-600 */
-      {-2, 0, 2, 2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 1, 2, 2, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 3, 0, 0, 0, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2, 1, 0, 1, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2,-1, 2,-1, 2,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 0, 0, 2, 0, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 3, 0, 3,      0.0,   0.0,  -26.0,      0.0,  0.0,  -11.0},
-      { 0, 0, 3, 0, 2,      0.0,   0.0,  -10.0,      0.0,  0.0,   -5.0},
-      {-1, 2, 2, 2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-1, 0, 4, 0, 0,    -13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 601-610 */
-      { 1, 2, 2, 0, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 3, 1, 2,-2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 1, 1, 4,-2, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-2,-1, 0, 6, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0,-2, 0, 4, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-2, 0, 0, 6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2,-2, 2, 4, 2,     -6.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0,-3, 2, 2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 0, 4, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-1,-1, 2, 3, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 611-620 */
-      {-2, 0, 2, 4, 0,     13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2,-1, 0, 2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 1, 0, 0, 3, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 0, 4, 1,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 0, 1, 0, 4, 0,    -11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1,-1, 2, 1, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 0, 0, 2, 2, 3,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 2, 2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-1, 0, 2, 2, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-2, 0, 4, 2, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-
-   /* 621-630 */
-      { 2, 1, 0, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 1, 0, 2, 0,    -12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2,-1, 2, 0, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 2, 1, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 1, 2, 2, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 0, 2, 0, 3,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 3, 0, 2, 0, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 1, 0, 2, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 1, 0, 3, 0, 3,      0.0,   0.0,   -5.0,      0.0,  0.0,   -2.0},
-      { 1, 1, 2, 1, 1,     -7.0,   0.0,    0.0,      4.0,  0.0,    0.0},
-
-   /* 631-640 */
-      { 0, 2, 2, 2, 2,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 2, 1, 2, 0, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 0, 4,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 4, 1, 2,-2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      {-1,-1, 0, 6, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      {-3,-1, 2, 6, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      {-1, 0, 0, 6, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-3, 0, 2, 6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 1,-1, 0, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 1,-1, 0, 4, 0,     12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 641-650 */
-      {-2, 0, 2, 5, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 1,-2, 2, 2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 3,-1, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1,-1, 2, 2, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0, 2, 3, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      {-1, 1, 2, 4, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 0, 1, 2, 3, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-1, 0, 4, 2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 0, 2, 1, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 5, 0, 0, 0, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 651-660 */
-      { 2, 1, 2, 1, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 1, 0, 4, 0, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 3, 1, 2, 0, 1,      7.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
-      { 3, 0, 4,-2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      {-2,-1, 2, 6, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 0, 6, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0,-2, 2, 4, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      {-2, 0, 2, 6, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
-      { 2, 0, 0, 4, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 2, 0, 0, 4, 0,     10.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-
-   /* 661-670 */
-      { 2,-2, 2, 2, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 0, 0, 2, 4, 0,      7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 1, 0, 2, 3, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
-      { 4, 0, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 2, 0, 2, 2, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
-      { 0, 0, 4, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 4,-1, 2, 0, 2,     -6.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 3, 0, 2, 1, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 2, 1, 2, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 4, 1, 2, 0, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-
-   /* 671-678 */
-      {-1,-1, 2, 6, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      {-1, 0, 2, 6, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 1,-1, 2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
-      { 1, 1, 2, 4, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
-      { 3, 1, 2, 2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
-      { 5, 0, 2, 0, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 2,-1, 2, 4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
-      { 2, 0, 2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0}
-   };
-
-/* Number of terms in the luni-solar nutation model */
-   const int NLS = (int) (sizeof xls / sizeof xls[0]);
-
-/* ------------------------ */
-/* Planetary nutation model */
-/* ------------------------ */
-
-/* The units for the sine and cosine coefficients are */
-/* 0.1 microarcsecond                                 */
-
-   static const struct {
-      int nl,               /* coefficients of l, F, D and Omega */
-          nf,
-          nd,
-          nom,
-          nme,              /* coefficients of planetary longitudes */
-          nve,
-          nea,
-          nma,
-          nju,
-          nsa,
-          nur,
-          nne,
-          npa;              /* coefficient of general precession */
-      int sp,cp;            /* longitude sin, cos coefficients */
-      int se,ce;            /* obliquity sin, cos coefficients */
-   } xpl[] = {
-
-   /* 1-10 */
-      { 0, 0, 0, 0, 0,  0,  8,-16, 4, 5, 0, 0, 0, 1440,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -8, 16,-4,-5, 0, 0, 2,   56,-117,  -42, -40},
-      { 0, 0, 0, 0, 0,  0,  8,-16, 4, 5, 0, 0, 2,  125, -43,    0, -54},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0,-1, 2, 2,    0,   5,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -4,  8,-1,-5, 0, 0, 2,    3,  -7,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 1,    3,   0,    0,  -2},
-      { 0, 1,-1, 1, 0,  0,  3, -8, 3, 0, 0, 0, 0, -114,   0,    0,  61},
-      {-1, 0, 0, 0, 0, 10, -3,  0, 0, 0, 0, 0, 0, -219,  89,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 6,-3, 0, 2,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0, -462,1604,    0,   0},
-
-   /* 11-20 */
-      { 0, 1,-1, 1, 0,  0, -5,  8,-3, 0, 0, 0, 0,   99,   0,    0, -53},
-      { 0, 0, 0, 0, 0,  0, -4,  8,-3, 0, 0, 0, 1,   -3,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  4, -8, 1, 5, 0, 0, 2,    0,   6,    2,   0},
-      { 0, 0, 0, 0, 0, -5,  6,  4, 0, 0, 0, 0, 2,    3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 2,  -12,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 1,   14,-218,  117,   8},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 2,-5, 0, 0, 0,   31,-481, -257, -17},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 0, -491, 128,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0,-2, 5, 0, 0, 0,-3084,5123, 2735,1647},
-      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 5, 0, 0, 1,-1444,2409,-1286,-771},
-
-   /* 21-30 */
-      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 5, 0, 0, 2,   11, -24,  -11,  -9},
-      { 2,-1,-1, 0, 0,  0,  3, -7, 0, 0, 0, 0, 0,   26,  -9,    0,   0},
-      { 1, 0,-2, 0, 0, 19,-21,  3, 0, 0, 0, 0, 0,  103, -60,    0,   0},
-      { 0, 1,-1, 1, 0,  2, -4,  0,-3, 0, 0, 0, 0,    0, -13,   -7,   0},
-      { 1, 0,-1, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,  -26, -29,  -16,  14},
-      { 0, 1,-1, 1, 0,  0, -1,  0,-4,10, 0, 0, 0,    9, -27,  -14,  -5},
-      {-2, 0, 2, 1, 0,  0,  2,  0, 0,-5, 0, 0, 0,   12,   0,    0,  -6},
-      { 0, 0, 0, 0, 0,  3, -7,  4, 0, 0, 0, 0, 0,   -7,   0,    0,   0},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 1,-1, 0, 0, 0,    0,  24,    0,   0},
-      {-2, 0, 2, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,  284,   0,    0,-151},
-
-   /* 31-40 */
-      {-1, 0, 0, 0, 0, 18,-16,  0, 0, 0, 0, 0, 0,  226, 101,    0,   0},
-      {-2, 1, 1, 2, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -8,   -2,   0},
-      {-1, 1,-1, 1, 0, 18,-17,  0, 0, 0, 0, 0, 0,    0,  -6,   -3,   0},
-      {-1, 0, 1, 1, 0,  0,  2, -2, 0, 0, 0, 0, 0,    5,   0,    0,  -3},
-      { 0, 0, 0, 0, 0, -8, 13,  0, 0, 0, 0, 0, 2,  -41, 175,   76,  17},
-      { 0, 2,-2, 2, 0, -8, 11,  0, 0, 0, 0, 0, 0,    0,  15,    6,   0},
-      { 0, 0, 0, 0, 0, -8, 13,  0, 0, 0, 0, 0, 1,  425, 212, -133, 269},
-      { 0, 1,-1, 1, 0, -8, 12,  0, 0, 0, 0, 0, 0, 1200, 598,  319,-641},
-      { 0, 0, 0, 0, 0,  8,-13,  0, 0, 0, 0, 0, 0,  235, 334,    0,   0},
-      { 0, 1,-1, 1, 0,  8,-14,  0, 0, 0, 0, 0, 0,   11, -12,   -7,  -6},
-
-   /* 41-50 */
-      { 0, 0, 0, 0, 0,  8,-13,  0, 0, 0, 0, 0, 1,    5,  -6,    3,   3},
-      {-2, 0, 2, 1, 0,  0,  2,  0,-4, 5, 0, 0, 0,   -5,   0,    0,   3},
-      {-2, 0, 2, 2, 0,  3, -3,  0, 0, 0, 0, 0, 0,    6,   0,    0,  -3},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-3, 1, 0, 0, 0,   15,   0,    0,   0},
-      { 0, 0, 0, 1, 0,  3, -5,  0, 2, 0, 0, 0, 0,   13,   0,    0,  -7},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-4, 3, 0, 0, 0,   -6,  -9,    0,   0},
-      { 0,-1, 1, 0, 0,  0,  0,  2, 0, 0, 0, 0, 0,  266, -78,    0,   0},
-      { 0, 0, 0, 1, 0,  0, -1,  2, 0, 0, 0, 0, 0, -460,-435, -232, 246},
-      { 0, 1,-1, 2, 0,  0, -2,  2, 0, 0, 0, 0, 0,    0,  15,    7,   0},
-      {-1, 1, 0, 1, 0,  3, -5,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
-
-   /* 51-60 */
-      {-1, 0, 1, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0, 131,    0,   0},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-2,-2, 0, 0, 0,    4,   0,    0,   0},
-      {-2, 2, 0, 2, 0,  0, -5,  9, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0,-1, 0, 0,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 1, 0, 0,    0,   3,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 2, 0,  -17, -19,  -10,   9},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 2, 1,   -9, -11,    6,  -5},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 2, 2,   -6,   0,    0,   3},
-      {-1, 0, 1, 0, 0,  0,  3, -4, 0, 0, 0, 0, 0,  -16,   8,    0,   0},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 0, 2, 0, 0, 0,    0,   3,    0,   0},
-
-   /* 61-70 */
-      { 0, 1,-1, 2, 0,  0, -1,  0, 0, 2, 0, 0, 0,   11,  24,   11,  -5},
-      { 0, 0, 0, 1, 0,  0, -9, 17, 0, 0, 0, 0, 0,   -3,  -4,   -2,   1},
-      { 0, 0, 0, 2, 0, -3,  5,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 2, 0, 0, 0,    0,  -8,   -4,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 1,-2, 0, 0, 0,    0,   3,    0,   0},
-      { 1, 0,-2, 0, 0, 17,-16,  0,-2, 0, 0, 0, 0,    0,   5,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 1,-3, 0, 0, 0,    0,   3,    2,   0},
-      {-2, 0, 2, 1, 0,  0,  5, -6, 0, 0, 0, 0, 0,   -6,   4,    2,   3},
-      { 0,-2, 2, 0, 0,  0,  9,-13, 0, 0, 0, 0, 0,   -3,  -5,    0,   0},
-      { 0, 1,-1, 2, 0,  0, -1,  0, 0, 1, 0, 0, 0,   -5,   0,    0,   2},
-
-   /* 71-80 */
-      { 0, 0, 0, 1, 0,  0,  0,  0, 0, 1, 0, 0, 0,    4,  24,   13,  -2},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 0, 1, 0, 0, 0,  -42,  20,    0,   0},
-      { 0,-2, 2, 0, 0,  5, -6,  0, 0, 0, 0, 0, 0,  -10, 233,    0,   0},
-      { 0,-1, 1, 1, 0,  5, -7,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-      {-2, 0, 2, 0, 0,  6, -8,  0, 0, 0, 0, 0, 0,   78, -18,    0,   0},
-      { 2, 1,-3, 1, 0, -6,  7,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 0, 0, 2, 0,  0,  0,  0, 1, 0, 0, 0, 0,    0,  -3,   -1,   0},
-      { 0,-1, 1, 1, 0,  0,  1,  0, 1, 0, 0, 0, 0,    0,  -4,   -2,   1},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0, 2, 0, 0,    0,  -8,   -4,  -1},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 2, 0, 1,    0,  -5,    3,   0},
-
-   /* 81-90 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 2, 0, 2,   -7,   0,    0,   3},
-      { 0, 0, 0, 0, 0,  0, -8, 15, 0, 0, 0, 0, 2,  -14,   8,    3,   6},
-      { 0, 0, 0, 0, 0,  0, -8, 15, 0, 0, 0, 0, 1,    0,   8,   -4,   0},
-      { 0, 1,-1, 1, 0,  0, -9, 15, 0, 0, 0, 0, 0,    0,  19,   10,   0},
-      { 0, 0, 0, 0, 0,  0,  8,-15, 0, 0, 0, 0, 0,   45, -22,    0,   0},
-      { 1,-1,-1, 0, 0,  0,  8,-15, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 2, 0,-2, 0, 0,  2, -5,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-5, 5, 0, 0, 0,    0,   3,    0,   0},
-      { 2, 0,-2, 1, 0,  0, -6,  8, 0, 0, 0, 0, 0,    3,   5,    3,  -2},
-      { 2, 0,-2, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,   89, -16,   -9, -48},
-
-   /* 91-100 */
-      {-2, 1, 1, 0, 0,  0,  1,  0,-3, 0, 0, 0, 0,    0,   3,    0,   0},
-      {-2, 1, 1, 1, 0,  0,  1,  0,-3, 0, 0, 0, 0,   -3,   7,    4,   2},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0, -349, -62,    0,   0},
-      {-2, 0, 2, 0, 0,  0,  6, -8, 0, 0, 0, 0, 0,  -15,  22,    0,   0},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-1,-5, 0, 0, 0,   -3,   0,    0,   0},
-      {-1, 0, 1, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,  -53,   0,    0,   0},
-      {-1, 1, 1, 1, 0,-20, 20,  0, 0, 0, 0, 0, 0,    5,   0,    0,  -3},
-      { 1, 0,-2, 0, 0, 20,-21,  0, 0, 0, 0, 0, 0,    0,  -8,    0,   0},
-      { 0, 0, 0, 1, 0,  0,  8,-15, 0, 0, 0, 0, 0,   15,  -7,   -4,  -8},
-      { 0, 2,-2, 1, 0,  0,-10, 15, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-
-   /* 101-110 */
-      { 0,-1, 1, 0, 0,  0,  1,  0, 1, 0, 0, 0, 0,  -21, -78,    0,   0},
-      { 0, 0, 0, 1, 0,  0,  0,  0, 1, 0, 0, 0, 0,   20, -70,  -37, -11},
-      { 0, 1,-1, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    0,   6,    3,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0,-2, 4, 0, 0, 0,    5,   3,    2,  -2},
-      { 2, 0,-2, 1, 0, -6,  8,  0, 0, 0, 0, 0, 0,  -17,  -4,   -2,   9},
-      { 0,-2, 2, 1, 0,  5, -6,  0, 0, 0, 0, 0, 0,    0,   6,    3,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0,-1, 0, 0, 1,   32,  15,   -8,  17},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0,-1, 0, 0, 0,  174,  84,   45, -93},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 0,   11,  56,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 1, 0, 0, 0,  -66, -12,   -6,  35},
-
-   /* 111-120 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 1,   47,   8,    4, -25},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 2,    0,   8,    4,   0},
-      { 0, 2,-2, 1, 0,  0, -9, 13, 0, 0, 0, 0, 0,   10, -22,  -12,  -5},
-      { 0, 0, 0, 1, 0,  0,  7,-13, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
-      {-2, 0, 2, 0, 0,  0,  5, -6, 0, 0, 0, 0, 0,  -24,  12,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  9,-17, 0, 0, 0, 0, 0,    5,  -6,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -9, 17, 0, 0, 0, 0, 2,    3,   0,    0,  -2},
-      { 1, 0,-1, 1, 0,  0, -3,  4, 0, 0, 0, 0, 0,    4,   3,    1,  -2},
-      { 1, 0,-1, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,  29,   15,   0},
-      { 0, 0, 0, 2, 0,  0, -1,  2, 0, 0, 0, 0, 0,   -5,  -4,   -2,   2},
-
-   /* 121-130 */
-      { 0,-1, 1, 1, 0,  0,  0,  2, 0, 0, 0, 0, 0,    8,  -3,   -1,  -5},
-      { 0,-2, 2, 0, 1,  0, -2,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
-      { 0, 0, 0, 0, 0,  3, -5,  0, 2, 0, 0, 0, 0,   10,   0,    0,   0},
-      {-2, 0, 2, 1, 0,  0,  2,  0,-3, 1, 0, 0, 0,    3,   0,    0,  -2},
-      {-2, 0, 2, 1, 0,  3, -3,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   3},
-      { 0, 0, 0, 1, 0,  8,-13,  0, 0, 0, 0, 0, 0,   46,  66,   35, -25},
-      { 0,-1, 1, 0, 0,  8,-12,  0, 0, 0, 0, 0, 0,  -14,   7,    0,   0},
-      { 0, 2,-2, 1, 0, -8, 11,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
-      {-1, 0, 1, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
-      {-1, 0, 0, 1, 0, 18,-16,  0, 0, 0, 0, 0, 0,  -68, -34,  -18,  36},
-
-   /* 131-140 */
-      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 1, 0, 0, 0,    0,  14,    7,   0},
-      { 0, 0, 0, 1, 0,  3, -7,  4, 0, 0, 0, 0, 0,   10,  -6,   -3,  -5},
-      {-2, 1, 1, 1, 0,  0, -3,  7, 0, 0, 0, 0, 0,   -5,  -4,   -2,   3},
-      { 0, 1,-1, 2, 0,  0, -1,  0,-2, 5, 0, 0, 0,   -3,   5,    2,   1},
-      { 0, 0, 0, 1, 0,  0,  0,  0,-2, 5, 0, 0, 0,   76,  17,    9, -41},
-      { 0, 0, 0, 1, 0,  0, -4,  8,-3, 0, 0, 0, 0,   84, 298,  159, -45},
-      { 1, 0, 0, 1, 0,-10,  3,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 2,-2, 1, 0,  0, -2,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
-      {-1, 0, 0, 1, 0, 10, -3,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-      { 0, 0, 0, 1, 0,  0,  4, -8, 3, 0, 0, 0, 0,  -82, 292,  156,  44},
-
-   /* 141-150 */
-      { 0, 0, 0, 1, 0,  0,  0,  0, 2,-5, 0, 0, 0,  -73,  17,    9,  39},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 2,-5, 0, 0, 0,   -9, -16,    0,   0},
-      { 2,-1,-1, 1, 0,  0,  3, -7, 0, 0, 0, 0, 0,    3,   0,   -1,  -2},
-      {-2, 0, 2, 0, 0,  0,  2,  0, 0,-5, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 1, 0, -3,  7, -4, 0, 0, 0, 0, 0,   -9,  -5,   -3,   5},
-      {-2, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0, -439,   0,    0,   0},
-      { 1, 0, 0, 1, 0,-18, 16,  0, 0, 0, 0, 0, 0,   57, -28,  -15, -30},
-      {-2, 1, 1, 1, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -6,   -3,   0},
-      { 0, 1,-1, 2, 0, -8, 12,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   2},
-      { 0, 0, 0, 1, 0, -8, 13,  0, 0, 0, 0, 0, 0,  -40,  57,   30,  21},
-
-   /* 151-160 */
-      { 0, 0, 0, 0, 0,  0,  1, -2, 0, 0, 0, 0, 1,   23,   7,    3, -13},
-      { 0, 1,-1, 1, 0,  0,  0, -2, 0, 0, 0, 0, 0,  273,  80,   43,-146},
-      { 0, 0, 0, 0, 0,  0,  1, -2, 0, 0, 0, 0, 0, -449, 430,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -2,  2, 0, 0, 0, 0, 0,   -8, -47,  -25,   4},
-      { 0, 0, 0, 0, 0,  0, -1,  2, 0, 0, 0, 0, 1,    6,  47,   25,  -3},
-      {-1, 0, 1, 1, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  23,   13,   0},
-      {-1, 0, 1, 1, 0,  0,  3, -4, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0,-2, 0, 0, 0,    3,  -4,   -2,  -2},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 2, 0, 0, 0,  -48,-110,  -59,  26},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 2, 0, 0, 1,   51, 114,   61, -27},
-
-   /* 161-170 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 2, 0, 0, 2, -133,   0,    0,  57},
-      { 0, 1,-1, 0, 0,  3, -6,  0, 0, 0, 0, 0, 0,    0,   4,    0,   0},
-      { 0, 0, 0, 1, 0, -3,  5,  0, 0, 0, 0, 0, 0,  -21,  -6,   -3,  11},
-      { 0, 1,-1, 2, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,  -3,   -1,   0},
-      { 0, 0, 0, 1, 0,  0, -2,  4, 0, 0, 0, 0, 0,  -11, -21,  -11,   6},
-      { 0, 2,-2, 1, 0, -5,  6,  0, 0, 0, 0, 0, 0,  -18,-436, -233,   9},
-      { 0,-1, 1, 0, 0,  5, -7,  0, 0, 0, 0, 0, 0,   35,  -7,    0,   0},
-      { 0, 0, 0, 1, 0,  5, -8,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
-      {-2, 0, 2, 1, 0,  6, -8,  0, 0, 0, 0, 0, 0,   11,  -3,   -1,  -6},
-      { 0, 0, 0, 1, 0,  0, -8, 15, 0, 0, 0, 0, 0,   -5,  -3,   -1,   3},
-
-   /* 171-180 */
-      {-2, 0, 2, 1, 0,  0,  2,  0,-3, 0, 0, 0, 0,  -53,  -9,   -5,  28},
-      {-2, 0, 2, 1, 0,  0,  6, -8, 0, 0, 0, 0, 0,    0,   3,    2,   1},
-      { 1, 0,-1, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,    4,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 3,-5, 0, 0, 0,    0,  -4,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 0, 0, 0, 0,  -50, 194,  103,  27},
-      { 0, 0, 0, 0, 0,  0,  0,  0,-1, 0, 0, 0, 1,  -13,  52,   28,   7},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 0,  -91, 248,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 1,    6,  49,   26,  -3},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,   -6, -47,  -25,   3},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 1,    0,   5,    3,   0},
-
-   /* 181-190 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 2,   52,  23,   10, -23},
-      { 0, 1,-1, 2, 0,  0, -1,  0, 0,-1, 0, 0, 0,   -3,   0,    0,   1},
-      { 0, 0, 0, 1, 0,  0,  0,  0, 0,-1, 0, 0, 0,    0,   5,    3,   0},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 0,-1, 0, 0, 0,   -4,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -7, 13, 0, 0, 0, 0, 2,   -4,   8,    3,   2},
-      { 0, 0, 0, 0, 0,  0,  7,-13, 0, 0, 0, 0, 0,   10,   0,    0,   0},
-      { 2, 0,-2, 1, 0,  0, -5,  6, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
-      { 0, 2,-2, 1, 0,  0, -8, 11, 0, 0, 0, 0, 0,    0,   8,    4,   0},
-      { 0, 2,-2, 1,-1,  0,  2,  0, 0, 0, 0, 0, 0,    0,   8,    4,   1},
-      {-2, 0, 2, 0, 0,  0,  4, -4, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
-
-   /* 191-200 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-2, 0, 0, 0,   -4,   0,    0,   0},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 3, 0, 0, 0,   -8,   4,    2,   4},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 3, 0, 0, 1,    8,  -4,   -2,  -4},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 3, 0, 0, 2,    0,  15,    7,   0},
-      {-2, 0, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0, -138,   0,    0,   0},
-      { 0, 0, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,  -7,   -3,   0},
-      { 0, 0, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -7,   -3,   0},
-      { 2, 0,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,   54,   0,    0, -29},
-      { 0, 1,-1, 2, 0,  0, -1,  0, 2, 0, 0, 0, 0,    0,  10,    4,   0},
-      { 0, 1,-1, 2, 0,  0,  0, -2, 0, 0, 0, 0, 0,   -7,   0,    0,   3},
-
-   /* 201-210 */
-      { 0, 0, 0, 1, 0,  0,  1, -2, 0, 0, 0, 0, 0,  -37,  35,   19,  20},
-      { 0,-1, 1, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0,    0,   4,    0,   0},
-      { 0,-1, 1, 0, 0,  0,  1,  0, 0,-2, 0, 0, 0,   -4,   9,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -2,  0, 0, 2, 0, 0, 0,    8,   0,    0,  -4},
-      { 0, 1,-1, 1, 0,  3, -6,  0, 0, 0, 0, 0, 0,   -9, -14,   -8,   5},
-      { 0, 0, 0, 0, 0,  3, -5,  0, 0, 0, 0, 0, 1,   -3,  -9,   -5,   3},
-      { 0, 0, 0, 0, 0,  3, -5,  0, 0, 0, 0, 0, 0, -145,  47,    0,   0},
-      { 0, 1,-1, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,  -10,  40,   21,   5},
-      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 1,   11, -49,  -26,  -7},
-      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 2,-2150,   0,    0, 932},
-
-   /* 211-220 */
-      { 0, 2,-2, 2, 0, -3,  3,  0, 0, 0, 0, 0, 0,  -12,   0,    0,   5},
-      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 2,   85,   0,    0, -37},
-      { 0, 0, 0, 0, 0,  0,  2, -4, 0, 0, 0, 0, 1,    4,   0,    0,  -2},
-      { 0, 1,-1, 1, 0,  0,  1, -4, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  2, -4, 0, 0, 0, 0, 0,  -86, 153,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 1,   -6,   9,    5,   3},
-      { 0, 1,-1, 1, 0,  0, -3,  4, 0, 0, 0, 0, 0,    9, -13,   -7,  -5},
-      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 1,   -8,  12,    6,   4},
-      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 2,  -51,   0,    0,  22},
-      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 2,  -11,-268, -116,   5},
-
-   /* 221-230 */
-      { 0, 2,-2, 2, 0, -5,  6,  0, 0, 0, 0, 0, 0,    0,  12,    5,   0},
-      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 2,    0,   7,    3,   0},
-      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 1,   31,   6,    3, -17},
-      { 0, 1,-1, 1, 0, -5,  7,  0, 0, 0, 0, 0, 0,  140,  27,   14, -75},
-      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 1,   57,  11,    6, -30},
-      { 0, 0, 0, 0, 0,  5, -8,  0, 0, 0, 0, 0, 0,  -14, -39,    0,   0},
-      { 0, 1,-1, 2, 0,  0, -1,  0,-1, 0, 0, 0, 0,    0,  -6,   -2,   0},
-      { 0, 0, 0, 1, 0,  0,  0,  0,-1, 0, 0, 0, 0,    4,  15,    8,  -2},
-      { 0,-1, 1, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    0,   4,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -2,  0, 1, 0, 0, 0, 0,   -3,   0,    0,   1},
-
-   /* 231-240 */
-      { 0, 0, 0, 0, 0,  0, -6, 11, 0, 0, 0, 0, 2,    0,  11,    5,   0},
-      { 0, 0, 0, 0, 0,  0,  6,-11, 0, 0, 0, 0, 0,    9,   6,    0,   0},
-      { 0, 0, 0, 0,-1,  0,  4,  0, 0, 0, 0, 0, 2,   -4,  10,    4,   2},
-      { 0, 0, 0, 0, 1,  0, -4,  0, 0, 0, 0, 0, 0,    5,   3,    0,   0},
-      { 2, 0,-2, 1, 0, -3,  3,  0, 0, 0, 0, 0, 0,   16,   0,    0,  -9},
-      {-2, 0, 2, 0, 0,  0,  2,  0, 0,-2, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -7,  9, 0, 0, 0, 0, 0,    0,   3,    2,  -1},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 4,-5, 0, 0, 2,    7,   0,    0,  -3},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 0,  -25,  22,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 1,   42, 223,  119, -22},
-
-   /* 241-250 */
-      { 0, 1,-1, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,  -27,-143,  -77,  14},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 1,    9,  49,   26,  -5},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 2,-1166,   0,    0, 505},
-      { 0, 2,-2, 2, 0,  0, -2,  0, 2, 0, 0, 0, 0,   -5,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 5, 0, 0, 2,   -6,   0,    0,   3},
-      { 0, 0, 0, 1, 0,  3, -5,  0, 0, 0, 0, 0, 0,   -8,   0,    1,   4},
-      { 0,-1, 1, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
-      { 0, 2,-2, 1, 0, -3,  3,  0, 0, 0, 0, 0, 0,  117,   0,    0, -63},
-      { 0, 0, 0, 1, 0,  0,  2, -4, 0, 0, 0, 0, 0,   -4,   8,    4,   2},
-      { 0, 2,-2, 1, 0,  0, -4,  4, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
-
-   /* 251-260 */
-      { 0, 1,-1, 2, 0, -5,  7,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  3, -6, 0, 0, 0, 0, 0,    0,  31,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 1,   -5,   0,    1,   3},
-      { 0, 1,-1, 1, 0,  0, -4,  6, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 2,  -24, -13,   -6,  10},
-      { 0,-1, 1, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    3,   0,    0,   0},
-      { 0, 0, 0, 1, 0,  2, -3,  0, 0, 0, 0, 0, 0,    0, -32,  -17,   0},
-      { 0, 0, 0, 0, 0,  0, -5,  9, 0, 0, 0, 0, 2,    8,  12,    5,  -3},
-      { 0, 0, 0, 0, 0,  0, -5,  9, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
-
-   /* 261-270 */
-      { 0, 0, 0, 0, 0,  0,  5, -9, 0, 0, 0, 0, 0,    7,  13,    0,   0},
-      { 0,-1, 1, 0, 0,  0,  1,  0,-2, 0, 0, 0, 0,   -3,  16,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,   50,   0,    0, -27},
-      {-2, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -5,   -3,   0},
-      { 0,-2, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,   13,   0,    0,   0},
-      { 0, 0, 0, 0, 0, -6, 10,  0, 0, 0, 0, 0, 1,    0,   5,    3,   1},
-      { 0, 0, 0, 0, 0, -6, 10,  0, 0, 0, 0, 0, 2,   24,   5,    2, -11},
-      { 0, 0, 0, 0, 0, -2,  3,  0, 0, 0, 0, 0, 2,    5, -11,   -5,  -2},
-      { 0, 0, 0, 0, 0, -2,  3,  0, 0, 0, 0, 0, 1,   30,  -3,   -2, -16},
-      { 0, 1,-1, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,   18,   0,    0,  -9},
-
-   /* 271-280 */
-      { 0, 0, 0, 0, 0,  2, -3,  0, 0, 0, 0, 0, 0,    8, 614,    0,   0},
-      { 0, 0, 0, 0, 0,  2, -3,  0, 0, 0, 0, 0, 1,    3,  -3,   -1,  -2},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 1,    6,  17,    9,  -3},
-      { 0, 1,-1, 1, 0,  0, -1,  0, 3, 0, 0, 0, 0,   -3,  -9,   -5,   2},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 1,    0,   6,    3,  -1},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 2, -127,  21,    9,  55},
-      { 0, 0, 0, 0, 0,  0,  4, -8, 0, 0, 0, 0, 0,    3,   5,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -4,  8, 0, 0, 0, 0, 2,   -6, -10,   -4,   3},
-      { 0,-2, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,    5,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -4,  7, 0, 0, 0, 0, 2,   16,   9,    4,  -7},
-
-   /* 281-290 */
-      { 0, 0, 0, 0, 0,  0, -4,  7, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  4, -7, 0, 0, 0, 0, 0,    0,  22,    0,   0},
-      { 0, 0, 0, 1, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,  19,   10,   0},
-      { 0, 2,-2, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,    7,   0,    0,  -4},
-      { 0, 0, 0, 0, 0,  0, -5, 10, 0, 0, 0, 0, 2,    0,  -5,   -2,   0},
-      { 0, 0, 0, 1, 0, -1,  2,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  0, 4, 0, 0, 0, 2,   -9,   3,    1,   4},
-      { 0, 0, 0, 0, 0,  0, -3,  5, 0, 0, 0, 0, 2,   17,   0,    0,  -7},
-      { 0, 0, 0, 0, 0,  0, -3,  5, 0, 0, 0, 0, 1,    0,  -3,   -2,  -1},
-      { 0, 0, 0, 0, 0,  0,  3, -5, 0, 0, 0, 0, 0,  -20,  34,    0,   0},
-
-   /* 291-300 */
-      { 0, 0, 0, 0, 0,  1, -2,  0, 0, 0, 0, 0, 1,  -10,   0,    1,   5},
-      { 0, 1,-1, 1, 0,  1, -3,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  1, -2,  0, 0, 0, 0, 0, 0,   22, -87,    0,   0},
-      { 0, 0, 0, 0, 0, -1,  2,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0, -1,  2,  0, 0, 0, 0, 0, 2,   -3,  -6,   -2,   1},
-      { 0, 0, 0, 0, 0, -7, 11,  0, 0, 0, 0, 0, 2,  -16,  -3,   -1,   7},
-      { 0, 0, 0, 0, 0, -7, 11,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
-      { 0,-2, 2, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  2, -3, 0, 0, 0, 0, 0,  -68,  39,    0,   0},
-      { 0, 2,-2, 1, 0, -4,  4,  0, 0, 0, 0, 0, 0,   27,   0,    0, -14},
-
-   /* 301-310 */
-      { 0,-1, 1, 0, 0,  4, -5,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1, -1, 0, 0, 0, 0, 0,  -25,   0,    0,   0},
-      { 0, 0, 0, 0, 0, -4,  7,  0, 0, 0, 0, 0, 1,  -12,  -3,   -2,   6},
-      { 0, 1,-1, 1, 0, -4,  6,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0, -4,  7,  0, 0, 0, 0, 0, 2,    3,  66,   29,  -1},
-      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 2,  490,   0,    0,-213},
-      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 1,  -22,  93,   49,  12},
-      { 0, 1,-1, 1, 0, -4,  5,  0, 0, 0, 0, 0, 0,   -7,  28,   15,   4},
-      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 1,   -3,  13,    7,   2},
-      { 0, 0, 0, 0, 0,  4, -6,  0, 0, 0, 0, 0, 0,  -46,  14,    0,   0},
-
-   /* 311-320 */
-      {-2, 0, 2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  1, 0, 0, 0, 0, 0,    2,   1,    0,   0},
-      { 0,-1, 1, 0, 0,  1,  0,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
-      { 0, 0, 0, 1, 0,  1, -1,  0, 0, 0, 0, 0, 0,  -28,   0,    0,  15},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 5, 0, 0, 0, 2,    5,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  1, -3, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -1,  3, 0, 0, 0, 0, 2,  -11,   0,    0,   5},
-      { 0, 0, 0, 0, 0,  0, -7, 12, 0, 0, 0, 0, 2,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0, -1,  1,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0, -1,  1,  0, 0, 0, 0, 0, 1,   25, 106,   57, -13},
-
-   /* 321-330 */
-      { 0, 1,-1, 1, 0, -1,  0,  0, 0, 0, 0, 0, 0,    5,  21,   11,  -3},
-      { 0, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0, 1485,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 1,   -7, -32,  -17,   4},
-      { 0, 1,-1, 1, 0,  1, -2,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
-      { 0, 0, 0, 0, 0,  0, -2,  5, 0, 0, 0, 0, 2,   -6,  -3,   -2,   3},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 4, 0, 0, 0, 2,   30,  -6,   -2, -13},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-4, 0, 0, 0, 0,   -4,   4,    0,   0},
-      { 0, 0, 0, 1, 0, -1,  1,  0, 0, 0, 0, 0, 0,  -19,   0,    0,  10},
-      { 0, 0, 0, 0, 0,  0, -6, 10, 0, 0, 0, 0, 2,    0,   4,    2,  -1},
-      { 0, 0, 0, 0, 0,  0, -6, 10, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-
-   /* 331-340 */
-      { 0, 2,-2, 1, 0,  0, -3,  0, 3, 0, 0, 0, 0,    4,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0, -3,  7, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
-      {-2, 0, 2, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -5,  8, 0, 0, 0, 0, 2,    5,   3,    1,  -2},
-      { 0, 0, 0, 0, 0,  0,  5, -8, 0, 0, 0, 0, 0,    0,  11,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 3, 0, 0, 0, 2,  118,   0,    0, -52},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 3, 0, 0, 0, 1,    0,  -5,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-3, 0, 0, 0, 0,  -28,  36,    0,   0},
-      { 0, 0, 0, 0, 0,  2, -4,  0, 0, 0, 0, 0, 0,    5,  -5,    0,   0},
-      { 0, 0, 0, 0, 0, -2,  4,  0, 0, 0, 0, 0, 1,   14, -59,  -31,  -8},
-
-   /* 341-350 */
-      { 0, 1,-1, 1, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,   9,    5,   1},
-      { 0, 0, 0, 0, 0, -2,  4,  0, 0, 0, 0, 0, 2, -458,   0,    0, 198},
-      { 0, 0, 0, 0, 0, -6,  9,  0, 0, 0, 0, 0, 2,    0, -45,  -20,   0},
-      { 0, 0, 0, 0, 0, -6,  9,  0, 0, 0, 0, 0, 1,    9,   0,    0,  -5},
-      { 0, 0, 0, 0, 0,  6, -9,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
-      { 0, 0, 0, 1, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -4,   -2,  -1},
-      { 0, 2,-2, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,   11,   0,    0,  -6},
-      { 0, 0, 0, 0, 0,  0, -4,  6, 0, 0, 0, 0, 2,    6,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  4, -6, 0, 0, 0, 0, 0,  -16,  23,    0,   0},
-      { 0, 0, 0, 1, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  -4,   -2,   0},
-
-   /* 351-360 */
-      { 0, 0, 0, 0, 0,  0, -1,  0, 2, 0, 0, 0, 2,   -5,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-2, 0, 0, 0, 0, -166, 269,    0,   0},
-      { 0, 0, 0, 1, 0,  0,  1,  0,-1, 0, 0, 0, 0,   15,   0,    0,  -8},
-      { 0, 0, 0, 0, 0, -5,  9,  0, 0, 0, 0, 0, 2,   10,   0,    0,  -4},
-      { 0, 0, 0, 0, 0,  0,  3, -4, 0, 0, 0, 0, 0,  -78,  45,    0,   0},
-      { 0, 0, 0, 0, 0, -3,  4,  0, 0, 0, 0, 0, 2,    0,  -5,   -2,   0},
-      { 0, 0, 0, 0, 0, -3,  4,  0, 0, 0, 0, 0, 1,    7,   0,    0,  -4},
-      { 0, 0, 0, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,   -5, 328,    0,   0},
-      { 0, 0, 0, 0, 0,  3, -4,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
-      { 0, 0, 0, 1, 0,  0,  2, -2, 0, 0, 0, 0, 0,    5,   0,    0,  -2},
-
-   /* 361-370 */
-      { 0, 0, 0, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-3, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 1,-5, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 1, 0, 0, 0, 1,    0,  -4,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,-1223, -26,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 1,    0,   7,    3,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-3, 5, 0, 0, 0,    3,   0,    0,   0},
-      { 0, 0, 0, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-2, 0, 0, 0,   -6,  20,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0, -368,   0,    0,   0},
-
-   /* 371-380 */
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-1, 0, 0, 0,  -75,   0,    0,   0},
-      { 0, 0, 0, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,   11,   0,    0,  -6},
-      { 0, 0, 0, 1, 0,  0, -2,  2, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
-      { 0, 0, 0, 0, 0, -8, 14,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 2,-5, 0, 0, 0,  -13, -30,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -8, 3, 0, 0, 0, 0,   21,   3,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -8, 3, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    8, -27,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  3, -8, 3, 0, 0, 0, 0,  -19, -11,    0,   0},
-
-   /* 381-390 */
-      { 0, 0, 0, 0, 0,  0, -3,  8,-3, 0, 0, 0, 2,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  1,  0,-2, 5, 0, 0, 2,    0,   5,    2,   0},
-      { 0, 0, 0, 0, 0, -8, 12,  0, 0, 0, 0, 0, 2,   -6,   0,    0,   2},
-      { 0, 0, 0, 0, 0, -8, 12,  0, 0, 0, 0, 0, 0,   -8,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 1,-2, 0, 0, 0,   -1,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 1, 0, 0, 2,  -14,   0,    0,   6},
-      { 0, 0, 0, 0, 0,  0,  0,  2, 0, 0, 0, 0, 0,    6,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  0,  2, 0, 0, 0, 0, 2,  -74,   0,    0,  32},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 2, 0, 0, 2,    0,  -3,   -1,   0},
-      { 0, 2,-2, 1, 0, -5,  5,  0, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
-
-   /* 391-400 */
-      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 0,    8,  11,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 1,    0,   3,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 2, -262,   0,    0, 114},
-      { 0, 0, 0, 0, 0,  3, -6,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
-      { 0, 0, 0, 0, 0, -3,  6,  0, 0, 0, 0, 0, 1,   -7,   0,    0,   4},
-      { 0, 0, 0, 0, 0, -3,  6,  0, 0, 0, 0, 0, 2,    0, -27,  -12,   0},
-      { 0, 0, 0, 0, 0,  0, -1,  4, 0, 0, 0, 0, 2,  -19,  -8,   -4,   8},
-      { 0, 0, 0, 0, 0, -5,  7,  0, 0, 0, 0, 0, 2,  202,   0,    0, -87},
-      { 0, 0, 0, 0, 0, -5,  7,  0, 0, 0, 0, 0, 1,   -8,  35,   19,   5},
-      { 0, 1,-1, 1, 0, -5,  6,  0, 0, 0, 0, 0, 0,    0,   4,    2,   0},
-
-   /* 401-410 */
-      { 0, 0, 0, 0, 0,  5, -7,  0, 0, 0, 0, 0, 0,   16,  -5,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,    5,   0,    0,  -3},
-      { 0, 0, 0, 0, 0,  0, -1,  0, 1, 0, 0, 0, 0,    0,  -3,    0,   0},
-      { 0, 0, 0, 0,-1,  0,  3,  0, 0, 0, 0, 0, 2,    1,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 2, 0, 0, 0, 2,  -35, -48,  -21,  15},
-      { 0, 0, 0, 0, 0,  0, -2,  6, 0, 0, 0, 0, 2,   -3,  -5,   -2,   1},
-      { 0, 0, 0, 1, 0,  2, -2,  0, 0, 0, 0, 0, 0,    6,   0,    0,  -3},
-      { 0, 0, 0, 0, 0,  0, -6,  9, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  0,  6, -9, 0, 0, 0, 0, 0,    0,  -5,    0,   0},
-      { 0, 0, 0, 0, 0, -2,  2,  0, 0, 0, 0, 0, 1,   12,  55,   29,  -6},
-
-   /* 411-420 */
-      { 0, 1,-1, 1, 0, -2,  1,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
-      { 0, 0, 0, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0, -598,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  2, -2,  0, 0, 0, 0, 0, 1,   -3, -13,   -7,   1},
-      { 0, 0, 0, 0, 0,  0,  1,  0, 3, 0, 0, 0, 2,   -5,  -7,   -3,   2},
-      { 0, 0, 0, 0, 0,  0, -5,  7, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  0,  5, -7, 0, 0, 0, 0, 0,    5,  -7,    0,   0},
-      { 0, 0, 0, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  4, -5, 0, 0, 0, 0, 0,   16,  -6,    0,   0},
-      { 0, 0, 0, 0, 0,  1, -3,  0, 0, 0, 0, 0, 0,    8,  -3,    0,   0},
-      { 0, 0, 0, 0, 0, -1,  3,  0, 0, 0, 0, 0, 1,    8, -31,  -16,  -4},
-
-   /* 421-430 */
-      { 0, 1,-1, 1, 0, -1,  2,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0, -1,  3,  0, 0, 0, 0, 0, 2,  113,   0,    0, -49},
-      { 0, 0, 0, 0, 0, -7, 10,  0, 0, 0, 0, 0, 2,    0, -24,  -10,   0},
-      { 0, 0, 0, 0, 0, -7, 10,  0, 0, 0, 0, 0, 1,    4,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  3, -3, 0, 0, 0, 0, 0,   27,   0,    0,   0},
-      { 0, 0, 0, 0, 0, -4,  8,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0, -4,  5,  0, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
-      { 0, 0, 0, 0, 0, -4,  5,  0, 0, 0, 0, 0, 1,    5,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  4, -5,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  1, 0, 0, 0, 0, 2,  -13,   0,    0,   6},
-
-   /* 431-440 */
-      { 0, 0, 0, 0, 0,  0, -2,  0, 5, 0, 0, 0, 2,    5,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  0,  0,  3, 0, 0, 0, 0, 2,  -18, -10,   -4,   8},
-      { 0, 0, 0, 0, 0,  1,  0,  0, 0, 0, 0, 0, 0,   -4, -28,    0,   0},
-      { 0, 0, 0, 0, 0,  1,  0,  0, 0, 0, 0, 0, 2,   -5,   6,    3,   2},
-      { 0, 0, 0, 0, 0, -9, 13,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0,  0, -1,  5, 0, 0, 0, 0, 2,   -5,  -9,   -4,   2},
-      { 0, 0, 0, 0, 0,  0, -2,  0, 4, 0, 0, 0, 2,   17,   0,    0,  -7},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-4, 0, 0, 0, 0,   11,   4,    0,   0},
-      { 0, 0, 0, 0, 0,  0, -2,  7, 0, 0, 0, 0, 2,    0,  -6,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   83,  15,    0,   0},
-
-   /* 441-450 */
-      { 0, 0, 0, 0, 0, -2,  5,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0, -2,  5,  0, 0, 0, 0, 0, 2,    0,-114,  -49,   0},
-      { 0, 0, 0, 0, 0, -6,  8,  0, 0, 0, 0, 0, 2,  117,   0,    0, -51},
-      { 0, 0, 0, 0, 0, -6,  8,  0, 0, 0, 0, 0, 1,   -5,  19,   10,   2},
-      { 0, 0, 0, 0, 0,  6, -8,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0, -3,  9, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -6, 0, 0, 0, 0, 0,    3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -6, 0, 0, 0, 0, 2,    0,  -6,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,  393,   3,    0,   0},
-
-   /* 451-460 */
-      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 1,   -4,  21,   11,   2},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 2,   -6,   0,   -1,   3},
-      { 0, 0, 0, 0, 0, -5, 10,  0, 0, 0, 0, 0, 2,   -3,   8,    4,   1},
-      { 0, 0, 0, 0, 0,  0,  4, -4, 0, 0, 0, 0, 0,    8,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  4, -4, 0, 0, 0, 0, 2,   18, -29,  -13,  -8},
-      { 0, 0, 0, 0, 0, -3,  3,  0, 0, 0, 0, 0, 1,    8,  34,   18,  -4},
-      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,   89,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 1,    3,  12,    6,  -1},
-      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 2,   54, -15,   -7, -24},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-3, 0, 0, 0,    0,   3,    0,   0},
-
-   /* 461-470 */
-      { 0, 0, 0, 0, 0,  0, -5, 13, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-1, 0, 0, 0, 0,    0,  35,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-1, 0, 0, 0, 2, -154, -30,  -13,  67},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-2, 0, 0, 0,   15,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-2, 0, 0, 1,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  3, -2, 0, 0, 0, 0, 0,    0,   9,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  3, -2, 0, 0, 0, 0, 2,   80, -71,  -31, -35},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-1, 0, 0, 2,    0, -20,   -9,   0},
-      { 0, 0, 0, 0, 0,  0, -6, 15, 0, 0, 0, 0, 2,   11,   5,    2,  -5},
-      { 0, 0, 0, 0, 0, -8, 15,  0, 0, 0, 0, 0, 2,   61, -96,  -42, -27},
-
-   /* 471-480 */
-      { 0, 0, 0, 0, 0, -3,  9, -4, 0, 0, 0, 0, 2,   14,   9,    4,  -6},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 2,-5, 0, 0, 2,  -11,  -6,   -3,   5},
-      { 0, 0, 0, 0, 0,  0, -2,  8,-1,-5, 0, 0, 2,    0,  -3,   -1,   0},
-      { 0, 0, 0, 0, 0,  0,  6, -8, 3, 0, 0, 0, 2,  123,-415, -180, -53},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 0,    0,   0,    0, -35},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 1,    7, -32,  -17,  -4},
-      { 0, 1,-1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -9,   -5,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 1,    0,  -4,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 2,  -89,   0,    0,  38},
-
-   /* 481-490 */
-      { 0, 0, 0, 0, 0,  0, -6, 16,-4,-5, 0, 0, 2,    0, -86,  -19,  -6},
-      { 0, 0, 0, 0, 0,  0, -2,  8,-3, 0, 0, 0, 2,    0,   0,  -19,   6},
-      { 0, 0, 0, 0, 0,  0, -2,  8,-3, 0, 0, 0, 2, -123,-416, -180,  53},
-      { 0, 0, 0, 0, 0,  0,  6, -8, 1, 5, 0, 0, 2,    0,  -3,   -1,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 5, 0, 0, 2,   12,  -6,   -3,  -5},
-      { 0, 0, 0, 0, 0,  3, -5,  4, 0, 0, 0, 0, 2,  -13,   9,    4,   6},
-      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 2,    0, -15,   -7,   0},
-      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 2,  -62, -97,  -42,  27},
-      { 0, 0, 0, 0, 0,  0, 11,  0, 0, 0, 0, 0, 2,  -11,   5,    2,   5},
-
-   /* 491-500 */
-      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 1, 0, 0, 2,    0, -19,   -8,   0},
-      { 0, 0, 0, 0, 0,  3, -3,  0, 2, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 2,-2, 1, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   4,    2,   0},
-      { 0, 1,-1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-      { 0, 2,-2, 1, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  1,  2, 0, 0, 0, 0, 2,  -85, -70,  -31,  37},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 1, 0, 0, 0, 2,  163, -12,   -5, -72},
-      { 0, 0, 0, 0, 0, -3,  7,  0, 0, 0, 0, 0, 2,  -63, -16,   -7,  28},
-      { 0, 0, 0, 0, 0,  0,  0,  4, 0, 0, 0, 0, 2,  -21, -32,  -14,   9},
-      { 0, 0, 0, 0, 0, -5,  6,  0, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
-
-   /* 501-510 */
-      { 0, 0, 0, 0, 0, -5,  6,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
-      { 0, 0, 0, 0, 0,  5, -6,  0, 0, 0, 0, 0, 0,    0,   8,    0,   0},
-      { 0, 0, 0, 0, 0,  5, -6,  0, 0, 0, 0, 0, 2,    3,  10,    4,  -1},
-      { 0, 0, 0, 0, 0,  0,  2,  0, 2, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  0, -1,  6, 0, 0, 0, 0, 2,    0,  -7,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  7, -9, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
-      { 0, 0, 0, 0, 0,  2, -1,  0, 0, 0, 0, 0, 0,    6,  19,    0,   0},
-      { 0, 0, 0, 0, 0,  2, -1,  0, 0, 0, 0, 0, 2,    5,-173,  -75,  -2},
-      { 0, 0, 0, 0, 0,  0,  6, -7, 0, 0, 0, 0, 2,    0,  -7,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -5, 0, 0, 0, 0, 2,    7, -12,   -5,  -3},
-
-   /* 511-520 */
-      { 0, 0, 0, 0, 0, -1,  4,  0, 0, 0, 0, 0, 1,   -3,   0,    0,   2},
-      { 0, 0, 0, 0, 0, -1,  4,  0, 0, 0, 0, 0, 2,    3,  -4,   -2,  -1},
-      { 0, 0, 0, 0, 0, -7,  9,  0, 0, 0, 0, 0, 2,   74,   0,    0, -32},
-      { 0, 0, 0, 0, 0, -7,  9,  0, 0, 0, 0, 0, 1,   -3,  12,    6,   2},
-      { 0, 0, 0, 0, 0,  0,  4, -3, 0, 0, 0, 0, 2,   26, -14,   -6, -11},
-      { 0, 0, 0, 0, 0,  0,  3, -1, 0, 0, 0, 0, 2,   19,   0,    0,  -8},
-      { 0, 0, 0, 0, 0, -4,  4,  0, 0, 0, 0, 0, 1,    6,  24,   13,  -3},
-      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,   83,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 1,    0, -10,   -5,   0},
-      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 2,   11,  -3,   -1,  -5},
-
-   /* 521-530 */
-      { 0, 0, 0, 0, 0,  0,  2,  1, 0, 0, 0, 0, 2,    3,   0,    1,  -1},
-      { 0, 0, 0, 0, 0,  0, -3,  0, 5, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 1,    5, -23,  -12,  -3},
-      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 2, -339,   0,    0, 147},
-      { 0, 0, 0, 0, 0, -9, 12,  0, 0, 0, 0, 0, 2,    0, -10,   -5,   0},
-      { 0, 0, 0, 0, 0,  0,  3,  0,-4, 0, 0, 0, 0,    5,   0,    0,   0},
-      { 0, 2,-2, 1, 0,  1, -1,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  0,  7, -8, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  3,  0,-3, 0, 0, 0, 0,   18,  -3,    0,   0},
-
-   /* 531-540 */
-      { 0, 0, 0, 0, 0,  0,  3,  0,-3, 0, 0, 0, 2,    9, -11,   -5,  -4},
-      { 0, 0, 0, 0, 0, -2,  6,  0, 0, 0, 0, 0, 2,   -8,   0,    0,   4},
-      { 0, 0, 0, 0, 0, -6,  7,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
-      { 0, 0, 0, 0, 0,  6, -7,  0, 0, 0, 0, 0, 0,    0,   9,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  6, -6, 0, 0, 0, 0, 2,    6,  -9,   -4,  -2},
-      { 0, 0, 0, 0, 0,  0,  3,  0,-2, 0, 0, 0, 0,   -4, -12,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  3,  0,-2, 0, 0, 0, 2,   67, -91,  -39, -29},
-      { 0, 0, 0, 0, 0,  0,  5, -4, 0, 0, 0, 0, 2,   30, -18,   -8, -13},
-      { 0, 0, 0, 0, 0,  3, -2,  0, 0, 0, 0, 0, 0,    0,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  3, -2,  0, 0, 0, 0, 0, 2,    0,-114,  -50,   0},
-
-   /* 541-550 */
-      { 0, 0, 0, 0, 0,  0,  3,  0,-1, 0, 0, 0, 2,    0,   0,    0,  23},
-      { 0, 0, 0, 0, 0,  0,  3,  0,-1, 0, 0, 0, 2,  517,  16,    7,-224},
-      { 0, 0, 0, 0, 0,  0,  3,  0, 0,-2, 0, 0, 2,    0,  -7,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  4, -2, 0, 0, 0, 0, 2,  143,  -3,   -1, -62},
-      { 0, 0, 0, 0, 0,  0,  3,  0, 0,-1, 0, 0, 2,   29,   0,    0, -13},
-      { 0, 2,-2, 1, 0,  0,  1,  0,-1, 0, 0, 0, 0,   -4,   0,    0,   2},
-      { 0, 0, 0, 0, 0, -8, 16,  0, 0, 0, 0, 0, 2,   -6,   0,    0,   3},
-      { 0, 0, 0, 0, 0,  0,  3,  0, 2,-5, 0, 0, 2,    5,  12,    5,  -2},
-      { 0, 0, 0, 0, 0,  0,  7, -8, 3, 0, 0, 0, 2,  -25,   0,    0,  11},
-      { 0, 0, 0, 0, 0,  0, -5, 16,-4,-5, 0, 0, 2,   -3,   0,    0,   1},
-
-   /* 551-560 */
-      { 0, 0, 0, 0, 0,  0,  3,  0, 0, 0, 0, 0, 2,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0,  0, -1,  8,-3, 0, 0, 0, 2,  -22,  12,    5,  10},
-      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 2,   50,   0,    0, -22},
-      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 1,    0,   7,    4,   0},
-      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 2,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0,  0,  2,  2, 0, 0, 0, 0, 2,   -4,   4,    2,   2},
-      { 0, 0, 0, 0, 0,  0,  3,  0, 1, 0, 0, 0, 2,   -5, -11,   -5,   2},
-      { 0, 0, 0, 0, 0, -3,  8,  0, 0, 0, 0, 0, 2,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0, -5,  5,  0, 0, 0, 0, 0, 1,    4,  17,    9,  -2},
-      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 0,   59,   0,    0,   0},
-
-   /* 561-570 */
-      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 1,    0,  -4,   -2,   0},
-      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 2,   -8,   0,    0,   4},
-      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 1,    4, -15,   -8,  -2},
-      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 2,  370,  -8,    0,-160},
-      { 0, 0, 0, 0, 0,  0,  7, -7, 0, 0, 0, 0, 2,    0,   0,   -3,   0},
-      { 0, 0, 0, 0, 0,  0,  7, -7, 0, 0, 0, 0, 2,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0,  0,  6, -5, 0, 0, 0, 0, 2,   -6,   3,    1,   3},
-      { 0, 0, 0, 0, 0,  7, -8,  0, 0, 0, 0, 0, 0,    0,   6,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  5, -3, 0, 0, 0, 0, 2,  -10,   0,    0,   4},
-
-   /* 571-580 */
-      { 0, 0, 0, 0, 0,  4, -3,  0, 0, 0, 0, 0, 2,    0,   9,    4,   0},
-      { 0, 0, 0, 0, 0,  1,  2,  0, 0, 0, 0, 0, 2,    4,  17,    7,  -2},
-      { 0, 0, 0, 0, 0, -9, 11,  0, 0, 0, 0, 0, 2,   34,   0,    0, -15},
-      { 0, 0, 0, 0, 0, -9, 11,  0, 0, 0, 0, 0, 1,    0,   5,    3,   0},
-      { 0, 0, 0, 0, 0,  0,  4,  0,-4, 0, 0, 0, 2,   -5,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  4,  0,-3, 0, 0, 0, 2,  -37,  -7,   -3,  16},
-      { 0, 0, 0, 0, 0, -6,  6,  0, 0, 0, 0, 0, 1,    3,  13,    7,  -2},
-      { 0, 0, 0, 0, 0,  6, -6,  0, 0, 0, 0, 0, 0,   40,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  6, -6,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  4,  0,-2, 0, 0, 0, 2, -184,  -3,   -1,  80},
-
-   /* 581-590 */
-      { 0, 0, 0, 0, 0,  0,  6, -4, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
-      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 1,    0, -10,   -6,  -1},
-      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 2,   31,  -6,    0, -13},
-      { 0, 0, 0, 0, 0,  0,  4,  0,-1, 0, 0, 0, 2,   -3, -32,  -14,   1},
-      { 0, 0, 0, 0, 0,  0,  4,  0, 0,-2, 0, 0, 2,   -7,   0,    0,   3},
-      { 0, 0, 0, 0, 0,  0,  5, -2, 0, 0, 0, 0, 2,    0,  -8,   -4,   0},
-      { 0, 0, 0, 0, 0,  0,  4,  0, 0, 0, 0, 0, 0,    3,  -4,    0,   0},
-      { 0, 0, 0, 0, 0,  8, -9,  0, 0, 0, 0, 0, 0,    0,   4,    0,   0},
-      { 0, 0, 0, 0, 0,  5, -4,  0, 0, 0, 0, 0, 2,    0,   3,    1,   0},
-
-   /* 591-600 */
-      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 2,   19, -23,  -10,   2},
-      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 1,    0,   0,    0, -10},
-      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 1,    0,   3,    2,   0},
-      { 0, 0, 0, 0, 0, -7,  7,  0, 0, 0, 0, 0, 1,    0,   9,    5,  -1},
-      { 0, 0, 0, 0, 0,  7, -7,  0, 0, 0, 0, 0, 0,   28,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 1,    0,  -7,   -4,   0},
-      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 2,    8,  -4,    0,  -4},
-      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 0,    0,   0,   -2,   0},
-      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  5,  0,-4, 0, 0, 0, 2,   -3,   0,    0,   1},
-
-   /* 601-610 */
-      { 0, 0, 0, 0, 0,  0,  5,  0,-3, 0, 0, 0, 2,   -9,   0,    1,   4},
-      { 0, 0, 0, 0, 0,  0,  5,  0,-2, 0, 0, 0, 2,    3,  12,    5,  -1},
-      { 0, 0, 0, 0, 0,  3,  0,  0, 0, 0, 0, 0, 2,   17,  -3,   -1,   0},
-      { 0, 0, 0, 0, 0, -8,  8,  0, 0, 0, 0, 0, 1,    0,   7,    4,   0},
-      { 0, 0, 0, 0, 0,  8, -8,  0, 0, 0, 0, 0, 0,   19,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  5, -3,  0, 0, 0, 0, 0, 1,    0,  -5,   -3,   0},
-      { 0, 0, 0, 0, 0,  5, -3,  0, 0, 0, 0, 0, 2,   14,  -3,    0,  -1},
-      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   0,   -1,   0},
-      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   0,    0,  -5},
-      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   5,    3,   0},
-
-   /* 611-620 */
-      { 0, 0, 0, 0, 0,  9, -9,  0, 0, 0, 0, 0, 0,   13,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  6, -4,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    2,   9,    4,   3},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    0,   0,    0,  -4},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    8,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 1,    0,   4,    2,   0},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    6,   0,    0,  -3},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    6,   0,    0,   0},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 1,    0,   3,    1,   0},
-      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    5,   0,    0,  -2},
-
-   /* 621-630 */
-      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
-      { 1, 0,-2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 1, 0,-2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    6,   0,    0,   0},
-      { 1, 0,-2, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    7,   0,    0,   0},
-      { 1, 0,-2, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
-      {-1, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
-      {-1, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,    6,   0,    0,   0},
-      {-1, 0, 2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -4,    0,   0},
-      { 1, 0,-2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -4,    0,   0},
-      {-2, 0, 2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    5,   0,    0,   0},
-
-   /* 631-640 */
-      {-1, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   -3,   0,    0,   0},
-      {-1, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    4,   0,    0,   0},
-      {-1, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
-      {-1, 0, 2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
-      { 1,-1, 1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
-      {-1, 0, 2, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   13,   0,    0,   0},
-      {-2, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   21,  11,    0,   0},
-      { 1, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -5,    0,   0},
-      {-1, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 0, 0,    0,  -5,   -2,   0},
-      { 1, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
-
-   /* 641-650 */
-      {-1, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -5,    0,   0},
-      {-1, 0, 2, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   2},
-      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   20,  10,    0,   0},
-      {-1, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,  -34,   0,    0,   0},
-      {-1, 0, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,  -19,   0,    0,   0},
-      { 1, 0,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,    3,   0,    0,  -2},
-      { 1, 2,-2, 2, 0, -3,  3,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-      { 1, 2,-2, 2, 0,  0, -2,  0, 2, 0, 0, 0, 0,   -6,   0,    0,   3},
-      { 1, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
-      { 1, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    3,   0,    0,   0},
-
-   /* 651-660 */
-      { 0, 0,-2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    3,   0,    0,   0},
-      { 0, 0,-2, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    4,   0,    0,   0},
-      { 0, 2, 0, 2, 0, -2,  2,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 2, 0, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    6,   0,    0,  -3},
-      { 0, 2, 0, 2, 0, -1,  1,  0, 0, 0, 0, 0, 0,   -8,   0,    0,   3},
-      { 0, 2, 0, 2, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   0},
-      { 0, 1, 1, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -3,   -2,   0},
-      { 1, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,  126, -63,  -27, -55},
-      {-1, 2, 0, 2, 0, 10, -3,  0, 0, 0, 0, 0, 0,   -5,   0,    1,   2},
-
-   /* 661-670 */
-      { 0, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,   -3,  28,   15,   2},
-      { 1, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,    5,   0,    1,  -2},
-      { 0, 2, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   9,    4,   1},
-      { 0, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   9,    4,  -1},
-      {-1, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0, -126, -63,  -27,  55},
-      { 2, 2,-2, 2, 0,  0, -2,  0, 3, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 1, 2, 0, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,   21, -11,   -6, -11},
-      { 0, 1, 1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
-      {-1, 2, 0, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,  -21, -11,   -6,  11},
-      {-2, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   1},
-
-   /* 671-680 */
-      { 0, 2, 0, 2, 0,  2, -3,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 0, 2, 0, 2, 0,  1, -1,  0, 0, 0, 0, 0, 0,    8,   0,    0,  -4},
-      { 0, 2, 0, 2, 0,  0,  1,  0,-1, 0, 0, 0, 0,   -6,   0,    0,   3},
-      { 0, 2, 0, 2, 0,  2, -2,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-      {-1, 2, 2, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 1, 2, 0, 2, 0, -1,  1,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
-      {-1, 2, 2, 2, 0,  0,  2,  0,-3, 0, 0, 0, 0,   -5,   0,    0,   2},
-      { 2, 2, 0, 2, 0,  0,  2,  0,-3, 0, 0, 0, 0,   24, -12,   -5, -11},
-      { 1, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   3,    1,   0},
-      { 1, 2, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   3,    1,   0},
-
-   /* 681-687 */
-      { 1, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
-      { 0, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,  -24, -12,   -5,  10},
-      { 2, 2, 0, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    4,   0,   -1,  -2},
-      {-1, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,   13,   0,    0,  -6},
-      {-1, 2, 2, 2, 0,  3, -3,  0, 0, 0, 0, 0, 0,    7,   0,    0,  -3},
-      { 1, 2, 0, 2, 0,  1, -1,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
-      { 0, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,    3,   0,    0,  -1}
-   };
-
-/* Number of terms in the planetary nutation model */
-   const int NPL = (int) (sizeof xpl / sizeof xpl[0]);
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* ------------------- */
-/* LUNI-SOLAR NUTATION */
-/* ------------------- */
-
-/* Fundamental (Delaunay) arguments */
-
-/* Mean anomaly of the Moon (IERS 2003). */
-   el = eraFal03(t);
-
-/* Mean anomaly of the Sun (MHB2000). */
-   elp = fmod(1287104.79305  +
-            t * (129596581.0481  +
-            t * (-0.5532  +
-            t * (0.000136  +
-            t * (-0.00001149)))), ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean longitude of the Moon minus that of the ascending node */
-/* (IERS 2003. */
-   f = eraFaf03(t);
-
-/* Mean elongation of the Moon from the Sun (MHB2000). */
-   d = fmod(1072260.70369  +
-          t * (1602961601.2090  +
-          t * (-6.3706  +
-          t * (0.006593  +
-          t * (-0.00003169)))), ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean longitude of the ascending node of the Moon (IERS 2003). */
-   om = eraFaom03(t);
-
-/* Initialize the nutation values. */
-   dp = 0.0;
-   de = 0.0;
-
-/* Summation of luni-solar nutation series (in reverse order). */
-   for (i = NLS-1; i >= 0; i--) {
-
-   /* Argument and functions. */
-      arg = fmod((double)xls[i].nl  * el +
-                 (double)xls[i].nlp * elp +
-                 (double)xls[i].nf  * f +
-                 (double)xls[i].nd  * d +
-                 (double)xls[i].nom * om, ERFA_D2PI);
-      sarg = sin(arg);
-      carg = cos(arg);
-
-   /* Term. */
-      dp += (xls[i].sp + xls[i].spt * t) * sarg + xls[i].cp * carg;
-      de += (xls[i].ce + xls[i].cet * t) * carg + xls[i].se * sarg;
-   }
-
-/* Convert from 0.1 microarcsec units to radians. */
-   dpsils = dp * U2R;
-   depsls = de * U2R;
-
-/* ------------------ */
-/* PLANETARY NUTATION */
-/* ------------------ */
-
-/* n.b.  The MHB2000 code computes the luni-solar and planetary nutation */
-/* in different functions, using slightly different Delaunay */
-/* arguments in the two cases.  This behaviour is faithfully */
-/* reproduced here.  Use of the IERS 2003 expressions for both */
-/* cases leads to negligible changes, well below */
-/* 0.1 microarcsecond. */
-
-/* Mean anomaly of the Moon (MHB2000). */
-   al = fmod(2.35555598 + 8328.6914269554 * t, ERFA_D2PI);
-
-/* Mean longitude of the Moon minus that of the ascending node */
-/*(MHB2000). */
-   af = fmod(1.627905234 + 8433.466158131 * t, ERFA_D2PI);
-
-/* Mean elongation of the Moon from the Sun (MHB2000). */
-   ad = fmod(5.198466741 + 7771.3771468121 * t, ERFA_D2PI);
-
-/* Mean longitude of the ascending node of the Moon (MHB2000). */
-   aom = fmod(2.18243920 - 33.757045 * t, ERFA_D2PI);
-
-/* General accumulated precession in longitude (IERS 2003). */
-   apa = eraFapa03(t);
-
-/* Planetary longitudes, Mercury through Uranus (IERS 2003). */
-   alme = eraFame03(t);
-   alve = eraFave03(t);
-   alea = eraFae03(t);
-   alma = eraFama03(t);
-   alju = eraFaju03(t);
-   alsa = eraFasa03(t);
-   alur = eraFaur03(t);
-
-/* Neptune longitude (MHB2000). */
-   alne = fmod(5.321159000 + 3.8127774000 * t, ERFA_D2PI);
-
-/* Initialize the nutation values. */
-   dp = 0.0;
-   de = 0.0;
-
-/* Summation of planetary nutation series (in reverse order). */
-   for (i = NPL-1; i >= 0; i--) {
-
-   /* Argument and functions. */
-      arg = fmod((double)xpl[i].nl  * al   +
-                 (double)xpl[i].nf  * af   +
-                 (double)xpl[i].nd  * ad   +
-                 (double)xpl[i].nom * aom  +
-                 (double)xpl[i].nme * alme +
-                 (double)xpl[i].nve * alve +
-                 (double)xpl[i].nea * alea +
-                 (double)xpl[i].nma * alma +
-                 (double)xpl[i].nju * alju +
-                 (double)xpl[i].nsa * alsa +
-                 (double)xpl[i].nur * alur +
-                 (double)xpl[i].nne * alne +
-                 (double)xpl[i].npa * apa, ERFA_D2PI);
-      sarg = sin(arg);
-      carg = cos(arg);
-
-   /* Term. */
-      dp += (double)xpl[i].sp * sarg + (double)xpl[i].cp * carg;
-      de += (double)xpl[i].se * sarg + (double)xpl[i].ce * carg;
-
-   }
-
-/* Convert from 0.1 microarcsec units to radians. */
-   dpsipl = dp * U2R;
-   depspl = de * U2R;
-
-/* ------- */
-/* RESULTS */
-/* ------- */
-
-/* Add luni-solar and planetary components. */
-   *dpsi = dpsils + dpsipl;
-   *deps = depsls + depspl;
-
-   return;
-
-}
-
-void eraNut00b(double date1, double date2, double *dpsi, double *deps)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, el, elp, f, d, om, arg, dp, de, sarg, carg,
-          dpsils, depsls, dpsipl, depspl;
-   int i;
-
-/* Units of 0.1 microarcsecond to radians */
-   static const double U2R = ERFA_DAS2R / 1e7;
-
-/* ---------------------------------------- */
-/* Fixed offsets in lieu of planetary terms */
-/* ---------------------------------------- */
-
-   static const double DPPLAN = -0.135 * ERFA_DMAS2R;
-   static const double DEPLAN =  0.388 * ERFA_DMAS2R;
-
-/* --------------------------------------------------- */
-/* Luni-solar nutation: argument and term coefficients */
-/* --------------------------------------------------- */
-
-/* The units for the sine and cosine coefficients are */
-/* 0.1 microarcsec and the same per Julian century    */
-
-   static const struct {
-      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
-      double ps,pst,pc;     /* longitude sin, t*sin, cos coefficients */
-      double ec,ect,es;     /* obliquity cos, t*cos, sin coefficients */
-
-   } x[] = {
-
-   /* 1-10 */
-      { 0, 0, 0, 0,1,
-         -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0},
-      { 0, 0, 2,-2,2,
-           -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0},
-      { 0, 0, 2, 0,2,-2276413.0,-234.0, 2796.0, 978459.0,-485.0,1374.0},
-      { 0, 0, 0, 0,2,2074554.0,  207.0, -698.0,-897492.0, 470.0,-291.0},
-      { 0, 1, 0, 0,0,1475877.0,-3633.0,11817.0, 73871.0,-184.0,-1924.0},
-      { 0, 1, 2,-2,2,-516821.0, 1226.0, -524.0, 224386.0,-677.0,-174.0},
-      { 1, 0, 0, 0,0, 711159.0,   73.0, -872.0,  -6750.0,   0.0, 358.0},
-      { 0, 0, 2, 0,1,-387298.0, -367.0,  380.0, 200728.0,  18.0, 318.0},
-      { 1, 0, 2, 0,2,-301461.0,  -36.0,  816.0, 129025.0, -63.0, 367.0},
-      { 0,-1, 2,-2,2, 215829.0, -494.0,  111.0, -95929.0, 299.0, 132.0},
-
-   /* 11-20 */
-      { 0, 0, 2,-2,1, 128227.0,  137.0,  181.0, -68982.0,  -9.0,  39.0},
-      {-1, 0, 2, 0,2, 123457.0,   11.0,   19.0, -53311.0,  32.0,  -4.0},
-      {-1, 0, 0, 2,0, 156994.0,   10.0, -168.0,  -1235.0,   0.0,  82.0},
-      { 1, 0, 0, 0,1,  63110.0,   63.0,   27.0, -33228.0,   0.0,  -9.0},
-      {-1, 0, 0, 0,1, -57976.0,  -63.0, -189.0,  31429.0,   0.0, -75.0},
-      {-1, 0, 2, 2,2, -59641.0,  -11.0,  149.0,  25543.0, -11.0,  66.0},
-      { 1, 0, 2, 0,1, -51613.0,  -42.0,  129.0,  26366.0,   0.0,  78.0},
-      {-2, 0, 2, 0,1,  45893.0,   50.0,   31.0, -24236.0, -10.0,  20.0},
-      { 0, 0, 0, 2,0,  63384.0,   11.0, -150.0,  -1220.0,   0.0,  29.0},
-      { 0, 0, 2, 2,2, -38571.0,   -1.0,  158.0,  16452.0, -11.0,  68.0},
-
-   /* 21-30 */
-      { 0,-2, 2,-2,2,  32481.0,    0.0,    0.0, -13870.0,   0.0,   0.0},
-      {-2, 0, 0, 2,0, -47722.0,    0.0,  -18.0,    477.0,   0.0, -25.0},
-      { 2, 0, 2, 0,2, -31046.0,   -1.0,  131.0,  13238.0, -11.0,  59.0},
-      { 1, 0, 2,-2,2,  28593.0,    0.0,   -1.0, -12338.0,  10.0,  -3.0},
-      {-1, 0, 2, 0,1,  20441.0,   21.0,   10.0, -10758.0,   0.0,  -3.0},
-      { 2, 0, 0, 0,0,  29243.0,    0.0,  -74.0,   -609.0,   0.0,  13.0},
-      { 0, 0, 2, 0,0,  25887.0,    0.0,  -66.0,   -550.0,   0.0,  11.0},
-      { 0, 1, 0, 0,1, -14053.0,  -25.0,   79.0,   8551.0,  -2.0, -45.0},
-      {-1, 0, 0, 2,1,  15164.0,   10.0,   11.0,  -8001.0,   0.0,  -1.0},
-      { 0, 2, 2,-2,2, -15794.0,   72.0,  -16.0,   6850.0, -42.0,  -5.0},
-
-   /* 31-40 */
-      { 0, 0,-2, 2,0,  21783.0,    0.0,   13.0,   -167.0,   0.0,  13.0},
-      { 1, 0, 0,-2,1, -12873.0,  -10.0,  -37.0,   6953.0,   0.0, -14.0},
-      { 0,-1, 0, 0,1, -12654.0,   11.0,   63.0,   6415.0,   0.0,  26.0},
-      {-1, 0, 2, 2,1, -10204.0,    0.0,   25.0,   5222.0,   0.0,  15.0},
-      { 0, 2, 0, 0,0,  16707.0,  -85.0,  -10.0,    168.0,  -1.0,  10.0},
-      { 1, 0, 2, 2,2,  -7691.0,    0.0,   44.0,   3268.0,   0.0,  19.0},
-      {-2, 0, 2, 0,0, -11024.0,    0.0,  -14.0,    104.0,   0.0,   2.0},
-      { 0, 1, 2, 0,2,   7566.0,  -21.0,  -11.0,  -3250.0,   0.0,  -5.0},
-      { 0, 0, 2, 2,1,  -6637.0,  -11.0,   25.0,   3353.0,   0.0,  14.0},
-      { 0,-1, 2, 0,2,  -7141.0,   21.0,    8.0,   3070.0,   0.0,   4.0},
-
-   /* 41-50 */
-      { 0, 0, 0, 2,1,  -6302.0,  -11.0,    2.0,   3272.0,   0.0,   4.0},
-      { 1, 0, 2,-2,1,   5800.0,   10.0,    2.0,  -3045.0,   0.0,  -1.0},
-      { 2, 0, 2,-2,2,   6443.0,    0.0,   -7.0,  -2768.0,   0.0,  -4.0},
-      {-2, 0, 0, 2,1,  -5774.0,  -11.0,  -15.0,   3041.0,   0.0,  -5.0},
-      { 2, 0, 2, 0,1,  -5350.0,    0.0,   21.0,   2695.0,   0.0,  12.0},
-      { 0,-1, 2,-2,1,  -4752.0,  -11.0,   -3.0,   2719.0,   0.0,  -3.0},
-      { 0, 0, 0,-2,1,  -4940.0,  -11.0,  -21.0,   2720.0,   0.0,  -9.0},
-      {-1,-1, 0, 2,0,   7350.0,    0.0,   -8.0,    -51.0,   0.0,   4.0},
-      { 2, 0, 0,-2,1,   4065.0,    0.0,    6.0,  -2206.0,   0.0,   1.0},
-      { 1, 0, 0, 2,0,   6579.0,    0.0,  -24.0,   -199.0,   0.0,   2.0},
-
-   /* 51-60 */
-      { 0, 1, 2,-2,1,   3579.0,    0.0,    5.0,  -1900.0,   0.0,   1.0},
-      { 1,-1, 0, 0,0,   4725.0,    0.0,   -6.0,    -41.0,   0.0,   3.0},
-      {-2, 0, 2, 0,2,  -3075.0,    0.0,   -2.0,   1313.0,   0.0,  -1.0},
-      { 3, 0, 2, 0,2,  -2904.0,    0.0,   15.0,   1233.0,   0.0,   7.0},
-      { 0,-1, 0, 2,0,   4348.0,    0.0,  -10.0,    -81.0,   0.0,   2.0},
-      { 1,-1, 2, 0,2,  -2878.0,    0.0,    8.0,   1232.0,   0.0,   4.0},
-      { 0, 0, 0, 1,0,  -4230.0,    0.0,    5.0,    -20.0,   0.0,  -2.0},
-      {-1,-1, 2, 2,2,  -2819.0,    0.0,    7.0,   1207.0,   0.0,   3.0},
-      {-1, 0, 2, 0,0,  -4056.0,    0.0,    5.0,     40.0,   0.0,  -2.0},
-      { 0,-1, 2, 2,2,  -2647.0,    0.0,   11.0,   1129.0,   0.0,   5.0},
-
-   /* 61-70 */
-      {-2, 0, 0, 0,1,  -2294.0,    0.0,  -10.0,   1266.0,   0.0,  -4.0},
-      { 1, 1, 2, 0,2,   2481.0,    0.0,   -7.0,  -1062.0,   0.0,  -3.0},
-      { 2, 0, 0, 0,1,   2179.0,    0.0,   -2.0,  -1129.0,   0.0,  -2.0},
-      {-1, 1, 0, 1,0,   3276.0,    0.0,    1.0,     -9.0,   0.0,   0.0},
-      { 1, 1, 0, 0,0,  -3389.0,    0.0,    5.0,     35.0,   0.0,  -2.0},
-      { 1, 0, 2, 0,0,   3339.0,    0.0,  -13.0,   -107.0,   0.0,   1.0},
-      {-1, 0, 2,-2,1,  -1987.0,    0.0,   -6.0,   1073.0,   0.0,  -2.0},
-      { 1, 0, 0, 0,2,  -1981.0,    0.0,    0.0,    854.0,   0.0,   0.0},
-      {-1, 0, 0, 1,0,   4026.0,    0.0, -353.0,   -553.0,   0.0,-139.0},
-      { 0, 0, 2, 1,2,   1660.0,    0.0,   -5.0,   -710.0,   0.0,  -2.0},
-
-   /* 71-77 */
-      {-1, 0, 2, 4,2,  -1521.0,    0.0,    9.0,    647.0,   0.0,   4.0},
-      {-1, 1, 0, 1,1,   1314.0,    0.0,    0.0,   -700.0,   0.0,   0.0},
-      { 0,-2, 2,-2,1,  -1283.0,    0.0,    0.0,    672.0,   0.0,   0.0},
-      { 1, 0, 2, 2,1,  -1331.0,    0.0,    8.0,    663.0,   0.0,   4.0},
-      {-2, 0, 2, 2,2,   1383.0,    0.0,   -2.0,   -594.0,   0.0,  -2.0},
-      {-1, 0, 0, 0,2,   1405.0,    0.0,    4.0,   -610.0,   0.0,   2.0},
-      { 1, 1, 2,-2,2,   1290.0,    0.0,    0.0,   -556.0,   0.0,   0.0}
-   };
-
-/* Number of terms in the series */
-   const int NLS = (int) (sizeof x / sizeof x[0]);
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental epoch J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* --------------------*/
-/* LUNI-SOLAR NUTATION */
-/* --------------------*/
-
-/* Fundamental (Delaunay) arguments from Simon et al. (1994) */
-
-/* Mean anomaly of the Moon. */
-   el = fmod(485868.249036 + (1717915923.2178) * t, ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean anomaly of the Sun. */
-   elp = fmod(1287104.79305 + (129596581.0481) * t, ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean argument of the latitude of the Moon. */
-   f = fmod(335779.526232 + (1739527262.8478) * t, ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean elongation of the Moon from the Sun. */
-   d = fmod(1072260.70369 + (1602961601.2090) * t, ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Mean longitude of the ascending node of the Moon. */
-   om = fmod(450160.398036 + (-6962890.5431) * t, ERFA_TURNAS) * ERFA_DAS2R;
-
-/* Initialize the nutation values. */
-   dp = 0.0;
-   de = 0.0;
-
-/* Summation of luni-solar nutation series (smallest terms first). */
-   for (i = NLS-1; i >= 0; i--) {
-
-   /* Argument and functions. */
-      arg = fmod( (double)x[i].nl  * el  +
-                  (double)x[i].nlp * elp +
-                  (double)x[i].nf  * f   +
-                  (double)x[i].nd  * d   +
-                  (double)x[i].nom * om, ERFA_D2PI  );
-      sarg = sin(arg);
-      carg = cos(arg);
-
-   /* Term. */
-      dp += (x[i].ps + x[i].pst * t) * sarg + x[i].pc * carg;
-      de += (x[i].ec + x[i].ect * t) * carg + x[i].es * sarg;
-   }
-
-/* Convert from 0.1 microarcsec units to radians. */
-   dpsils = dp * U2R;
-   depsls = de * U2R;
-
-/* ------------------------------*/
-/* IN LIEU OF PLANETARY NUTATION */
-/* ------------------------------*/
-
-/* Fixed offset to correct for missing terms in truncated series. */
-   dpsipl = DPPLAN;
-   depspl = DEPLAN;
-
-/* --------*/
-/* RESULTS */
-/* --------*/
-
-/* Add luni-solar and planetary components. */
-   *dpsi = dpsils + dpsipl;
-   *deps = depsls + depspl;
-
-   return;
-
-}
-
-void eraNut06a(double date1, double date2, double *dpsi, double *deps)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, fj2, dp, de;
-
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Factor correcting for secular variation of J2. */
-   fj2 = -2.7774e-6 * t;
-
-/* Obtain IAU 2000A nutation. */
-   eraNut00a(date1, date2, &dp, &de);
-
-/* Apply P03 adjustments (Wallace & Capitaine, 2006, Eqs.5). */
-   *dpsi = dp + dp * (0.4697e-6 + fj2);
-   *deps = de + de * fj2;
-
-   return;
-
-}
-
-void eraNut80(double date1, double date2, double *dpsi, double *deps)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, el, elp, f, d, om, dp, de, arg, s, c;
-   int j;
-
-/* Units of 0.1 milliarcsecond to radians */
-   const double U2R = ERFA_DAS2R / 1e4;
-
-/* ------------------------------------------------ */
-/* Table of multiples of arguments and coefficients */
-/* ------------------------------------------------ */
-
-/* The units for the sine and cosine coefficients are 0.1 mas and */
-/* the same per Julian century */
-
-   static const struct {
-      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
-      double sp,spt;        /* longitude sine, 1 and t coefficients */
-      double ce,cet;        /* obliquity cosine, 1 and t coefficients */
-   } x[] = {
-
-   /* 1-10 */
-      {  0,  0,  0,  0,  1, -171996.0, -174.2,  92025.0,    8.9 },
-      {  0,  0,  0,  0,  2,    2062.0,    0.2,   -895.0,    0.5 },
-      { -2,  0,  2,  0,  1,      46.0,    0.0,    -24.0,    0.0 },
-      {  2,  0, -2,  0,  0,      11.0,    0.0,      0.0,    0.0 },
-      { -2,  0,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
-      {  1, -1,  0, -1,  0,      -3.0,    0.0,      0.0,    0.0 },
-      {  0, -2,  2, -2,  1,      -2.0,    0.0,      1.0,    0.0 },
-      {  2,  0, -2,  0,  1,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  2, -2,  2,  -13187.0,   -1.6,   5736.0,   -3.1 },
-      {  0,  1,  0,  0,  0,    1426.0,   -3.4,     54.0,   -0.1 },
-
-   /* 11-20 */
-      {  0,  1,  2, -2,  2,    -517.0,    1.2,    224.0,   -0.6 },
-      {  0, -1,  2, -2,  2,     217.0,   -0.5,    -95.0,    0.3 },
-      {  0,  0,  2, -2,  1,     129.0,    0.1,    -70.0,    0.0 },
-      {  2,  0,  0, -2,  0,      48.0,    0.0,      1.0,    0.0 },
-      {  0,  0,  2, -2,  0,     -22.0,    0.0,      0.0,    0.0 },
-      {  0,  2,  0,  0,  0,      17.0,   -0.1,      0.0,    0.0 },
-      {  0,  1,  0,  0,  1,     -15.0,    0.0,      9.0,    0.0 },
-      {  0,  2,  2, -2,  2,     -16.0,    0.1,      7.0,    0.0 },
-      {  0, -1,  0,  0,  1,     -12.0,    0.0,      6.0,    0.0 },
-      { -2,  0,  0,  2,  1,      -6.0,    0.0,      3.0,    0.0 },
-
-   /* 21-30 */
-      {  0, -1,  2, -2,  1,      -5.0,    0.0,      3.0,    0.0 },
-      {  2,  0,  0, -2,  1,       4.0,    0.0,     -2.0,    0.0 },
-      {  0,  1,  2, -2,  1,       4.0,    0.0,     -2.0,    0.0 },
-      {  1,  0,  0, -1,  0,      -4.0,    0.0,      0.0,    0.0 },
-      {  2,  1,  0, -2,  0,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  0, -2,  2,  1,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  1, -2,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  0,  0,  2,       1.0,    0.0,      0.0,    0.0 },
-      { -1,  0,  0,  1,  1,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
-
-   /* 31-40 */
-      {  0,  0,  2,  0,  2,   -2274.0,   -0.2,    977.0,   -0.5 },
-      {  1,  0,  0,  0,  0,     712.0,    0.1,     -7.0,    0.0 },
-      {  0,  0,  2,  0,  1,    -386.0,   -0.4,    200.0,    0.0 },
-      {  1,  0,  2,  0,  2,    -301.0,    0.0,    129.0,   -0.1 },
-      {  1,  0,  0, -2,  0,    -158.0,    0.0,     -1.0,    0.0 },
-      { -1,  0,  2,  0,  2,     123.0,    0.0,    -53.0,    0.0 },
-      {  0,  0,  0,  2,  0,      63.0,    0.0,     -2.0,    0.0 },
-      {  1,  0,  0,  0,  1,      63.0,    0.1,    -33.0,    0.0 },
-      { -1,  0,  0,  0,  1,     -58.0,   -0.1,     32.0,    0.0 },
-      { -1,  0,  2,  2,  2,     -59.0,    0.0,     26.0,    0.0 },
-
-   /* 41-50 */
-      {  1,  0,  2,  0,  1,     -51.0,    0.0,     27.0,    0.0 },
-      {  0,  0,  2,  2,  2,     -38.0,    0.0,     16.0,    0.0 },
-      {  2,  0,  0,  0,  0,      29.0,    0.0,     -1.0,    0.0 },
-      {  1,  0,  2, -2,  2,      29.0,    0.0,    -12.0,    0.0 },
-      {  2,  0,  2,  0,  2,     -31.0,    0.0,     13.0,    0.0 },
-      {  0,  0,  2,  0,  0,      26.0,    0.0,     -1.0,    0.0 },
-      { -1,  0,  2,  0,  1,      21.0,    0.0,    -10.0,    0.0 },
-      { -1,  0,  0,  2,  1,      16.0,    0.0,     -8.0,    0.0 },
-      {  1,  0,  0, -2,  1,     -13.0,    0.0,      7.0,    0.0 },
-      { -1,  0,  2,  2,  1,     -10.0,    0.0,      5.0,    0.0 },
-
-   /* 51-60 */
-      {  1,  1,  0, -2,  0,      -7.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  2,  0,  2,       7.0,    0.0,     -3.0,    0.0 },
-      {  0, -1,  2,  0,  2,      -7.0,    0.0,      3.0,    0.0 },
-      {  1,  0,  2,  2,  2,      -8.0,    0.0,      3.0,    0.0 },
-      {  1,  0,  0,  2,  0,       6.0,    0.0,      0.0,    0.0 },
-      {  2,  0,  2, -2,  2,       6.0,    0.0,     -3.0,    0.0 },
-      {  0,  0,  0,  2,  1,      -6.0,    0.0,      3.0,    0.0 },
-      {  0,  0,  2,  2,  1,      -7.0,    0.0,      3.0,    0.0 },
-      {  1,  0,  2, -2,  1,       6.0,    0.0,     -3.0,    0.0 },
-      {  0,  0,  0, -2,  1,      -5.0,    0.0,      3.0,    0.0 },
-
-   /* 61-70 */
-      {  1, -1,  0,  0,  0,       5.0,    0.0,      0.0,    0.0 },
-      {  2,  0,  2,  0,  1,      -5.0,    0.0,      3.0,    0.0 },
-      {  0,  1,  0, -2,  0,      -4.0,    0.0,      0.0,    0.0 },
-      {  1,  0, -2,  0,  0,       4.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  0,  1,  0,      -4.0,    0.0,      0.0,    0.0 },
-      {  1,  1,  0,  0,  0,      -3.0,    0.0,      0.0,    0.0 },
-      {  1,  0,  2,  0,  0,       3.0,    0.0,      0.0,    0.0 },
-      {  1, -1,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
-      { -1, -1,  2,  2,  2,      -3.0,    0.0,      1.0,    0.0 },
-      { -2,  0,  0,  0,  1,      -2.0,    0.0,      1.0,    0.0 },
-
-   /* 71-80 */
-      {  3,  0,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
-      {  0, -1,  2,  2,  2,      -3.0,    0.0,      1.0,    0.0 },
-      {  1,  1,  2,  0,  2,       2.0,    0.0,     -1.0,    0.0 },
-      { -1,  0,  2, -2,  1,      -2.0,    0.0,      1.0,    0.0 },
-      {  2,  0,  0,  0,  1,       2.0,    0.0,     -1.0,    0.0 },
-      {  1,  0,  0,  0,  2,      -2.0,    0.0,      1.0,    0.0 },
-      {  3,  0,  0,  0,  0,       2.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  2,  1,  2,       2.0,    0.0,     -1.0,    0.0 },
-      { -1,  0,  0,  0,  2,       1.0,    0.0,     -1.0,    0.0 },
-      {  1,  0,  0, -4,  0,      -1.0,    0.0,      0.0,    0.0 },
-
-   /* 81-90 */
-      { -2,  0,  2,  2,  2,       1.0,    0.0,     -1.0,    0.0 },
-      { -1,  0,  2,  4,  2,      -2.0,    0.0,      1.0,    0.0 },
-      {  2,  0,  0, -4,  0,      -1.0,    0.0,      0.0,    0.0 },
-      {  1,  1,  2, -2,  2,       1.0,    0.0,     -1.0,    0.0 },
-      {  1,  0,  2,  2,  1,      -1.0,    0.0,      1.0,    0.0 },
-      { -2,  0,  2,  4,  2,      -1.0,    0.0,      1.0,    0.0 },
-      { -1,  0,  4,  0,  2,       1.0,    0.0,      0.0,    0.0 },
-      {  1, -1,  0, -2,  0,       1.0,    0.0,      0.0,    0.0 },
-      {  2,  0,  2, -2,  1,       1.0,    0.0,     -1.0,    0.0 },
-      {  2,  0,  2,  2,  2,      -1.0,    0.0,      0.0,    0.0 },
-
-   /* 91-100 */
-      {  1,  0,  0,  2,  1,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  4, -2,  2,       1.0,    0.0,      0.0,    0.0 },
-      {  3,  0,  2, -2,  2,       1.0,    0.0,      0.0,    0.0 },
-      {  1,  0,  2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  2,  0,  1,       1.0,    0.0,      0.0,    0.0 },
-      { -1, -1,  0,  2,  1,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  0, -2,  0,  1,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  2, -1,  2,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  0,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
-      {  1,  0, -2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
-
-   /* 101-106 */
-      {  0, -1,  2,  0,  1,      -1.0,    0.0,      0.0,    0.0 },
-      {  1,  1,  0, -2,  1,      -1.0,    0.0,      0.0,    0.0 },
-      {  1,  0, -2,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
-      {  2,  0,  0,  2,  0,       1.0,    0.0,      0.0,    0.0 },
-      {  0,  0,  2,  4,  2,      -1.0,    0.0,      0.0,    0.0 },
-      {  0,  1,  0,  1,  0,       1.0,    0.0,      0.0,    0.0 }
-   };
-
-/* Number of terms in the series */
-   const int NT = (int) (sizeof x / sizeof x[0]);
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental epoch J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* --------------------- */
-/* Fundamental arguments */
-/* --------------------- */
-
-/* Mean longitude of Moon minus mean longitude of Moon's perigee. */
-   el = eraAnpm(
-        (485866.733 + (715922.633 + (31.310 + 0.064 * t) * t) * t)
-        * ERFA_DAS2R + fmod(1325.0 * t, 1.0) * ERFA_D2PI);
-
-/* Mean longitude of Sun minus mean longitude of Sun's perigee. */
-   elp = eraAnpm(
-         (1287099.804 + (1292581.224 + (-0.577 - 0.012 * t) * t) * t)
-         * ERFA_DAS2R + fmod(99.0 * t, 1.0) * ERFA_D2PI);
-
-/* Mean longitude of Moon minus mean longitude of Moon's node. */
-   f = eraAnpm(
-       (335778.877 + (295263.137 + (-13.257 + 0.011 * t) * t) * t)
-       * ERFA_DAS2R + fmod(1342.0 * t, 1.0) * ERFA_D2PI);
-
-/* Mean elongation of Moon from Sun. */
-   d = eraAnpm(
-       (1072261.307 + (1105601.328 + (-6.891 + 0.019 * t) * t) * t)
-       * ERFA_DAS2R + fmod(1236.0 * t, 1.0) * ERFA_D2PI);
-
-/* Longitude of the mean ascending node of the lunar orbit on the */
-/* ecliptic, measured from the mean equinox of date. */
-   om = eraAnpm(
-        (450160.280 + (-482890.539 + (7.455 + 0.008 * t) * t) * t)
-        * ERFA_DAS2R + fmod(-5.0 * t, 1.0) * ERFA_D2PI);
-
-/* --------------- */
-/* Nutation series */
-/* --------------- */
-
-/* Initialize nutation components. */
-   dp = 0.0;
-   de = 0.0;
-
-/* Sum the nutation terms, ending with the biggest. */
-   for (j = NT-1; j >= 0; j--) {
-
-   /* Form argument for current term. */
-      arg = (double)x[j].nl  * el
-          + (double)x[j].nlp * elp
-          + (double)x[j].nf  * f
-          + (double)x[j].nd  * d
-          + (double)x[j].nom * om;
-
-   /* Accumulate current nutation term. */
-      s = x[j].sp + x[j].spt * t;
-      c = x[j].ce + x[j].cet * t;
-      if (s != 0.0) dp += s * sin(arg);
-      if (c != 0.0) de += c * cos(arg);
-   }
-
-/* Convert results from 0.1 mas units to radians. */
-   *dpsi = dp * U2R;
-   *deps = de * U2R;
-
-   return;
-
-}
-
-void eraNutm80(double date1, double date2, double rmatn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsi, deps, epsa;
-
-
-/* Nutation components and mean obliquity. */
-   eraNut80(date1, date2, &dpsi, &deps);
-   epsa = eraObl80(date1, date2);
-
-/* Build the rotation matrix. */
-   eraNumat(epsa, dpsi, deps, rmatn);
-
-   return;
-
-}
-
-double eraObl06(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, eps0;
-
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Mean obliquity. */
-   eps0 = (84381.406     +
-          (-46.836769    +
-          ( -0.0001831   +
-          (  0.00200340  +
-          ( -0.000000576 +
-          ( -0.0000000434) * t) * t) * t) * t) * t) * ERFA_DAS2R;
-
-   return eps0;
-
-}
-
-double eraObl80(double date1, double date2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, eps0;
-
-
-/* Interval between fundamental epoch J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Mean obliquity of date. */
-   eps0 = ERFA_DAS2R * (84381.448  +
-                  (-46.8150   +
-                  (-0.00059   +
-                  ( 0.001813) * t) * t) * t);
-
-   return eps0;
-
-}
-
-void eraP06e(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)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t;
-
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Obliquity at J2000.0. */
-
-   *eps0 = 84381.406 * ERFA_DAS2R;
-
-/* Luni-solar precession. */
-
-   *psia = ( 5038.481507     +
-           (   -1.0790069    +
-           (   -0.00114045   +
-           (    0.000132851  +
-           (   -0.0000000951 )
-           * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Inclination of mean equator with respect to the J2000.0 ecliptic. */
-
-   *oma = *eps0 + ( -0.025754     +
-                  (  0.0512623    +
-                  ( -0.00772503   +
-                  ( -0.000000467  +
-                  (  0.0000003337 )
-                  * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Ecliptic pole x, J2000.0 ecliptic triad. */
-
-   *bpa = (  4.199094     +
-          (  0.1939873    +
-          ( -0.00022466   +
-          ( -0.000000912  +
-          (  0.0000000120 )
-          * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Ecliptic pole -y, J2000.0 ecliptic triad. */
-
-   *bqa = ( -46.811015     +
-          (   0.0510283    +
-          (   0.00052413   +
-          (  -0.000000646  +
-          (  -0.0000000172 )
-          * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Angle between moving and J2000.0 ecliptics. */
-
-   *pia = ( 46.998973     +
-          ( -0.0334926    +
-          ( -0.00012559   +
-          (  0.000000113  +
-          ( -0.0000000022 )
-          * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Longitude of ascending node of the moving ecliptic. */
-
-   *bpia = ( 629546.7936      +
-           (   -867.95758     +
-           (      0.157992    +
-           (     -0.0005371   +
-           (     -0.00004797  +
-           (      0.000000072 )
-           * t) * t) * t) * t) * t) * ERFA_DAS2R;
-
-/* Mean obliquity of the ecliptic. */
-
-   *epsa = eraObl06(date1, date2);
-
-/* Planetary precession. */
-
-   *chia = ( 10.556403     +
-           ( -2.3814292    +
-           ( -0.00121197   +
-           (  0.000170663  +
-           ( -0.0000000560 )
-           * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Equatorial precession: minus the third of the 323 Euler angles. */
-
-   *za = (   -2.650545     +
-         ( 2306.077181     +
-         (    1.0927348    +
-         (    0.01826837   +
-         (   -0.000028596  +
-         (   -0.0000002904 )
-         * t) * t) * t) * t) * t) * ERFA_DAS2R;
-
-/* Equatorial precession: minus the first of the 323 Euler angles. */
-
-   *zetaa = (    2.650545     +
-            ( 2306.083227     +
-            (    0.2988499    +
-            (    0.01801828   +
-            (   -0.000005971  +
-            (   -0.0000003173 )
-            * t) * t) * t) * t) * t) * ERFA_DAS2R;
-
-/* Equatorial precession: second of the 323 Euler angles. */
-
-   *thetaa = ( 2004.191903     +
-             (   -0.4294934    +
-             (   -0.04182264   +
-             (   -0.000007089  +
-             (   -0.0000001274 )
-             * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* General precession. */
-
-   *pa = ( 5028.796195     +
-         (    1.1054348    +
-         (    0.00007964   +
-         (   -0.000023857  +
-         (    0.0000000383 )
-         * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-/* Fukushima-Williams angles for precession. */
-
-   *gam = ( 10.556403     +
-          (  0.4932044    +
-          ( -0.00031238   +
-          ( -0.000002788  +
-          (  0.0000000260 )
-          * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-   *phi = *eps0 + ( -46.811015     +
-                  (   0.0511269    +
-                  (   0.00053289   +
-                  (  -0.000000440  +
-                  (  -0.0000000176 )
-                  * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-   *psi = ( 5038.481507     +
-          (    1.5584176    +
-          (   -0.00018522   +
-          (   -0.000026452  +
-          (   -0.0000000148 )
-          * t) * t) * t) * t) * t * ERFA_DAS2R;
-
-   return;
-
-}
-
-void eraP2pv(double p[3], double pv[2][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraCp(p, pv[0]);
-   eraZp(pv[1]);
-
-   return;
-
-}
-
-void eraP2s(double p[3], double *theta, double *phi, double *r)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraC2s(p, theta, phi);
-   *r = eraPm(p);
-
-   return;
-
-}
-
-double eraPap(double a[3], double b[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double am, au[3], bm, st, ct, xa, ya, za, eta[3], xi[3], a2b[3], pa;
-
-
-/* Modulus and direction of the a vector. */
-   eraPn(a, &am, au);
-
-/* Modulus of the b vector. */
-   bm = eraPm(b);
-
-/* Deal with the case of a null vector. */
-   if ((am == 0.0) || (bm == 0.0)) {
-      st = 0.0;
-      ct = 1.0;
-   } else {
-
-   /* The "north" axis tangential from a (arbitrary length). */
-      xa = a[0];
-      ya = a[1];
-      za = a[2];
-      eta[0] = -xa * za;
-      eta[1] = -ya * za;
-      eta[2] =  xa*xa + ya*ya;
-
-   /* The "east" axis tangential from a (same length). */
-      eraPxp(eta, au, xi);
-
-   /* The vector from a to b. */
-      eraPmp(b, a, a2b);
-
-   /* Resolve into components along the north and east axes. */
-      st = eraPdp(a2b, xi);
-      ct = eraPdp(a2b, eta);
-
-   /* Deal with degenerate cases. */
-      if ((st == 0.0) && (ct == 0.0)) ct = 1.0;
-   }
-
-/* Position angle. */
-   pa = atan2(st, ct);
-
-   return pa;
-
-}
-
-double eraPas(double al, double ap, double bl, double bp)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dl, x, y, pa;
-
-
-   dl = bl - al;
-   y = sin(dl) * cos(bp);
-   x = sin(bp) * cos(ap) - cos(bp) * sin(ap) * cos(dl);
-   pa = ((x != 0.0) || (y != 0.0)) ? atan2(y, x) : 0.0;
-
-   return pa;
-
-}
-
-void eraPb06(double date1, double date2,
-             double *bzeta, double *bz, double *btheta)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r[3][3], r31, r32;
-
-
-/* Precession matrix via Fukushima-Williams angles. */
-   eraPmat06(date1, date2, r);
-
-/* Solve for z. */
-   *bz = atan2(r[1][2], r[0][2]);
-
-/* Remove it from the matrix. */
-   eraRz(*bz, r);
-
-/* Solve for the remaining two angles. */
-   *bzeta = atan2 (r[1][0], r[1][1]);
-   r31 = r[2][0];
-   r32 = r[2][1];
-   *btheta = atan2(-ERFA_DSIGN(sqrt(r31 * r31 + r32 * r32), r[0][2]),
-                   r[2][2]);
-
-   return;
-
-}
-
-double eraPdp(double a[3], double b[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double w;
-
-
-   w  = a[0] * b[0]
-      + a[1] * b[1]
-      + a[2] * b[2];
-
-   return w;
-
-}
-
-void eraPfw06(double date1, double date2,
-              double *gamb, double *phib, double *psib, double *epsa)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t;
-
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* P03 bias+precession angles. */
-   *gamb = (    -0.052928     +
-           (    10.556378     +
-           (     0.4932044    +
-           (    -0.00031238   +
-           (    -0.000002788  +
-           (     0.0000000260 )
-           * t) * t) * t) * t) * t) * ERFA_DAS2R;
-   *phib = ( 84381.412819     +
-           (   -46.811016     +
-           (     0.0511268    +
-           (     0.00053289   +
-           (    -0.000000440  +
-           (    -0.0000000176 )
-           * t) * t) * t) * t) * t) * ERFA_DAS2R;
-   *psib = (    -0.041775     +
-           (  5038.481484     +
-           (     1.5584175    +
-           (    -0.00018522   +
-           (    -0.000026452  +
-           (    -0.0000000148 )
-           * t) * t) * t) * t) * t) * ERFA_DAS2R;
-   *epsa =  eraObl06(date1, date2);
-
-   return;
-
-}
-
-int eraPlan94(double date1, double date2, int np, double pv[2][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Gaussian constant */
-   static const double GK = 0.017202098950;
-
-/* Sin and cos of J2000.0 mean obliquity (IAU 1976) */
-   static const double SINEPS = 0.3977771559319137;
-   static const double COSEPS = 0.9174820620691818;
-
-/* Maximum number of iterations allowed to solve Kepler's equation */
-   static const int KMAX = 10;
-
-   int jstat, i, k;
-   double t, da, dl, de, dp, di, dom, dmu, arga, argl, am,
-          ae, dae, ae2, at, r, v, si2, xq, xp, tl, xsw,
-          xcw, xm2, xf, ci2, xms, xmc, xpxq2, x, y, z;
-
-/* Planetary inverse masses */
-   static const double amas[] = { 6023600.0,       /* Mercury */
-                                   408523.5,       /* Venus   */
-                                   328900.5,       /* EMB     */
-                                  3098710.0,       /* Mars    */
-                                     1047.355,     /* Jupiter */
-                                     3498.5,       /* Saturn  */
-                                    22869.0,       /* Uranus  */
-                                    19314.0 };     /* Neptune */
-
-/*
-** Tables giving the mean Keplerian elements, limited to t^2 terms:
-**
-**   a       semi-major axis (AU)
-**   dlm     mean longitude (degree and arcsecond)
-**   e       eccentricity
-**   pi      longitude of the perihelion (degree and arcsecond)
-**   dinc    inclination (degree and arcsecond)
-**   omega   longitude of the ascending node (degree and arcsecond)
-*/
-
-   static const double a[][3] = {
-       {  0.3870983098,           0.0,     0.0 },  /* Mercury */
-       {  0.7233298200,           0.0,     0.0 },  /* Venus   */
-       {  1.0000010178,           0.0,     0.0 },  /* EMB     */
-       {  1.5236793419,         3e-10,     0.0 },  /* Mars    */
-       {  5.2026032092,     19132e-10, -39e-10 },  /* Jupiter */
-       {  9.5549091915, -0.0000213896, 444e-10 },  /* Saturn  */
-       { 19.2184460618,     -3716e-10, 979e-10 },  /* Uranus  */
-       { 30.1103868694,    -16635e-10, 686e-10 }   /* Neptune */
-   };
-
-   static const double dlm[][3] = {
-       { 252.25090552, 5381016286.88982,  -1.92789 },
-       { 181.97980085, 2106641364.33548,   0.59381 },
-       { 100.46645683, 1295977422.83429,  -2.04411 },
-       { 355.43299958,  689050774.93988,   0.94264 },
-       {  34.35151874,  109256603.77991, -30.60378 },
-       {  50.07744430,   43996098.55732,  75.61614 },
-       { 314.05500511,   15424811.93933,  -1.75083 },
-       { 304.34866548,    7865503.20744,   0.21103 }
-   };
-
-   static const double e[][3] = {
-       { 0.2056317526,  0.0002040653,    -28349e-10 },
-       { 0.0067719164, -0.0004776521,     98127e-10 },
-       { 0.0167086342, -0.0004203654, -0.0000126734 },
-       { 0.0934006477,  0.0009048438,    -80641e-10 },
-       { 0.0484979255,  0.0016322542, -0.0000471366 },
-       { 0.0555481426, -0.0034664062, -0.0000643639 },
-       { 0.0463812221, -0.0002729293,  0.0000078913 },
-       { 0.0094557470,  0.0000603263,           0.0 }
-   };
-
-   static const double pi[][3] = {
-       {  77.45611904,  5719.11590,   -4.83016 },
-       { 131.56370300,   175.48640, -498.48184 },
-       { 102.93734808, 11612.35290,   53.27577 },
-       { 336.06023395, 15980.45908,  -62.32800 },
-       {  14.33120687,  7758.75163,  259.95938 },
-       {  93.05723748, 20395.49439,  190.25952 },
-       { 173.00529106,  3215.56238,  -34.09288 },
-       {  48.12027554,  1050.71912,   27.39717 }
-   };
-
-   static const double dinc[][3] = {
-       { 7.00498625, -214.25629,   0.28977 },
-       { 3.39466189,  -30.84437, -11.67836 },
-       {        0.0,  469.97289,  -3.35053 },
-       { 1.84972648, -293.31722,  -8.11830 },
-       { 1.30326698,  -71.55890,  11.95297 },
-       { 2.48887878,   91.85195, -17.66225 },
-       { 0.77319689,  -60.72723,   1.25759 },
-       { 1.76995259,    8.12333,   0.08135 }
-   };
-
-   static const double omega[][3] = {
-       {  48.33089304,  -4515.21727,  -31.79892 },
-       {  76.67992019, -10008.48154,  -51.32614 },
-       { 174.87317577,  -8679.27034,   15.34191 },
-       {  49.55809321, -10620.90088, -230.57416 },
-       { 100.46440702,   6362.03561,  326.52178 },
-       { 113.66550252,  -9240.19942,  -66.23743 },
-       {  74.00595701,   2669.15033,  145.93964 },
-       { 131.78405702,   -221.94322,   -0.78728 }
-   };
-
-/* Tables for trigonometric terms to be added to the mean elements of */
-/* the semi-major axes */
-
-   static const double kp[][9] = {
-    {   69613, 75645, 88306, 59899, 15746, 71087, 142173,  3086,    0 },
-    {   21863, 32794, 26934, 10931, 26250, 43725,  53867, 28939,    0 },
-    {   16002, 21863, 32004, 10931, 14529, 16368,  15318, 32794,    0 },
-    {    6345,  7818, 15636,  7077,  8184, 14163,   1107,  4872,    0 },
-    {    1760,  1454,  1167,   880,   287,  2640,     19,  2047, 1454 },
-    {     574,     0,   880,   287,    19,  1760,   1167,   306,  574 },
-    {     204,     0,   177,  1265,     4,   385,    200,   208,  204 },
-    {       0,   102,   106,     4,    98,  1367,    487,   204,    0 }
-   };
-
-   static const double ca[][9] = {
-    {       4,    -13,    11,   -9,    -9,   -3,     -1,     4,     0 },
-    {    -156,     59,   -42,    6,    19,  -20,    -10,   -12,     0 },
-    {      64,   -152,    62,   -8,    32,  -41,     19,   -11,     0 },
-    {     124,    621,  -145,  208,    54,  -57,     30,    15,     0 },
-    {  -23437,  -2634,  6601, 6259, -1507,-1821,   2620, -2115, -1489 },
-    {   62911,-119919, 79336,17814,-24241,12068,   8306, -4893,  8902 },
-    {  389061,-262125,-44088, 8387,-22976,-2093,   -615, -9720,  6633 },
-    { -412235,-157046,-31430,37817, -9740,  -13,  -7449,  9644,     0 }
-   };
-
-   static const double sa[][9] = {
-    {     -29,    -1,     9,     6,    -6,     5,     4,     0,     0 },
-    {     -48,  -125,   -26,   -37,    18,   -13,   -20,    -2,     0 },
-    {    -150,   -46,    68,    54,    14,    24,   -28,    22,     0 },
-    {    -621,   532,  -694,   -20,   192,   -94,    71,   -73,     0 },
-    {  -14614,-19828, -5869,  1881, -4372, -2255,   782,   930,   913 },
-    {  139737,     0, 24667, 51123, -5102,  7429, -4095, -1976, -9566 },
-    { -138081,     0, 37205,-49039,-41901,-33872,-27037,-12474, 18797 },
-    {       0, 28492,133236, 69654, 52322,-49577,-26430, -3593,     0 }
-   };
-
-/* Tables giving the trigonometric terms to be added to the mean */
-/* elements of the mean longitudes */
-
-   static const double kq[][10] = {
-    {   3086,15746,69613,59899,75645,88306, 12661,  2658,    0,     0 },
-    {  21863,32794,10931,   73, 4387,26934,  1473,  2157,    0,     0 },
-    {     10,16002,21863,10931, 1473,32004,  4387,    73,    0,     0 },
-    {     10, 6345, 7818, 1107,15636, 7077,  8184,   532,   10,     0 },
-    {     19, 1760, 1454,  287, 1167,  880,   574,  2640,   19,  1454 },
-    {     19,  574,  287,  306, 1760,   12,    31,    38,   19,   574 },
-    {      4,  204,  177,    8,   31,  200,  1265,   102,    4,   204 },
-    {      4,  102,  106,    8,   98, 1367,   487,   204,    4,   102 }
-   };
-
-   static const double cl[][10] = {
-    {      21,   -95, -157,   41,   -5,   42,  23,  30,      0,     0 },
-    {    -160,  -313, -235,   60,  -74,  -76, -27,  34,      0,     0 },
-    {    -325,  -322,  -79,  232,  -52,   97,  55, -41,      0,     0 },
-    {    2268,  -979,  802,  602, -668,  -33, 345, 201,    -55,     0 },
-    {    7610, -4997,-7689,-5841,-2617, 1115,-748,-607,   6074,   354 },
-    {  -18549, 30125,20012, -730,  824,   23,1289,-352, -14767, -2062 },
-    { -135245,-14594, 4197,-4030,-5630,-2898,2540,-306,   2939,  1986 },
-    {   89948,  2103, 8963, 2695, 3682, 1648, 866,-154,  -1963,  -283 }
-   };
-
-   static const double sl[][10] = {
-    {   -342,   136,  -23,   62,   66,  -52, -33,    17,     0,     0 },
-    {    524,  -149,  -35,  117,  151,  122, -71,   -62,     0,     0 },
-    {   -105,  -137,  258,   35, -116,  -88,-112,   -80,     0,     0 },
-    {    854,  -205, -936, -240,  140, -341, -97,  -232,   536,     0 },
-    { -56980,  8016, 1012, 1448,-3024,-3710, 318,   503,  3767,   577 },
-    { 138606,-13478,-4964, 1441,-1319,-1482, 427,  1236, -9167, -1918 },
-    {  71234,-41116, 5334,-4935,-1848,   66, 434, -1748,  3780,  -701 },
-    { -47645, 11647, 2166, 3194,  679,    0,-244,  -419, -2531,    48 }
-   };
-
-/*--------------------------------------------------------------------*/
-
-/* Validate the planet number. */
-   if ((np < 1) || (np > 8)) {
-      jstat = -1;
-
-   /* Reset the result in case of failure. */
-      for (k = 0; k < 2; k++) {
-         for (i = 0; i < 3; i++) {
-            pv[k][i] = 0.0;
-         }
-      }
-
-   } else {
-
-   /* Decrement the planet number to start at zero. */
-      np--;
-
-   /* Time: Julian millennia since J2000.0. */
-      t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM;
-
-   /* OK status unless remote date. */
-      jstat = fabs(t) <= 1.0 ? 0 : 1;
-
-   /* Compute the mean elements. */
-      da = a[np][0] +
-          (a[np][1] +
-           a[np][2] * t) * t;
-      dl = (3600.0 * dlm[np][0] +
-                    (dlm[np][1] +
-                     dlm[np][2] * t) * t) * ERFA_DAS2R;
-      de = e[np][0] +
-         ( e[np][1] +
-           e[np][2] * t) * t;
-      dp = eraAnpm((3600.0 * pi[np][0] +
-                            (pi[np][1] +
-                             pi[np][2] * t) * t) * ERFA_DAS2R);
-      di = (3600.0 * dinc[np][0] +
-                    (dinc[np][1] +
-                     dinc[np][2] * t) * t) * ERFA_DAS2R;
-      dom = eraAnpm((3600.0 * omega[np][0] +
-                             (omega[np][1] +
-                              omega[np][2] * t) * t) * ERFA_DAS2R);
-
-   /* Apply the trigonometric terms. */
-      dmu = 0.35953620 * t;
-      for (k = 0; k < 8; k++) {
-         arga = kp[np][k] * dmu;
-         argl = kq[np][k] * dmu;
-         da += (ca[np][k] * cos(arga) +
-                sa[np][k] * sin(arga)) * 1e-7;
-         dl += (cl[np][k] * cos(argl) +
-                sl[np][k] * sin(argl)) * 1e-7;
-      }
-      arga = kp[np][8] * dmu;
-      da += t * (ca[np][8] * cos(arga) +
-                 sa[np][8] * sin(arga)) * 1e-7;
-      for (k = 8; k < 10; k++) {
-         argl = kq[np][k] * dmu;
-         dl += t * (cl[np][k] * cos(argl) +
-                    sl[np][k] * sin(argl)) * 1e-7;
-      }
-      dl = fmod(dl, ERFA_D2PI);
-
-   /* Iterative soln. of Kepler's equation to get eccentric anomaly. */
-      am = dl - dp;
-      ae = am + de * sin(am);
-      k = 0;
-      dae = 1.0;
-      while (k < KMAX && fabs(dae) > 1e-12) {
-         dae = (am - ae + de * sin(ae)) / (1.0 - de * cos(ae));
-         ae += dae;
-         k++;
-         if (k == KMAX-1) jstat = 2;
-      }
-
-   /* True anomaly. */
-      ae2 = ae / 2.0;
-      at = 2.0 * atan2(sqrt((1.0 + de) / (1.0 - de)) * sin(ae2),
-                                                       cos(ae2));
-
-   /* Distance (AU) and speed (radians per day). */
-      r = da * (1.0 - de * cos(ae));
-      v = GK * sqrt((1.0 + 1.0 / amas[np]) / (da * da * da));
-
-      si2 = sin(di / 2.0);
-      xq = si2 * cos(dom);
-      xp = si2 * sin(dom);
-      tl = at + dp;
-      xsw = sin(tl);
-      xcw = cos(tl);
-      xm2 = 2.0 * (xp * xcw - xq * xsw);
-      xf = da / sqrt(1  -  de * de);
-      ci2 = cos(di / 2.0);
-      xms = (de * sin(dp) + xsw) * xf;
-      xmc = (de * cos(dp) + xcw) * xf;
-      xpxq2 = 2 * xp * xq;
-
-   /* Position (J2000.0 ecliptic x,y,z in AU). */
-      x = r * (xcw - xm2 * xp);
-      y = r * (xsw + xm2 * xq);
-      z = r * (-xm2 * ci2);
-
-   /* Rotate to equatorial. */
-      pv[0][0] = x;
-      pv[0][1] = y * COSEPS - z * SINEPS;
-      pv[0][2] = y * SINEPS + z * COSEPS;
-
-   /* Velocity (J2000.0 ecliptic xdot,ydot,zdot in AU/d). */
-      x = v * (( -1.0 + 2.0 * xp * xp) * xms + xpxq2 * xmc);
-      y = v * ((  1.0 - 2.0 * xq * xq) * xmc - xpxq2 * xms);
-      z = v * (2.0 * ci2 * (xp * xms + xq * xmc));
-
-   /* Rotate to equatorial. */
-      pv[1][0] = x;
-      pv[1][1] = y * COSEPS - z * SINEPS;
-      pv[1][2] = y * SINEPS + z * COSEPS;
-
-   }
-
-/* Return the status. */
-   return jstat;
-
-}
-
-double eraPm(double p[3])
-/*
-**  - - - - - -
-**   e r a P m
-**  - - - - - -
-**
-**  Modulus of p-vector.
-**
-**  Given:
-**     p      double[3]     p-vector
-**
-**  Returned (function value):
-**            double        modulus
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   return sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
-
-}
-
-void eraPmat00(double date1, double date2, double rbp[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rb[3][3], rp[3][3];
-
-
-/* Obtain the required matrix (discarding others). */
-   eraBp00(date1, date2, rb, rp, rbp);
-
-   return;
-
-}
-
-void eraPmat06(double date1, double date2, double rbp[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gamb, phib, psib, epsa;
-
-
-/* Bias-precession Fukushima-Williams angles. */
-   eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa);
-
-/* Form the matrix. */
-   eraFw2m(gamb, phib, psib, epsa, rbp);
-
-   return;
-
-}
-
-void eraPmat76(double date1, double date2, double rmatp[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double zeta, z, theta, wmat[3][3];
-
-
-/* Precession Euler angles, J2000.0 to specified date. */
-   eraPrec76(ERFA_DJ00, 0.0, date1, date2, &zeta, &z, &theta);
-
-/* Form the rotation matrix. */
-   eraIr(  wmat);
-   eraRz( -zeta, wmat);
-   eraRy(  theta, wmat);
-   eraRz( -z, wmat);
-   eraCr( wmat, rmatp);
-
-   return;
-
-}
-
-void eraPmp(double a[3], double b[3], double amb[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   amb[0] = a[0] - b[0];
-   amb[1] = a[1] - b[1];
-   amb[2] = a[2] - b[2];
-
-   return;
-
-}
-
-void eraPmpx(double rc, double dc, double pr, double pd,
-             double px, double rv, double pmt, double pob[3],
-             double pco[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Km/s to au/year */
-   const double VF = ERFA_DAYSEC*ERFA_DJM/ERFA_DAU;
-
-/* Light time for 1 au, Julian years */
-   const double AULTY = ERFA_AULT/ERFA_DAYSEC/ERFA_DJY;
-
-   int i;
-   double sr, cr, sd, cd, x, y, z, p[3], dt, pxr, w, pdz, pm[3];
-
-
-/* Spherical coordinates to unit vector (and useful functions). */
-   sr = sin(rc);
-   cr = cos(rc);
-   sd = sin(dc);
-   cd = cos(dc);
-   p[0] = x = cr*cd;
-   p[1] = y = sr*cd;
-   p[2] = z = sd;
-
-/* Proper motion time interval (y) including Roemer effect. */
-   dt = pmt + eraPdp(p,pob)*AULTY;
-
-/* Space motion (radians per year). */
-   pxr = px * ERFA_DAS2R;
-   w = VF * rv * pxr;
-   pdz = pd * z;
-   pm[0] = - pr*y - pdz*cr + w*x;
-   pm[1] =   pr*x - pdz*sr + w*y;
-   pm[2] =   pd*cd + w*z;
-
-/* Coordinate direction of star (unit vector, BCRS). */
-   for (i = 0; i < 3; i++) {
-      p[i] += dt*pm[i] - pxr*pob[i];
-   }
-   eraPn(p, &w, pco);
-
-/* Finished. */
-
-}
-
-int eraPmsafe(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Minimum allowed parallax (arcsec) */
-   const double PXMIN = 5e-7;
-
-/* Factor giving maximum allowed transverse speed of about 1% c */
-   const double F = 326.0;
-
-   int jpx, j;
-   double pm, px1a;
-
-
-/* Proper motion in one year (radians). */
-   pm = eraSeps(ra1, dec1, ra1+pmr1, dec1+pmd1);
-
-/* Override the parallax to reduce the chances of a warning status. */
-   jpx = 0;
-   px1a = px1;
-   pm *= F;
-   if (px1a < pm) {jpx = 1; px1a = pm;}
-   if (px1a < PXMIN) {jpx = 1; px1a = PXMIN;}
-
-/* Carry out the transformation using the modified parallax. */
-   j = eraStarpm(ra1, dec1, pmr1, pmd1, px1a, rv1,
-                 ep1a, ep1b, ep2a, ep2b,
-                 ra2, dec2, pmr2, pmd2, px2, rv2);
-
-/* Revise and return the status. */
-   if (! j%2) j += jpx;
-   return j;
-
-/* Finished. */
-
-}
-
-void eraPn(double p[3], double *r, double u[3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double w;
-
-
-/* Obtain the modulus and test for zero. */
-   w = eraPm(p);
-   if (w == 0.0) {
-
-   /* Null vector. */
-      eraZp(u);
-
-   } else {
-
-   /* Unit vector. */
-      eraSxp(1.0/w, p, u);
-   }
-
-/* Return the modulus. */
-   *r = w;
-
-   return;
-
-}
-
-void eraPn00(double date1, double date2, double dpsi, double deps,
-             double *epsa,
-             double rb[3][3], double rp[3][3], double rbp[3][3],
-             double rn[3][3], double rbpn[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsipr, depspr, rbpw[3][3], rnw[3][3];
-
-
-/* IAU 2000 precession-rate adjustments. */
-   eraPr00(date1, date2, &dpsipr, &depspr);
-
-/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
-   *epsa = eraObl80(date1, date2) + depspr;
-
-/* Frame bias and precession matrices and their product. */
-   eraBp00(date1, date2, rb, rp, rbpw);
-   eraCr(rbpw, rbp);
-
-/* Nutation matrix. */
-   eraNumat(*epsa, dpsi, deps, rnw);
-   eraCr(rnw, rn);
-
-/* Bias-precession-nutation matrix (classical). */
-   eraRxr(rnw, rbpw, rbpn);
-
-   return;
-
-}
-
-void eraPn00a(double date1, double date2,
-              double *dpsi, double *deps, double *epsa,
-              double rb[3][3], double rp[3][3], double rbp[3][3],
-              double rn[3][3], double rbpn[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Nutation. */
-   eraNut00a(date1, date2, dpsi, deps);
-
-/* Remaining results. */
-   eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
-
-   return;
-
-}
-
-void eraPn00b(double date1, double date2,
-              double *dpsi, double *deps, double *epsa,
-              double rb[3][3], double rp[3][3], double rbp[3][3],
-              double rn[3][3], double rbpn[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Nutation. */
-   eraNut00b(date1, date2, dpsi, deps);
-
-/* Remaining results. */
-   eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
-
-   return;
-
-}
-
-void eraPn06(double date1, double date2, double dpsi, double deps,
-             double *epsa,
-             double rb[3][3], double rp[3][3], double rbp[3][3],
-             double rn[3][3], double rbpn[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gamb, phib, psib, eps, r1[3][3], r2[3][3], rt[3][3];
-
-
-/* Bias-precession Fukushima-Williams angles of J2000.0 = frame bias. */
-   eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &eps);
-
-/* B matrix. */
-   eraFw2m(gamb, phib, psib, eps, r1);
-   eraCr(r1, rb);
-
-/* Bias-precession Fukushima-Williams angles of date. */
-   eraPfw06(date1, date2, &gamb, &phib, &psib, &eps);
-
-/* Bias-precession matrix. */
-   eraFw2m(gamb, phib, psib, eps, r2);
-   eraCr(r2, rbp);
-
-/* Solve for precession matrix. */
-   eraTr(r1, rt);
-   eraRxr(r2, rt, rp);
-
-/* Equinox-based bias-precession-nutation matrix. */
-   eraFw2m(gamb, phib, psib + dpsi, eps + deps, r1);
-   eraCr(r1, rbpn);
-
-/* Solve for nutation matrix. */
-   eraTr(r2, rt);
-   eraRxr(r1, rt, rn);
-
-/* Obliquity, mean of date. */
-   *epsa = eps;
-
-   return;
-
-}
-
-void eraPn06a(double date1, double date2,
-              double *dpsi, double *deps, double *epsa,
-              double rb[3][3], double rp[3][3], double rbp[3][3],
-              double rn[3][3], double rbpn[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Nutation. */
-   eraNut06a(date1, date2, dpsi, deps);
-
-/* Remaining results. */
-   eraPn06(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
-
-   return;
-
-}
-
-void eraPnm00a(double date1, double date2, double rbpn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3];
-
-
-/* Obtain the required matrix (discarding other results). */
-   eraPn00a(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn);
-
-   return;
-
-}
-
-void eraPnm00b(double date1, double date2, double rbpn[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3];
-
-
-/* Obtain the required matrix (discarding other results). */
-   eraPn00b(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn);
-
-   return;
-
-}
-
-void eraPnm06a(double date1, double date2, double rnpb[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double gamb, phib, psib, epsa, dp, de;
-
-
-/* Fukushima-Williams angles for frame bias and precession. */
-   eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa);
-
-/* Nutation components. */
-   eraNut06a(date1, date2, &dp, &de);
-
-/* Equinox based nutation x precession x bias matrix. */
-   eraFw2m(gamb, phib, psib + dp, epsa + de, rnpb);
-
-   return;
-
-}
-
-void eraPnm80(double date1, double date2, double rmatpn[3][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rmatp[3][3], rmatn[3][3];
-
-
-/* Precession matrix, J2000.0 to date. */
-   eraPmat76(date1, date2, rmatp);
-
-/* Nutation matrix. */
-   eraNutm80(date1, date2, rmatn);
-
-/* Combine the matrices:  PN = N x P. */
-   eraRxr(rmatn, rmatp, rmatpn);
-
-   return;
-
-}
-
-void eraPom00(double xp, double yp, double sp, double rpom[3][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Construct the matrix. */
-   eraIr(rpom);
-   eraRz(sp, rpom);
-   eraRy(-xp, rpom);
-   eraRx(-yp, rpom);
-
-   return;
-
-}
-
-void eraPpp(double a[3], double b[3], double apb[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   apb[0] = a[0] + b[0];
-   apb[1] = a[1] + b[1];
-   apb[2] = a[2] + b[2];
-
-   return;
-
-}
-
-void eraPpsp(double a[3], double s, double b[3], double apsb[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double sb[3];
-
-
-/* s*b. */
-   eraSxp(s, b, sb);
-
-/* a + s*b. */
-   eraPpp(a, sb, apsb);
-
-   return;
-
-}
-
-void eraPr00(double date1, double date2, double *dpsipr, double *depspr)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t;
-
-/* Precession and obliquity corrections (radians per century) */
-   static const double PRECOR = -0.29965 * ERFA_DAS2R,
-                       OBLCOR = -0.02524 * ERFA_DAS2R;
-
-
-/* Interval between fundamental epoch J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Precession rate contributions with respect to IAU 1976/80. */
-   *dpsipr = PRECOR * t;
-   *depspr = OBLCOR * t;
-
-   return;
-
-}
-
-void eraPrec76(double date01, double date02, double date11, double date12,
-               double *zeta, double *z, double *theta)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t0, t, tas2r, w;
-
-
-/* Interval between fundamental epoch J2000.0 and start date (JC). */
-   t0 = ((date01 - ERFA_DJ00) + date02) / ERFA_DJC;
-
-/* Interval over which precession required (JC). */
-   t = ((date11 - date01) + (date12 - date02)) / ERFA_DJC;
-
-/* Euler angles. */
-   tas2r = t * ERFA_DAS2R;
-   w = 2306.2181 + (1.39656 - 0.000139 * t0) * t0;
-
-   *zeta = (w + ((0.30188 - 0.000344 * t0) + 0.017998 * t) * t) * tas2r;
-
-   *z = (w + ((1.09468 + 0.000066 * t0) + 0.018203 * t) * t) * tas2r;
-
-   *theta = ((2004.3109 + (-0.85330 - 0.000217 * t0) * t0)
-          + ((-0.42665 - 0.000217 * t0) - 0.041833 * t) * t) * tas2r;
-
-   return;
-
-}
-
-void eraPv2p(double pv[2][3], double p[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraCp(pv[0], p);
-
-   return;
-
-}
-
-void eraPv2s(double pv[2][3],
-             double *theta, double *phi, double *r,
-             double *td, double *pd, double *rd)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y, z, xd, yd, zd, rxy2, rxy, r2, rtrue, rw, xyp;
-
-
-/* Components of position/velocity vector. */
-   x  = pv[0][0];
-   y  = pv[0][1];
-   z  = pv[0][2];
-   xd = pv[1][0];
-   yd = pv[1][1];
-   zd = pv[1][2];
-
-/* Component of r in XY plane squared. */
-   rxy2 = x*x + y*y;
-
-/* Modulus squared. */
-   r2 = rxy2 + z*z;
-
-/* Modulus. */
-   rtrue = sqrt(r2);
-
-/* If null vector, move the origin along the direction of movement. */
-   rw = rtrue;
-   if (rtrue == 0.0) {
-       x = xd;
-       y = yd;
-       z = zd;
-       rxy2 = x*x + y*y;
-       r2 = rxy2 + z*z;
-       rw = sqrt(r2);
-   }
-
-/* Position and velocity in spherical coordinates. */
-   rxy = sqrt(rxy2);
-   xyp = x*xd + y*yd;
-   if (rxy2 != 0.0) {
-       *theta = atan2(y, x);
-       *phi = atan2(z, rxy);
-       *td = (x*yd - y*xd) / rxy2;
-       *pd = (zd*rxy2 - z*xyp) / (r2*rxy);
-   } else {
-       *theta = 0.0;
-       *phi = (z != 0.0) ? atan2(z, rxy) : 0.0;
-       *td = 0.0;
-       *pd = 0.0;
-   }
-   *r = rtrue;
-   *rd = (rw != 0.0) ? (xyp + z*zd) / rw : 0.0;
-
-   return;
-
-}
-
-void eraPvdpv(double a[2][3], double b[2][3], double adb[2])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double adbd, addb;
-
-
-/* a . b = constant part of result. */
-   adb[0] = eraPdp(a[0], b[0]);
-
-/* a . bdot */
-   adbd = eraPdp(a[0], b[1]);
-
-/* adot . b */
-   addb = eraPdp(a[1], b[0]);
-
-/* Velocity part of result. */
-   adb[1] = adbd + addb;
-
-   return;
-
-}
-
-void eraPvm(double pv[2][3], double *r, double *s)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Distance. */
-   *r = eraPm(pv[0]);
-
-/* Speed. */
-   *s = eraPm(pv[1]);
-
-   return;
-
-}
-
-void eraPvmpv(double a[2][3], double b[2][3], double amb[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraPmp(a[0], b[0], amb[0]);
-   eraPmp(a[1], b[1], amb[1]);
-
-   return;
-
-}
-
-void eraPvppv(double a[2][3], double b[2][3], double apb[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraPpp(a[0], b[0], apb[0]);
-   eraPpp(a[1], b[1], apb[1]);
-
-   return;
-
-}
-
-int eraPvstar(double pv[2][3], double *ra, double *dec,
-              double *pmr, double *pmd, double *px, double *rv)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double r, x[3], vr, ur[3], vt, ut[3], bett, betr, d, w, del,
-          usr[3], ust[3], a, rad, decd, rd;
-
-
-/* Isolate the radial component of the velocity (AU/day, inertial). */
-   eraPn(pv[0], &r, x);
-   vr = eraPdp(x, pv[1]);
-   eraSxp(vr, x, ur);
-
-/* Isolate the transverse component of the velocity (AU/day, inertial). */
-   eraPmp(pv[1], ur, ut);
-   vt = eraPm(ut);
-
-/* Special-relativity dimensionless parameters. */
-   bett = vt / ERFA_DC;
-   betr = vr / ERFA_DC;
-
-/* The inertial-to-observed correction terms. */
-   d = 1.0 + betr;
-   w = 1.0 - betr*betr - bett*bett;
-   if (d == 0.0 || w < 0) return -1;
-   del = sqrt(w) - 1.0;
-
-/* Apply relativistic correction factor to radial velocity component. */
-   w = (betr != 0) ? (betr - del) / (betr * d) : 1.0;
-   eraSxp(w, ur, usr);
-
-/* Apply relativistic correction factor to tangential velocity */
-/* component.                                                  */
-   eraSxp(1.0/d, ut, ust);
-
-/* Combine the two to obtain the observed velocity vector (AU/day). */
-   eraPpp(usr, ust, pv[1]);
-
-/* Cartesian to spherical. */
-   eraPv2s(pv, &a, dec, &r, &rad, &decd, &rd);
-   if (r == 0.0) return -2;
-
-/* Return RA in range 0 to 2pi. */
-   *ra = eraAnp(a);
-
-/* Return proper motions in radians per year. */
-   *pmr = rad * ERFA_DJY;
-   *pmd = decd * ERFA_DJY;
-
-/* Return parallax in arcsec. */
-   *px = ERFA_DR2AS / r;
-
-/* Return radial velocity in km/s. */
-   *rv = 1e-3 * rd * ERFA_DAU / ERFA_DAYSEC;
-
-/* OK status. */
-   return 0;
-
-}
-
-void eraPvtob(double elong, double phi, double hm,
-              double xp, double yp, double sp, double theta,
-              double pv[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Earth rotation rate in radians per UT1 second */
-   const double OM = 1.00273781191135448 * ERFA_D2PI / ERFA_DAYSEC;
-
-   double xyzm[3], rpm[3][3], xyz[3], x, y, z, s, c;
-
-
-/* Geodetic to geocentric transformation (ERFA_WGS84). */
-   (void) eraGd2gc(1, elong, phi, hm, xyzm);
-
-/* Polar motion and TIO position. */
-   eraPom00(xp, yp, sp, rpm);
-   eraTrxp(rpm, xyzm, xyz);
-   x = xyz[0];
-   y = xyz[1];
-   z = xyz[2];
-
-/* Functions of ERA. */
-   s = sin(theta);
-   c = cos(theta);
-
-/* Position. */
-   pv[0][0] = c*x - s*y;
-   pv[0][1] = s*x + c*y;
-   pv[0][2] = z;
-
-/* Velocity. */
-   pv[1][0] = OM * ( -s*x - c*y );
-   pv[1][1] = OM * (  c*x - s*y );
-   pv[1][2] = 0.0;
-
-/* Finished. */
-
-}
-
-void eraPvu(double dt, double pv[2][3], double upv[2][3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraPpsp(pv[0], dt, pv[1], upv[0]);
-   eraCp(pv[1], upv[1]);
-
-   return;
-
-}
-
-void eraPvup(double dt, double pv[2][3], double p[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   p[0] = pv[0][0] + dt * pv[1][0];
-   p[1] = pv[0][1] + dt * pv[1][1];
-   p[2] = pv[0][2] + dt * pv[1][2];
-
-   return;
-
-}
-
-void eraPvxpv(double a[2][3], double b[2][3], double axb[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double wa[2][3], wb[2][3], axbd[3], adxb[3];
-
-
-/* Make copies of the inputs. */
-   eraCpv(a, wa);
-   eraCpv(b, wb);
-
-/* a x b = position part of result. */
-   eraPxp(wa[0], wb[0], axb[0]);
-
-/* a x bdot + adot x b = velocity part of result. */
-   eraPxp(wa[0], wb[1], axbd);
-   eraPxp(wa[1], wb[0], adxb);
-   eraPpp(axbd, adxb, axb[1]);
-
-   return;
-
-}
-
-void eraPxp(double a[3], double b[3], double axb[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double xa, ya, za, xb, yb, zb;
-
-
-   xa = a[0];
-   ya = a[1];
-   za = a[2];
-   xb = b[0];
-   yb = b[1];
-   zb = b[2];
-   axb[0] = ya*zb - za*yb;
-   axb[1] = za*xb - xa*zb;
-   axb[2] = xa*yb - ya*xb;
-
-   return;
-
-}
-
-void eraRefco(double phpa, double tc, double rh, double wl,
-              double *refa, double *refb)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int optic;
-   double p, t, r, w, ps, pw, tk, wlsq, gamma, beta;
-
-
-/* Decide whether optical/IR or radio case:  switch at 100 microns. */
-   optic = ( wl <= 100.0 );
-
-/* Restrict parameters to safe values. */
-   t = ERFA_GMAX ( tc, -150.0 );
-   t = ERFA_GMIN ( t, 200.0 );
-   p = ERFA_GMAX ( phpa, 0.0 );
-   p = ERFA_GMIN ( p, 10000.0 );
-   r = ERFA_GMAX ( rh, 0.0 );
-   r = ERFA_GMIN ( r, 1.0 );
-   w = ERFA_GMAX ( wl, 0.1 );
-   w = ERFA_GMIN ( w, 1e6 );
-
-/* Water vapour pressure at the observer. */
-   if ( p > 0.0 ) {
-      ps = pow ( 10.0, ( 0.7859 + 0.03477*t ) /
-                          ( 1.0 + 0.00412*t ) ) *
-                 ( 1.0 + p * ( 4.5e-6 + 6e-10*t*t )  );
-      pw = r * ps / ( 1.0 - (1.0-r)*ps/p );
-   } else {
-      pw = 0.0;
-   }
-
-/* Refractive index minus 1 at the observer. */
-   tk = t + 273.15;
-   if ( optic ) {
-      wlsq = w * w;
-      gamma = ( ( 77.53484e-6 +
-                 ( 4.39108e-7 + 3.666e-9/wlsq ) / wlsq ) * p
-                    - 11.2684e-6*pw ) / tk;
-   } else {
-      gamma = ( 77.6890e-6*p - ( 6.3938e-6 - 0.375463/tk ) * pw ) / tk;
-   }
-
-/* Formula for beta from Stone, with empirical adjustments. */
-   beta = 4.4474e-6 * tk;
-   if ( ! optic ) beta -= 0.0074 * pw * beta;
-
-/* Refraction constants from Green. */
-   *refa = gamma * ( 1.0 - beta );
-   *refb = - gamma * ( beta - gamma / 2.0 );
-
-/* Finished. */
-
-}
-
-void eraRm2v(double r[3][3], double w[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y, z, s2, c2, phi, f;
-
-
-   x = r[1][2] - r[2][1];
-   y = r[2][0] - r[0][2];
-   z = r[0][1] - r[1][0];
-   s2 = sqrt(x*x + y*y + z*z);
-   if (s2 != 0) {
-      c2 = r[0][0] + r[1][1] + r[2][2] - 1.0;
-      phi = atan2(s2, c2);
-      f =  phi / s2;
-      w[0] = x * f;
-      w[1] = y * f;
-      w[2] = z * f;
-   } else {
-      w[0] = 0.0;
-      w[1] = 0.0;
-      w[2] = 0.0;
-   }
-
-   return;
-
-}
-
-void eraRv2m(double w[3], double r[3][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double x, y, z, phi, s, c, f;
-
-
-/* Euler angle (magnitude of rotation vector) and functions. */
-   x = w[0];
-   y = w[1];
-   z = w[2];
-   phi = sqrt(x*x + y*y + z*z);
-   s = sin(phi);
-   c = cos(phi);
-   f = 1.0 - c;
-
-/* Euler axis (direction of rotation vector), perhaps null. */
-   if (phi != 0.0) {
-       x /= phi;
-       y /= phi;
-       z /= phi;
-   }
-
-/* Form the rotation matrix. */
-   r[0][0] = x*x*f + c;
-   r[0][1] = x*y*f + z*s;
-   r[0][2] = x*z*f - y*s;
-   r[1][0] = y*x*f - z*s;
-   r[1][1] = y*y*f + c;
-   r[1][2] = y*z*f + x*s;
-   r[2][0] = z*x*f + y*s;
-   r[2][1] = z*y*f - x*s;
-   r[2][2] = z*z*f + c;
-
-   return;
-
-}
-
-void eraRx(double phi, double r[3][3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double s, c, a10, a11, a12, a20, a21, a22;
-
-
-   s = sin(phi);
-   c = cos(phi);
-
-   a10 =   c*r[1][0] + s*r[2][0];
-   a11 =   c*r[1][1] + s*r[2][1];
-   a12 =   c*r[1][2] + s*r[2][2];
-   a20 = - s*r[1][0] + c*r[2][0];
-   a21 = - s*r[1][1] + c*r[2][1];
-   a22 = - s*r[1][2] + c*r[2][2];
-
-   r[1][0] = a10;
-   r[1][1] = a11;
-   r[1][2] = a12;
-   r[2][0] = a20;
-   r[2][1] = a21;
-   r[2][2] = a22;
-
-   return;
-
-}
-
-void eraRxp(double r[3][3], double p[3], double rp[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double w, wrp[3];
-   int i, j;
-
-
-/* Matrix r * vector p. */
-   for (j = 0; j < 3; j++) {
-       w = 0.0;
-       for (i = 0; i < 3; i++) {
-           w += r[j][i] * p[i];
-       }
-       wrp[j] = w;
-   }
-
-/* Return the result. */
-   eraCp(wrp, rp);
-
-   return;
-
-}
-
-void eraRxpv(double r[3][3], double pv[2][3], double rpv[2][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraRxp(r, pv[0], rpv[0]);
-   eraRxp(r, pv[1], rpv[1]);
-
-   return;
-
-}
-
-void eraRxr(double a[3][3], double b[3][3], double atb[3][3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int i, j, k;
-   double w, wm[3][3];
-
-
-   for (i = 0; i < 3; i++) {
-      for (j = 0; j < 3; j++) {
-         w = 0.0;
-         for (k = 0; k < 3; k++) {
-            w +=  a[i][k] * b[k][j];
-         }
-         wm[i][j] = w;
-      }
-   }
-   eraCr(wm, atb);
-
-   return;
-
-}
-
-void eraRy(double theta, double r[3][3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double s, c, a00, a01, a02, a20, a21, a22;
-
-
-   s = sin(theta);
-   c = cos(theta);
-
-   a00 = c*r[0][0] - s*r[2][0];
-   a01 = c*r[0][1] - s*r[2][1];
-   a02 = c*r[0][2] - s*r[2][2];
-   a20 = s*r[0][0] + c*r[2][0];
-   a21 = s*r[0][1] + c*r[2][1];
-   a22 = s*r[0][2] + c*r[2][2];
-
-   r[0][0] = a00;
-   r[0][1] = a01;
-   r[0][2] = a02;
-   r[2][0] = a20;
-   r[2][1] = a21;
-   r[2][2] = a22;
-
-   return;
-
-}
-
-void eraRz(double psi, double r[3][3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double s, c, a00, a01, a02, a10, a11, a12;
-
-
-   s = sin(psi);
-   c = cos(psi);
-
-   a00 =   c*r[0][0] + s*r[1][0];
-   a01 =   c*r[0][1] + s*r[1][1];
-   a02 =   c*r[0][2] + s*r[1][2];
-   a10 = - s*r[0][0] + c*r[1][0];
-   a11 = - s*r[0][1] + c*r[1][1];
-   a12 = - s*r[0][2] + c*r[1][2];
-
-   r[0][0] = a00;
-   r[0][1] = a01;
-   r[0][2] = a02;
-   r[1][0] = a10;
-   r[1][1] = a11;
-   r[1][2] = a12;
-
-   return;
-
-}
-
-double eraS00(double date1, double date2, double x, double y)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Time since J2000.0, in Julian centuries */
-   double t;
-
-/* Miscellaneous */
-   int i, j;
-   double a, w0, w1, w2, w3, w4, w5;
-
-/* Fundamental arguments */
-   double fa[8];
-
-/* Returned value */
-   double s;
-
-/* --------------------- */
-/* The series for s+XY/2 */
-/* --------------------- */
-
-   typedef struct {
-      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
-      double s, c;     /* sine and cosine coefficients */
-   } TERM;
-
-/* Polynomial coefficients */
-   static const double sp[] = {
-
-   /* 1-6 */
-          94.00e-6,
-        3808.35e-6,
-        -119.94e-6,
-      -72574.09e-6,
-          27.70e-6,
-          15.61e-6
-   };
-
-/* Terms of order t^0 */
-   static const TERM s0[] = {
-
-   /* 1-10 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0}, -2640.73e-6,   0.39e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},   -63.53e-6,   0.02e-6 },
-      {{ 0,  0,  2, -2,  3,  0,  0,  0},   -11.75e-6,  -0.01e-6 },
-      {{ 0,  0,  2, -2,  1,  0,  0,  0},   -11.21e-6,  -0.01e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},     4.57e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  3,  0,  0,  0},    -2.02e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  1,  0,  0,  0},    -1.98e-6,   0.00e-6 },
-      {{ 0,  0,  0,  0,  3,  0,  0,  0},     1.72e-6,   0.00e-6 },
-      {{ 0,  1,  0,  0,  1,  0,  0,  0},     1.41e-6,   0.01e-6 },
-      {{ 0,  1,  0,  0, -1,  0,  0,  0},     1.26e-6,   0.01e-6 },
-
-   /* 11-20 */
-      {{ 1,  0,  0,  0, -1,  0,  0,  0},     0.63e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0,  1,  0,  0,  0},     0.63e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  3,  0,  0,  0},    -0.46e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  1,  0,  0,  0},    -0.45e-6,   0.00e-6 },
-      {{ 0,  0,  4, -4,  4,  0,  0,  0},    -0.36e-6,   0.00e-6 },
-      {{ 0,  0,  1, -1,  1, -8, 12,  0},     0.24e-6,   0.12e-6 },
-      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.32e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.28e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  3,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  1,  0,  0,  0},    -0.26e-6,   0.00e-6 },
-
-   /* 21-30 */
-      {{ 0,  0,  2, -2,  0,  0,  0,  0},     0.21e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -3,  0,  0,  0},    -0.19e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -1,  0,  0,  0},    -0.18e-6,   0.00e-6 },
-      {{ 0,  0,  0,  0,  0,  8,-13, -1},     0.10e-6,  -0.05e-6 },
-      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.15e-6,   0.00e-6 },
-      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.14e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  2,  0,  0,  0},     0.14e-6,   0.00e-6 },
-      {{ 1,  0,  0, -2,  1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
-      {{ 1,  0,  0, -2, -1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
-      {{ 0,  0,  4, -2,  4,  0,  0,  0},    -0.13e-6,   0.00e-6 },
-
-   /* 31-33 */
-      {{ 0,  0,  2, -2,  4,  0,  0,  0},     0.11e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -3,  0,  0,  0},    -0.11e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -1,  0,  0,  0},    -0.11e-6,   0.00e-6 }
-   };
-
-/* Terms of order t^1 */
-   static const TERM s1[] ={
-
-   /* 1-3 */
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -0.07e-6,   3.57e-6 },
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},     1.71e-6,  -0.03e-6 },
-      {{ 0,  0,  2, -2,  3,  0,  0,  0},     0.00e-6,   0.48e-6 }
-   };
-
-/* Terms of order t^2 */
-   static const TERM s2[] ={
-
-   /* 1-10 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},   743.53e-6,  -0.17e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},    56.91e-6,   0.06e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},     9.84e-6,  -0.01e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -8.85e-6,   0.01e-6 },
-      {{ 0,  1,  0,  0,  0,  0,  0,  0},    -6.38e-6,  -0.05e-6 },
-      {{ 1,  0,  0,  0,  0,  0,  0,  0},    -3.07e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  2,  0,  0,  0},     2.23e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  1,  0,  0,  0},     1.67e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  2,  0,  0,  0},     1.30e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -2,  0,  0,  0},     0.93e-6,   0.00e-6 },
-
-   /* 11-20 */
-      {{ 1,  0,  0, -2,  0,  0,  0,  0},     0.68e-6,   0.00e-6 },
-      {{ 0,  0,  2, -2,  1,  0,  0,  0},    -0.55e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -2,  0,  0,  0},     0.53e-6,   0.00e-6 },
-      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0,  1,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0, -2, -2, -2,  0,  0,  0},    -0.26e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0, -1,  0,  0,  0},    -0.25e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  1,  0,  0,  0},     0.22e-6,   0.00e-6 },
-      {{ 2,  0,  0, -2,  0,  0,  0,  0},    -0.21e-6,   0.00e-6 },
-      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.20e-6,   0.00e-6 },
-
-   /* 21-25 */
-      {{ 0,  0,  2,  2,  2,  0,  0,  0},     0.17e-6,   0.00e-6 },
-      {{ 2,  0,  2,  0,  2,  0,  0,  0},     0.13e-6,   0.00e-6 },
-      {{ 2,  0,  0,  0,  0,  0,  0,  0},    -0.13e-6,   0.00e-6 },
-      {{ 1,  0,  2, -2,  2,  0,  0,  0},    -0.12e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.11e-6,   0.00e-6 }
-   };
-
-/* Terms of order t^3 */
-   static const TERM s3[] ={
-
-   /* 1-4 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},     0.30e-6, -23.51e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},    -0.03e-6,  -1.39e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.01e-6,  -0.24e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},     0.00e-6,   0.22e-6 }
-   };
-
-/* Terms of order t^4 */
-   static const TERM s4[] ={
-
-   /* 1-1 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.26e-6,  -0.01e-6 }
-   };
-
-/* Number of terms in the series */
-   const int NS0 = (int) (sizeof s0 / sizeof (TERM));
-   const int NS1 = (int) (sizeof s1 / sizeof (TERM));
-   const int NS2 = (int) (sizeof s2 / sizeof (TERM));
-   const int NS3 = (int) (sizeof s3 / sizeof (TERM));
-   const int NS4 = (int) (sizeof s4 / sizeof (TERM));
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental epoch J2000.0 and current date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Fundamental Arguments (from IERS Conventions 2003) */
-
-/* Mean anomaly of the Moon. */
-   fa[0] = eraFal03(t);
-
-/* Mean anomaly of the Sun. */
-   fa[1] = eraFalp03(t);
-
-/* Mean longitude of the Moon minus that of the ascending node. */
-   fa[2] = eraFaf03(t);
-
-/* Mean elongation of the Moon from the Sun. */
-   fa[3] = eraFad03(t);
-
-/* Mean longitude of the ascending node of the Moon. */
-   fa[4] = eraFaom03(t);
-
-/* Mean longitude of Venus. */
-   fa[5] = eraFave03(t);
-
-/* Mean longitude of Earth. */
-   fa[6] = eraFae03(t);
-
-/* General precession in longitude. */
-   fa[7] = eraFapa03(t);
-
-/* Evaluate s. */
-   w0 = sp[0];
-   w1 = sp[1];
-   w2 = sp[2];
-   w3 = sp[3];
-   w4 = sp[4];
-   w5 = sp[5];
-
-   for (i = NS0-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-       a += (double)s0[i].nfa[j] * fa[j];
-   }
-   w0 += s0[i].s * sin(a) + s0[i].c * cos(a);
-   }
-
-   for (i = NS1-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-       a += (double)s1[i].nfa[j] * fa[j];
-   }
-   w1 += s1[i].s * sin(a) + s1[i].c * cos(a);
-   }
-
-   for (i = NS2-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-       a += (double)s2[i].nfa[j] * fa[j];
-   }
-   w2 += s2[i].s * sin(a) + s2[i].c * cos(a);
-   }
-
-   for (i = NS3-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-       a += (double)s3[i].nfa[j] * fa[j];
-   }
-   w3 += s3[i].s * sin(a) + s3[i].c * cos(a);
-   }
-
-   for (i = NS4-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-       a += (double)s4[i].nfa[j] * fa[j];
-   }
-   w4 += s4[i].s * sin(a) + s4[i].c * cos(a);
-   }
-
-   s = (w0 +
-       (w1 +
-       (w2 +
-       (w3 +
-       (w4 +
-        w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0;
-
-   return s;
-
-}
-
-double eraS00a(double date1, double date2)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3], x, y, s;
-
-
-/* Bias-precession-nutation-matrix, IAU 2000A. */
-   eraPnm00a(date1, date2, rbpn);
-
-/* Extract the CIP coordinates. */
-   eraBpn2xy(rbpn, &x, &y);
-
-/* Compute the CIO locator s, given the CIP coordinates. */
-   s = eraS00(date1, date2, x, y);
-
-   return s;
-
-}
-
-double eraS00b(double date1, double date2)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3], x, y, s;
-
-
-/* Bias-precession-nutation-matrix, IAU 2000B. */
-   eraPnm00b(date1, date2, rbpn);
-
-/* Extract the CIP coordinates. */
-   eraBpn2xy(rbpn, &x, &y);
-
-/* Compute the CIO locator s, given the CIP coordinates. */
-   s = eraS00(date1, date2, x, y);
-
-   return s;
-
-}
-
-double eraS06(double date1, double date2, double x, double y)
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Time since J2000.0, in Julian centuries */
-   double t;
-
-/* Miscellaneous */
-   int i, j;
-   double a, w0, w1, w2, w3, w4, w5;
-
-/* Fundamental arguments */
-   double fa[8];
-
-/* Returned value */
-   double s;
-
-/* --------------------- */
-/* The series for s+XY/2 */
-/* --------------------- */
-
-   typedef struct {
-      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
-      double s, c;     /* sine and cosine coefficients */
-   } TERM;
-
-/* Polynomial coefficients */
-   static const double sp[] = {
-
-   /* 1-6 */
-          94.00e-6,
-        3808.65e-6,
-        -122.68e-6,
-      -72574.11e-6,
-          27.98e-6,
-          15.62e-6
-   };
-
-/* Terms of order t^0 */
-   static const TERM s0[] = {
-
-   /* 1-10 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0}, -2640.73e-6,   0.39e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},   -63.53e-6,   0.02e-6 },
-      {{ 0,  0,  2, -2,  3,  0,  0,  0},   -11.75e-6,  -0.01e-6 },
-      {{ 0,  0,  2, -2,  1,  0,  0,  0},   -11.21e-6,  -0.01e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},     4.57e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  3,  0,  0,  0},    -2.02e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  1,  0,  0,  0},    -1.98e-6,   0.00e-6 },
-      {{ 0,  0,  0,  0,  3,  0,  0,  0},     1.72e-6,   0.00e-6 },
-      {{ 0,  1,  0,  0,  1,  0,  0,  0},     1.41e-6,   0.01e-6 },
-      {{ 0,  1,  0,  0, -1,  0,  0,  0},     1.26e-6,   0.01e-6 },
-
-   /* 11-20 */
-      {{ 1,  0,  0,  0, -1,  0,  0,  0},     0.63e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0,  1,  0,  0,  0},     0.63e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  3,  0,  0,  0},    -0.46e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  1,  0,  0,  0},    -0.45e-6,   0.00e-6 },
-      {{ 0,  0,  4, -4,  4,  0,  0,  0},    -0.36e-6,   0.00e-6 },
-      {{ 0,  0,  1, -1,  1, -8, 12,  0},     0.24e-6,   0.12e-6 },
-      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.32e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.28e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  3,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  1,  0,  0,  0},    -0.26e-6,   0.00e-6 },
-
-   /* 21-30 */
-      {{ 0,  0,  2, -2,  0,  0,  0,  0},     0.21e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -3,  0,  0,  0},    -0.19e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -1,  0,  0,  0},    -0.18e-6,   0.00e-6 },
-      {{ 0,  0,  0,  0,  0,  8,-13, -1},     0.10e-6,  -0.05e-6 },
-      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.15e-6,   0.00e-6 },
-      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.14e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  2,  0,  0,  0},     0.14e-6,   0.00e-6 },
-      {{ 1,  0,  0, -2,  1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
-      {{ 1,  0,  0, -2, -1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
-      {{ 0,  0,  4, -2,  4,  0,  0,  0},    -0.13e-6,   0.00e-6 },
-
-   /* 31-33 */
-      {{ 0,  0,  2, -2,  4,  0,  0,  0},     0.11e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -3,  0,  0,  0},    -0.11e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -1,  0,  0,  0},    -0.11e-6,   0.00e-6 }
-   };
-
-/* Terms of order t^1 */
-   static const TERM s1[] = {
-
-   /* 1 - 3 */
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -0.07e-6,   3.57e-6 },
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},     1.73e-6,  -0.03e-6 },
-      {{ 0,  0,  2, -2,  3,  0,  0,  0},     0.00e-6,   0.48e-6 }
-   };
-
-/* Terms of order t^2 */
-   static const TERM s2[] = {
-
-   /* 1-10 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},   743.52e-6,  -0.17e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},    56.91e-6,   0.06e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},     9.84e-6,  -0.01e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -8.85e-6,   0.01e-6 },
-      {{ 0,  1,  0,  0,  0,  0,  0,  0},    -6.38e-6,  -0.05e-6 },
-      {{ 1,  0,  0,  0,  0,  0,  0,  0},    -3.07e-6,   0.00e-6 },
-      {{ 0,  1,  2, -2,  2,  0,  0,  0},     2.23e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  1,  0,  0,  0},     1.67e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  2,  0,  0,  0},     1.30e-6,   0.00e-6 },
-      {{ 0,  1, -2,  2, -2,  0,  0,  0},     0.93e-6,   0.00e-6 },
-
-   /* 11-20 */
-      {{ 1,  0,  0, -2,  0,  0,  0,  0},     0.68e-6,   0.00e-6 },
-      {{ 0,  0,  2, -2,  1,  0,  0,  0},    -0.55e-6,   0.00e-6 },
-      {{ 1,  0, -2,  0, -2,  0,  0,  0},     0.53e-6,   0.00e-6 },
-      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0,  1,  0,  0,  0},    -0.27e-6,   0.00e-6 },
-      {{ 1,  0, -2, -2, -2,  0,  0,  0},    -0.26e-6,   0.00e-6 },
-      {{ 1,  0,  0,  0, -1,  0,  0,  0},    -0.25e-6,   0.00e-6 },
-      {{ 1,  0,  2,  0,  1,  0,  0,  0},     0.22e-6,   0.00e-6 },
-      {{ 2,  0,  0, -2,  0,  0,  0,  0},    -0.21e-6,   0.00e-6 },
-      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.20e-6,   0.00e-6 },
-
-   /* 21-25 */
-      {{ 0,  0,  2,  2,  2,  0,  0,  0},     0.17e-6,   0.00e-6 },
-      {{ 2,  0,  2,  0,  2,  0,  0,  0},     0.13e-6,   0.00e-6 },
-      {{ 2,  0,  0,  0,  0,  0,  0,  0},    -0.13e-6,   0.00e-6 },
-      {{ 1,  0,  2, -2,  2,  0,  0,  0},    -0.12e-6,   0.00e-6 },
-      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.11e-6,   0.00e-6 }
-   };
-
-/* Terms of order t^3 */
-   static const TERM s3[] = {
-
-   /* 1-4 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},     0.30e-6, -23.42e-6 },
-      {{ 0,  0,  2, -2,  2,  0,  0,  0},    -0.03e-6,  -1.46e-6 },
-      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.01e-6,  -0.25e-6 },
-      {{ 0,  0,  0,  0,  2,  0,  0,  0},     0.00e-6,   0.23e-6 }
-   };
-
-/* Terms of order t^4 */
-   static const TERM s4[] = {
-
-   /* 1-1 */
-      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.26e-6,  -0.01e-6 }
-   };
-
-/* Number of terms in the series */
-   static const int NS0 = (int) (sizeof s0 / sizeof (TERM));
-   static const int NS1 = (int) (sizeof s1 / sizeof (TERM));
-   static const int NS2 = (int) (sizeof s2 / sizeof (TERM));
-   static const int NS3 = (int) (sizeof s3 / sizeof (TERM));
-   static const int NS4 = (int) (sizeof s4 / sizeof (TERM));
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental epoch J2000.0 and current date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Fundamental Arguments (from IERS Conventions 2003) */
-
-/* Mean anomaly of the Moon. */
-   fa[0] = eraFal03(t);
-
-/* Mean anomaly of the Sun. */
-   fa[1] = eraFalp03(t);
-
-/* Mean longitude of the Moon minus that of the ascending node. */
-   fa[2] = eraFaf03(t);
-
-/* Mean elongation of the Moon from the Sun. */
-   fa[3] = eraFad03(t);
-
-/* Mean longitude of the ascending node of the Moon. */
-   fa[4] = eraFaom03(t);
-
-/* Mean longitude of Venus. */
-   fa[5] = eraFave03(t);
-
-/* Mean longitude of Earth. */
-   fa[6] = eraFae03(t);
-
-/* General precession in longitude. */
-   fa[7] = eraFapa03(t);
-
-/* Evaluate s. */
-   w0 = sp[0];
-   w1 = sp[1];
-   w2 = sp[2];
-   w3 = sp[3];
-   w4 = sp[4];
-   w5 = sp[5];
-
-   for (i = NS0-1; i >= 0; i--) {
-   a = 0.0;
-   for (j = 0; j < 8; j++) {
-      a += (double)s0[i].nfa[j] * fa[j];
-   }
-   w0 += s0[i].s * sin(a) + s0[i].c * cos(a);
-   }
-
-   for (i = NS1-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)s1[i].nfa[j] * fa[j];
-      }
-      w1 += s1[i].s * sin(a) + s1[i].c * cos(a);
-   }
-
-   for (i = NS2-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)s2[i].nfa[j] * fa[j];
-      }
-      w2 += s2[i].s * sin(a) + s2[i].c * cos(a);
-   }
-
-   for (i = NS3-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)s3[i].nfa[j] * fa[j];
-      }
-      w3 += s3[i].s * sin(a) + s3[i].c * cos(a);
-   }
-
-   for (i = NS4-1; i >= 0; i--) {
-      a = 0.0;
-      for (j = 0; j < 8; j++) {
-         a += (double)s4[i].nfa[j] * fa[j];
-      }
-      w4 += s4[i].s * sin(a) + s4[i].c * cos(a);
-   }
-
-   s = (w0 +
-       (w1 +
-       (w2 +
-       (w3 +
-       (w4 +
-        w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0;
-
-   return s;
-
-}
-
-double eraS06a(double date1, double date2)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rnpb[3][3], x, y, s;
-
-
-/* Bias-precession-nutation-matrix, IAU 20006/2000A. */
-   eraPnm06a(date1, date2, rnpb);
-
-/* Extract the CIP coordinates. */
-   eraBpn2xy(rnpb, &x, &y);
-
-/* Compute the CIO locator s, given the CIP coordinates. */
-   s = eraS06(date1, date2, x, y);
-
-   return s;
-
-}
-
-void eraS2c(double theta, double phi, double c[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double cp;
-
-
-   cp = cos(phi);
-   c[0] = cos(theta) * cp;
-   c[1] = sin(theta) * cp;
-   c[2] = sin(phi);
-
-   return;
-
-}
-
-void eraS2p(double theta, double phi, double r, double p[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double u[3];
-
-
-   eraS2c(theta, phi, u);
-   eraSxp(r, u, p);
-
-   return;
-
-}
-
-void eraS2pv(double theta, double phi, double r,
-             double td, double pd, double rd,
-             double pv[2][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double st, ct, sp, cp, rcp, x, y, rpd, w;
-
-
-   st = sin(theta);
-   ct = cos(theta);
-   sp = sin(phi);
-   cp = cos(phi);
-   rcp = r * cp;
-   x = rcp * ct;
-   y = rcp * st;
-   rpd = r * pd;
-   w = rpd*sp - cp*rd;
-
-   pv[0][0] = x;
-   pv[0][1] = y;
-   pv[0][2] = r * sp;
-   pv[1][0] = -y*td - w*ct;
-   pv[1][1] =  x*td - w*st;
-   pv[1][2] = rpd*cp + sp*rd;
-
-   return;
-
-}
-
-void eraS2xpv(double s1, double s2, double pv[2][3], double spv[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraSxp(s1, pv[0], spv[0]);
-   eraSxp(s2, pv[1], spv[1]);
-
-   return;
-
-}
-
-double eraSepp(double a[3], double b[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double axb[3], ss, cs, s;
-
-
-/* Sine of angle between the vectors, multiplied by the two moduli. */
-   eraPxp(a, b, axb);
-   ss = eraPm(axb);
-
-/* Cosine of the angle, multiplied by the two moduli. */
-   cs = eraPdp(a, b);
-
-/* The angle. */
-   s = ((ss != 0.0) || (cs != 0.0)) ? atan2(ss, cs) : 0.0;
-
-   return s;
-
-}
-
-double eraSeps(double al, double ap, double bl, double bp)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double ac[3], bc[3], s;
-
-
-/* Spherical to Cartesian. */
-   eraS2c(al, ap, ac);
-   eraS2c(bl, bp, bc);
-
-/* Angle between the vectors. */
-   s = eraSepp(ac, bc);
-
-   return s;
-
-}
-
-double eraSp00(double date1, double date2)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double t, sp;
-
-
-/* Interval between fundamental epoch J2000.0 and current date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Approximate s'. */
-   sp = -47e-6 * t * ERFA_DAS2R;
-
-   return sp;
-
-}
-
-int eraStarpm(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)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double pv1[2][3], tl1, dt, pv[2][3], r2, rdv, v2, c2mv2, tl2,
-          pv2[2][3];
-   int j1, j2, j;
-
-
-/* RA,Dec etc. at the "before" epoch to space motion pv-vector. */
-   j1 = eraStarpv(ra1, dec1, pmr1, pmd1, px1, rv1, pv1);
-
-/* Light time when observed (days). */
-   tl1 = eraPm(pv1[0]) / ERFA_DC;
-
-/* Time interval, "before" to "after" (days). */
-   dt = (ep2a - ep1a) + (ep2b - ep1b);
-
-/* Move star along track from the "before" observed position to the */
-/* "after" geometric position. */
-   eraPvu(dt + tl1, pv1, pv);
-
-/* From this geometric position, deduce the observed light time (days) */
-/* at the "after" epoch (with theoretically unneccessary error check). */
-   r2 = eraPdp(pv[0], pv[0]);
-   rdv = eraPdp(pv[0], pv[1]);
-   v2 = eraPdp(pv[1], pv[1]);
-   c2mv2 = ERFA_DC*ERFA_DC - v2;
-   if (c2mv2 <=  0) return -1;
-   tl2 = (-rdv + sqrt(rdv*rdv + c2mv2*r2)) / c2mv2;
-
-/* Move the position along track from the observed place at the */
-/* "before" epoch to the observed place at the "after" epoch. */
-   eraPvu(dt + (tl1 - tl2), pv1, pv2);
-
-/* Space motion pv-vector to RA,Dec etc. at the "after" epoch. */
-   j2 = eraPvstar(pv2, ra2, dec2, pmr2, pmd2, px2, rv2);
-
-/* Final status. */
-   j = (j2 == 0) ? j1 : -1;
-
-   return j;
-
-}
-
-int eraStarpv(double ra, double dec,
-              double pmr, double pmd, double px, double rv,
-              double pv[2][3])
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-/* Smallest allowed parallax */
-   static const double PXMIN = 1e-7;
-
-/* Largest allowed speed (fraction of c) */
-   static const double VMAX = 0.5;
-
-/* Maximum number of iterations for relativistic solution */
-   static const int IMAX = 100;
-
-   int i, iwarn;
-   double w, r, rd, rad, decd, v, x[3], usr[3], ust[3],
-          vsr, vst, betst, betsr, bett, betr,
-          dd, ddel, ur[3], ut[3],
-          d = 0.0, del = 0.0,       /* to prevent */
-          odd = 0.0, oddel = 0.0,   /* compiler   */
-          od = 0.0, odel = 0.0;     /* warnings   */
-
-
-/* Distance (AU). */
-   if (px >= PXMIN) {
-      w = px;
-      iwarn = 0;
-   } else {
-      w = PXMIN;
-      iwarn = 1;
-   }
-   r = ERFA_DR2AS / w;
-
-/* Radial velocity (AU/day). */
-   rd = ERFA_DAYSEC * rv * 1e3 / ERFA_DAU;
-
-/* Proper motion (radian/day). */
-   rad = pmr / ERFA_DJY;
-   decd = pmd / ERFA_DJY;
-
-/* To pv-vector (AU,AU/day). */
-   eraS2pv(ra, dec, r, rad, decd, rd, pv);
-
-/* If excessive velocity, arbitrarily set it to zero. */
-   v = eraPm(pv[1]);
-   if (v / ERFA_DC > VMAX) {
-      eraZp(pv[1]);
-      iwarn += 2;
-   }
-
-/* Isolate the radial component of the velocity (AU/day). */
-   eraPn(pv[0], &w, x);
-   vsr = eraPdp(x, pv[1]);
-   eraSxp(vsr, x, usr);
-
-/* Isolate the transverse component of the velocity (AU/day). */
-   eraPmp(pv[1], usr, ust);
-   vst = eraPm(ust);
-
-/* Special-relativity dimensionless parameters. */
-   betsr = vsr / ERFA_DC;
-   betst = vst / ERFA_DC;
-
-/* Determine the inertial-to-observed relativistic correction terms. */
-   bett = betst;
-   betr = betsr;
-   for (i = 0; i < IMAX; i++) {
-      d = 1.0 + betr;
-      del = sqrt(1.0 - betr*betr - bett*bett) - 1.0;
-      betr = d * betsr + del;
-      bett = d * betst;
-      if (i > 0) {
-         dd = fabs(d - od);
-         ddel = fabs(del - odel);
-         if ((i > 1) && (dd >= odd) && (ddel >= oddel)) break;
-         odd = dd;
-         oddel = ddel;
-      }
-      od = d;
-      odel = del;
-   }
-   if (i >= IMAX) iwarn += 4;
-
-/* Replace observed radial velocity with inertial value. */
-   w = (betsr != 0.0) ? d + del / betsr : 1.0;
-   eraSxp(w, usr, ur);
-
-/* Replace observed tangential velocity with inertial value. */
-   eraSxp(d, ust, ut);
-
-/* Combine the two to obtain the inertial space velocity. */
-   eraPpp(ur, ut, pv[1]);
-
-/* Return the status. */
-   return iwarn;
-
-}
-
-void eraSxp(double s, double p[3], double sp[3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   sp[0] = s * p[0];
-   sp[1] = s * p[1];
-   sp[2] = s * p[2];
-
-   return;
-
-}
-
-void eraSxpv(double s, double pv[2][3], double spv[2][3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraS2xpv(s, s, pv, spv);
-
-   return;
-
-}
-
-int eraTaitt(double tai1, double tai2, double *tt1, double *tt2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* TT minus TAI (days). */
-   static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC;
-
-
-/* Result, safeguarding precision. */
-   if ( tai1 > tai2 ) {
-      *tt1 = tai1;
-      *tt2 = tai2 + dtat;
-   } else {
-      *tt1 = tai1 + dtat;
-      *tt2 = tai2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTaiut1(double tai1, double tai2, double dta,
-              double *ut11, double *ut12)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtad;
-
-
-/* Result, safeguarding precision. */
-   dtad = dta / ERFA_DAYSEC;
-   if ( tai1 > tai2 ) {
-      *ut11 = tai1;
-      *ut12 = tai2 + dtad;
-   } else {
-      *ut11 = tai1 + dtad;
-      *ut12 = tai2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int big1;
-   int i, j;
-   double a1, a2, u1, u2, g1, g2;
-
-
-/* Put the two parts of the TAI into big-first order. */
-   big1 = ( tai1 >= tai2 );
-   if ( big1 ) {
-      a1 = tai1;
-      a2 = tai2;
-   } else {
-      a1 = tai2;
-      a2 = tai1;
-   }
-
-/* Initial guess for UTC. */
-   u1 = a1;
-   u2 = a2;
-
-/* Iterate (though in most cases just once is enough). */
-   for ( i = 0; i < 3; i++ ) {
-
-   /* Guessed UTC to TAI. */
-      j = eraUtctai(u1, u2, &g1, &g2);
-      if ( j < 0 ) return j;
-
-   /* Adjust guessed UTC. */
-      u2 += a1 - g1;
-      u2 += a2 - g2;
-   }
-
-/* Return the UTC result, preserving the TAI order. */
-   if ( big1 ) {
-      *utc1 = u1;
-      *utc2 = u2;
-   } else {
-      *utc1 = u2;
-      *utc2 = u1;
-   }
-
-/* Status. */
-   return j;
-
-}
-
-int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */
-   static const double t77td = ERFA_DJM0 + ERFA_DJM77;
-   static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC;
-
-/* TDB (days) at TAI 1977 Jan 1.0 */
-   static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC;
-
-   double d;
-
-
-/* Result, safeguarding precision. */
-   if ( tcb1 > tcb2 ) {
-      d = tcb1 - t77td;
-      *tdb1 = tcb1;
-      *tdb2 = tcb2 + tdb0 - ( d + ( tcb2 - t77tf ) ) * ERFA_ELB;
-   } else {
-      d = tcb2 - t77td;
-      *tdb1 = tcb1 + tdb0 - ( d + ( tcb1 - t77tf ) ) * ERFA_ELB;
-      *tdb2 = tcb2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* 1977 Jan 1 00:00:32.184 TT, as MJD */
-   static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC;
-
-
-/* Result, safeguarding precision. */
-   if ( tcg1 > tcg2 ) {
-      *tt1 = tcg1;
-      *tt2 = tcg2 - ( ( tcg1 - ERFA_DJM0 ) + ( tcg2 - t77t ) ) * ERFA_ELG;
-   } else {
-      *tt1 = tcg1 - ( ( tcg2 - ERFA_DJM0 ) + ( tcg1 - t77t ) ) * ERFA_ELG;
-      *tt2 = tcg2;
-   }
-
-/* OK status. */
-   return 0;
-
-}
-
-int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */
-   static const double t77td = ERFA_DJM0 + ERFA_DJM77;
-   static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC;
-
-/* TDB (days) at TAI 1977 Jan 1.0 */
-   static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC;
-
-/* TDB to TCB rate */
-   static const double elbb = ERFA_ELB/(1.0-ERFA_ELB);
-
-   double d, f;
-
-
-/* Result, preserving date format but safeguarding precision. */
-   if ( tdb1 > tdb2 ) {
-      d = t77td - tdb1;
-      f  = tdb2 - tdb0;
-      *tcb1 = tdb1;
-      *tcb2 = f - ( d - ( f - t77tf ) ) * elbb;
-   } else {
-      d = t77td - tdb2;
-      f  = tdb1 - tdb0;
-      *tcb1 = f + ( d - ( f - t77tf ) ) * elbb;
-      *tcb2 = tdb2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTdbtt(double tdb1, double tdb2, double dtr,
-             double *tt1, double *tt2 )
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtrd;
-
-
-/* Result, safeguarding precision. */
-   dtrd = dtr / ERFA_DAYSEC;
-   if ( tdb1 > tdb2 ) {
-      *tt1 = tdb1;
-      *tt2 = tdb2 - dtrd;
-   } else {
-      *tt1 = tdb1 - dtrd;
-      *tt2 = tdb2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTf2a(char s, int ihour, int imin, double sec, double *rad)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Compute the interval. */
-   *rad  = ( s == '-' ? -1.0 : 1.0 ) *
-           ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) +
-                             ( (double) abs(imin) ) ) +
-                                        fabs(sec) ) * ERFA_DS2R;
-
-/* Validate arguments and return status. */
-   if ( ihour < 0 || ihour > 23 ) return 1;
-   if ( imin < 0 || imin > 59 ) return 2;
-   if ( sec < 0.0 || sec >= 60.0 ) return 3;
-   return 0;
-
-}
-
-int eraTf2d(char s, int ihour, int imin, double sec, double *days)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Compute the interval. */
-   *days  = ( s == '-' ? -1.0 : 1.0 ) *
-            ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) +
-                              ( (double) abs(imin) ) ) +
-                                         fabs(sec) ) / ERFA_DAYSEC;
-
-/* Validate arguments and return status. */
-   if ( ihour < 0 || ihour > 23 ) return 1;
-   if ( imin < 0 || imin > 59 ) return 2;
-   if ( sec < 0.0 || sec >= 60.0 ) return 3;
-   return 0;
-
-}
-
-void eraTr(double r[3][3], double rt[3][3])
-/*
-**  - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double wm[3][3];
-   int i, j;
-
-
-   for (i = 0; i < 3; i++) {
-      for (j = 0; j < 3; j++) {
-         wm[i][j] = r[j][i];
-      }
-   }
-   eraCr(wm, rt);
-
-   return;
-
-}
-
-void eraTrxp(double r[3][3], double p[3], double trp[3])
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double tr[3][3];
-
-
-/* Transpose of matrix r. */
-   eraTr(r, tr);
-
-/* Matrix tr * vector p -> vector trp. */
-   eraRxp(tr, p, trp);
-
-   return;
-
-}
-
-void eraTrxpv(double r[3][3], double pv[2][3], double trpv[2][3])
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double tr[3][3];
-
-
-/* Transpose of matrix r. */
-   eraTr(r, tr);
-
-/* Matrix tr * vector pv -> vector trpv. */
-   eraRxpv(tr, pv, trpv);
-
-   return;
-
-}
-
-int eraTttai(double tt1, double tt2, double *tai1, double *tai2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* TT minus TAI (days). */
-   static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC;
-
-
-/* Result, safeguarding precision. */
-   if ( tt1 > tt2 ) {
-      *tai1 = tt1;
-      *tai2 = tt2 - dtat;
-   } else {
-      *tai1 = tt1 - dtat;
-      *tai2 = tt2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* 1977 Jan 1 00:00:32.184 TT, as MJD */
-   static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC;
-
-/* TT to TCG rate */
-   static const double elgg = ERFA_ELG/(1.0-ERFA_ELG);
-
-
-/* Result, safeguarding precision. */
-   if ( tt1 > tt2 ) {
-      *tcg1 = tt1;
-      *tcg2 = tt2 + ( ( tt1 - ERFA_DJM0 ) + ( tt2 - t77t ) ) * elgg;
-   } else {
-      *tcg1 = tt1 + ( ( tt2 - ERFA_DJM0 ) + ( tt1 - t77t ) ) * elgg;
-      *tcg2 = tt2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTttdb(double tt1, double tt2, double dtr,
-             double *tdb1, double *tdb2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtrd;
-
-
-/* Result, safeguarding precision. */
-   dtrd = dtr / ERFA_DAYSEC;
-   if ( tt1 > tt2 ) {
-      *tdb1 = tt1;
-      *tdb2 = tt2 + dtrd;
-   } else {
-      *tdb1 = tt1 + dtrd;
-      *tdb2 = tt2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraTtut1(double tt1, double tt2, double dt,
-             double *ut11, double *ut12)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtd;
-
-
-/* Result, safeguarding precision. */
-   dtd = dt / ERFA_DAYSEC;
-   if ( tt1 > tt2 ) {
-      *ut11 = tt1;
-      *ut12 = tt2 - dtd;
-   } else {
-      *ut11 = tt1 - dtd;
-      *ut12 = tt2;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraUt1tai(double ut11, double ut12, double dta,
-              double *tai1, double *tai2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtad;
-
-
-/* Result, safeguarding precision. */
-   dtad = dta / ERFA_DAYSEC;
-   if ( ut11 > ut12 ) {
-      *tai1 = ut11;
-      *tai2 = ut12 - dtad;
-   } else {
-      *tai1 = ut11 - dtad;
-      *tai2 = ut12;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraUt1tt(double ut11, double ut12, double dt,
-             double *tt1, double *tt2)
-/*
-**  - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double dtd;
-
-
-/* Result, safeguarding precision. */
-   dtd = dt / ERFA_DAYSEC;
-   if ( ut11 > ut12 ) {
-      *tt1 = ut11;
-      *tt2 = ut12 + dtd;
-   } else {
-      *tt1 = ut11 + dtd;
-      *tt2 = ut12;
-   }
-
-/* Status (always OK). */
-   return 0;
-
-}
-
-int eraUt1utc(double ut11, double ut12, double dut1,
-              double *utc1, double *utc2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int big1;
-   int i, iy, im, id, js;
-   double duts, u1, u2, d1, dats1, d2, fd, dats2, ddats, us1, us2, du;
-
-
-/* UT1-UTC in seconds. */
-   duts = dut1;
-
-/* Put the two parts of the UT1 into big-first order. */
-   big1 = ( ut11 >= ut12 );
-   if ( big1 ) {
-      u1 = ut11;
-      u2 = ut12;
-   } else {
-      u1 = ut12;
-      u2 = ut11;
-   }
-
-/* See if the UT1 can possibly be in a leap-second day. */
-   d1 = u1;
-   dats1 = 0;
-   for ( i = -1; i <= 3; i++ ) {
-      d2 = u2 + (double) i;
-      if ( eraJd2cal(d1, d2, &iy, &im, &id, &fd) ) return -1;
-      js = eraDat(iy, im, id, 0.0, &dats2);
-      if ( js < 0 ) return -1;
-      if ( i == - 1 ) dats1 = dats2;
-      ddats = dats2 - dats1;
-      if ( fabs(ddats) >= 0.5 ) {
-
-      /* Yes, leap second nearby: ensure UT1-UTC is "before" value. */
-         if ( ddats * duts >= 0 ) duts -= ddats;
-
-      /* UT1 for the start of the UTC day that ends in a leap. */
-         if ( eraCal2jd(iy, im, id, &d1, &d2) ) return -1;
-         us1 = d1;
-         us2 = d2 - 1.0 + duts/ERFA_DAYSEC;
-
-      /* Is the UT1 after this point? */
-         du = u1 - us1;
-         du += u2 - us2;
-         if ( du > 0 ) {
-
-         /* Yes:  fraction of the current UTC day that has elapsed. */
-            fd = du * ERFA_DAYSEC / ( ERFA_DAYSEC + ddats );
-
-         /* Ramp UT1-UTC to bring about ERFA's JD(UTC) convention. */
-            duts += ddats * ( fd <= 1.0 ? fd : 1.0 );
-         }
-
-      /* Done. */
-         break;
-      }
-      dats1 = dats2;
-   }
-
-/* Subtract the (possibly adjusted) UT1-UTC from UT1 to give UTC. */
-   u2 -= duts / ERFA_DAYSEC;
-
-/* Result, safeguarding precision. */
-   if ( big1 ) {
-      *utc1 = u1;
-      *utc2 = u2;
-   } else {
-      *utc1 = u2;
-      *utc2 = u1;
-   }
-
-/* Status. */
-   return js;
-
-}
-
-int eraUtctai(double utc1, double utc2, double *tai1, double *tai2)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int big1;
-   int iy, im, id, j, iyt, imt, idt;
-   double u1, u2, fd, dat0, dat12, w, dat24, dlod, dleap, z1, z2, a2;
-
-
-/* Put the two parts of the UTC into big-first order. */
-   big1 = ( utc1 >= utc2 );
-   if ( big1 ) {
-      u1 = utc1;
-      u2 = utc2;
-   } else {
-      u1 = utc2;
-      u2 = utc1;
-   }
-
-/* Get TAI-UTC at 0h today. */
-   j = eraJd2cal(u1, u2, &iy, &im, &id, &fd);
-   if ( j ) return j;
-   j = eraDat(iy, im, id, 0.0, &dat0);
-   if ( j < 0 ) return j;
-
-/* Get TAI-UTC at 12h today (to detect drift). */
-   j = eraDat(iy, im, id, 0.5, &dat12);
-   if ( j < 0 ) return j;
-
-/* Get TAI-UTC at 0h tomorrow (to detect jumps). */
-   j = eraJd2cal(u1+1.5, u2-fd, &iyt, &imt, &idt, &w);
-   if ( j ) return j;
-   j = eraDat(iyt, imt, idt, 0.0, &dat24);
-   if ( j < 0 ) return j;
-
-/* Separate TAI-UTC change into per-day (DLOD) and any jump (DLEAP). */
-   dlod = 2.0 * (dat12 - dat0);
-   dleap = dat24 - (dat0 + dlod);
-
-/* Remove any scaling applied to spread leap into preceding day. */
-   fd *= (ERFA_DAYSEC+dleap)/ERFA_DAYSEC;
-
-/* Scale from (pre-1972) UTC seconds to SI seconds. */
-   fd *= (ERFA_DAYSEC+dlod)/ERFA_DAYSEC;
-
-/* Today's calendar date to 2-part JD. */
-   if ( eraCal2jd(iy, im, id, &z1, &z2) ) return -1;
-
-/* Assemble the TAI result, preserving the UTC split and order. */
-   a2 = z1 - u1;
-   a2 += z2;
-   a2 += fd + dat0/ERFA_DAYSEC;
-   if ( big1 ) {
-      *tai1 = u1;
-      *tai2 = a2;
-   } else {
-      *tai1 = a2;
-      *tai2 = u1;
-   }
-
-/* Status. */
-   return j;
-
-}
-
-int eraUtcut1(double utc1, double utc2, double dut1,
-              double *ut11, double *ut12)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   int iy, im, id, js, jw;
-   double w, dat, dta, tai1, tai2;
-
-
-/* Look up TAI-UTC. */
-   if ( eraJd2cal(utc1, utc2, &iy, &im, &id, &w) ) return -1;
-   js = eraDat ( iy, im, id, 0.0, &dat);
-   if ( js < 0 ) return -1;
-
-/* Form UT1-TAI. */
-   dta = dut1 - dat;
-
-/* UTC to TAI to UT1. */
-   jw = eraUtctai(utc1, utc2, &tai1, &tai2);
-   if ( jw < 0 ) {
-      return -1;
-   } else if ( jw > 0 ) {
-      js = jw;
-   }
-   if ( eraTaiut1(tai1, tai2, dta, ut11, ut12) ) return -1;
-
-/* Status. */
-   return js;
-
-}
-
-void eraXy06(double date1, double date2, double *x, double *y)
-/*
-**  - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-
-/* Maximum power of T in the polynomials for X and Y */
-   enum { MAXPT = 5 };
-
-/* Polynomial coefficients (arcsec, X then Y). */
-   static const double xyp[2][MAXPT+1] = {
-
-      {    -0.016617,
-         2004.191898,
-           -0.4297829,
-           -0.19861834,
-            0.000007578,
-            0.0000059285
-      },
-      {    -0.006951,
-           -0.025896,
-          -22.4072747,
-            0.00190059,
-            0.001112526,
-            0.0000001358
-      }
-   };
-
-/* Fundamental-argument multipliers:  luni-solar terms */
-   static const int mfals[][5] = {
-
-   /* 1-10 */
-      {  0,   0,   0,   0,   1 },
-      {  0,   0,   2,  -2,   2 },
-      {  0,   0,   2,   0,   2 },
-      {  0,   0,   0,   0,   2 },
-      {  0,   1,   0,   0,   0 },
-      {  0,   1,   2,  -2,   2 },
-      {  1,   0,   0,   0,   0 },
-      {  0,   0,   2,   0,   1 },
-      {  1,   0,   2,   0,   2 },
-      {  0,   1,  -2,   2,  -2 },
-
-   /* 11-20 */
-      {  0,   0,   2,  -2,   1 },
-      {  1,   0,  -2,   0,  -2 },
-      {  1,   0,   0,  -2,   0 },
-      {  1,   0,   0,   0,   1 },
-      {  1,   0,   0,   0,  -1 },
-      {  1,   0,  -2,  -2,  -2 },
-      {  1,   0,   2,   0,   1 },
-      {  2,   0,  -2,   0,  -1 },
-      {  0,   0,   0,   2,   0 },
-      {  0,   0,   2,   2,   2 },
-
-   /* 21-30 */
-      {  2,   0,   0,  -2,   0 },
-      {  0,   2,  -2,   2,  -2 },
-      {  2,   0,   2,   0,   2 },
-      {  1,   0,   2,  -2,   2 },
-      {  1,   0,  -2,   0,  -1 },
-      {  2,   0,   0,   0,   0 },
-      {  0,   0,   2,   0,   0 },
-      {  0,   1,   0,   0,   1 },
-      {  1,   0,   0,  -2,  -1 },
-      {  0,   2,   2,  -2,   2 },
-
-   /* 31-40 */
-      {  0,   0,   2,  -2,   0 },
-      {  1,   0,   0,  -2,   1 },
-      {  0,   1,   0,   0,  -1 },
-      {  0,   2,   0,   0,   0 },
-      {  1,   0,  -2,  -2,  -1 },
-      {  1,   0,   2,   2,   2 },
-      {  0,   1,   2,   0,   2 },
-      {  2,   0,  -2,   0,   0 },
-      {  0,   0,   2,   2,   1 },
-      {  0,   1,  -2,   0,  -2 },
-
-   /* 41-50 */
-      {  0,   0,   0,   2,   1 },
-      {  1,   0,   2,  -2,   1 },
-      {  2,   0,   0,  -2,  -1 },
-      {  2,   0,   2,  -2,   2 },
-      {  2,   0,   2,   0,   1 },
-      {  0,   0,   0,   2,  -1 },
-      {  0,   1,  -2,   2,  -1 },
-      {  1,   1,   0,  -2,   0 },
-      {  2,   0,   0,  -2,   1 },
-      {  1,   0,   0,   2,   0 },
-
-   /* 51-60 */
-      {  0,   1,   2,  -2,   1 },
-      {  1,  -1,   0,   0,   0 },
-      {  0,   1,  -1,   1,  -1 },
-      {  2,   0,  -2,   0,  -2 },
-      {  0,   1,   0,  -2,   0 },
-      {  1,   0,   0,  -1,   0 },
-      {  3,   0,   2,   0,   2 },
-      {  0,   0,   0,   1,   0 },
-      {  1,  -1,   2,   0,   2 },
-      {  1,   1,  -2,  -2,  -2 },
-
-   /* 61-70 */
-      {  1,   0,  -2,   0,   0 },
-      {  2,   0,   0,   0,  -1 },
-      {  0,   1,  -2,  -2,  -2 },
-      {  1,   1,   2,   0,   2 },
-      {  2,   0,   0,   0,   1 },
-      {  1,   1,   0,   0,   0 },
-      {  1,   0,  -2,   2,  -1 },
-      {  1,   0,   2,   0,   0 },
-      {  1,  -1,   0,  -1,   0 },
-      {  1,   0,   0,   0,   2 },
-
-   /* 71-80 */
-      {  1,   0,  -1,   0,  -1 },
-      {  0,   0,   2,   1,   2 },
-      {  1,   0,  -2,  -4,  -2 },
-      {  1,  -1,   0,  -1,  -1 },
-      {  1,   0,   2,   2,   1 },
-      {  0,   2,  -2,   2,  -1 },
-      {  1,   0,   0,   0,  -2 },
-      {  2,   0,  -2,  -2,  -2 },
-      {  1,   1,   2,  -2,   2 },
-      {  2,   0,  -2,  -4,  -2 },
-
-   /* 81-90 */
-      {  1,   0,  -4,   0,  -2 },
-      {  2,   0,   2,  -2,   1 },
-      {  1,   0,   0,  -1,  -1 },
-      {  2,   0,   2,   2,   2 },
-      {  3,   0,   0,   0,   0 },
-      {  1,   0,   0,   2,   1 },
-      {  0,   0,   2,  -2,  -1 },
-      {  3,   0,   2,  -2,   2 },
-      {  0,   0,   4,  -2,   2 },
-      {  1,   0,   0,  -4,   0 },
-
-   /* 91-100 */
-      {  0,   1,   2,   0,   1 },
-      {  2,   0,   0,  -4,   0 },
-      {  1,   1,   0,  -2,  -1 },
-      {  2,   0,  -2,   0,   1 },
-      {  0,   0,   2,   0,  -1 },
-      {  0,   1,  -2,   0,  -1 },
-      {  0,   1,   0,   0,   2 },
-      {  0,   0,   2,  -1,   2 },
-      {  0,   0,   2,   4,   2 },
-      {  2,   1,   0,  -2,   0 },
-
-   /* 101-110 */
-      {  1,   1,   0,  -2,   1 },
-      {  1,  -1,   0,  -2,   0 },
-      {  1,  -1,   0,  -1,  -2 },
-      {  1,  -1,   0,   0,   1 },
-      {  0,   1,  -2,   2,   0 },
-      {  0,   1,   0,   0,  -2 },
-      {  1,  -1,   2,   2,   2 },
-      {  1,   0,   0,   2,  -1 },
-      {  1,  -1,  -2,  -2,  -2 },
-      {  3,   0,   2,   0,   1 },
-
-   /* 111-120 */
-      {  0,   1,   2,   2,   2 },
-      {  1,   0,   2,  -2,   0 },
-      {  1,   1,  -2,  -2,  -1 },
-      {  1,   0,   2,  -4,   1 },
-      {  0,   1,  -2,  -2,  -1 },
-      {  2,  -1,   2,   0,   2 },
-      {  0,   0,   0,   2,   2 },
-      {  1,  -1,   2,   0,   1 },
-      {  1,  -1,  -2,   0,  -2 },
-      {  0,   1,   0,   2,   0 },
-
-   /* 121-130 */
-      {  0,   1,   2,  -2,   0 },
-      {  0,   0,   0,   1,   1 },
-      {  1,   0,  -2,  -2,   0 },
-      {  0,   3,   2,  -2,   2 },
-      {  2,   1,   2,   0,   2 },
-      {  1,   1,   0,   0,   1 },
-      {  2,   0,   0,   2,   0 },
-      {  1,   1,   2,   0,   1 },
-      {  1,   0,   0,  -2,  -2 },
-      {  1,   0,  -2,   2,   0 },
-
-   /* 131-140 */
-      {  1,   0,  -1,   0,  -2 },
-      {  0,   1,   0,  -2,   1 },
-      {  0,   1,   0,   1,   0 },
-      {  0,   0,   0,   1,  -1 },
-      {  1,   0,  -2,   2,  -2 },
-      {  1,  -1,   0,   0,  -1 },
-      {  0,   0,   0,   4,   0 },
-      {  1,  -1,   0,   2,   0 },
-      {  1,   0,   2,   1,   2 },
-      {  1,   0,   2,  -1,   2 },
-
-   /* 141-150 */
-      {  0,   0,   2,   1,   1 },
-      {  1,   0,   0,  -2,   2 },
-      {  1,   0,  -2,   0,   1 },
-      {  1,   0,  -2,  -4,  -1 },
-      {  0,   0,   2,   2,   0 },
-      {  1,   1,   2,  -2,   1 },
-      {  1,   0,  -2,   1,  -1 },
-      {  0,   0,   1,   0,   1 },
-      {  2,   0,  -2,  -2,  -1 },
-      {  4,   0,   2,   0,   2 },
-
-   /* 151-160 */
-      {  2,  -1,   0,   0,   0 },
-      {  2,   1,   2,  -2,   2 },
-      {  0,   1,   2,   1,   2 },
-      {  1,   0,   4,  -2,   2 },
-      {  1,   1,   0,   0,  -1 },
-      {  2,   0,   2,   0,   0 },
-      {  2,   0,  -2,  -4,  -1 },
-      {  1,   0,  -1,   0,   0 },
-      {  1,   0,   0,   1,   0 },
-      {  0,   1,   0,   2,   1 },
-
-   /* 161-170 */
-      {  1,   0,  -4,   0,  -1 },
-      {  1,   0,   0,  -4,  -1 },
-      {  2,   0,   2,   2,   1 },
-      {  2,   1,   0,   0,   0 },
-      {  0,   0,   2,  -3,   2 },
-      {  1,   2,   0,  -2,   0 },
-      {  0,   3,   0,   0,   0 },
-      {  0,   0,   4,   0,   2 },
-      {  0,   0,   2,  -4,   1 },
-      {  2,   0,   0,  -2,  -2 },
-
-   /* 171-180 */
-      {  1,   1,  -2,  -4,  -2 },
-      {  0,   1,   0,  -2,  -1 },
-      {  0,   0,   0,   4,   1 },
-      {  3,   0,   2,  -2,   1 },
-      {  1,   0,   2,   4,   2 },
-      {  1,   1,  -2,   0,  -2 },
-      {  0,   0,   4,  -2,   1 },
-      {  2,  -2,   0,  -2,   0 },
-      {  2,   1,   0,  -2,  -1 },
-      {  0,   2,   0,  -2,   0 },
-
-   /* 181-190 */
-      {  1,   0,   0,  -1,   1 },
-      {  1,   1,   2,   2,   2 },
-      {  3,   0,   0,   0,  -1 },
-      {  2,   0,   0,  -4,  -1 },
-      {  3,   0,   2,   2,   2 },
-      {  0,   0,   2,   4,   1 },
-      {  0,   2,  -2,  -2,  -2 },
-      {  1,  -1,   0,  -2,  -1 },
-      {  0,   0,   2,  -1,   1 },
-      {  2,   0,   0,   2,   1 },
-
-   /* 191-200 */
-      {  1,  -1,  -2,   2,  -1 },
-      {  0,   0,   0,   2,  -2 },
-      {  2,   0,   0,  -4,   1 },
-      {  1,   0,   0,  -4,   1 },
-      {  2,   0,   2,  -4,   1 },
-      {  4,   0,   2,  -2,   2 },
-      {  2,   1,  -2,   0,  -1 },
-      {  2,   1,  -2,  -4,  -2 },
-      {  3,   0,   0,  -4,   0 },
-      {  1,  -1,   2,   2,   1 },
-
-   /* 201-210 */
-      {  1,  -1,  -2,   0,  -1 },
-      {  0,   2,   0,   0,   1 },
-      {  1,   2,  -2,  -2,  -2 },
-      {  1,   1,   0,  -4,   0 },
-      {  2,   0,   0,  -2,   2 },
-      {  0,   2,   2,  -2,   1 },
-      {  1,   0,   2,   0,  -1 },
-      {  2,   1,   0,  -2,   1 },
-      {  2,  -1,  -2,   0,  -1 },
-      {  1,  -1,  -2,  -2,  -1 },
-
-   /* 211-220 */
-      {  0,   1,  -2,   1,  -2 },
-      {  1,   0,  -4,   2,  -2 },
-      {  0,   1,   2,   2,   1 },
-      {  3,   0,   0,   0,   1 },
-      {  2,  -1,   2,   2,   2 },
-      {  0,   1,  -2,  -4,  -2 },
-      {  1,   0,  -2,  -3,  -2 },
-      {  2,   0,   0,   0,   2 },
-      {  1,  -1,   0,  -2,  -2 },
-      {  2,   0,  -2,   2,  -1 },
-
-   /* 221-230 */
-      {  0,   2,  -2,   0,  -2 },
-      {  3,   0,  -2,   0,  -1 },
-      {  2,  -1,   2,   0,   1 },
-      {  1,   0,  -2,  -1,  -2 },
-      {  0,   0,   2,   0,   3 },
-      {  2,   0,  -4,   0,  -2 },
-      {  2,   1,   0,  -4,   0 },
-      {  1,   1,  -2,   1,  -1 },
-      {  0,   2,   2,   0,   2 },
-      {  1,  -1,   2,  -2,   2 },
-
-   /* 231-240 */
-      {  1,  -1,   0,  -2,   1 },
-      {  2,   1,   2,   0,   1 },
-      {  1,   0,   2,  -4,   2 },
-      {  1,   1,  -2,   0,  -1 },
-      {  1,   1,   0,   2,   0 },
-      {  1,   0,   0,  -3,   0 },
-      {  2,   0,   2,  -1,   2 },
-      {  0,   2,   0,   0,  -1 },
-      {  2,  -1,   0,  -2,   0 },
-      {  4,   0,   0,   0,   0 },
-
-   /* 241-250 */
-      {  2,   1,  -2,  -2,  -2 },
-      {  0,   2,  -2,   2,   0 },
-      {  1,   0,   2,   1,   1 },
-      {  1,   0,  -1,   0,  -3 },
-      {  3,  -1,   2,   0,   2 },
-      {  2,   0,   2,  -2,   0 },
-      {  1,  -2,   0,   0,   0 },
-      {  2,   0,   0,   0,  -2 },
-      {  1,   0,   0,   4,   0 },
-      {  0,   1,   0,   1,   1 },
-
-   /* 251-260 */
-      {  1,   0,   2,   2,   0 },
-      {  0,   1,   0,   2,  -1 },
-      {  0,   1,   0,   1,  -1 },
-      {  0,   0,   2,  -2,   3 },
-      {  3,   1,   2,   0,   2 },
-      {  1,   1,   2,   1,   2 },
-      {  1,   1,  -2,   2,  -1 },
-      {  2,  -1,   2,  -2,   2 },
-      {  1,  -2,   2,   0,   2 },
-      {  1,   0,   2,  -4,   0 },
-
-   /* 261-270 */
-      {  0,   0,   1,   0,   0 },
-      {  1,   0,   2,  -3,   1 },
-      {  1,  -2,   0,  -2,   0 },
-      {  2,   0,   0,   2,  -1 },
-      {  1,   1,   2,  -4,   1 },
-      {  4,   0,   2,   0,   1 },
-      {  0,   1,   2,   1,   1 },
-      {  1,   2,   2,  -2,   2 },
-      {  2,   0,   2,   1,   2 },
-      {  2,   1,   2,  -2,   1 },
-
-   /* 271-280 */
-      {  1,   0,   2,  -1,   1 },
-      {  1,   0,   4,  -2,   1 },
-      {  1,  -1,   2,  -2,   1 },
-      {  0,   1,   0,  -4,   0 },
-      {  3,   0,  -2,  -2,  -2 },
-      {  0,   0,   4,  -4,   2 },
-      {  2,   0,  -4,  -2,  -2 },
-      {  2,  -2,   0,  -2,  -1 },
-      {  1,   0,   2,  -2,  -1 },
-      {  2,   0,  -2,  -6,  -2 },
-
-   /* 281-290 */
-      {  1,   0,  -2,   1,  -2 },
-      {  1,   0,  -2,   2,   1 },
-      {  1,  -1,   0,   2,  -1 },
-      {  1,   0,  -2,   1,   0 },
-      {  2,  -1,   0,  -2,   1 },
-      {  1,  -1,   0,   2,   1 },
-      {  2,   0,  -2,  -2,   0 },
-      {  1,   0,   2,  -3,   2 },
-      {  0,   0,   0,   4,  -1 },
-      {  2,  -1,   0,   0,   1 },
-
-   /* 291-300 */
-      {  2,   0,   4,  -2,   2 },
-      {  0,   0,   2,   3,   2 },
-      {  0,   1,   4,  -2,   2 },
-      {  0,   1,  -2,   2,   1 },
-      {  1,   1,   0,   2,   1 },
-      {  1,   0,   0,   4,   1 },
-      {  0,   0,   4,   0,   1 },
-      {  2,   0,   0,  -3,   0 },
-      {  1,   0,   0,  -1,  -2 },
-      {  1,  -2,  -2,  -2,  -2 },
-
-   /* 301-310 */
-      {  3,   0,   0,   2,   0 },
-      {  2,   0,   2,  -4,   2 },
-      {  1,   1,  -2,  -4,  -1 },
-      {  1,   0,  -2,  -6,  -2 },
-      {  2,  -1,   0,   0,  -1 },
-      {  2,  -1,   0,   2,   0 },
-      {  0,   1,   2,  -2,  -1 },
-      {  1,   1,   0,   1,   0 },
-      {  1,   2,   0,  -2,  -1 },
-      {  1,   0,   0,   1,  -1 },
-
-   /* 311-320 */
-      {  0,   0,   1,   0,   2 },
-      {  3,   1,   2,  -2,   2 },
-      {  1,   0,  -4,  -2,  -2 },
-      {  1,   0,   2,   4,   1 },
-      {  1,  -2,   2,   2,   2 },
-      {  1,  -1,  -2,  -4,  -2 },
-      {  0,   0,   2,  -4,   2 },
-      {  0,   0,   2,  -3,   1 },
-      {  2,   1,  -2,   0,   0 },
-      {  3,   0,  -2,  -2,  -1 },
-
-   /* 321-330 */
-      {  2,   0,   2,   4,   2 },
-      {  0,   0,   0,   0,   3 },
-      {  2,  -1,  -2,  -2,  -2 },
-      {  2,   0,   0,  -1,   0 },
-      {  3,   0,   2,  -4,   2 },
-      {  2,   1,   2,   2,   2 },
-      {  0,   0,   3,   0,   3 },
-      {  1,   1,   2,   2,   1 },
-      {  2,   1,   0,   0,  -1 },
-      {  1,   2,   0,  -2,   1 },
-
-   /* 331-340 */
-      {  3,   0,   2,   2,   1 },
-      {  1,  -1,  -2,   2,  -2 },
-      {  1,   1,   0,  -1,   0 },
-      {  1,   2,   0,   0,   0 },
-      {  1,   0,   4,   0,   2 },
-      {  1,  -1,   2,   4,   2 },
-      {  2,   1,   0,   0,   1 },
-      {  1,   0,   0,   2,   2 },
-      {  1,  -1,  -2,   2,   0 },
-      {  0,   2,  -2,  -2,  -1 },
-
-   /* 341-350 */
-      {  2,   0,  -2,   0,   2 },
-      {  5,   0,   2,   0,   2 },
-      {  3,   0,  -2,  -6,  -2 },
-      {  1,  -1,   2,  -1,   2 },
-      {  3,   0,   0,  -4,  -1 },
-      {  1,   0,   0,   1,   1 },
-      {  1,   0,  -4,   2,  -1 },
-      {  0,   1,   2,  -4,   1 },
-      {  1,   2,   2,   0,   2 },
-      {  0,   1,   0,  -2,  -2 },
-
-   /* 351-360 */
-      {  0,   0,   2,  -1,   0 },
-      {  1,   0,   1,   0,   1 },
-      {  0,   2,   0,  -2,   1 },
-      {  3,   0,   2,   0,   0 },
-      {  1,   1,  -2,   1,   0 },
-      {  2,   1,  -2,  -4,  -1 },
-      {  3,  -1,   0,   0,   0 },
-      {  2,  -1,  -2,   0,   0 },
-      {  4,   0,   2,  -2,   1 },
-      {  2,   0,  -2,   2,   0 },
-
-   /* 361-370 */
-      {  1,   1,   2,  -2,   0 },
-      {  1,   0,  -2,   4,  -1 },
-      {  1,   0,  -2,  -2,   1 },
-      {  2,   0,   2,  -4,   0 },
-      {  1,   1,   0,  -2,  -2 },
-      {  1,   1,  -2,  -2,   0 },
-      {  1,   0,   1,  -2,   1 },
-      {  2,  -1,  -2,  -4,  -2 },
-      {  3,   0,  -2,   0,  -2 },
-      {  0,   1,  -2,  -2,   0 },
-
-   /* 371-380 */
-      {  3,   0,   0,  -2,  -1 },
-      {  1,   0,  -2,  -3,  -1 },
-      {  0,   1,   0,  -4,  -1 },
-      {  1,  -2,   2,  -2,   1 },
-      {  0,   1,  -2,   1,  -1 },
-      {  1,  -1,   0,   0,   2 },
-      {  2,   0,   0,   1,   0 },
-      {  1,  -2,   0,   2,   0 },
-      {  1,   2,  -2,  -2,  -1 },
-      {  0,   0,   4,  -4,   1 },
-
-   /* 381-390 */
-      {  0,   1,   2,   4,   2 },
-      {  0,   1,  -4,   2,  -2 },
-      {  3,   0,  -2,   0,   0 },
-      {  2,  -1,   2,   2,   1 },
-      {  0,   1,  -2,  -4,  -1 },
-      {  4,   0,   2,   2,   2 },
-      {  2,   0,  -2,  -3,  -2 },
-      {  2,   0,   0,  -6,   0 },
-      {  1,   0,   2,   0,   3 },
-      {  3,   1,   0,   0,   0 },
-
-   /* 391-400 */
-      {  3,   0,   0,  -4,   1 },
-      {  1,  -1,   2,   0,   0 },
-      {  1,  -1,   0,  -4,   0 },
-      {  2,   0,  -2,   2,  -2 },
-      {  1,   1,   0,  -2,   2 },
-      {  4,   0,   0,  -2,   0 },
-      {  2,   2,   0,  -2,   0 },
-      {  0,   1,   2,   0,   0 },
-      {  1,   1,   0,  -4,   1 },
-      {  1,   0,   0,  -4,  -2 },
-
-   /* 401-410 */
-      {  0,   0,   0,   1,   2 },
-      {  3,   0,   0,   2,   1 },
-      {  1,   1,   0,  -4,  -1 },
-      {  0,   0,   2,   2,  -1 },
-      {  1,   1,   2,   0,   0 },
-      {  1,  -1,   2,  -4,   1 },
-      {  1,   1,   0,   0,   2 },
-      {  0,   0,   2,   6,   2 },
-      {  4,   0,  -2,  -2,  -1 },
-      {  2,   1,   0,  -4,  -1 },
-
-   /* 411-420 */
-      {  0,   0,   0,   3,   1 },
-      {  1,  -1,  -2,   0,   0 },
-      {  0,   0,   2,   1,   0 },
-      {  1,   0,   0,   2,  -2 },
-      {  3,  -1,   2,   2,   2 },
-      {  3,  -1,   2,  -2,   2 },
-      {  1,   0,   0,  -1,   2 },
-      {  1,  -2,   2,  -2,   2 },
-      {  0,   1,   0,   2,   2 },
-      {  0,   1,  -2,  -1,  -2 },
-
-   /* 421-430 */
-      {  1,   1,  -2,   0,   0 },
-      {  0,   2,   2,  -2,   0 },
-      {  3,  -1,  -2,  -1,  -2 },
-      {  1,   0,   0,  -6,   0 },
-      {  1,   0,  -2,  -4,   0 },
-      {  2,   1,   0,  -4,   1 },
-      {  2,   0,   2,   0,  -1 },
-      {  2,   0,  -4,   0,  -1 },
-      {  0,   0,   3,   0,   2 },
-      {  2,   1,  -2,  -2,  -1 },
-
-   /* 431-440 */
-      {  1,  -2,   0,   0,   1 },
-      {  2,  -1,   0,  -4,   0 },
-      {  0,   0,   0,   3,   0 },
-      {  5,   0,   2,  -2,   2 },
-      {  1,   2,  -2,  -4,  -2 },
-      {  1,   0,   4,  -4,   2 },
-      {  0,   0,   4,  -1,   2 },
-      {  3,   1,   0,  -4,   0 },
-      {  3,   0,   0,  -6,   0 },
-      {  2,   0,   0,   2,   2 },
-
-   /* 441-450 */
-      {  2,  -2,   2,   0,   2 },
-      {  1,   0,   0,  -3,   1 },
-      {  1,  -2,  -2,   0,  -2 },
-      {  1,  -1,  -2,  -3,  -2 },
-      {  0,   0,   2,  -2,  -2 },
-      {  2,   0,  -2,  -4,   0 },
-      {  1,   0,  -4,   0,   0 },
-      {  0,   1,   0,  -1,   0 },
-      {  4,   0,   0,   0,  -1 },
-      {  3,   0,   2,  -1,   2 },
-
-   /* 451-460 */
-      {  3,  -1,   2,   0,   1 },
-      {  2,   0,   2,  -1,   1 },
-      {  1,   2,   2,  -2,   1 },
-      {  1,   1,   0,   2,  -1 },
-      {  0,   2,   2,   0,   1 },
-      {  3,   1,   2,   0,   1 },
-      {  1,   1,   2,   1,   1 },
-      {  1,   1,   0,  -1,   1 },
-      {  1,  -2,   0,  -2,  -1 },
-      {  4,   0,   0,  -4,   0 },
-
-   /* 461-470 */
-      {  2,   1,   0,   2,   0 },
-      {  1,  -1,   0,   4,   0 },
-      {  0,   1,   0,  -2,   2 },
-      {  0,   0,   2,   0,  -2 },
-      {  1,   0,  -1,   0,   1 },
-      {  3,   0,   2,  -2,   0 },
-      {  2,   0,   2,   2,   0 },
-      {  1,   2,   0,  -4,   0 },
-      {  1,  -1,   0,  -3,   0 },
-      {  0,   1,   0,   4,   0 },
-
-   /* 471 - 480 */
-      {  0,   1,  -2,   0,   0 },
-      {  2,   2,   2,  -2,   2 },
-      {  0,   0,   0,   1,  -2 },
-      {  0,   2,  -2,   0,  -1 },
-      {  4,   0,   2,  -4,   2 },
-      {  2,   0,  -4,   2,  -2 },
-      {  2,  -1,  -2,   0,  -2 },
-      {  1,   1,   4,  -2,   2 },
-      {  1,   1,   2,  -4,   2 },
-      {  1,   0,   2,   3,   2 },
-
-   /* 481-490 */
-      {  1,   0,   0,   4,  -1 },
-      {  0,   0,   0,   4,   2 },
-      {  2,   0,   0,   4,   0 },
-      {  1,   1,  -2,   2,   0 },
-      {  2,   1,   2,   1,   2 },
-      {  2,   1,   2,  -4,   1 },
-      {  2,   0,   2,   1,   1 },
-      {  2,   0,  -4,  -2,  -1 },
-      {  2,   0,  -2,  -6,  -1 },
-      {  2,  -1,   2,  -1,   2 },
-
-   /* 491-500 */
-      {  1,  -2,   2,   0,   1 },
-      {  1,  -2,   0,  -2,   1 },
-      {  1,  -1,   0,  -4,  -1 },
-      {  0,   2,   2,   2,   2 },
-      {  0,   2,  -2,  -4,  -2 },
-      {  0,   1,   2,   3,   2 },
-      {  0,   1,   0,  -4,   1 },
-      {  3,   0,   0,  -2,   1 },
-      {  2,   1,  -2,   0,   1 },
-      {  2,   0,   4,  -2,   1 },
-
-   /* 501-510 */
-      {  2,   0,   0,  -3,  -1 },
-      {  2,  -2,   0,  -2,   1 },
-      {  2,  -1,   2,  -2,   1 },
-      {  1,   0,   0,  -6,  -1 },
-      {  1,  -2,   0,   0,  -1 },
-      {  1,  -2,  -2,  -2,  -1 },
-      {  0,   1,   4,  -2,   1 },
-      {  0,   0,   2,   3,   1 },
-      {  2,  -1,   0,  -1,   0 },
-      {  1,   3,   0,  -2,   0 },
-
-   /* 511-520 */
-      {  0,   3,   0,  -2,   0 },
-      {  2,  -2,   2,  -2,   2 },
-      {  0,   0,   4,  -2,   0 },
-      {  4,  -1,   2,   0,   2 },
-      {  2,   2,  -2,  -4,  -2 },
-      {  4,   1,   2,   0,   2 },
-      {  4,  -1,  -2,  -2,  -2 },
-      {  2,   1,   0,  -2,  -2 },
-      {  2,   1,  -2,  -6,  -2 },
-      {  2,   0,   0,  -1,   1 },
-
-   /* 521-530 */
-      {  2,  -1,  -2,   2,  -1 },
-      {  1,   1,  -2,   2,  -2 },
-      {  1,   1,  -2,  -3,  -2 },
-      {  1,   0,   3,   0,   3 },
-      {  1,   0,  -2,   1,   1 },
-      {  1,   0,  -2,   0,   2 },
-      {  1,  -1,   2,   1,   2 },
-      {  1,  -1,   0,   0,  -2 },
-      {  1,  -1,  -4,   2,  -2 },
-      {  0,   3,  -2,  -2,  -2 },
-
-   /* 531-540 */
-      {  0,   1,   0,   4,   1 },
-      {  0,   0,   4,   2,   2 },
-      {  3,   0,  -2,  -2,   0 },
-      {  2,  -2,   0,   0,   0 },
-      {  1,   1,   2,  -4,   0 },
-      {  1,   1,   0,  -3,   0 },
-      {  1,   0,   2,  -3,   0 },
-      {  1,  -1,   2,  -2,   0 },
-      {  0,   2,   0,   2,   0 },
-      {  0,   0,   2,   4,   0 },
-
-   /* 541-550 */
-      {  1,   0,   1,   0,   0 },
-      {  3,   1,   2,  -2,   1 },
-      {  3,   0,   4,  -2,   2 },
-      {  3,   0,   2,   1,   2 },
-      {  3,   0,   0,   2,  -1 },
-      {  3,   0,   0,   0,   2 },
-      {  3,   0,  -2,   2,  -1 },
-      {  2,   0,   4,  -4,   2 },
-      {  2,   0,   2,  -3,   2 },
-      {  2,   0,   0,   4,   1 },
-
-   /* 551-560 */
-      {  2,   0,   0,  -3,   1 },
-      {  2,   0,  -4,   2,  -1 },
-      {  2,   0,  -2,  -2,   1 },
-      {  2,  -2,   2,   2,   2 },
-      {  2,  -2,   0,  -2,  -2 },
-      {  2,  -1,   0,   2,   1 },
-      {  2,  -1,   0,   2,  -1 },
-      {  1,   1,   2,   4,   2 },
-      {  1,   1,   0,   1,   1 },
-      {  1,   1,   0,   1,  -1 },
-
-   /* 561-570 */
-      {  1,   1,  -2,  -6,  -2 },
-      {  1,   0,   0,  -3,  -1 },
-      {  1,   0,  -4,  -2,  -1 },
-      {  1,   0,  -2,  -6,  -1 },
-      {  1,  -2,   2,   2,   1 },
-      {  1,  -2,  -2,   2,  -1 },
-      {  1,  -1,  -2,  -4,  -1 },
-      {  0,   2,   0,   0,   2 },
-      {  0,   1,   2,  -4,   2 },
-      {  0,   1,  -2,   4,  -1 },
-
-   /* 571-580 */
-      {  5,   0,   0,   0,   0 },
-      {  3,   0,   0,  -3,   0 },
-      {  2,   2,   0,  -4,   0 },
-      {  1,  -1,   2,   2,   0 },
-      {  0,   1,   0,   3,   0 },
-      {  4,   0,  -2,   0,  -1 },
-      {  3,   0,  -2,  -6,  -1 },
-      {  3,   0,  -2,  -1,  -1 },
-      {  2,   1,   2,   2,   1 },
-      {  2,   1,   0,   2,   1 },
-
-   /* 581-590 */
-      {  2,   0,   2,   4,   1 },
-      {  2,   0,   2,  -6,   1 },
-      {  2,   0,   2,  -2,  -1 },
-      {  2,   0,   0,  -6,  -1 },
-      {  2,  -1,  -2,  -2,  -1 },
-      {  1,   2,   2,   0,   1 },
-      {  1,   2,   0,   0,   1 },
-      {  1,   0,   4,   0,   1 },
-      {  1,   0,   2,  -6,   1 },
-      {  1,   0,   2,  -4,  -1 },
-
-   /* 591-600 */
-      {  1,   0,  -1,  -2,  -1 },
-      {  1,  -1,   2,   4,   1 },
-      {  1,  -1,   2,  -3,   1 },
-      {  1,  -1,   0,   4,   1 },
-      {  1,  -1,  -2,   1,  -1 },
-      {  0,   1,   2,  -2,   3 },
-      {  3,   0,   0,  -2,   0 },
-      {  1,   0,   1,  -2,   0 },
-      {  0,   2,   0,  -4,   0 },
-      {  0,   0,   2,  -4,   0 },
-
-   /* 601-610 */
-      {  0,   0,   1,  -1,   0 },
-      {  0,   0,   0,   6,   0 },
-      {  0,   2,   0,   0,  -2 },
-      {  0,   1,  -2,   2,  -3 },
-      {  4,   0,   0,   2,   0 },
-      {  3,   0,   0,  -1,   0 },
-      {  3,  -1,   0,   2,   0 },
-      {  2,   1,   0,   1,   0 },
-      {  2,   1,   0,  -6,   0 },
-      {  2,  -1,   2,   0,   0 },
-
-   /* 611-620 */
-      {  1,   0,   2,  -1,   0 },
-      {  1,  -1,   0,   1,   0 },
-      {  1,  -1,  -2,  -2,   0 },
-      {  0,   1,   2,   2,   0 },
-      {  0,   0,   2,  -3,   0 },
-      {  2,   2,   0,  -2,  -1 },
-      {  2,  -1,  -2,   0,   1 },
-      {  1,   2,   2,  -4,   1 },
-      {  0,   1,   4,  -4,   2 },
-      {  0,   0,   0,   3,   2 },
-
-   /* 621-630 */
-      {  5,   0,   2,   0,   1 },
-      {  4,   1,   2,  -2,   2 },
-      {  4,   0,  -2,  -2,   0 },
-      {  3,   1,   2,   2,   2 },
-      {  3,   1,   0,  -2,   0 },
-      {  3,   1,  -2,  -6,  -2 },
-      {  3,   0,   0,   0,  -2 },
-      {  3,   0,  -2,  -4,  -2 },
-      {  3,  -1,   0,  -3,   0 },
-      {  3,  -1,   0,  -2,   0 },
-
-   /* 631-640 */
-      {  2,   1,   2,   0,   0 },
-      {  2,   1,   2,  -4,   2 },
-      {  2,   1,   2,  -2,   0 },
-      {  2,   1,   0,  -3,   0 },
-      {  2,   1,  -2,   0,  -2 },
-      {  2,   0,   0,  -4,   2 },
-      {  2,   0,   0,  -4,  -2 },
-      {  2,   0,  -2,  -5,  -2 },
-      {  2,  -1,   2,   4,   2 },
-      {  2,  -1,   0,  -2,   2 },
-
-   /* 641-650 */
-      {  1,   3,  -2,  -2,  -2 },
-      {  1,   1,   0,   0,  -2 },
-      {  1,   1,   0,  -6,   0 },
-      {  1,   1,  -2,   1,  -2 },
-      {  1,   1,  -2,  -1,  -2 },
-      {  1,   0,   2,   1,   0 },
-      {  1,   0,   0,   3,   0 },
-      {  1,   0,   0,  -4,   2 },
-      {  1,   0,  -2,   4,  -2 },
-      {  1,  -2,   0,  -1,   0 },
-
-   /* 651-NFLS */
-      {  0,   1,  -4,   2,  -1 },
-      {  1,   0,  -2,   0,  -3 },
-      {  0,   0,   4,  -4,   4 }
-   };
-
-/* Number of frequencies:  luni-solar */
-   static const int NFLS = (int) (sizeof mfals / sizeof (int) / 5);
-
-/* Fundamental-argument multipliers:  planetary terms */
-   static const int mfapl[][14] = {
-
-   /* 1-10 */
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -1,  2,  0,  0,  0,  0,  0 },
-
-   /* 11-20 */
-      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  2, -5,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -1,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -8,  3,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6, -8,  3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
-
-   /* 21-30 */
-      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  1,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  1, -1,  1,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  1 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-
-   /* 31-40 */
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  1 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
-
-   /* 41-50 */
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  0,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -2,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2, -1,  0,  0,  0,  0,  0,  2 },
-      {  1,  0,  0,  0,  0,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  1,  0,  0,  0,  2 },
-
-   /* 51-60 */
-      {  0,  0,  1, -1,  1,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -1,  0,  0,  0,  2 },
-      {  1,  0,  2,  0,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  1 },
-      {  1,  0, -2,  0, -2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-
-   /* 61-70 */
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0,  0,  3, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-11,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0 },
-
-   /* 71-80 */
-      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -2,  0,  0,  0,  2 },
-      {  0,  0,  1, -1,  1,  0,  0, -5,  8, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0,  0 },
-
-   /* 81-90 */
-      {  2,  0,  0, -2,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0, -1 },
-      {  2,  0,  0, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  8,-13,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0, -2,  5,  0,  0,  0 },
-      {  1,  0,  0, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2 },
-      {  1,  0,  0,  0, -1,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  2, -5,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
-
-   /* 91-100 */
-      {  1,  0,  0, -2,  0,  0, 19,-21,  3,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -8, 13,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2 },
-      {  1,  0,  0,  0,  1,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-16,  4,  5,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  3, -7,  0,  0,  0,  0,  0, -2 },
-
-   /* 101-110 */
-      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1 },
-      {  2,  0,  0, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  2 },
-
-   /* 111-120 */
-      {  0,  0,  0,  0,  1,  0,  0,  1, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  2 },
-      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-
-   /* 121-130 */
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-10,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0, -2 },
-      {  1,  0,  0, -1,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-
-   /* 131-140 */
-      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  1,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
-
-   /* 141-150 */
-      {  1,  0,  0, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -4,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  9,-11,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -4,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -1,  0,  0,  0,  2 },
-
-   /* 151-160 */
-      {  1,  0,  0, -1,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1,  1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -4, 10,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0, -2 },
-      {  0,  0,  2, -2,  1,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
-
-   /* 161-170 */
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0, -1,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -3,  0,  0,  0,  0,  2 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  0,  2,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -9, 13,  0,  0,  0,  0,  0 },
-      {  2,  0,  2,  0,  2,  0,  0,  2,  0, -3,  0,  0,  0,  0 },
-
-   /* 171-180 */
-      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
-      {  1,  0,  0, -1, -1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  1 },
-      {  1,  0,  2,  0,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  1,  0, -2,  0, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -2,  4,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0 },
-
-   /* 181-190 */
-      {  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  2,  0,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -8,  3,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  7, -8,  3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  1,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -1,  0,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  1 },
-
-   /* 191-200 */
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7,-10,  0,  0,  0,  0,  0, -2 },
-      {  1,  0,  0, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  2, -5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1,  1,  0,  0, -9, 15,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0 },
-
-   /* 201-210 */
-      {  0,  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -1,  0,  0,  2 },
-      {  2,  0,  0, -2,  1,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1,  1,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  8,-14,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-
-   /* 211-220 */
-      {  0,  0,  0,  0,  1,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  1,  0,  0,  2 },
-      {  2,  0, -1, -1,  0,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
-
-   /* 221-230 */
-      {  2,  0,  0, -2,  0,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  1,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -9,  4,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0, -2 },
-
-   /* 231-240 */
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -4,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  1 },
-      {  0,  0,  0,  0,  0,  0,  7,-11,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  3, -5,  4,  0,  0,  0,  0,  2 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -1,  1,  0,  0,  0 },
-      {  2,  0,  0,  0,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  2,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0, -1 },
-
-   /* 241-250 */
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  2, -4,  0, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  3, -5,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -3,  0,  0,  0,  2 },
-      {  0,  0,  2, -2,  2,  0, -8, 11,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -2,  0,  0,  0 },
-
-   /* 251-260 */
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  2, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0, -2, -2, -2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  1 },
-
-   /* 261-270 */
-      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  2, -5,  0,  0,  2 },
-      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  0,  5,  0,  0,  0 },
-      {  2,  0,  0, -2, -1,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8, -8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  2, -5,  0,  0,  2 },
-      {  0,  0,  0,  0,  1,  0,  3, -7,  4,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-
-   /* 271-280 */
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-15,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  1,  0,  0,  0,  2 },
-      {  1,  0,  0, -1,  0,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -3,  7, -4,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -2,  0,  0,  0,  2 },
-
-   /* 281-290 */
-      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  2, -2,  2,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-11,  0,  0,  0,  0, -2 },
-
-   /* 291-300 */
-      {  0,  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  9,-12,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  1, -1,  0,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0, -1 },
-
-   /* 301-310 */
-      {  0,  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1, -1,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -5,  0,  0,  0,  0, -2 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  3, -1,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0,  2 },
-
-   /* 311-320 */
-      {  0,  0,  0,  0,  0,  0,  9, -9,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  3,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  2, -4,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  1 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  2 },
-      {  0,  0,  2,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-
-   /* 321-330 */
-      {  0,  0,  2,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  0 },
-      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -3,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  5,-10,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  2, -2,  1, -1,  0,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  2,  0,  0 },
-
-   /* 331-340 */
-      {  0,  0,  0,  0,  1,  0,  3, -5,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  9, -9,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -8, 11,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  0,  2,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  2,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  2, -6,  0,  0,  0,  0,  0, -2 },
-
-   /* 341-350 */
-      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -2,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  7,-13,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  3,  0,  0,  0,  2 },
-      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8, -8,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  8,-10,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  1 },
-
-   /* 351-360 */
-      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -4,  0,  0,  0,  0 },
-      {  2,  0,  0, -2, -1,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0, -2 },
-      {  2,  0, -1, -1, -1,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
-
-   /* 361-370 */
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  4, -3,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-11,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  1,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  1,  5,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6, -5,  0,  0,  0,  0,  2 },
-      {  1,  0, -2, -2, -2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  1 },
-
-   /* 371-380 */
-      {  0,  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0,  0, -2,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0, -2,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1, -6,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  7,-13,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  2 },
-
-   /* 381-390 */
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -8, 15,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2, -2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  1,  0,  2, -2,  2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  1,  0, -1,  1, -1,  0,-18, 17,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  2, -2, -1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-
-   /* 391-400 */
-      {  0,  0,  0,  0,  1,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-16,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2 },
-      {  0,  0,  0,  0,  2,  0,  0, -1,  2,  0,  0,  0,  0,  0 },
-      {  2,  0, -1, -1, -2,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -2,  4,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  2 },
-      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  4, -5,  0,  0,  0 },
-
-   /* 401-410 */
-      {  2,  0,  0, -2, -1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -1, -1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-      {  1,  0, -1, -1, -1,  0, 20,-20,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  1, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -2,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  5, -8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, -1,  0,  0,  0 },
-
-   /* 411-420 */
-      {  0,  0,  0,  0,  0,  0,  9,-11,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0, -2,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0 },
-
-   /* 421-430 */
-      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -6,  0,  0,  0,  0, -2 },
-      {  1,  0,  0, -2,  0,  0, 20,-21,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-12,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  8,-12,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  9,-17,  0,  0,  0,  0,  0 },
-
-   /* 431-440 */
-      {  0,  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  1,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -7,  0,  0,  0,  0, -2 },
-      {  1,  0,  0, -1,  1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
-      {  1,  0, -2,  0, -2,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -9, 17,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0,  0, -2 },
-      {  1,  0, -2, -2, -2,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  1,  0, -1,  1, -1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-
-   /* 441-450 */
-      {  0,  0,  2, -2,  2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  2, -2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,-10,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -4,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -5,  0,  0,  0, -2 },
-
-   /* 451-460 */
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -5,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0,  1 },
-      {  1,  0,  0, -2,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -7,  4,  0,  0,  0,  0,  0 },
-      {  2,  0,  2,  0,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1, -1,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  1,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0, -2 },
-
-   /* 461-470 */
-      {  1,  0,  0, -1,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -3,  0,  3,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0, -5,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  1, -3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -4,  6,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0, -1,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
-
-   /* 471-480 */
-      {  0,  0,  0,  0,  1,  0,  3, -4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7,-10,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  3, -8,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  7, -8,  0,  0,  0,  0,  2 },
-
-   /* 481-490 */
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -8,  3,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0, -1 },
-      {  2,  0,  0, -2, -1,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
-      {  2,  0, -1, -1,  1,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -7,  9,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0, -1 },
-
-   /* 491-500 */
-      {  0,  0,  1, -1,  2,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7, -8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  1,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  3, -1,  0,  0,  0 },
-      {  1,  0,  1,  1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  1,  0,  0, -2, -1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-
-   /* 501-510 */
-      {  1,  0,  0, -1, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
-      {  1,  0, -1,  0, -1,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -4,  4,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0, -8, 11,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0,  0,  0, -9, 13,  0,  0,  0,  0,  0 },
-      {  0,  0,  1,  1,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0,  1, -4,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  1, -3,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0,  7,-13,  0,  0,  0,  0,  0 },
-
-   /* 511-520 */
-      {  0,  0,  0,  0,  1,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  7,-11,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  6, -4,  0,  0,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0,  1 },
-
-   /* 521-530 */
-      {  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  9,-17,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-
-   /* 531-540 */
-      {  2,  0,  0, -2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0, 17,-16,  0, -2,  0,  0,  0,  0 },
-      {  1,  0,  0, -1,  0,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -4,  0,  0,  0,  0 },
-
-   /* 541-550 */
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1, -2, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  2 },
-      {  2,  0,  0, -2,  0,  0,  0, -4,  4,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  2,  2,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-
-   /* 551-560 */
-      {  1,  0,  0, -2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0, -4,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  2,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
-
-   /* 561-570 */
-      {  0,  0,  0,  0,  0,  0,  8, -9,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0 },
-      {  2,  0, -2, -2, -2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  1,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0, -1,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
-
-   /* 571-580 */
-      {  0,  0,  2,  0,  2,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  0,  2,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  2,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
-      {  2,  0,  2, -2,  2,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  2,  0,  1, -3,  1,  0, -6,  7,  0,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  2, -5,  0,  0,  0,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  5, -5,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  1,  5,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  0,  5,  0,  0,  0 },
-
-   /* 581-590 */
-      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  0,  2,  0,  0,  0 },
-      {  2,  0,  0, -2,  0,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
-      {  2,  0, -2,  0, -2,  0,  0,  5, -9,  0,  0,  0,  0,  0 },
-      {  2,  0, -1, -1,  0,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
-      {  1,  0,  2,  0,  2,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  2,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
-      {  1,  0,  2,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
-      {  1,  0,  2,  0,  2,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  2, -2,  2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
-      {  1,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-
-   /* 591-600 */
-      {  1,  0,  0,  0,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
-      {  1,  0,  0, -2,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
-      {  1,  0, -2, -2, -2,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
-      {  1,  0, -1,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  1,  0, -1, -1,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
-      {  0,  0,  2,  2,  2,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  1,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  1,  0,  0,-10, 15,  0,  0,  0,  0,  0 },
-      {  0,  0,  2, -2,  0, -1,  0,  2,  0,  0,  0,  0,  0,  0 },
-
-   /* 601-610 */
-      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
-      {  0,  0,  1, -1,  2,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -4,  6,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  1,  0, -1,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0, -2,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  1, -1, -1,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  2,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
-
-   /* 611-620 */
-      {  0,  0,  0,  2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  2,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  1,  0, -1,  2,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  9,-13,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  8,-14,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  8,-11,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0, -2 },
-
-   /* 621-630 */
-      {  0,  0,  0,  0,  0,  0,  5, -6, -4,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  5, -4,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  2,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  7,-12,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0, -2 },
-
-   /* 631-640 */
-      {  0,  0,  0,  0,  0,  0,  0,  6, -8,  1,  5,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6, -4,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -4,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0, -1 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  3,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,-16,  4,  5,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  5,-13,  0,  0,  0,  0, -2 },
-
-   /* 641-650 */
-      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -5,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -9,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  3, -7,  0,  0,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -3,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  2, -8,  1,  5,  0,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1, -5,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -3,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  5,  0,  0,  0 },
-
-   /* 651-NFPL */
-      {  0,  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -6,  3,  0, -2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2 },
-      {  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0 }
-   };
-
-/* Number of frequencies:  planetary */
-   static const int NFPL = (int) (sizeof mfapl / sizeof (int) / 14);
-
-/* Pointers into amplitudes array, one pointer per frequency */
-   static const int nc[] = {
-
-   /* 1-100 */
-       1,    21,    37,    51,    65,    79,    91,   103,   115,   127,
-     139,   151,   163,   172,   184,   196,   207,   219,   231,   240,
-     252,   261,   273,   285,   297,   309,   318,   327,   339,   351,
-     363,   372,   384,   396,   405,   415,   423,   435,   444,   452,
-     460,   467,   474,   482,   490,   498,   506,   513,   521,   528,
-     536,   543,   551,   559,   566,   574,   582,   590,   597,   605,
-     613,   620,   628,   636,   644,   651,   658,   666,   674,   680,
-     687,   695,   702,   710,   717,   725,   732,   739,   746,   753,
-     760,   767,   774,   782,   790,   798,   805,   812,   819,   826,
-     833,   840,   846,   853,   860,   867,   874,   881,   888,   895,
-
-   /* 101-200 */
-     901,   908,   914,   921,   928,   934,   941,   948,   955,   962,
-     969,   976,   982,   989,   996,  1003,  1010,  1017,  1024,  1031,
-    1037,  1043,  1050,  1057,  1064,  1071,  1078,  1084,  1091,  1098,
-    1104,  1112,  1118,  1124,  1131,  1138,  1145,  1151,  1157,  1164,
-    1171,  1178,  1185,  1192,  1199,  1205,  1212,  1218,  1226,  1232,
-    1239,  1245,  1252,  1259,  1266,  1272,  1278,  1284,  1292,  1298,
-    1304,  1310,  1316,  1323,  1329,  1335,  1341,  1347,  1353,  1359,
-    1365,  1371,  1377,  1383,  1389,  1396,  1402,  1408,  1414,  1420,
-    1426,  1434,  1440,  1446,  1452,  1459,  1465,  1471,  1477,  1482,
-    1488,  1493,  1499,  1504,  1509,  1514,  1520,  1527,  1532,  1538,
-
-   /* 201-300 */
-    1543,  1548,  1553,  1558,  1564,  1569,  1574,  1579,  1584,  1589,
-    1594,  1596,  1598,  1600,  1602,  1605,  1608,  1610,  1612,  1617,
-    1619,  1623,  1625,  1627,  1629,  1632,  1634,  1640,  1642,  1644,
-    1646,  1648,  1650,  1652,  1654,  1658,  1660,  1662,  1664,  1668,
-    1670,  1672,  1673,  1675,  1679,  1681,  1683,  1684,  1686,  1688,
-    1690,  1693,  1695,  1697,  1701,  1703,  1705,  1707,  1709,  1711,
-    1712,  1715,  1717,  1721,  1723,  1725,  1727,  1729,  1731,  1733,
-    1735,  1737,  1739,  1741,  1743,  1745,  1747,  1749,  1751,  1753,
-    1755,  1757,  1759,  1761,  1762,  1764,  1766,  1768,  1769,  1771,
-    1773,  1775,  1777,  1779,  1781,  1783,  1785,  1787,  1788,  1790,
-
-   /* 301-400 */
-    1792,  1794,  1796,  1798,  1800,  1802,  1804,  1806,  1807,  1809,
-    1811,  1815,  1817,  1819,  1821,  1823,  1825,  1827,  1829,  1831,
-    1833,  1835,  1837,  1839,  1840,  1842,  1844,  1848,  1850,  1852,
-    1854,  1856,  1858,  1859,  1860,  1862,  1864,  1866,  1868,  1869,
-    1871,  1873,  1875,  1877,  1879,  1881,  1883,  1885,  1887,  1889,
-    1891,  1892,  1896,  1898,  1900,  1901,  1903,  1905,  1907,  1909,
-    1910,  1911,  1913,  1915,  1919,  1921,  1923,  1927,  1929,  1931,
-    1933,  1935,  1937,  1939,  1943,  1945,  1947,  1948,  1949,  1951,
-    1953,  1955,  1957,  1958,  1960,  1962,  1964,  1966,  1968,  1970,
-    1971,  1973,  1974,  1975,  1977,  1979,  1980,  1981,  1982,  1984,
-
-   /* 401-500 */
-    1986,  1988,  1990,  1992,  1994,  1995,  1997,  1999,  2001,  2003,
-    2005,  2007,  2008,  2009,  2011,  2013,  2015,  2017,  2019,  2021,
-    2023,  2024,  2025,  2027,  2029,  2031,  2033,  2035,  2037,  2041,
-    2043,  2045,  2046,  2047,  2049,  2051,  2053,  2055,  2056,  2057,
-    2059,  2061,  2063,  2065,  2067,  2069,  2070,  2071,  2072,  2074,
-    2076,  2078,  2080,  2082,  2084,  2086,  2088,  2090,  2092,  2094,
-    2095,  2096,  2097,  2099,  2101,  2105,  2106,  2107,  2108,  2109,
-    2110,  2111,  2113,  2115,  2119,  2121,  2123,  2125,  2127,  2129,
-    2131,  2133,  2135,  2136,  2137,  2139,  2141,  2143,  2145,  2147,
-    2149,  2151,  2153,  2155,  2157,  2159,  2161,  2163,  2165,  2167,
-
-   /* 501-600 */
-    2169,  2171,  2173,  2175,  2177,  2179,  2181,  2183,  2185,  2186,
-    2187,  2188,  2192,  2193,  2195,  2197,  2199,  2201,  2203,  2205,
-    2207,  2209,  2211,  2213,  2217,  2219,  2221,  2223,  2225,  2227,
-    2229,  2231,  2233,  2234,  2235,  2236,  2237,  2238,  2239,  2240,
-    2241,  2244,  2246,  2248,  2250,  2252,  2254,  2256,  2258,  2260,
-    2262,  2264,  2266,  2268,  2270,  2272,  2274,  2276,  2278,  2280,
-    2282,  2284,  2286,  2288,  2290,  2292,  2294,  2296,  2298,  2300,
-    2302,  2303,  2304,  2305,  2306,  2307,  2309,  2311,  2313,  2315,
-    2317,  2319,  2321,  2323,  2325,  2327,  2329,  2331,  2333,  2335,
-    2337,  2341,  2343,  2345,  2347,  2349,  2351,  2352,  2355,  2356,
-
-   /* 601-700 */
-    2357,  2358,  2359,  2361,  2363,  2364,  2365,  2366,  2367,  2368,
-    2369,  2370,  2371,  2372,  2373,  2374,  2376,  2378,  2380,  2382,
-    2384,  2385,  2386,  2387,  2388,  2389,  2390,  2391,  2392,  2393,
-    2394,  2395,  2396,  2397,  2398,  2399,  2400,  2401,  2402,  2403,
-    2404,  2405,  2406,  2407,  2408,  2409,  2410,  2411,  2412,  2413,
-    2414,  2415,  2417,  2418,  2430,  2438,  2445,  2453,  2460,  2468,
-    2474,  2480,  2488,  2496,  2504,  2512,  2520,  2527,  2535,  2543,
-    2550,  2558,  2566,  2574,  2580,  2588,  2596,  2604,  2612,  2619,
-    2627,  2634,  2642,  2648,  2656,  2664,  2671,  2679,  2685,  2693,
-    2701,  2709,  2717,  2725,  2733,  2739,  2747,  2753,  2761,  2769,
-
-   /* 701-800 */
-    2777,  2785,  2793,  2801,  2809,  2817,  2825,  2833,  2841,  2848,
-    2856,  2864,  2872,  2878,  2884,  2892,  2898,  2906,  2914,  2922,
-    2930,  2938,  2944,  2952,  2958,  2966,  2974,  2982,  2988,  2996,
-    3001,  3009,  3017,  3025,  3032,  3039,  3045,  3052,  3059,  3067,
-    3069,  3076,  3083,  3090,  3098,  3105,  3109,  3111,  3113,  3120,
-    3124,  3128,  3132,  3136,  3140,  3144,  3146,  3150,  3158,  3161,
-    3165,  3166,  3168,  3172,  3176,  3180,  3182,  3185,  3189,  3193,
-    3194,  3197,  3200,  3204,  3208,  3212,  3216,  3219,  3221,  3222,
-    3226,  3230,  3234,  3238,  3242,  3243,  3247,  3251,  3254,  3258,
-    3262,  3266,  3270,  3274,  3275,  3279,  3283,  3287,  3289,  3293,
-
-   /* 801-900 */
-    3296,  3300,  3303,  3307,  3311,  3315,  3319,  3321,  3324,  3327,
-    3330,  3334,  3338,  3340,  3342,  3346,  3350,  3354,  3358,  3361,
-    3365,  3369,  3373,  3377,  3381,  3385,  3389,  3393,  3394,  3398,
-    3402,  3406,  3410,  3413,  3417,  3421,  3425,  3429,  3433,  3435,
-    3439,  3443,  3446,  3450,  3453,  3457,  3458,  3461,  3464,  3468,
-    3472,  3476,  3478,  3481,  3485,  3489,  3493,  3497,  3501,  3505,
-    3507,  3511,  3514,  3517,  3521,  3524,  3525,  3527,  3529,  3533,
-    3536,  3540,  3541,  3545,  3548,  3551,  3555,  3559,  3563,  3567,
-    3569,  3570,  3574,  3576,  3578,  3582,  3586,  3590,  3593,  3596,
-    3600,  3604,  3608,  3612,  3616,  3620,  3623,  3626,  3630,  3632,
-
-   /* 901-1000 */
-    3636,  3640,  3643,  3646,  3648,  3652,  3656,  3660,  3664,  3667,
-    3669,  3671,  3675,  3679,  3683,  3687,  3689,  3693,  3694,  3695,
-    3699,  3703,  3705,  3707,  3710,  3713,  3717,  3721,  3725,  3729,
-    3733,  3736,  3740,  3744,  3748,  3752,  3754,  3757,  3759,  3763,
-    3767,  3770,  3773,  3777,  3779,  3783,  3786,  3790,  3794,  3798,
-    3801,  3805,  3809,  3813,  3817,  3821,  3825,  3827,  3831,  3835,
-    3836,  3837,  3840,  3844,  3848,  3852,  3856,  3859,  3863,  3867,
-    3869,  3871,  3875,  3879,  3883,  3887,  3890,  3894,  3898,  3901,
-    3905,  3909,  3913,  3917,  3921,  3922,  3923,  3924,  3926,  3930,
-    3932,  3936,  3938,  3940,  3944,  3948,  3952,  3956,  3959,  3963,
-
-   /* 1001-1100 */
-    3965,  3969,  3973,  3977,  3979,  3981,  3982,  3986,  3989,  3993,
-    3997,  4001,  4004,  4006,  4009,  4012,  4016,  4020,  4024,  4026,
-    4028,  4032,  4036,  4040,  4044,  4046,  4050,  4054,  4058,  4060,
-    4062,  4063,  4064,  4068,  4071,  4075,  4077,  4081,  4083,  4087,
-    4089,  4091,  4095,  4099,  4101,  4103,  4105,  4107,  4111,  4115,
-    4119,  4123,  4127,  4129,  4131,  4135,  4139,  4141,  4143,  4145,
-    4149,  4153,  4157,  4161,  4165,  4169,  4173,  4177,  4180,  4183,
-    4187,  4191,  4195,  4198,  4201,  4205,  4209,  4212,  4213,  4216,
-    4217,  4221,  4223,  4226,  4230,  4234,  4236,  4240,  4244,  4248,
-    4252,  4256,  4258,  4262,  4264,  4266,  4268,  4270,  4272,  4276,
-
-   /* 1101-1200 */
-    4279,  4283,  4285,  4287,  4289,  4293,  4295,  4299,  4300,  4301,
-    4305,  4309,  4313,  4317,  4319,  4323,  4325,  4329,  4331,  4333,
-    4335,  4337,  4341,  4345,  4349,  4351,  4353,  4357,  4361,  4365,
-    4367,  4369,  4373,  4377,  4381,  4383,  4387,  4389,  4391,  4395,
-    4399,  4403,  4407,  4411,  4413,  4414,  4415,  4418,  4419,  4421,
-    4423,  4427,  4429,  4431,  4433,  4435,  4437,  4439,  4443,  4446,
-    4450,  4452,  4456,  4458,  4460,  4462,  4466,  4469,  4473,  4477,
-    4481,  4483,  4487,  4489,  4491,  4493,  4497,  4499,  4501,  4504,
-    4506,  4510,  4513,  4514,  4515,  4518,  4521,  4522,  4525,  4526,
-    4527,  4530,  4533,  4534,  4537,  4541,  4542,  4543,  4544,  4545,
-
-   /* 1201-1300 */
-    4546,  4547,  4550,  4553,  4554,  4555,  4558,  4561,  4564,  4567,
-    4568,  4571,  4574,  4575,  4578,  4581,  4582,  4585,  4586,  4588,
-    4590,  4592,  4596,  4598,  4602,  4604,  4608,  4612,  4613,  4616,
-    4619,  4622,  4623,  4624,  4625,  4626,  4629,  4632,  4633,  4636,
-    4639,  4640,  4641,  4642,  4643,  4644,  4645,  4648,  4649,  4650,
-    4651,  4652,  4653,  4656,  4657,  4660,  4661,  4664,  4667,  4670,
-    4671,  4674,  4675,  4676,  4677,  4678,  4681,  4682,  4683,  4684,
-    4687,  4688,  4689,  4692,  4693,  4696,  4697,  4700,  4701,  4702,
-    4703,  4704,  4707,  4708,  4711,  4712,  4715,  4716,  4717,  4718,
-    4719,  4720,  4721,  4722,  4723,  4726,  4729,  4730,  4733,  4736,
-
-   /* 1301-(NFLS+NFPL) */
-    4737,  4740,  4741,  4742,  4745,  4746,  4749,  4752,  4753
-   };
-
-/* Amplitude coefficients (microarcsec);  indexed using the nc array. */
-   static const double a[] = {
-
-   /* 1-105 */
-         -6844318.44,     9205236.26,1328.67,1538.18,      205833.11,
-           153041.79,       -3309.73, 853.32,2037.98,       -2301.27,
-       81.46, 120.56, -20.39, -15.22,   1.73,  -1.61,  -0.10,   0.11,
-       -0.02,  -0.02,     -523908.04,      573033.42,-544.75,-458.66,
-            12814.01,       11714.49, 198.97,-290.91, 155.74,-143.27,
-       -2.75,  -1.03,  -1.27,  -1.16,   0.00,  -0.01,      -90552.22,
-            97846.69, 111.23, 137.41,2187.91,2024.68,  41.44, -51.26,
-       26.92, -24.46,  -0.46,  -0.28,  -0.22,  -0.20,       82168.76,
-           -89618.24, -27.64, -29.05,       -2004.36,       -1837.32,
-      -36.07,  48.00, -24.43,  22.41,   0.47,   0.24,   0.20,   0.18,
-            58707.02,7387.02, 470.05,-192.40, 164.33,       -1312.21,
-     -179.73, -28.93, -17.36,  -1.83,  -0.50,   3.57,   0.00,   0.13,
-           -20557.78,       22438.42, -20.84, -17.40, 501.82, 459.68,
-       59.20, -67.30,   6.08,  -5.61,  -1.36,  -1.19,       28288.28,
-     -674.99, -34.69,  35.80, -15.07,-632.54, -11.19,   0.78,  -8.41,
-        0.17,   0.01,   0.07,      -15406.85,       20069.50,  15.12,
-
-   /* 106-219 */
-       31.80, 448.76, 344.50,  -5.77,   1.41,   4.59,  -5.02,   0.17,
-        0.24,      -11991.74,       12902.66,  32.46,  36.70, 288.49,
-      268.14,   5.70,  -7.06,   3.57,  -3.23,  -0.06,  -0.04,
-            -8584.95,       -9592.72,   4.42, -13.20,-214.50, 192.06,
-       23.87,  29.83,   2.54,   2.40,   0.60,  -0.48,5095.50,
-            -6918.22,   7.19,   3.92,-154.91,-113.94,   2.86,  -1.04,
-       -1.52,   1.73,  -0.07,  -0.10,       -4910.93,       -5331.13,
-        0.76,   0.40,-119.21, 109.81,   2.16,   3.20,   1.46,   1.33,
-        0.04,  -0.02,       -6245.02,-123.48,  -6.68,  -8.20,  -2.76,
-      139.64,   2.71,   0.15,   1.86,2511.85,       -3323.89,   1.07,
-       -0.90, -74.33, -56.17,   1.16,  -0.01,  -0.75,   0.83,  -0.02,
-       -0.04,2307.58,3143.98,  -7.52,   7.50,  70.31, -51.60,   1.46,
-        0.16,  -0.69,  -0.79,   0.02,  -0.05,2372.58,2554.51,   5.93,
-       -6.60,  57.12, -53.05,  -0.96,  -1.24,  -0.71,  -0.64,  -0.01,
-            -2053.16,2636.13,   5.13,   7.80,  58.94,  45.91,  -0.42,
-       -0.12,   0.61,  -0.66,   0.02,   0.03,       -1825.49,
-
-   /* 220-339 */
-            -2423.59,   1.23,  -2.00, -54.19,  40.82,  -1.07,  -1.02,
-        0.54,   0.61,  -0.04,   0.04,2521.07,-122.28,  -5.97,   2.90,
-       -2.73, -56.37,  -0.82,   0.13,  -0.75,       -1534.09,1645.01,
-        6.29,   6.80,  36.78,  34.30,   0.92,  -1.25,   0.46,  -0.41,
-       -0.02,  -0.01,1898.27,  47.70,  -0.72,   2.50,   1.07, -42.45,
-       -0.94,   0.02,  -0.56,       -1292.02,       -1387.00,   0.00,
-        0.00, -31.01,  28.89,   0.68,   0.00,   0.38,   0.35,  -0.01,
-       -0.01,       -1234.96,1323.81,   5.21,   5.90,  29.60,  27.61,
-        0.74,  -1.22,   0.37,  -0.33,  -0.02,  -0.01,1137.48,
-            -1233.89,  -0.04,  -0.30, -27.59, -25.43,  -0.61,   1.00,
-       -0.34,   0.31,   0.01,   0.01,-813.13,       -1075.60,   0.40,
-        0.30, -24.05,  18.18,  -0.40,  -0.01,   0.24,   0.27,  -0.01,
-        0.01,1163.22, -60.90,  -2.94,   1.30,  -1.36, -26.01,  -0.58,
-        0.07,  -0.35,1029.70, -55.55,  -2.63,   1.10,  -1.25, -23.02,
-       -0.52,   0.06,  -0.31,-556.26, 852.85,   3.16,  -4.48,  19.06,
-       12.44,  -0.81,  -0.27,   0.17,  -0.21,   0.00,   0.02,-603.52,
-
-   /* 340-467 */
-     -800.34,   0.44,   0.10, -17.90,  13.49,  -0.08,  -0.01,   0.18,
-        0.20,  -0.01,   0.01,-628.24, 684.99,  -0.64,  -0.50,  15.32,
-       14.05,   3.18,  -4.19,   0.19,  -0.17,  -0.09,  -0.07,-866.48,
-      -16.26,   0.52,  -1.30,  -0.36,  19.37,   0.43,  -0.01,   0.26,
-     -512.37, 695.54,  -1.47,  -1.40,  15.55,  11.46,  -0.16,   0.03,
-        0.15,  -0.17,   0.01,   0.01, 506.65, 643.75,   2.54,  -2.62,
-       14.40, -11.33,  -0.77,  -0.06,  -0.15,  -0.16,   0.00,   0.01,
-      664.57,  16.81,  -0.40,   1.00,   0.38, -14.86,  -3.71,  -0.09,
-       -0.20, 405.91, 522.11,   0.99,  -1.50,  11.67,  -9.08,  -0.25,
-       -0.02,  -0.12,  -0.13,-305.78, 326.60,   1.75,   1.90,   7.30,
-        6.84,   0.20,  -0.04, 300.99,-325.03,  -0.44,  -0.50,  -7.27,
-       -6.73,  -1.01,   0.01,   0.00,   0.08,   0.00,   0.02, 438.51,
-       10.47,  -0.56,  -0.20,   0.24,  -9.81,  -0.24,   0.01,  -0.13,
-     -264.02, 335.24,   0.99,   1.40,   7.49,   5.90,  -0.27,  -0.02,
-      284.09, 307.03,   0.32,  -0.40,   6.87,  -6.35,  -0.99,  -0.01,
-     -250.54, 327.11,   0.08,   0.40,   7.31,   5.60,  -0.30, 230.72,
-
-   /* 468-595 */
-     -304.46,   0.08,  -0.10,  -6.81,  -5.16,   0.27, 229.78, 304.17,
-       -0.60,   0.50,   6.80,  -5.14,   0.33,   0.01, 256.30,-276.81,
-       -0.28,  -0.40,  -6.19,  -5.73,  -0.14,   0.01,-212.82, 269.45,
-        0.84,   1.20,   6.02,   4.76,   0.14,  -0.02, 196.64, 272.05,
-       -0.84,   0.90,   6.08,  -4.40,   0.35,   0.02, 188.95, 272.22,
-       -0.12,   0.30,   6.09,  -4.22,   0.34,-292.37,  -5.10,  -0.32,
-       -0.40,  -0.11,   6.54,   0.14,   0.01, 161.79,-220.67,   0.24,
-        0.10,  -4.93,  -3.62,  -0.08, 261.54, -19.94,  -0.95,   0.20,
-       -0.45,  -5.85,  -0.13,   0.02, 142.16,-190.79,   0.20,   0.10,
-       -4.27,  -3.18,  -0.07, 187.95,  -4.11,  -0.24,   0.30,  -0.09,
-       -4.20,  -0.09,   0.01,   0.00,   0.00, -79.08, 167.90,   0.04,
-        0.00,   3.75,   1.77, 121.98, 131.04,  -0.08,   0.10,   2.93,
-       -2.73,  -0.06,-172.95,  -8.11,  -0.40,  -0.20,  -0.18,   3.87,
-        0.09,   0.01,-160.15, -55.30, -14.04,  13.90,  -1.23,   3.58,
-        0.40,   0.31,-115.40, 123.20,   0.60,   0.70,   2.75,   2.58,
-        0.08,  -0.01,-168.26,  -2.00,   0.20,  -0.20,  -0.04,   3.76,
-
-   /* 596-723 */
-        0.08,-114.49, 123.20,   0.32,   0.40,   2.75,   2.56,   0.07,
-       -0.01, 112.14, 120.70,   0.28,  -0.30,   2.70,  -2.51,  -0.07,
-       -0.01, 161.34,   4.03,   0.20,   0.20,   0.09,  -3.61,  -0.08,
-       91.31, 126.64,  -0.40,   0.40,   2.83,  -2.04,  -0.04,   0.01,
-      105.29, 112.90,   0.44,  -0.50,   2.52,  -2.35,  -0.07,  -0.01,
-       98.69,-106.20,  -0.28,  -0.30,  -2.37,  -2.21,  -0.06,   0.01,
-       86.74,-112.94,  -0.08,  -0.20,  -2.53,  -1.94,  -0.05,-134.81,
-        3.51,   0.20,  -0.20,   0.08,   3.01,   0.07,  79.03, 107.31,
-       -0.24,   0.20,   2.40,  -1.77,  -0.04,   0.01, 132.81, -10.77,
-       -0.52,   0.10,  -0.24,  -2.97,  -0.07,   0.01,-130.31,  -0.90,
-        0.04,   0.00,   0.00,   2.91, -78.56,  85.32,   0.00,   0.00,
-        1.91,   1.76,   0.04,   0.00,   0.00, -41.53,  89.10,   0.02,
-        0.00,   1.99,   0.93,  66.03, -71.00,  -0.20,  -0.20,  -1.59,
-       -1.48,  -0.04,  60.50,  64.70,   0.36,  -0.40,   1.45,  -1.35,
-       -0.04,  -0.01, -52.27, -70.01,   0.00,   0.00,  -1.57,   1.17,
-        0.03, -52.95,  66.29,   0.32,   0.40,   1.48,   1.18,   0.04,
-
-   /* 724-851 */
-       -0.01,  51.02,  67.25,   0.00,   0.00,   1.50,  -1.14,  -0.03,
-      -55.66, -60.92,   0.16,  -0.20,  -1.36,   1.24,   0.03, -54.81,
-      -59.20,  -0.08,   0.20,  -1.32,   1.23,   0.03,  51.32, -55.60,
-        0.00,   0.00,  -1.24,  -1.15,  -0.03,  48.29,  51.80,   0.20,
-       -0.20,   1.16,  -1.08,  -0.03, -45.59, -49.00,  -0.12,   0.10,
-       -1.10,   1.02,   0.03,  40.54, -52.69,  -0.04,  -0.10,  -1.18,
-       -0.91,  -0.02, -40.58, -49.51,  -1.00,   1.00,  -1.11,   0.91,
-        0.04,   0.02, -43.76,  46.50,   0.36,   0.40,   1.04,   0.98,
-        0.03,  -0.01,  62.65,  -5.00,  -0.24,   0.00,  -0.11,  -1.40,
-       -0.03,   0.01, -38.57,  49.59,   0.08,   0.10,   1.11,   0.86,
-        0.02, -33.22, -44.04,   0.08,  -0.10,  -0.98,   0.74,   0.02,
-       37.15, -39.90,  -0.12,  -0.10,  -0.89,  -0.83,  -0.02,  36.68,
-      -39.50,  -0.04,  -0.10,  -0.88,  -0.82,  -0.02, -53.22,  -3.91,
-       -0.20,   0.00,  -0.09,   1.19,   0.03,  32.43, -42.19,  -0.04,
-       -0.10,  -0.94,  -0.73,  -0.02, -51.00,  -2.30,  -0.12,  -0.10,
-        0.00,   1.14, -29.53, -39.11,   0.04,   0.00,  -0.87,   0.66,
-
-   /* 852-979 */
-        0.02,  28.50, -38.92,  -0.08,  -0.10,  -0.87,  -0.64,  -0.02,
-       26.54,  36.95,  -0.12,   0.10,   0.83,  -0.59,  -0.01,  26.54,
-       34.59,   0.04,  -0.10,   0.77,  -0.59,  -0.02,  28.35, -32.55,
-       -0.16,   0.20,  -0.73,  -0.63,  -0.01, -28.00,  30.40,   0.00,
-        0.00,   0.68,   0.63,   0.01, -27.61,  29.40,   0.20,   0.20,
-        0.66,   0.62,   0.02,  40.33,   0.40,  -0.04,   0.10,   0.00,
-       -0.90, -23.28,  31.61,  -0.08,  -0.10,   0.71,   0.52,   0.01,
-       37.75,   0.80,   0.04,   0.10,   0.00,  -0.84,  23.66,  25.80,
-        0.00,   0.00,   0.58,  -0.53,  -0.01,  21.01, -27.91,   0.00,
-        0.00,  -0.62,  -0.47,  -0.01, -34.81,   2.89,   0.04,   0.00,
-        0.00,   0.78, -23.49, -25.31,   0.00,   0.00,  -0.57,   0.53,
-        0.01, -23.47,  25.20,   0.16,   0.20,   0.56,   0.52,   0.02,
-       19.58,  27.50,  -0.12,   0.10,   0.62,  -0.44,  -0.01, -22.67,
-      -24.40,  -0.08,   0.10,  -0.55,   0.51,   0.01, -19.97,  25.00,
-        0.12,   0.20,   0.56,   0.45,   0.01,  21.28, -22.80,  -0.08,
-       -0.10,  -0.51,  -0.48,  -0.01, -30.47,   0.91,   0.04,   0.00,
-
-   /* 980-1107 */
-        0.00,   0.68,  18.58,  24.00,   0.04,  -0.10,   0.54,  -0.42,
-       -0.01, -18.02,  24.40,  -0.04,  -0.10,   0.55,   0.40,   0.01,
-       17.74,  22.50,   0.08,  -0.10,   0.50,  -0.40,  -0.01, -19.41,
-       20.70,   0.08,   0.10,   0.46,   0.43,   0.01, -18.64,  20.11,
-        0.00,   0.00,   0.45,   0.42,   0.01, -16.75,  21.60,   0.04,
-        0.10,   0.48,   0.37,   0.01, -18.42, -20.00,   0.00,   0.00,
-       -0.45,   0.41,   0.01, -26.77,   1.41,   0.08,   0.00,   0.00,
-        0.60, -26.17,  -0.19,   0.00,   0.00,   0.00,   0.59, -15.52,
-       20.51,   0.00,   0.00,   0.46,   0.35,   0.01, -25.42,  -1.91,
-       -0.08,   0.00,  -0.04,   0.57,   0.45, -17.42,  18.10,   0.00,
-        0.00,   0.40,   0.39,   0.01,  16.39, -17.60,  -0.08,  -0.10,
-       -0.39,  -0.37,  -0.01, -14.37,  18.91,   0.00,   0.00,   0.42,
-        0.32,   0.01,  23.39,  -2.40,  -0.12,   0.00,   0.00,  -0.52,
-       14.32, -18.50,  -0.04,  -0.10,  -0.41,  -0.32,  -0.01,  15.69,
-       17.08,   0.00,   0.00,   0.38,  -0.35,  -0.01, -22.99,   0.50,
-        0.04,   0.00,   0.00,   0.51,   0.00,   0.00,  14.47, -17.60,
-
-   /* 1108-1235 */
-       -0.01,   0.00,  -0.39,  -0.32, -13.33,  18.40,  -0.04,  -0.10,
-        0.41,   0.30,  22.47,  -0.60,  -0.04,   0.00,   0.00,  -0.50,
-      -12.78, -17.41,   0.04,   0.00,  -0.39,   0.29,   0.01, -14.10,
-      -15.31,   0.04,   0.00,  -0.34,   0.32,   0.01,  11.98,  16.21,
-       -0.04,   0.00,   0.36,  -0.27,  -0.01,  19.65,  -1.90,  -0.08,
-        0.00,   0.00,  -0.44,  19.61,  -1.50,  -0.08,   0.00,   0.00,
-       -0.44,  13.41, -14.30,  -0.04,  -0.10,  -0.32,  -0.30,  -0.01,
-      -13.29,  14.40,   0.00,   0.00,   0.32,   0.30,   0.01,  11.14,
-      -14.40,  -0.04,   0.00,  -0.32,  -0.25,  -0.01,  12.24, -13.38,
-        0.04,   0.00,  -0.30,  -0.27,  -0.01,  10.07, -13.81,   0.04,
-        0.00,  -0.31,  -0.23,  -0.01,  10.46,  13.10,   0.08,  -0.10,
-        0.29,  -0.23,  -0.01,  16.55,  -1.71,  -0.08,   0.00,   0.00,
-       -0.37,   9.75, -12.80,   0.00,   0.00,  -0.29,  -0.22,  -0.01,
-        9.11,  12.80,   0.00,   0.00,   0.29,  -0.20,   0.00,   0.00,
-       -6.44, -13.80,   0.00,   0.00,  -0.31,   0.14,  -9.19, -12.00,
-        0.00,   0.00,  -0.27,   0.21, -10.30,  10.90,   0.08,   0.10,
-
-   /* 1236-1363 */
-        0.24,   0.23,   0.01,  14.92,  -0.80,  -0.04,   0.00,   0.00,
-       -0.33,  10.02, -10.80,   0.00,   0.00,  -0.24,  -0.22,  -0.01,
-       -9.75,  10.40,   0.04,   0.00,   0.23,   0.22,   0.01,   9.67,
-      -10.40,  -0.04,   0.00,  -0.23,  -0.22,  -0.01,  -8.28, -11.20,
-        0.04,   0.00,  -0.25,   0.19,  13.32,  -1.41,  -0.08,   0.00,
-        0.00,  -0.30,   8.27,  10.50,   0.04,   0.00,   0.23,  -0.19,
-        0.00,   0.00,  13.13,   0.00,   0.00,   0.00,   0.00,  -0.29,
-      -12.93,   0.70,   0.04,   0.00,   0.00,   0.29,   7.91, -10.20,
-        0.00,   0.00,  -0.23,  -0.18,  -7.84, -10.00,  -0.04,   0.00,
-       -0.22,   0.18,   7.44,   9.60,   0.00,   0.00,   0.21,  -0.17,
-       -7.64,   9.40,   0.08,   0.10,   0.21,   0.17,   0.01, -11.38,
-        0.60,   0.04,   0.00,   0.00,   0.25,  -7.48,   8.30,   0.00,
-        0.00,   0.19,   0.17, -10.98,  -0.20,   0.00,   0.00,   0.00,
-        0.25,  10.98,   0.20,   0.00,   0.00,   0.00,  -0.25,   7.40,
-       -7.90,  -0.04,   0.00,  -0.18,  -0.17,  -6.09,   8.40,  -0.04,
-        0.00,   0.19,   0.14,  -6.94,  -7.49,   0.00,   0.00,  -0.17,
-
-   /* 1364-1491 */
-        0.16,   6.92,   7.50,   0.04,   0.00,   0.17,  -0.15,   6.20,
-        8.09,   0.00,   0.00,   0.18,  -0.14,  -6.12,   7.80,   0.04,
-        0.00,   0.17,   0.14,   5.85,  -7.50,   0.00,   0.00,  -0.17,
-       -0.13,  -6.48,   6.90,   0.08,   0.10,   0.15,   0.14,   0.01,
-        6.32,   6.90,   0.00,   0.00,   0.15,  -0.14,   5.61,  -7.20,
-        0.00,   0.00,  -0.16,  -0.13,   9.07,   0.00,   0.00,   0.00,
-        0.00,  -0.20,   5.25,   6.90,   0.00,   0.00,   0.15,  -0.12,
-       -8.47,  -0.40,   0.00,   0.00,   0.00,   0.19,   6.32,  -5.39,
-       -1.11,   1.10,  -0.12,  -0.14,   0.02,   0.02,   5.73,  -6.10,
-       -0.04,   0.00,  -0.14,  -0.13,   4.70,   6.60,  -0.04,   0.00,
-        0.15,  -0.11,  -4.90,  -6.40,   0.00,   0.00,  -0.14,   0.11,
-       -5.33,   5.60,   0.04,   0.10,   0.13,   0.12,   0.01,  -4.81,
-        6.00,   0.04,   0.00,   0.13,   0.11,   5.13,   5.50,   0.04,
-        0.00,   0.12,  -0.11,   4.50,   5.90,   0.00,   0.00,   0.13,
-       -0.10,  -4.22,   6.10,   0.00,   0.00,   0.14,  -4.53,   5.70,
-        0.00,   0.00,   0.13,   0.10,   4.18,   5.70,   0.00,   0.00,
-
-   /* 1492-1619 */
-        0.13,  -4.75,  -5.19,   0.00,   0.00,  -0.12,   0.11,  -4.06,
-        5.60,   0.00,   0.00,   0.13,  -3.98,   5.60,  -0.04,   0.00,
-        0.13,   4.02,  -5.40,   0.00,   0.00,  -0.12,   4.49,  -4.90,
-       -0.04,   0.00,  -0.11,  -0.10,  -3.62,  -5.40,  -0.16,   0.20,
-       -0.12,   0.00,   0.01,   4.38,   4.80,   0.00,   0.00,   0.11,
-       -6.40,  -0.10,   0.00,   0.00,   0.00,   0.14,  -3.98,   5.00,
-        0.04,   0.00,   0.11,  -3.82,  -5.00,   0.00,   0.00,  -0.11,
-       -3.71,   5.07,   0.00,   0.00,   0.11,   4.14,   4.40,   0.00,
-        0.00,   0.10,  -6.01,  -0.50,  -0.04,   0.00,   0.00,   0.13,
-       -4.04,   4.39,   0.00,   0.00,   0.10,   3.45,  -4.72,   0.00,
-        0.00,  -0.11,   3.31,   4.71,   0.00,   0.00,   0.11,   3.26,
-       -4.50,   0.00,   0.00,  -0.10,  -3.26,  -4.50,   0.00,   0.00,
-       -0.10,  -3.34,  -4.40,   0.00,   0.00,  -0.10,  -3.74,  -4.00,
-        3.70,   4.00,   3.34,  -4.30,   3.30,  -4.30,  -3.66,   3.90,
-        0.04,   3.66,   3.90,   0.04,  -3.62,  -3.90,  -3.61,   3.90,
-       -0.20,   5.30,   0.00,   0.00,   0.12,   3.06,   4.30,   3.30,
-
-   /* 1620-1747 */
-        4.00,   0.40,   0.20,   3.10,   4.10,  -3.06,   3.90,  -3.30,
-       -3.60,  -3.30,   3.36,   0.01,   3.14,   3.40,  -4.57,  -0.20,
-        0.00,   0.00,   0.00,   0.10,  -2.70,  -3.60,   2.94,  -3.20,
-       -2.90,   3.20,   2.47,  -3.40,   2.55,  -3.30,   2.80,  -3.08,
-        2.51,   3.30,  -4.10,   0.30,  -0.12,  -0.10,   4.10,   0.20,
-       -2.74,   3.00,   2.46,   3.23,  -3.66,   1.20,  -0.20,   0.20,
-        3.74,  -0.40,  -2.51,  -2.80,  -3.74,   2.27,  -2.90,   0.00,
-        0.00,  -2.50,   2.70,  -2.51,   2.60,  -3.50,   0.20,   3.38,
-       -2.22,  -2.50,   3.26,  -0.40,   1.95,  -2.60,   3.22,  -0.40,
-       -0.04,  -1.79,  -2.60,   1.91,   2.50,   0.74,   3.05,  -0.04,
-        0.08,   2.11,  -2.30,  -2.11,   2.20,  -1.87,  -2.40,   2.03,
-       -2.20,  -2.03,   2.20,   2.98,   0.00,   0.00,   2.98,  -1.71,
-        2.40,   2.94,  -0.10,  -0.12,   0.10,   1.67,   2.40,  -1.79,
-        2.30,  -1.79,   2.20,  -1.67,   2.20,   1.79,  -2.00,   1.87,
-       -1.90,   1.63,  -2.10,  -1.59,   2.10,   1.55,  -2.10,  -1.55,
-        2.10,  -2.59,  -0.20,  -1.75,  -1.90,  -1.75,   1.90,  -1.83,
-
-   /* 1748-1875 */
-       -1.80,   1.51,   2.00,  -1.51,  -2.00,   1.71,   1.80,   1.31,
-        2.10,  -1.43,   2.00,   1.43,   2.00,  -2.43,  -1.51,   1.90,
-       -1.47,   1.90,   2.39,   0.20,  -2.39,   1.39,   1.90,   1.39,
-       -1.80,   1.47,  -1.60,   1.47,  -1.60,   1.43,  -1.50,  -1.31,
-        1.60,   1.27,  -1.60,  -1.27,   1.60,   1.27,  -1.60,   2.03,
-        1.35,   1.50,  -1.39,  -1.40,   1.95,  -0.20,  -1.27,   1.49,
-        1.19,   1.50,   1.27,   1.40,   1.15,   1.50,   1.87,  -0.10,
-       -1.12,  -1.50,   1.87,  -1.11,  -1.50,  -1.11,  -1.50,   0.00,
-        0.00,   1.19,   1.40,   1.27,  -1.30,  -1.27,  -1.30,  -1.15,
-        1.40,  -1.23,   1.30,  -1.23,  -1.30,   1.22,  -1.29,   1.07,
-       -1.40,   1.75,  -0.20,  -1.03,  -1.40,  -1.07,   1.20,  -1.03,
-        1.15,   1.07,   1.10,   1.51,  -1.03,   1.10,   1.03,  -1.10,
-        0.00,   0.00,  -1.03,  -1.10,   0.91,  -1.20,  -0.88,  -1.20,
-       -0.88,   1.20,  -0.95,   1.10,  -0.95,  -1.10,   1.43,  -1.39,
-        0.95,  -1.00,  -0.95,   1.00,  -0.80,   1.10,   0.91,  -1.00,
-       -1.35,   0.88,   1.00,  -0.83,   1.00,  -0.91,   0.90,   0.91,
-
-   /* 1876-2003 */
-        0.90,   0.88,  -0.90,  -0.76,  -1.00,  -0.76,   1.00,   0.76,
-        1.00,  -0.72,   1.00,   0.84,  -0.90,   0.84,   0.90,   1.23,
-        0.00,   0.00,  -0.52,  -1.10,  -0.68,   1.00,   1.19,  -0.20,
-        1.19,   0.76,   0.90,   1.15,  -0.10,   1.15,  -0.10,   0.72,
-       -0.90,  -1.15,  -1.15,   0.68,   0.90,  -0.68,   0.90,  -1.11,
-        0.00,   0.00,   0.20,   0.79,   0.80,  -1.11,  -0.10,   0.00,
-        0.00,  -0.48,  -1.00,  -0.76,  -0.80,  -0.72,  -0.80,  -1.07,
-       -0.10,   0.64,   0.80,  -0.64,  -0.80,   0.64,   0.80,   0.40,
-        0.60,   0.52,  -0.50,  -0.60,  -0.80,  -0.71,   0.70,  -0.99,
-        0.99,   0.56,   0.80,  -0.56,   0.80,   0.68,  -0.70,   0.68,
-        0.70,  -0.95,  -0.64,   0.70,   0.64,   0.70,  -0.60,   0.70,
-       -0.60,  -0.70,  -0.91,  -0.10,  -0.51,   0.76,  -0.91,  -0.56,
-        0.70,   0.88,   0.88,  -0.63,  -0.60,   0.55,  -0.60,  -0.80,
-        0.80,  -0.80,  -0.52,   0.60,   0.52,   0.60,   0.52,  -0.60,
-       -0.48,   0.60,   0.48,   0.60,   0.48,   0.60,  -0.76,   0.44,
-       -0.60,   0.52,  -0.50,  -0.52,   0.50,   0.40,   0.60,  -0.40,
-
-   /* 2004-2131 */
-       -0.60,   0.40,  -0.60,   0.72,  -0.72,  -0.51,  -0.50,  -0.48,
-        0.50,   0.48,  -0.50,  -0.48,   0.50,  -0.48,   0.50,   0.48,
-       -0.50,  -0.48,  -0.50,  -0.68,  -0.68,   0.44,   0.50,  -0.64,
-       -0.10,  -0.64,  -0.10,  -0.40,   0.50,   0.40,   0.50,   0.40,
-        0.50,   0.00,   0.00,  -0.40,  -0.50,  -0.36,  -0.50,   0.36,
-       -0.50,   0.60,  -0.60,   0.40,  -0.40,   0.40,   0.40,  -0.40,
-        0.40,  -0.40,   0.40,  -0.56,  -0.56,   0.36,  -0.40,  -0.36,
-        0.40,   0.36,  -0.40,  -0.36,  -0.40,   0.36,   0.40,   0.36,
-        0.40,  -0.52,   0.52,   0.52,   0.32,   0.40,  -0.32,   0.40,
-       -0.32,   0.40,  -0.32,   0.40,   0.32,  -0.40,  -0.32,  -0.40,
-        0.32,  -0.40,   0.28,  -0.40,  -0.28,   0.40,   0.28,  -0.40,
-        0.28,   0.40,   0.48,  -0.48,   0.48,   0.36,  -0.30,  -0.36,
-       -0.30,   0.00,   0.00,   0.20,   0.40,  -0.44,   0.44,  -0.44,
-       -0.44,  -0.44,  -0.44,   0.32,  -0.30,   0.32,   0.30,   0.24,
-        0.30,  -0.12,  -0.10,  -0.28,   0.30,   0.28,   0.30,   0.28,
-        0.30,   0.28,  -0.30,   0.28,  -0.30,   0.28,  -0.30,   0.28,
-
-   /* 2132-2259 */
-        0.30,  -0.28,   0.30,   0.40,   0.40,  -0.24,   0.30,   0.24,
-       -0.30,   0.24,  -0.30,  -0.24,  -0.30,   0.24,   0.30,   0.24,
-       -0.30,  -0.24,   0.30,   0.24,  -0.30,  -0.24,  -0.30,   0.24,
-       -0.30,   0.24,   0.30,  -0.24,   0.30,  -0.24,   0.30,   0.20,
-       -0.30,   0.20,  -0.30,   0.20,  -0.30,   0.20,   0.30,   0.20,
-       -0.30,   0.20,  -0.30,   0.20,   0.30,   0.20,   0.30,  -0.20,
-       -0.30,   0.20,  -0.30,   0.20,  -0.30,  -0.36,  -0.36,  -0.36,
-       -0.04,   0.30,   0.12,  -0.10,  -0.32,  -0.24,   0.20,   0.24,
-        0.20,   0.20,  -0.20,  -0.20,  -0.20,  -0.20,  -0.20,   0.20,
-        0.20,   0.20,  -0.20,   0.20,   0.20,   0.20,   0.20,  -0.20,
-       -0.20,   0.00,   0.00,  -0.20,  -0.20,  -0.20,   0.20,  -0.20,
-        0.20,   0.20,  -0.20,  -0.20,  -0.20,   0.20,   0.20,   0.20,
-        0.20,   0.20,  -0.20,   0.20,  -0.20,   0.28,   0.28,   0.28,
-        0.28,   0.28,   0.28,  -0.28,   0.28,   0.12,   0.00,   0.24,
-        0.16,  -0.20,   0.16,  -0.20,   0.16,  -0.20,   0.16,   0.20,
-       -0.16,   0.20,   0.16,   0.20,  -0.16,   0.20,  -0.16,   0.20,
-
-   /* 2260-2387 */
-       -0.16,   0.20,   0.16,  -0.20,   0.16,   0.20,   0.16,  -0.20,
-       -0.16,   0.20,  -0.16,  -0.20,  -0.16,   0.20,   0.16,   0.20,
-        0.16,  -0.20,   0.16,  -0.20,   0.16,   0.20,   0.16,   0.20,
-        0.16,   0.20,  -0.16,  -0.20,   0.16,   0.20,  -0.16,   0.20,
-        0.16,   0.20,  -0.16,  -0.20,   0.16,  -0.20,   0.16,  -0.20,
-       -0.16,  -0.20,   0.24,  -0.24,  -0.24,   0.24,   0.24,   0.12,
-        0.20,   0.12,   0.20,  -0.12,  -0.20,   0.12,  -0.20,   0.12,
-       -0.20,  -0.12,   0.20,  -0.12,   0.20,  -0.12,  -0.20,   0.12,
-        0.20,   0.12,   0.20,   0.12,  -0.20,  -0.12,   0.20,   0.12,
-       -0.20,  -0.12,   0.20,   0.12,   0.20,   0.00,   0.00,  -0.12,
-        0.20,  -0.12,   0.20,   0.12,  -0.20,  -0.12,   0.20,   0.12,
-        0.20,   0.00,  -0.21,  -0.20,   0.00,   0.00,   0.20,  -0.20,
-       -0.20,  -0.20,   0.20,  -0.16,  -0.10,   0.00,   0.17,   0.16,
-        0.16,   0.16,   0.16,  -0.16,   0.16,   0.16,  -0.16,   0.16,
-       -0.16,   0.16,   0.12,   0.10,   0.12,  -0.10,  -0.12,   0.10,
-       -0.12,   0.10,   0.12,  -0.10,  -0.12,   0.12,  -0.12,   0.12,
-
-   /* 2388-2515 */
-       -0.12,   0.12,  -0.12,  -0.12,  -0.12,  -0.12,  -0.12,  -0.12,
-       -0.12,   0.12,   0.12,   0.12,   0.12,  -0.12,  -0.12,   0.12,
-        0.12,   0.12,  -0.12,   0.12,  -0.12,  -0.12,  -0.12,   0.12,
-       -0.12,  -0.12,   0.12,   0.00,   0.11,   0.11,-122.67, 164.70,
-      203.78, 273.50,   3.58,   2.74,   6.18,  -4.56,   0.00,  -0.04,
-        0.00,  -0.07,  57.44, -77.10,  95.82, 128.60,  -1.77,  -1.28,
-        2.85,  -2.14,  82.14,  89.50,   0.00,   0.00,   2.00,  -1.84,
-       -0.04,  47.73, -64.10,  23.79,  31.90,  -1.45,  -1.07,   0.69,
-       -0.53, -46.38,  50.50,   0.00,   0.00,   1.13,   1.04,   0.02,
-      -18.38,   0.00,  63.80,   0.00,   0.00,   0.41,   0.00,  -1.43,
-       59.07,   0.00,   0.00,   0.00,   0.00,  -1.32,  57.28,   0.00,
-        0.00,   0.00,   0.00,  -1.28, -48.65,   0.00,  -1.15,   0.00,
-        0.00,   1.09,   0.00,   0.03, -18.30,  24.60, -17.30, -23.20,
-        0.56,   0.41,  -0.51,   0.39, -16.91,  26.90,   8.43,  13.30,
-        0.60,   0.38,   0.31,  -0.19,   1.23,  -1.70, -19.13, -25.70,
-       -0.03,  -0.03,  -0.58,   0.43,  -0.72,   0.90, -17.34, -23.30,
-
-   /* 2516-2643 */
-        0.03,   0.02,  -0.52,   0.39, -19.49, -21.30,   0.00,   0.00,
-       -0.48,   0.44,   0.01,  20.57, -20.10,   0.64,   0.70,  -0.45,
-       -0.46,   0.00,  -0.01,   4.89,   5.90, -16.55,  19.90,   0.14,
-       -0.11,   0.44,   0.37,  18.22,  19.80,   0.00,   0.00,   0.44,
-       -0.41,  -0.01,   4.89,  -5.30, -16.51, -18.00,  -0.11,  -0.11,
-       -0.41,   0.37, -17.86,   0.00,  17.10,   0.00,   0.00,   0.40,
-        0.00,  -0.38,   0.32,   0.00,  24.42,   0.00,   0.00,  -0.01,
-        0.00,  -0.55, -23.79,   0.00,   0.00,   0.00,   0.00,   0.53,
-       14.72, -16.00,  -0.32,   0.00,  -0.36,  -0.33,  -0.01,   0.01,
-        3.34,  -4.50,  11.86,  15.90,  -0.11,  -0.07,   0.35,  -0.27,
-       -3.26,   4.40,  11.62,  15.60,   0.09,   0.07,   0.35,  -0.26,
-      -19.53,   0.00,   5.09,   0.00,   0.00,   0.44,   0.00,  -0.11,
-      -13.48,  14.70,   0.00,   0.00,   0.33,   0.30,   0.01,  10.86,
-      -14.60,   3.18,   4.30,  -0.33,  -0.24,   0.09,  -0.07, -11.30,
-      -15.10,   0.00,   0.00,  -0.34,   0.25,   0.01,   2.03,  -2.70,
-       10.82,  14.50,  -0.07,  -0.05,   0.32,  -0.24,  17.46,   0.00,
-
-   /* 2644-2771 */
-        0.00,   0.00,   0.00,  -0.39,  16.43,   0.00,   0.52,   0.00,
-        0.00,  -0.37,   0.00,  -0.01,   9.35,   0.00,  13.29,   0.00,
-        0.00,  -0.21,   0.00,  -0.30, -10.42,  11.40,   0.00,   0.00,
-        0.25,   0.23,   0.01,   0.44,   0.50, -10.38,  11.30,   0.02,
-       -0.01,   0.25,   0.23, -14.64,   0.00,   0.00,   0.00,   0.00,
-        0.33,   0.56,   0.80,  -8.67,  11.70,   0.02,  -0.01,   0.26,
-        0.19,  13.88,   0.00,  -2.47,   0.00,   0.00,  -0.31,   0.00,
-        0.06,  -1.99,   2.70,   7.72,  10.30,   0.06,   0.04,   0.23,
-       -0.17,  -0.20,   0.00,  13.05,   0.00,   0.00,   0.00,   0.00,
-       -0.29,   6.92,  -9.30,   3.34,   4.50,  -0.21,  -0.15,   0.10,
-       -0.07,  -6.60,   0.00,  10.70,   0.00,   0.00,   0.15,   0.00,
-       -0.24,  -8.04,  -8.70,   0.00,   0.00,  -0.19,   0.18, -10.58,
-        0.00,  -3.10,   0.00,   0.00,   0.24,   0.00,   0.07,  -7.32,
-        8.00,  -0.12,  -0.10,   0.18,   0.16,   1.63,   1.70,   6.96,
-       -7.60,   0.03,  -0.04,  -0.17,  -0.16,  -3.62,   0.00,   9.86,
-        0.00,   0.00,   0.08,   0.00,  -0.22,   0.20,  -0.20,  -6.88,
-
-   /* 2772-2899 */
-       -7.50,   0.00,   0.00,  -0.17,   0.15,  -8.99,   0.00,   4.02,
-        0.00,   0.00,   0.20,   0.00,  -0.09,  -1.07,   1.40,  -5.69,
-       -7.70,   0.03,   0.02,  -0.17,   0.13,   6.48,  -7.20,  -0.48,
-       -0.50,  -0.16,  -0.14,  -0.01,   0.01,   5.57,  -7.50,   1.07,
-        1.40,  -0.17,  -0.12,   0.03,  -0.02,   8.71,   0.00,   3.54,
-        0.00,   0.00,  -0.19,   0.00,  -0.08,   0.40,   0.00,   9.27,
-        0.00,   0.00,  -0.01,   0.00,  -0.21,  -6.13,   6.70,  -1.19,
-       -1.30,   0.15,   0.14,  -0.03,   0.03,   5.21,  -5.70,  -2.51,
-       -2.60,  -0.13,  -0.12,  -0.06,   0.06,   5.69,  -6.20,  -0.12,
-       -0.10,  -0.14,  -0.13,  -0.01,   2.03,  -2.70,   4.53,   6.10,
-       -0.06,  -0.05,   0.14,  -0.10,   5.01,   5.50,  -2.51,   2.70,
-        0.12,  -0.11,   0.06,   0.06,  -1.91,   2.60,  -4.38,  -5.90,
-        0.06,   0.04,  -0.13,   0.10,   4.65,  -6.30,   0.00,   0.00,
-       -0.14,  -0.10,  -5.29,   5.70,   0.00,   0.00,   0.13,   0.12,
-       -2.23,  -4.00,  -4.65,   4.20,  -0.09,   0.05,   0.10,   0.10,
-       -4.53,   6.10,   0.00,   0.00,   0.14,   0.10,   2.47,   2.70,
-
-   /* 2900-3027 */
-       -4.46,   4.90,   0.06,  -0.06,   0.11,   0.10,  -5.05,   5.50,
-        0.84,   0.90,   0.12,   0.11,   0.02,  -0.02,   4.97,  -5.40,
-       -1.71,   0.00,  -0.12,  -0.11,   0.00,   0.04,  -0.99,  -1.30,
-        4.22,  -5.70,  -0.03,   0.02,  -0.13,  -0.09,   0.99,   1.40,
-        4.22,  -5.60,   0.03,  -0.02,  -0.13,  -0.09,  -4.69,  -5.20,
-        0.00,   0.00,  -0.12,   0.10,  -3.42,   0.00,   6.09,   0.00,
-        0.00,   0.08,   0.00,  -0.14,  -4.65,  -5.10,   0.00,   0.00,
-       -0.11,   0.10,   0.00,   0.00,  -4.53,  -5.00,   0.00,   0.00,
-       -0.11,   0.10,  -2.43,  -2.70,  -3.82,   4.20,  -0.06,   0.05,
-        0.10,   0.09,   0.00,   0.00,  -4.53,   4.90,   0.00,   0.00,
-        0.11,   0.10,  -4.49,  -4.90,   0.00,   0.00,  -0.11,   0.10,
-        2.67,  -2.90,  -3.62,  -3.90,  -0.06,  -0.06,  -0.09,   0.08,
-        3.94,  -5.30,   0.00,   0.00,  -0.12,  -3.38,   3.70,  -2.78,
-       -3.10,   0.08,   0.08,  -0.07,   0.06,   3.18,  -3.50,  -2.82,
-       -3.10,  -0.08,  -0.07,  -0.07,   0.06,  -5.77,   0.00,   1.87,
-        0.00,   0.00,   0.13,   0.00,  -0.04,   3.54,  -4.80,  -0.64,
-
-   /* 3028-3155 */
-       -0.90,  -0.11,   0.00,  -0.02,  -3.50,  -4.70,   0.68,  -0.90,
-       -0.11,   0.00,  -0.02,   5.49,   0.00,   0.00,   0.00,   0.00,
-       -0.12,   1.83,  -2.50,   2.63,   3.50,  -0.06,   0.00,   0.08,
-        3.02,  -4.10,   0.68,   0.90,  -0.09,   0.00,   0.02,   0.00,
-        0.00,   5.21,   0.00,   0.00,   0.00,   0.00,  -0.12,  -3.54,
-        3.80,   2.70,   3.60,  -1.35,   1.80,   0.08,   0.00,   0.04,
-       -2.90,   3.90,   0.68,   0.90,   0.09,   0.00,   0.02,   0.80,
-       -1.10,  -2.78,  -3.70,  -0.02,   0.00,  -0.08,   4.10,   0.00,
-       -2.39,   0.00,   0.00,  -0.09,   0.00,   0.05,  -1.59,   2.10,
-        2.27,   3.00,   0.05,   0.00,   0.07,  -2.63,   3.50,  -0.48,
-       -0.60,  -2.94,  -3.20,  -2.94,   3.20,   2.27,  -3.00,  -1.11,
-       -1.50,  -0.07,   0.00,  -0.03,  -0.56,  -0.80,  -2.35,   3.10,
-        0.00,  -0.60,  -3.42,   1.90,  -0.12,  -0.10,   2.63,  -2.90,
-        2.51,   2.80,  -0.64,   0.70,  -0.48,  -0.60,   2.19,  -2.90,
-        0.24,  -0.30,   2.15,   2.90,   2.15,  -2.90,   0.52,   0.70,
-        2.07,  -2.80,  -3.10,   0.00,   1.79,   0.00,   0.00,   0.07,
-
-   /* 3156-3283 */
-        0.00,  -0.04,   0.88,   0.00,  -3.46,   2.11,   2.80,  -0.36,
-        0.50,   3.54,  -0.20,  -3.50,  -1.39,   1.50,  -1.91,  -2.10,
-       -1.47,   2.00,   1.39,   1.90,   2.07,  -2.30,   0.91,   1.00,
-        1.99,  -2.70,   3.30,   0.00,   0.60,  -0.44,  -0.70,  -1.95,
-        2.60,   2.15,  -2.40,  -0.60,  -0.70,   3.30,   0.84,   0.00,
-       -3.10,  -3.10,   0.00,  -0.72,  -0.32,   0.40,  -1.87,  -2.50,
-        1.87,  -2.50,   0.32,   0.40,  -0.24,   0.30,  -1.87,  -2.50,
-       -0.24,  -0.30,   1.87,  -2.50,  -2.70,   0.00,   1.55,   2.03,
-        2.20,  -2.98,  -1.99,  -2.20,   0.12,  -0.10,  -0.40,   0.50,
-        1.59,   2.10,   0.00,   0.00,  -1.79,   2.00,  -1.03,   1.40,
-       -1.15,  -1.60,   0.32,   0.50,   1.39,  -1.90,   2.35,  -1.27,
-        1.70,   0.60,   0.80,  -0.32,  -0.40,   1.35,  -1.80,   0.44,
-        0.00,   2.23,  -0.84,   0.90,  -1.27,  -1.40,  -1.47,   1.60,
-       -0.28,  -0.30,  -0.28,   0.40,  -1.27,  -1.70,   0.28,  -0.40,
-       -1.43,  -1.50,   0.00,   0.00,  -1.27,  -1.70,   2.11,  -0.32,
-       -0.40,  -1.23,   1.60,   1.19,  -1.30,  -0.72,  -0.80,   0.72,
-
-   /* 3284-3411 */
-       -0.80,  -1.15,  -1.30,  -1.35,  -1.50,  -1.19,  -1.60,  -0.12,
-        0.20,   1.79,   0.00,  -0.88,  -0.28,   0.40,   1.11,   1.50,
-       -1.83,   0.00,   0.56,  -0.12,   0.10,  -1.27,  -1.40,   0.00,
-        0.00,   1.15,   1.50,  -0.12,   0.20,   1.11,   1.50,   0.36,
-       -0.50,  -1.07,  -1.40,  -1.11,   1.50,   1.67,   0.00,   0.80,
-       -1.11,   0.00,   1.43,   1.23,  -1.30,  -0.24,  -1.19,  -1.30,
-       -0.24,   0.20,  -0.44,  -0.90,  -0.95,   1.10,   1.07,  -1.40,
-        1.15,  -1.30,   1.03,  -1.10,  -0.56,  -0.60,  -0.68,   0.90,
-       -0.76,  -1.00,  -0.24,  -0.30,   0.95,  -1.30,   0.56,   0.70,
-        0.84,  -1.10,  -0.56,   0.00,  -1.55,   0.91,  -1.30,   0.28,
-        0.30,   0.16,  -0.20,   0.95,   1.30,   0.40,  -0.50,  -0.88,
-       -1.20,   0.95,  -1.10,  -0.48,  -0.50,   0.00,   0.00,  -1.07,
-        1.20,   0.44,  -0.50,   0.95,   1.10,   0.00,   0.00,   0.92,
-       -1.30,   0.95,   1.00,  -0.52,   0.60,   1.59,   0.24,  -0.40,
-        0.91,   1.20,   0.84,  -1.10,  -0.44,  -0.60,   0.84,   1.10,
-       -0.44,   0.60,  -0.44,   0.60,  -0.84,  -1.10,  -0.80,   0.00,
-
-   /* 3412-3539 */
-        1.35,   0.76,   0.20,  -0.91,  -1.00,   0.20,  -0.30,  -0.91,
-       -1.20,  -0.95,   1.00,  -0.48,  -0.50,   0.88,   1.00,   0.48,
-       -0.50,  -0.95,  -1.10,   0.20,  -0.20,  -0.99,   1.10,  -0.84,
-        1.10,  -0.24,  -0.30,   0.20,  -0.30,   0.84,   1.10,  -1.39,
-        0.00,  -0.28,  -0.16,   0.20,   0.84,   1.10,   0.00,   0.00,
-        1.39,   0.00,   0.00,  -0.95,   1.00,   1.35,  -0.99,   0.00,
-        0.88,  -0.52,   0.00,  -1.19,   0.20,   0.20,   0.76,  -1.00,
-        0.00,   0.00,   0.76,   1.00,   0.00,   0.00,   0.76,   1.00,
-       -0.76,   1.00,   0.00,   0.00,   1.23,   0.76,   0.80,  -0.32,
-        0.40,  -0.72,   0.80,  -0.40,  -0.40,   0.00,   0.00,  -0.80,
-       -0.90,  -0.68,   0.90,  -0.16,  -0.20,  -0.16,  -0.20,   0.68,
-       -0.90,  -0.36,   0.50,  -0.56,  -0.80,   0.72,  -0.90,   0.44,
-       -0.60,  -0.48,  -0.70,  -0.16,   0.00,  -1.11,   0.32,   0.00,
-       -1.07,   0.60,  -0.80,  -0.28,  -0.40,  -0.64,   0.00,   0.91,
-        1.11,   0.64,  -0.90,   0.76,  -0.80,   0.00,   0.00,  -0.76,
-       -0.80,   1.03,   0.00,  -0.36,  -0.64,  -0.70,   0.36,  -0.40,
-
-   /* 3540-3667 */
-        1.07,   0.36,  -0.50,  -0.52,  -0.70,   0.60,   0.00,   0.88,
-        0.95,   0.00,   0.48,   0.16,  -0.20,   0.60,   0.80,   0.16,
-       -0.20,  -0.60,  -0.80,   0.00,  -1.00,   0.12,   0.20,   0.16,
-       -0.20,   0.68,   0.70,   0.59,  -0.80,  -0.99,  -0.56,  -0.60,
-        0.36,  -0.40,  -0.68,  -0.70,  -0.68,  -0.70,  -0.36,  -0.50,
-       -0.44,   0.60,   0.64,   0.70,  -0.12,   0.10,  -0.52,   0.60,
-        0.36,   0.40,   0.00,   0.00,   0.95,  -0.84,   0.00,   0.44,
-        0.56,   0.60,   0.32,  -0.30,   0.00,   0.00,   0.60,   0.70,
-        0.00,   0.00,   0.60,   0.70,  -0.12,  -0.20,   0.52,  -0.70,
-        0.00,   0.00,   0.56,   0.70,  -0.12,   0.10,  -0.52,  -0.70,
-        0.00,   0.00,   0.88,  -0.76,   0.00,  -0.44,   0.00,   0.00,
-       -0.52,  -0.70,   0.52,  -0.70,   0.36,  -0.40,  -0.44,  -0.50,
-        0.00,   0.00,   0.60,   0.60,   0.84,   0.00,   0.12,  -0.24,
-        0.00,   0.80,  -0.56,   0.60,  -0.32,  -0.30,   0.48,  -0.50,
-        0.28,  -0.30,  -0.48,  -0.50,   0.12,   0.20,   0.48,  -0.60,
-        0.48,   0.60,  -0.12,   0.20,   0.24,   0.00,   0.76,  -0.52,
-
-   /* 3668-3795 */
-       -0.60,  -0.52,   0.60,   0.48,  -0.50,  -0.24,  -0.30,   0.12,
-       -0.10,   0.48,   0.60,   0.52,  -0.20,   0.36,   0.40,  -0.44,
-        0.50,  -0.24,  -0.30,  -0.48,  -0.60,  -0.44,  -0.60,  -0.12,
-        0.10,   0.76,   0.76,   0.20,  -0.20,   0.48,   0.50,   0.40,
-       -0.50,  -0.24,  -0.30,   0.44,  -0.60,   0.44,  -0.60,   0.36,
-        0.00,  -0.64,   0.72,   0.00,  -0.12,   0.00,  -0.10,  -0.40,
-       -0.60,  -0.20,  -0.20,  -0.44,   0.50,  -0.44,   0.50,   0.20,
-        0.20,  -0.44,  -0.50,   0.20,  -0.20,  -0.20,   0.20,  -0.44,
-       -0.50,   0.64,   0.00,   0.32,  -0.36,   0.50,  -0.20,  -0.30,
-        0.12,  -0.10,   0.48,   0.50,  -0.12,   0.30,  -0.36,  -0.50,
-        0.00,   0.00,   0.48,   0.50,  -0.48,   0.50,   0.68,   0.00,
-       -0.12,   0.56,  -0.40,   0.44,  -0.50,  -0.12,  -0.10,   0.24,
-        0.30,  -0.40,   0.40,   0.64,   0.00,  -0.24,   0.64,   0.00,
-       -0.20,   0.00,   0.00,   0.44,  -0.50,   0.44,   0.50,  -0.12,
-        0.20,  -0.36,  -0.50,   0.12,   0.00,   0.64,  -0.40,   0.50,
-        0.00,   0.10,   0.00,   0.00,  -0.40,   0.50,   0.00,   0.00,
-
-   /* 3796-3923 */
-       -0.40,  -0.50,   0.56,   0.00,   0.28,   0.00,   0.10,   0.36,
-        0.50,   0.00,  -0.10,   0.36,  -0.50,   0.36,   0.50,   0.00,
-       -0.10,   0.24,  -0.20,  -0.36,  -0.40,   0.16,   0.20,   0.40,
-       -0.40,   0.00,   0.00,  -0.36,  -0.50,  -0.36,  -0.50,  -0.32,
-       -0.50,  -0.12,   0.10,   0.20,   0.20,  -0.36,   0.40,  -0.60,
-        0.60,   0.28,   0.00,   0.52,   0.12,  -0.10,   0.40,   0.40,
-        0.00,  -0.50,   0.20,  -0.20,  -0.32,   0.40,   0.16,   0.20,
-       -0.16,   0.20,   0.32,   0.40,   0.56,   0.00,  -0.12,   0.32,
-       -0.40,  -0.16,  -0.20,   0.00,   0.00,   0.40,   0.40,  -0.40,
-       -0.40,  -0.40,   0.40,  -0.36,   0.40,   0.12,   0.10,   0.00,
-        0.10,   0.36,   0.40,   0.00,  -0.10,   0.36,   0.40,  -0.36,
-        0.40,   0.00,   0.10,   0.32,   0.00,   0.44,   0.12,   0.20,
-        0.28,  -0.40,   0.00,   0.00,   0.36,   0.40,   0.32,  -0.40,
-       -0.16,   0.12,   0.10,   0.32,  -0.40,   0.20,   0.30,  -0.24,
-        0.30,   0.00,   0.10,   0.32,   0.40,   0.00,  -0.10,  -0.32,
-       -0.40,  -0.32,   0.40,   0.00,   0.10,  -0.52,  -0.52,   0.52,
-
-   /* 3924-4051 */
-        0.32,  -0.40,   0.00,   0.00,   0.32,   0.40,   0.32,  -0.40,
-        0.00,   0.00,  -0.32,  -0.40,  -0.32,   0.40,   0.32,   0.40,
-        0.00,   0.00,   0.32,   0.40,   0.00,   0.00,  -0.32,  -0.40,
-        0.00,   0.00,   0.32,   0.40,   0.16,   0.20,   0.32,  -0.30,
-       -0.16,   0.00,  -0.48,  -0.20,   0.20,  -0.28,  -0.30,   0.28,
-       -0.40,   0.00,   0.00,   0.28,  -0.40,   0.00,   0.00,   0.28,
-       -0.40,   0.00,   0.00,  -0.28,  -0.40,   0.28,   0.40,  -0.28,
-       -0.40,  -0.48,  -0.20,   0.20,   0.24,   0.30,   0.44,   0.00,
-        0.16,   0.24,   0.30,   0.16,  -0.20,   0.24,   0.30,  -0.12,
-        0.20,   0.20,   0.30,  -0.16,   0.20,   0.00,   0.00,   0.44,
-       -0.32,   0.30,   0.24,   0.00,  -0.36,   0.36,   0.00,   0.24,
-        0.12,  -0.20,   0.20,   0.30,  -0.12,   0.00,  -0.28,   0.30,
-       -0.24,   0.30,   0.12,   0.10,  -0.28,  -0.30,  -0.28,   0.30,
-        0.00,   0.00,  -0.28,  -0.30,   0.00,   0.00,  -0.28,  -0.30,
-        0.00,   0.00,   0.28,   0.30,   0.00,   0.00,  -0.28,  -0.30,
-       -0.28,   0.30,   0.00,   0.00,  -0.28,  -0.30,   0.00,   0.00,
-
-   /* 4052-4179 */
-        0.28,   0.30,   0.00,   0.00,  -0.28,   0.30,   0.28,  -0.30,
-       -0.28,   0.30,   0.40,   0.40,  -0.24,   0.30,   0.00,  -0.10,
-        0.16,   0.00,   0.36,  -0.20,   0.30,  -0.12,  -0.10,  -0.24,
-       -0.30,   0.00,   0.00,  -0.24,   0.30,  -0.24,   0.30,   0.00,
-        0.00,  -0.24,   0.30,  -0.24,   0.30,   0.24,  -0.30,   0.00,
-        0.00,   0.24,  -0.30,   0.00,   0.00,   0.24,   0.30,   0.24,
-       -0.30,   0.24,   0.30,  -0.24,   0.30,  -0.24,   0.30,  -0.20,
-        0.20,  -0.16,  -0.20,   0.00,   0.00,  -0.32,   0.20,   0.00,
-        0.10,   0.20,  -0.30,   0.20,  -0.20,   0.12,   0.20,  -0.16,
-        0.20,   0.16,   0.20,   0.20,   0.30,   0.20,   0.30,   0.00,
-        0.00,  -0.20,   0.30,   0.00,   0.00,   0.20,   0.30,  -0.20,
-       -0.30,  -0.20,  -0.30,   0.20,  -0.30,   0.00,   0.00,   0.20,
-        0.30,   0.00,   0.00,   0.20,   0.30,   0.00,   0.00,   0.20,
-        0.30,   0.00,   0.00,   0.20,   0.30,   0.00,   0.00,   0.20,
-       -0.30,   0.00,   0.00,  -0.20,  -0.30,   0.00,   0.00,  -0.20,
-        0.30,   0.00,   0.00,  -0.20,   0.30,   0.00,   0.00,   0.36,
-
-   /* 4180-4307 */
-        0.00,   0.00,   0.36,   0.12,   0.10,  -0.24,   0.20,   0.12,
-       -0.20,  -0.16,  -0.20,  -0.13,   0.10,   0.22,   0.21,   0.20,
-        0.00,  -0.28,   0.32,   0.00,  -0.12,  -0.20,  -0.20,   0.12,
-       -0.10,   0.12,   0.10,  -0.20,   0.20,   0.00,   0.00,  -0.32,
-        0.32,   0.00,   0.00,   0.32,   0.32,   0.00,   0.00,  -0.24,
-       -0.20,   0.24,   0.20,   0.20,   0.00,  -0.24,   0.00,   0.00,
-       -0.24,  -0.20,   0.00,   0.00,   0.24,   0.20,  -0.24,  -0.20,
-        0.00,   0.00,  -0.24,   0.20,   0.16,  -0.20,   0.12,   0.10,
-        0.20,   0.20,   0.00,  -0.10,  -0.12,   0.10,  -0.16,  -0.20,
-       -0.12,  -0.10,  -0.16,   0.20,   0.20,   0.20,   0.00,   0.00,
-       -0.20,   0.20,  -0.20,   0.20,  -0.20,   0.20,  -0.20,   0.20,
-        0.20,  -0.20,  -0.20,  -0.20,   0.00,   0.00,  -0.20,   0.20,
-        0.20,   0.00,  -0.20,   0.00,   0.00,  -0.20,   0.20,  -0.20,
-        0.20,  -0.20,  -0.20,  -0.20,  -0.20,   0.00,   0.00,   0.20,
-        0.20,   0.20,   0.20,   0.12,  -0.20,  -0.12,  -0.10,   0.28,
-       -0.28,   0.16,  -0.20,   0.00,  -0.10,   0.00,   0.10,  -0.16,
-
-   /* 4308-4435 */
-        0.20,   0.00,  -0.10,  -0.16,  -0.20,   0.00,  -0.10,   0.16,
-       -0.20,   0.16,  -0.20,   0.00,   0.00,   0.16,   0.20,  -0.16,
-        0.20,   0.00,   0.00,   0.16,   0.20,   0.16,  -0.20,   0.16,
-       -0.20,  -0.16,   0.20,   0.16,  -0.20,   0.00,   0.00,   0.16,
-        0.20,   0.00,   0.00,   0.16,   0.20,   0.00,   0.00,  -0.16,
-       -0.20,   0.16,  -0.20,  -0.16,  -0.20,   0.00,   0.00,  -0.16,
-       -0.20,   0.00,   0.00,  -0.16,   0.20,   0.00,   0.00,   0.16,
-       -0.20,   0.16,   0.20,   0.16,   0.20,   0.00,   0.00,  -0.16,
-       -0.20,   0.00,   0.00,  -0.16,  -0.20,   0.00,   0.00,   0.16,
-        0.20,   0.16,   0.20,   0.00,   0.00,   0.16,   0.20,   0.16,
-       -0.20,   0.16,   0.20,   0.00,   0.00,  -0.16,   0.20,   0.00,
-        0.10,   0.12,  -0.20,   0.12,  -0.20,   0.00,  -0.10,   0.00,
-       -0.10,   0.12,   0.20,   0.00,  -0.10,  -0.12,   0.20,  -0.15,
-        0.20,  -0.24,   0.24,   0.00,   0.00,   0.24,   0.24,   0.12,
-       -0.20,  -0.12,  -0.20,   0.00,   0.00,   0.12,   0.20,   0.12,
-       -0.20,   0.12,   0.20,   0.12,   0.20,   0.12,   0.20,   0.12,
-
-   /* 4436-4563 */
-       -0.20,  -0.12,   0.20,   0.00,   0.00,   0.12,   0.20,   0.12,
-        0.00,  -0.20,   0.00,   0.00,  -0.12,  -0.20,   0.12,  -0.20,
-        0.00,   0.00,   0.12,   0.20,  -0.12,   0.20,  -0.12,   0.20,
-        0.12,  -0.20,   0.00,   0.00,   0.12,   0.20,   0.20,   0.00,
-        0.12,   0.00,   0.00,  -0.12,   0.20,   0.00,   0.00,  -0.12,
-       -0.20,   0.00,   0.00,  -0.12,  -0.20,  -0.12,  -0.20,   0.00,
-        0.00,   0.12,  -0.20,   0.12,  -0.20,   0.12,   0.20,  -0.12,
-       -0.20,   0.00,   0.00,   0.12,  -0.20,   0.12,  -0.20,   0.12,
-        0.20,   0.12,   0.00,   0.20,  -0.12,  -0.20,   0.00,   0.00,
-        0.12,   0.20,  -0.16,   0.00,   0.16,  -0.20,   0.20,   0.00,
-        0.00,  -0.20,   0.00,   0.00,  -0.20,   0.20,   0.00,   0.00,
-        0.20,   0.20,  -0.20,   0.00,   0.00,  -0.20,   0.12,   0.00,
-       -0.16,   0.20,   0.00,   0.00,   0.20,   0.12,  -0.10,   0.00,
-        0.10,   0.16,  -0.16,  -0.16,  -0.16,  -0.16,  -0.16,   0.00,
-        0.00,  -0.16,   0.00,   0.00,  -0.16,  -0.16,  -0.16,   0.00,
-        0.00,  -0.16,   0.00,   0.00,   0.16,   0.00,   0.00,   0.16,
-
-   /* 4564-4691 */
-        0.00,   0.00,   0.16,   0.16,   0.00,   0.00,  -0.16,   0.00,
-        0.00,  -0.16,  -0.16,   0.00,   0.00,   0.16,   0.00,   0.00,
-       -0.16,  -0.16,   0.00,   0.00,  -0.16,  -0.16,   0.12,   0.10,
-        0.12,  -0.10,   0.12,   0.10,   0.00,   0.00,   0.12,   0.10,
-       -0.12,   0.10,   0.00,   0.00,   0.12,   0.10,   0.12,  -0.10,
-        0.00,   0.00,  -0.12,  -0.10,   0.00,   0.00,   0.12,   0.10,
-        0.12,   0.00,   0.00,   0.12,   0.00,   0.00,  -0.12,   0.00,
-        0.00,   0.12,   0.12,   0.12,   0.12,   0.12,   0.00,   0.00,
-        0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,   0.12,
-        0.00,   0.00,   0.12,  -0.12,  -0.12,   0.12,   0.12,  -0.12,
-       -0.12,   0.00,   0.00,   0.12,  -0.12,   0.12,   0.12,  -0.12,
-       -0.12,   0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
-        0.12,   0.00,   0.00,   0.12,   0.00,   0.00,   0.12,   0.00,
-        0.00,   0.12,  -0.12,   0.00,   0.00,  -0.12,   0.12,  -0.12,
-       -0.12,   0.12,   0.00,   0.00,   0.12,   0.12,   0.12,  -0.12,
-        0.00,   0.00,  -0.12,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
-
-   /* 4692-NA */
-       -0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,  -0.12,
-       -0.12,  -0.12,  -0.12,   0.12,   0.00,   0.00,   0.12,  -0.12,
-        0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,   0.12,  -0.12,
-       -0.12,  -0.12,  -0.12,   0.12,   0.12,  -0.12,  -0.12,   0.00,
-        0.00,  -0.12,   0.00,   0.00,  -0.12,   0.12,   0.00,   0.00,
-        0.12,   0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
-       -0.12,   0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,
-        0.12,   0.00,   0.00,   0.12,   0.12,   0.08,   0.00,   0.04
-   };
-
-/* Number of amplitude coefficients */
-   static const int NA = (int) (sizeof a / sizeof (double));
-
-/* Amplitude usage: X or Y, sin or cos, power of T. */
-   static const int jaxy[] = {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1};
-   static const int jasc[] = {0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0};
-   static const int japt[] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4};
-
-/* Miscellaneous */
-   double t, w, pt[MAXPT+1], fa[14], xypr[2], xypl[2], xyls[2], arg,
-          sc[2];
-   int jpt, i, j, jxy, ialast, ifreq, m, ia, jsc;
-
-/*--------------------------------------------------------------------*/
-
-/* Interval between fundamental date J2000.0 and given date (JC). */
-   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
-
-/* Powers of T. */
-   w = 1.0;
-   for (jpt = 0; jpt <= MAXPT; jpt++) {
-      pt[jpt] = w;
-      w *= t;
-   }
-
-/* Initialize totals in X and Y:  polynomial, luni-solar, planetary. */
-   for (jxy = 0; jxy < 2; jxy++) {
-      xypr[jxy] = 0.0;
-      xyls[jxy] = 0.0;
-      xypl[jxy] = 0.0;
-   }
-
-/* --------------------------------- */
-/* Fundamental arguments (IERS 2003) */
-/* --------------------------------- */
-
-/* Mean anomaly of the Moon. */
-   fa[0] = eraFal03(t);
-
-/* Mean anomaly of the Sun. */
-   fa[1] = eraFalp03(t);
-
-/* Mean argument of the latitude of the Moon. */
-   fa[2] = eraFaf03(t);
-
-/* Mean elongation of the Moon from the Sun. */
-   fa[3] = eraFad03(t);
-
-/* Mean longitude of the ascending node of the Moon. */
-   fa[4] = eraFaom03(t);
-
-/* Planetary longitudes, Mercury through Neptune. */
-   fa[5] = eraFame03(t);
-   fa[6] = eraFave03(t);
-   fa[7] = eraFae03(t);
-   fa[8] = eraFama03(t);
-   fa[9] = eraFaju03(t);
-   fa[10] = eraFasa03(t);
-   fa[11] = eraFaur03(t);
-   fa[12] = eraFane03(t);
-
-/* General accumulated precession in longitude. */
-   fa[13] = eraFapa03(t);
-
-/* -------------------------------------- */
-/* Polynomial part of precession-nutation */
-/* -------------------------------------- */
-
-   for (jxy = 0; jxy < 2; jxy++) {
-      for (j = MAXPT; j >= 0; j--) {
-         xypr[jxy] += xyp[jxy][j] * pt[j];
-      }
-   }
-
-/* ---------------------------------- */
-/* Nutation periodic terms, planetary */
-/* ---------------------------------- */
-
-/* Work backwards through the coefficients per frequency list. */
-   ialast = NA;
-   for (ifreq = NFPL-1; ifreq >= 0; ifreq--) {
-
-   /* Obtain the argument functions. */
-      arg = 0.0;
-      for (i = 0; i < 14; i++) {
-         m = mfapl[ifreq][i];
-         if (m != 0) arg += (double)m * fa[i];
-      }
-      sc[0] = sin(arg);
-      sc[1] = cos(arg);
-
-   /* Work backwards through the amplitudes at this frequency. */
-      ia = nc[ifreq+NFLS];
-      for (i = ialast; i >= ia; i--) {
-
-      /* Coefficient number (0 = 1st). */
-         j = i-ia;
-
-      /* X or Y. */
-         jxy = jaxy[j];
-
-      /* Sin or cos. */
-         jsc = jasc[j];
-
-      /* Power of T. */
-         jpt = japt[j];
-
-      /* Accumulate the component. */
-         xypl[jxy] += a[i-1] * sc[jsc] * pt[jpt];
-      }
-      ialast = ia-1;
-   }
-
-/* ----------------------------------- */
-/* Nutation periodic terms, luni-solar */
-/* ----------------------------------- */
-
-/* Continue working backwards through the number of coefficients list. */
-   for (ifreq = NFLS-1; ifreq >= 0; ifreq--) {
-
-   /* Obtain the argument functions. */
-      arg = 0.0;
-      for (i = 0; i < 5; i++) {
-         m = mfals[ifreq][i];
-         if (m != 0) arg += (double)m * fa[i];
-      }
-      sc[0] = sin(arg);
-      sc[1] = cos(arg);
-
-   /* Work backwards through the amplitudes at this frequency. */
-      ia = nc[ifreq];
-      for (i = ialast; i >= ia; i--) {
-
-      /* Coefficient number (0 = 1st). */
-         j = i-ia;
-
-      /* X or Y. */
-         jxy = jaxy[j];
-
-      /* Sin or cos. */
-         jsc = jasc[j];
-
-      /* Power of T. */
-         jpt = japt[j];
-
-      /* Accumulate the component. */
-         xyls[jxy] += a[i-1] * sc[jsc] * pt[jpt];
-      }
-      ialast = ia-1;
-   }
-
-/* ------------------------------------ */
-/* Results:  CIP unit vector components */
-/* ------------------------------------ */
-
-   *x = ERFA_DAS2R * (xypr[0] + (xyls[0] + xypl[0]) / 1e6);
-   *y = ERFA_DAS2R * (xypr[1] + (xyls[1] + xypl[1]) / 1e6);
-
-   return;
-
-}
-
-void eraXys00a(double date1, double date2,
-               double *x, double *y, double *s)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3];
-
-
-/* Form the bias-precession-nutation matrix, IAU 2000A. */
-   eraPnm00a(date1, date2, rbpn);
-
-/* Extract X,Y. */
-   eraBpn2xy(rbpn, x, y);
-
-/* Obtain s. */
-   *s = eraS00(date1, date2, *x, *y);
-
-   return;
-
-}
-
-void eraXys00b(double date1, double date2,
-               double *x, double *y, double *s)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3];
-
-
-/* Form the bias-precession-nutation matrix, IAU 2000A. */
-   eraPnm00b(date1, date2, rbpn);
-
-/* Extract X,Y. */
-   eraBpn2xy(rbpn, x, y);
-
-/* Obtain s. */
-   *s = eraS00(date1, date2, *x, *y);
-
-   return;
-
-}
-
-void eraXys06a(double date1, double date2,
-               double *x, double *y, double *s)
-/*
-**  - - - - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   double rbpn[3][3];
-
-
-/* Form the bias-precession-nutation matrix, IAU 2006/2000A. */
-   eraPnm06a(date1, date2, rbpn);
-
-/* Extract X,Y. */
-   eraBpn2xy(rbpn, x, y);
-
-/* Obtain s. */
-   *s = eraS06(date1, date2, *x, *y);
-
-   return;
-
-}
-
-void eraZp(double p[3])
-/*
-**  - - - - - -
-**   e r a Z p
-**  - - - - - -
-**
-**  Zero a p-vector.
-**
-**  Returned:
-**     p        double[3]      p-vector
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   p[0] = 0.0;
-   p[1] = 0.0;
-   p[2] = 0.0;
-
-   return;
-
-}
-
-void eraZpv(double pv[2][3])
-/*
-**  - - - - - - -
-**   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-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   eraZp(pv[0]);
-   eraZp(pv[1]);
-
-   return;
-
-}
-
-void eraZr(double r[3][3])
-/*
-**  - - - - - -
-**   e r a Z r
-**  - - - - - -
-**
-**  Initialize an r-matrix to the null matrix.
-**
-**  Returned:
-**     r        double[3][3]    r-matrix
-**
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  Derived, with permission, from the SOFA library.  See notes at end of file.
-*/
-{
-   r[0][0] = 0.0;
-   r[0][1] = 0.0;
-   r[0][2] = 0.0;
-   r[1][0] = 0.0;
-   r[1][1] = 0.0;
-   r[1][2] = 0.0;
-   r[2][0] = 0.0;
-   r[2][1] = 0.0;
-   r[2][2] = 0.0;
-
-   return;
-
-}
-
-/*----------------------------------------------------------------------
-**  
-**  
-**  Copyright (C) 2013-2014, NumFOCUS Foundation.
-**  All rights reserved.
-**  
-**  This library is derived, with permission, from the International
-**  Astronomical Union's "Standards of Fundamental Astronomy" library,
-**  available from http://www.iausofa.org.
-**  
-**  The ERFA version is intended to retain identical functionality to
-**  the SOFA library, but made distinct through different function and
-**  file names, as set out in the SOFA license conditions.  The SOFA
-**  original has a role as a reference standard for the IAU and IERS,
-**  and consequently redistribution is permitted only in its unaltered
-**  state.  The ERFA version is not subject to this restriction and
-**  therefore can be included in distributions which do not support the
-**  concept of "read only" software.
-**  
-**  Although the intent is to replicate the SOFA API (other than
-**  replacement of prefix names) and results (with the exception of
-**  bugs;  any that are discovered will be fixed), SOFA is not
-**  responsible for any errors found in this version of the library.
-**  
-**  If you wish to acknowledge the SOFA heritage, please acknowledge
-**  that you are using a library derived from SOFA, rather than SOFA
-**  itself.
-**  
-**  
-**  TERMS AND CONDITIONS
-**  
-**  Redistribution and use in source and binary forms, with or without
-**  modification, are permitted provided that the following conditions
-**  are met:
-**  
-**  1 Redistributions of source code must retain the above copyright
-**    notice, this list of conditions and the following disclaimer.
-**  
-**  2 Redistributions in binary form must reproduce the above copyright
-**    notice, this list of conditions and the following disclaimer in
-**    the documentation and/or other materials provided with the
-**    distribution.
-**  
-**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
-**    the International Astronomical Union nor the names of its
-**    contributors may be used to endorse or promote products derived
-**    from this software without specific prior written permission.
-**  
-**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
-**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-**  POSSIBILITY OF SUCH DAMAGE.
-**  
-*/
diff --git a/cextern/erfa/erfa.h b/cextern/erfa/erfa.h
index 31a9306..cf23a80 100644
--- a/cextern/erfa/erfa.h
+++ b/cextern/erfa/erfa.h
@@ -1,148 +1,21 @@
-//Derived from erfa version 1.1.0
+// This copy of ERFA is bundled with Astropy, based on ERFA v1.1.1
 
 #ifndef ERFAHDEF
 #define ERFAHDEF
 
-#include <math.h>
-
 /*
 **  - - - - - - -
 **   e r f a . h
 **  - - - - - - -
 **
-**  Prototype function declarations and macros for erfa library.
+**  Prototype function declarations for ERFA library.
 **
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
 */
 
-/* Star-independent astrometry parameters */
-typedef struct {
-   double pmt;        /* PM time interval (SSB, Julian years) */
-   double eb[3];      /* SSB to observer (vector, au) */
-   double eh[3];      /* Sun to observer (unit vector) */
-   double em;         /* distance from Sun to observer (au) */
-   double v[3];       /* barycentric observer velocity (vector, c) */
-   double bm1;        /* sqrt(1-|v|^2): reciprocal of Lorenz factor */
-   double bpn[3][3];  /* bias-precession-nutation matrix */
-   double along;      /* longitude + s' + dERA(DUT) (radians) */
-   double phi;        /* geodetic latitude (radians) */
-   double xpl;        /* polar motion xp wrt local meridian (radians) */
-   double ypl;        /* polar motion yp wrt local meridian (radians) */
-   double sphi;       /* sine of geodetic latitude */
-   double cphi;       /* cosine of geodetic latitude */
-   double diurab;     /* magnitude of diurnal aberration vector */
-   double eral;       /* "local" Earth rotation angle (radians) */
-   double refa;       /* refraction constant A (radians) */
-   double refb;       /* refraction constant B (radians) */
-} eraASTROM;
-/* (Vectors eb, eh, em and v are all with respect to BCRS axes.) */
-
-/* Body parameters for light deflection */
-typedef struct {
-   double bm;         /* mass of the body (solar masses) */
-   double dl;         /* deflection limiter (radians^2/2) */
-   double pv[2][3];   /* barycentric PV of the body (au, au/day) */
-} eraLDBODY;
-
-/* Pi */
-#define ERFA_DPI (3.141592653589793238462643)
-
-/* 2Pi */
-#define ERFA_D2PI (6.283185307179586476925287)
-
-/* Radians to degrees */
-#define ERFA_DR2D (57.29577951308232087679815)
-
-/* Degrees to radians */
-#define ERFA_DD2R (1.745329251994329576923691e-2)
-
-/* Radians to arcseconds */
-#define ERFA_DR2AS (206264.8062470963551564734)
-
-/* Arcseconds to radians */
-#define ERFA_DAS2R (4.848136811095359935899141e-6)
-
-/* Seconds of time to radians */
-#define ERFA_DS2R (7.272205216643039903848712e-5)
-
-/* Arcseconds in a full circle */
-#define ERFA_TURNAS (1296000.0)
-
-/* Milliarcseconds to radians */
-#define ERFA_DMAS2R (ERFA_DAS2R / 1e3)
-
-/* Length of tropical year B1900 (days) */
-#define ERFA_DTY (365.242198781)
-
-/* Seconds per day. */
-#define ERFA_DAYSEC (86400.0)
-
-/* Days per Julian year */
-#define ERFA_DJY (365.25)
-
-/* Days per Julian century */
-#define ERFA_DJC (36525.0)
-
-/* Days per Julian millennium */
-#define ERFA_DJM (365250.0)
-
-/* Reference epoch (J2000.0), Julian Date */
-#define ERFA_DJ00 (2451545.0)
-
-/* Julian Date of Modified Julian Date zero */
-#define ERFA_DJM0 (2400000.5)
-
-/* Reference epoch (J2000.0), Modified Julian Date */
-#define ERFA_DJM00 (51544.5)
-
-/* 1977 Jan 1.0 as MJD */
-#define ERFA_DJM77 (43144.0)
-
-/* TT minus TAI (s) */
-#define ERFA_TTMTAI (32.184)
-
-/* Astronomical unit (m) */
-#define ERFA_DAU (149597870e3)
-
-/* Speed of light (m/s) */
-#define ERFA_CMPS 299792458.0
-
-/* Light time for 1 au (s) */
-#define ERFA_AULT 499.004782
-
-/* Speed of light (AU per day) */
-#define ERFA_DC (ERFA_DAYSEC / ERFA_AULT)
-
-/* L_G = 1 - d(TT)/d(TCG) */
-#define ERFA_ELG (6.969290134e-10)
-
-/* L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0 */
-#define ERFA_ELB (1.550519768e-8)
-#define ERFA_TDB0 (-6.55e-5)
-
-/* Schwarzschild radius of the Sun (au) */
-/* = 2 * 1.32712440041e20 / (2.99792458e8)^2 / 1.49597870700e11 */
-#define ERFA_SRS 1.97412574336e-8
-
-/* ERFA_DINT(A) - truncate to nearest whole number towards zero (double) */
-#define ERFA_DINT(A) ((A)<0.0?ceil(A):floor(A))
-
-/* ERFA_DNINT(A) - round to nearest whole number (double) */
-#define ERFA_DNINT(A) ((A)<0.0?ceil((A)-0.5):floor((A)+0.5))
-
-/* ERFA_DSIGN(A,B) - magnitude of A with sign of B (double) */
-#define ERFA_DSIGN(A,B) ((B)<0.0?-fabs(A):fabs(A))
-
-/* max(A,B) - larger (most +ve) of two numbers (generic) */
-#define ERFA_GMAX(A,B) (((A)>(B))?(A):(B))
-
-/* min(A,B) - smaller (least +ve) of two numbers (generic) */
-#define ERFA_GMIN(A,B) (((A)<(B))?(A):(B))
-
-/* Reference ellipsoids */
-#define ERFA_WGS84 1
-#define ERFA_GRS80 2
-#define ERFA_WGS72 3
-
+#include "erfam.h"
+#include "math.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -180,7 +53,7 @@ void eraApco(double date1, double date2,
              eraASTROM *astrom);
 int eraApco13(double utc1, double utc2, double dut1,
               double elong, double phi, double hm, double xp, double yp,
-              double phpa, double tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               eraASTROM *astrom, double *eo);
 void eraApcs(double date1, double date2, double pv[2][3],
              double ebpv[2][3], double ehp[3],
@@ -195,7 +68,7 @@ void eraApio(double sp, double theta,
              eraASTROM *astrom);
 int eraApio13(double utc1, double utc2, double dut1,
               double elong, double phi, double hm, double xp, double yp,
-              double phpa, double tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               eraASTROM *astrom);
 void eraAtci13(double rc, double dc,
                double pr, double pd, double px, double rv,
@@ -213,7 +86,7 @@ int eraAtco13(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 tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               double *aob, double *zob, double *hob,
               double *dob, double *rob, double *eo);
 void eraAtic13(double ri, double di,
@@ -226,7 +99,7 @@ void eraAticqn(double ri, double di, eraASTROM *astrom,
 int eraAtio13(double ri, double di,
               double utc1, double utc2, double dut1,
               double elong, double phi, double hm, double xp, double yp,
-              double phpa, double tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               double *aob, double *zob, double *hob,
               double *dob, double *rob);
 void eraAtioq(double ri, double di, eraASTROM *astrom,
@@ -235,12 +108,12 @@ void eraAtioq(double ri, double di, eraASTROM *astrom,
 int eraAtoc13(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 tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               double *rc, double *dc);
 int eraAtoi13(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 tk, double rh, double wl,
+              double phpa, double tc, double rh, double wl,
               double *ri, double *di);
 void eraAtoiq(const char *type,
               double ob1, double ob2, eraASTROM *astrom,
@@ -251,17 +124,14 @@ void eraLdn(int n, eraLDBODY b[], double ob[3], double sc[3],
             double sn[3]);
 void eraLdsun(double p[3], double e[3], double em, double p1[3]);
 void eraPmpx(double rc, double dc, double pr, double pd,
-             double px, double rv, double pmt, double vob[3],
+             double px, double rv, double pmt, double pob[3],
              double pco[3]);
 int eraPmsafe(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);
-void eraPvtob(double elong, double phi, double hm,
-              double xp, double yp, double sp, double theta,
-              double pv[2][3]);
-void eraRefco(double phpa, double tk, double rh, double wl,
+void eraRefco(double phpa, double tc, double rh, double wl,
               double *refa, double *refb);
 
 /* Astronomy/Ephemerides */
@@ -371,8 +241,10 @@ void eraPnm00b(double date1, double date2, double rbpn[3][3]);
 void eraPnm06a(double date1, double date2, double rnpb[3][3]);
 void eraPnm80(double date1, double date2, double rmatpn[3][3]);
 void eraPom00(double xp, double yp, double sp, double rpom[3][3]);
-void eraPr00(double date1, double date2, double *dpsipr, double *depspr);
-void eraPrec76(double ep01, double ep02, double ep11, double ep12,
+void eraPr00(double date1, double date2,
+             double *dpsipr, double *depspr);
+void eraPrec76(double date01, double date02,
+               double date11, double date12,
                double *zeta, double *z, double *theta);
 double eraS00(double date1, double date2, double x, double y);
 double eraS00a(double date1, double date2);
@@ -562,8 +434,13 @@ void eraS2xpv(double s1, double s2, double pv[2][3], double spv[2][3]);
 void eraSxp(double s, double p[3], double sp[3]);
 void eraSxpv(double s, double pv[2][3], double spv[2][3]);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 
+/* Copyright2 */
 /*----------------------------------------------------------------------
 **  
 **  
diff --git a/cextern/erfa/erfam.h b/cextern/erfa/erfam.h
new file mode 100644
index 0000000..f6d8b71
--- /dev/null
+++ b/cextern/erfa/erfam.h
@@ -0,0 +1,208 @@
+#ifndef ERFAMHDEF
+#define ERFAMHDEF
+
+/*
+**  - - - - - - - -
+**   e r f a m . h
+**  - - - - - - - -
+**
+**  Macros used by ERFA library.
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+
+/* Star-independent astrometry parameters */
+typedef struct {
+   double pmt;        /* PM time interval (SSB, Julian years) */
+   double eb[3];      /* SSB to observer (vector, au) */
+   double eh[3];      /* Sun to observer (unit vector) */
+   double em;         /* distance from Sun to observer (au) */
+   double v[3];       /* barycentric observer velocity (vector, c) */
+   double bm1;        /* sqrt(1-|v|^2): reciprocal of Lorenz factor */
+   double bpn[3][3];  /* bias-precession-nutation matrix */
+   double along;      /* longitude + s' + dERA(DUT) (radians) */
+   double phi;        /* geodetic latitude (radians) */
+   double xpl;        /* polar motion xp wrt local meridian (radians) */
+   double ypl;        /* polar motion yp wrt local meridian (radians) */
+   double sphi;       /* sine of geodetic latitude */
+   double cphi;       /* cosine of geodetic latitude */
+   double diurab;     /* magnitude of diurnal aberration vector */
+   double eral;       /* "local" Earth rotation angle (radians) */
+   double refa;       /* refraction constant A (radians) */
+   double refb;       /* refraction constant B (radians) */
+} eraASTROM;
+/* (Vectors eb, eh, em and v are all with respect to BCRS axes.) */
+
+/* Body parameters for light deflection */
+typedef struct {
+   double bm;         /* mass of the body (solar masses) */
+   double dl;         /* deflection limiter (radians^2/2) */
+   double pv[2][3];   /* barycentric PV of the body (au, au/day) */
+} eraLDBODY;
+
+/* Pi */
+#define ERFA_DPI (3.141592653589793238462643)
+
+/* 2Pi */
+#define ERFA_D2PI (6.283185307179586476925287)
+
+/* Radians to degrees */
+#define ERFA_DR2D (57.29577951308232087679815)
+
+/* Degrees to radians */
+#define ERFA_DD2R (1.745329251994329576923691e-2)
+
+/* Radians to arcseconds */
+#define ERFA_DR2AS (206264.8062470963551564734)
+
+/* Arcseconds to radians */
+#define ERFA_DAS2R (4.848136811095359935899141e-6)
+
+/* Seconds of time to radians */
+#define ERFA_DS2R (7.272205216643039903848712e-5)
+
+/* Arcseconds in a full circle */
+#define ERFA_TURNAS (1296000.0)
+
+/* Milliarcseconds to radians */
+#define ERFA_DMAS2R (ERFA_DAS2R / 1e3)
+
+/* Length of tropical year B1900 (days) */
+#define ERFA_DTY (365.242198781)
+
+/* Seconds per day. */
+#define ERFA_DAYSEC (86400.0)
+
+/* Days per Julian year */
+#define ERFA_DJY (365.25)
+
+/* Days per Julian century */
+#define ERFA_DJC (36525.0)
+
+/* Days per Julian millennium */
+#define ERFA_DJM (365250.0)
+
+/* Reference epoch (J2000.0), Julian Date */
+#define ERFA_DJ00 (2451545.0)
+
+/* Julian Date of Modified Julian Date zero */
+#define ERFA_DJM0 (2400000.5)
+
+/* Reference epoch (J2000.0), Modified Julian Date */
+#define ERFA_DJM00 (51544.5)
+
+/* 1977 Jan 1.0 as MJD */
+#define ERFA_DJM77 (43144.0)
+
+/* TT minus TAI (s) */
+#define ERFA_TTMTAI (32.184)
+
+/* Astronomical unit (m) */
+#define ERFA_DAU (149597870e3)
+
+/* Speed of light (m/s) */
+#define ERFA_CMPS 299792458.0
+
+/* Light time for 1 au (s) */
+#define ERFA_AULT 499.004782
+
+/* Speed of light (AU per day) */
+#define ERFA_DC (ERFA_DAYSEC / ERFA_AULT)
+
+/* L_G = 1 - d(TT)/d(TCG) */
+#define ERFA_ELG (6.969290134e-10)
+
+/* L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0 */
+#define ERFA_ELB (1.550519768e-8)
+#define ERFA_TDB0 (-6.55e-5)
+
+/* Schwarzschild radius of the Sun (au) */
+/* = 2 * 1.32712440041e20 / (2.99792458e8)^2 / 1.49597870700e11 */
+#define ERFA_SRS 1.97412574336e-8
+
+/* ERFA_DINT(A) - truncate to nearest whole number towards zero (double) */
+#define ERFA_DINT(A) ((A)<0.0?ceil(A):floor(A))
+
+/* ERFA_DNINT(A) - round to nearest whole number (double) */
+#define ERFA_DNINT(A) ((A)<0.0?ceil((A)-0.5):floor((A)+0.5))
+
+/* ERFA_DSIGN(A,B) - magnitude of A with sign of B (double) */
+#define ERFA_DSIGN(A,B) ((B)<0.0?-fabs(A):fabs(A))
+
+/* max(A,B) - larger (most +ve) of two numbers (generic) */
+#define ERFA_GMAX(A,B) (((A)>(B))?(A):(B))
+
+/* min(A,B) - smaller (least +ve) of two numbers (generic) */
+#define ERFA_GMIN(A,B) (((A)<(B))?(A):(B))
+
+/* Reference ellipsoids */
+#define ERFA_WGS84 1
+#define ERFA_GRS80 2
+#define ERFA_WGS72 3
+
+#endif
+
+
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fad03.c b/cextern/erfa/fad03.c
new file mode 100644
index 0000000..5f10c0f
--- /dev/null
+++ b/cextern/erfa/fad03.c
@@ -0,0 +1,112 @@
+#include "erfa.h"
+
+double eraFad03(double t)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean elongation of the Moon from the Sun (IERS Conventions 2003). */
+   a = fmod(          1072260.703692 +
+             t * ( 1602961601.2090 +
+             t * (        - 6.3706 +
+             t * (          0.006593 +
+             t * (        - 0.00003169 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fae03.c b/cextern/erfa/fae03.c
new file mode 100644
index 0000000..c332ee4
--- /dev/null
+++ b/cextern/erfa/fae03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFae03(double t)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Earth (IERS Conventions 2003). */
+   a = fmod(1.753470314 + 628.3075849991 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/faf03.c b/cextern/erfa/faf03.c
new file mode 100644
index 0000000..74e8e6b
--- /dev/null
+++ b/cextern/erfa/faf03.c
@@ -0,0 +1,115 @@
+#include "erfa.h"
+
+double eraFaf03(double t)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of the Moon minus that of the ascending node */
+/* (IERS Conventions 2003).                                    */
+   a = fmod(           335779.526232 +
+             t * ( 1739527262.8478 +
+             t * (       - 12.7512 +
+             t * (        - 0.001037 +
+             t * (          0.00000417 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
+
+   return a;
+
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/faju03.c b/cextern/erfa/faju03.c
new file mode 100644
index 0000000..28988b7
--- /dev/null
+++ b/cextern/erfa/faju03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFaju03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Jupiter (IERS Conventions 2003). */
+   a = fmod(0.599546497 + 52.9690962641 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fal03.c b/cextern/erfa/fal03.c
new file mode 100644
index 0000000..648f733
--- /dev/null
+++ b/cextern/erfa/fal03.c
@@ -0,0 +1,112 @@
+#include "erfa.h"
+
+double eraFal03(double t)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean anomaly of the Moon (IERS Conventions 2003). */
+   a = fmod(           485868.249036  +
+             t * ( 1717915923.2178 +
+             t * (         31.8792 +
+             t * (          0.051635 +
+             t * (        - 0.00024470 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/falp03.c b/cextern/erfa/falp03.c
new file mode 100644
index 0000000..c299837
--- /dev/null
+++ b/cextern/erfa/falp03.c
@@ -0,0 +1,112 @@
+#include "erfa.h"
+
+double eraFalp03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean anomaly of the Sun (IERS Conventions 2003). */
+   a = fmod(         1287104.793048 +
+             t * ( 129596581.0481 +
+             t * (       - 0.5532 +
+             t * (         0.000136 +
+             t * (       - 0.00001149 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fama03.c b/cextern/erfa/fama03.c
new file mode 100644
index 0000000..770c82b
--- /dev/null
+++ b/cextern/erfa/fama03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFama03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Mars (IERS Conventions 2003). */
+   a = fmod(6.203480913 + 334.0612426700 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fame03.c b/cextern/erfa/fame03.c
new file mode 100644
index 0000000..74caff8
--- /dev/null
+++ b/cextern/erfa/fame03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFame03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Mercury (IERS Conventions 2003). */
+   a = fmod(4.402608842 + 2608.7903141574 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fane03.c b/cextern/erfa/fane03.c
new file mode 100644
index 0000000..66b13e6
--- /dev/null
+++ b/cextern/erfa/fane03.c
@@ -0,0 +1,108 @@
+#include "erfa.h"
+
+double eraFane03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Neptune (IERS Conventions 2003). */
+   a = fmod(5.311886287 + 3.8133035638 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/faom03.c b/cextern/erfa/faom03.c
new file mode 100644
index 0000000..b349466
--- /dev/null
+++ b/cextern/erfa/faom03.c
@@ -0,0 +1,113 @@
+#include "erfa.h"
+
+double eraFaom03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of the Moon's ascending node */
+/* (IERS Conventions 2003).                    */
+   a = fmod(          450160.398036 +
+             t * ( - 6962890.5431 +
+             t * (         7.4722 +
+             t * (         0.007702 +
+             t * (       - 0.00005939 ) ) ) ), ERFA_TURNAS ) * ERFA_DAS2R;
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fapa03.c b/cextern/erfa/fapa03.c
new file mode 100644
index 0000000..3db1ac8
--- /dev/null
+++ b/cextern/erfa/fapa03.c
@@ -0,0 +1,112 @@
+#include "erfa.h"
+
+double eraFapa03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* General accumulated precession in longitude. */
+   a = (0.024381750 + 0.00000538691 * t) * t;
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fasa03.c b/cextern/erfa/fasa03.c
new file mode 100644
index 0000000..1f19e2b
--- /dev/null
+++ b/cextern/erfa/fasa03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFasa03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Saturn (IERS Conventions 2003). */
+   a = fmod(0.874016757 + 21.3299104960 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/faur03.c b/cextern/erfa/faur03.c
new file mode 100644
index 0000000..f15a9b8
--- /dev/null
+++ b/cextern/erfa/faur03.c
@@ -0,0 +1,108 @@
+#include "erfa.h"
+
+double eraFaur03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Uranus (IERS Conventions 2003). */
+   a = fmod(5.481293872 + 7.4781598567 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fave03.c b/cextern/erfa/fave03.c
new file mode 100644
index 0000000..0f60dd3
--- /dev/null
+++ b/cextern/erfa/fave03.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+double eraFave03(double t)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double a;
+
+
+/* Mean longitude of Venus (IERS Conventions 2003). */
+   a = fmod(3.176146697 + 1021.3285546211 * t, ERFA_D2PI);
+
+   return a;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fk52h.c b/cextern/erfa/fk52h.c
new file mode 100644
index 0000000..59bdaa1
--- /dev/null
+++ b/cextern/erfa/fk52h.c
@@ -0,0 +1,152 @@
+#include "erfa.h"
+
+void eraFk52h(double r5, double d5,
+              double dr5, double dd5, double px5, double rv5,
+              double *rh, double *dh,
+              double *drh, double *ddh, double *pxh, double *rvh)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i;
+   double pv5[2][3], r5h[3][3], s5h[3], wxp[3], vv[3], pvh[2][3];
+
+
+/* FK5 barycentric position/velocity pv-vector (normalized). */
+   eraStarpv(r5, d5, dr5, dd5, px5, rv5, pv5);
+
+/* FK5 to Hipparcos orientation matrix and spin vector. */
+   eraFk5hip(r5h, s5h);
+
+/* Make spin units per day instead of per year. */
+   for ( i = 0; i < 3; s5h[i++] /= 365.25 );
+
+/* Orient the FK5 position into the Hipparcos system. */
+   eraRxp(r5h, pv5[0], pvh[0]);
+
+/* Apply spin to the position giving an extra space motion component. */
+   eraPxp(pv5[0], s5h, wxp);
+
+/* Add this component to the FK5 space motion. */
+   eraPpp(wxp, pv5[1], vv);
+
+/* Orient the FK5 space motion into the Hipparcos system. */
+   eraRxp(r5h, vv, pvh[1]);
+
+/* Hipparcos pv-vector to spherical. */
+   eraPvstar(pvh, rh, dh, drh, ddh, pxh, rvh);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fk5hip.c b/cextern/erfa/fk5hip.c
new file mode 100644
index 0000000..77299f3
--- /dev/null
+++ b/cextern/erfa/fk5hip.c
@@ -0,0 +1,135 @@
+#include "erfa.h"
+
+void eraFk5hip(double r5h[3][3], double s5h[3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double v[3];
+
+/* FK5 wrt Hipparcos orientation and spin (radians, radians/year) */
+   double epx, epy, epz;
+   double omx, omy, omz;
+
+
+   epx = -19.9e-3 * ERFA_DAS2R;
+   epy =  -9.1e-3 * ERFA_DAS2R;
+   epz =  22.9e-3 * ERFA_DAS2R;
+
+   omx = -0.30e-3 * ERFA_DAS2R;
+   omy =  0.60e-3 * ERFA_DAS2R;
+   omz =  0.70e-3 * ERFA_DAS2R;
+
+/* FK5 to Hipparcos orientation expressed as an r-vector. */
+   v[0] = epx;
+   v[1] = epy;
+   v[2] = epz;
+
+/* Re-express as an r-matrix. */
+   eraRv2m(v, r5h);
+
+/* Hipparcos wrt FK5 spin expressed as an r-vector. */
+   s5h[0] = omx;
+   s5h[1] = omy;
+   s5h[2] = omz;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fk5hz.c b/cextern/erfa/fk5hz.c
new file mode 100644
index 0000000..7481783
--- /dev/null
+++ b/cextern/erfa/fk5hz.c
@@ -0,0 +1,169 @@
+#include "erfa.h"
+
+void eraFk5hz(double r5, double d5, double date1, double date2,
+              double *rh, double *dh)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, p5e[3], r5h[3][3], s5h[3], vst[3], rst[3][3], p5[3],
+          ph[3], w;
+
+
+/* Interval from given date to fundamental epoch J2000.0 (JY). */
+   t = - ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
+
+/* FK5 barycentric position vector. */
+   eraS2c(r5, d5, p5e);
+
+/* FK5 to Hipparcos orientation matrix and spin vector. */
+   eraFk5hip(r5h, s5h);
+
+/* Accumulated Hipparcos wrt FK5 spin over that interval. */
+   eraSxp(t, s5h, vst);
+
+/* Express the accumulated spin as a rotation matrix. */
+   eraRv2m(vst, rst);
+
+/* Derotate the vector's FK5 axes back to date. */
+   eraTrxp(rst, p5e, p5);
+
+/* Rotate the vector into the Hipparcos system. */
+   eraRxp(r5h, p5, ph);
+
+/* Hipparcos vector to spherical. */
+   eraC2s(ph, &w, dh);
+   *rh = eraAnp(w);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fw2m.c b/cextern/erfa/fw2m.c
new file mode 100644
index 0000000..a66bf22
--- /dev/null
+++ b/cextern/erfa/fw2m.c
@@ -0,0 +1,143 @@
+#include "erfa.h"
+
+void eraFw2m(double gamb, double phib, double psi, double eps,
+             double r[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Construct the matrix. */
+   eraIr(r);
+   eraRz(gamb, r);
+   eraRx(phib, r);
+   eraRz(-psi, r);
+   eraRx(-eps, r);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/fw2xy.c b/cextern/erfa/fw2xy.c
new file mode 100644
index 0000000..0ef2a74
--- /dev/null
+++ b/cextern/erfa/fw2xy.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+void eraFw2xy(double gamb, double phib, double psi, double eps,
+              double *x, double *y)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r[3][3];
+
+
+/* Form NxPxB matrix. */
+   eraFw2m(gamb, phib, psi, eps, r);
+
+/* Extract CIP X,Y. */
+   eraBpn2xy(r, x, y);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gc2gd.c b/cextern/erfa/gc2gd.c
new file mode 100644
index 0000000..ff5cc5d
--- /dev/null
+++ b/cextern/erfa/gc2gd.c
@@ -0,0 +1,143 @@
+#include "erfa.h"
+
+int eraGc2gd ( int n, double xyz[3],
+               double *elong, double *phi, double *height )
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   double a, f;
+
+
+/* Obtain reference ellipsoid parameters. */
+   j = eraEform ( n, &a, &f );
+
+/* If OK, transform x,y,z to longitude, geodetic latitude, height. */
+   if ( j == 0 ) {
+      j = eraGc2gde ( a, f, xyz, elong, phi, height );
+      if ( j < 0 ) j = -2;
+   }
+
+/* Deal with any errors. */
+   if ( j < 0 ) {
+      *elong = -1e9;
+      *phi = -1e9;
+      *height = -1e9;
+   }
+
+/* Return the status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gc2gde.c b/cextern/erfa/gc2gde.c
new file mode 100644
index 0000000..6afa064
--- /dev/null
+++ b/cextern/erfa/gc2gde.c
@@ -0,0 +1,208 @@
+#include "erfa.h"
+
+int eraGc2gde ( double a, double f, double xyz[3],
+                double *elong, double *phi, double *height )
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double aeps2, e2, e4t, ec2, ec, b, x, y, z, p2, absz, p, s0, pn, zc,
+                 c0, c02, c03, s02, s03, a02, a0, a03, d0, f0, b0, s1,
+                 cc, s12, cc2;
+
+
+/* ------------- */
+/* Preliminaries */
+/* ------------- */
+
+/* Validate ellipsoid parameters. */
+   if ( f < 0.0 || f >= 1.0 ) return -1;
+   if ( a <= 0.0 ) return -2;
+
+/* Functions of ellipsoid parameters (with further validation of f). */
+   aeps2 = a*a * 1e-32;
+   e2 = (2.0 - f) * f;
+   e4t = e2*e2 * 1.5;
+   ec2 = 1.0 - e2;
+   if ( ec2 <= 0.0 ) return -1;
+   ec = sqrt(ec2);
+   b = a * ec;
+
+/* Cartesian components. */
+   x = xyz[0];
+   y = xyz[1];
+   z = xyz[2];
+
+/* Distance from polar axis squared. */
+   p2 = x*x + y*y;
+
+/* Longitude. */
+   *elong = p2 != 0.0 ? atan2(y, x) : 0.0;
+
+/* Unsigned z-coordinate. */
+   absz = fabs(z);
+
+/* Proceed unless polar case. */
+   if ( p2 > aeps2 ) {
+
+   /* Distance from polar axis. */
+      p = sqrt(p2);
+
+   /* Normalization. */
+      s0 = absz / a;
+      pn = p / a;
+      zc = ec * s0;
+
+   /* Prepare Newton correction factors. */
+      c0 = ec * pn;
+      c02 = c0 * c0;
+      c03 = c02 * c0;
+      s02 = s0 * s0;
+      s03 = s02 * s0;
+      a02 = c02 + s02;
+      a0 = sqrt(a02);
+      a03 = a02 * a0;
+      d0 = zc*a03 + e2*s03;
+      f0 = pn*a03 - e2*c03;
+
+   /* Prepare Halley correction factor. */
+      b0 = e4t * s02 * c02 * pn * (a0 - ec);
+      s1 = d0*f0 - b0*s0;
+      cc = ec * (f0*f0 - b0*c0);
+
+   /* Evaluate latitude and height. */
+      *phi = atan(s1/cc);
+      s12 = s1 * s1;
+      cc2 = cc * cc;
+      *height = (p*cc + absz*s1 - a * sqrt(ec2*s12 + cc2)) /
+                                                        sqrt(s12 + cc2);
+   } else {
+
+   /* Exception: pole. */
+      *phi = ERFA_DPI / 2.0;
+      *height = absz - b;
+   }
+
+/* Restore sign of latitude. */
+   if ( z < 0 ) *phi = -*phi;
+
+/* OK status. */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gd2gc.c b/cextern/erfa/gd2gc.c
new file mode 100644
index 0000000..d6bc399
--- /dev/null
+++ b/cextern/erfa/gd2gc.c
@@ -0,0 +1,142 @@
+#include "erfa.h"
+
+int eraGd2gc ( int n, double elong, double phi, double height,
+               double xyz[3] )
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j;
+   double a, f;
+
+
+/* Obtain reference ellipsoid parameters. */
+   j = eraEform ( n, &a, &f );
+
+/* If OK, transform longitude, geodetic latitude, height to x,y,z. */
+   if ( j == 0 ) {
+      j = eraGd2gce ( a, f, elong, phi, height, xyz );
+      if ( j != 0 ) j = -2;
+   }
+
+/* Deal with any errors. */
+   if ( j != 0 ) eraZp ( xyz );
+
+/* Return the status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gd2gce.c b/cextern/erfa/gd2gce.c
new file mode 100644
index 0000000..5aae512
--- /dev/null
+++ b/cextern/erfa/gd2gce.c
@@ -0,0 +1,146 @@
+#include "erfa.h"
+
+int eraGd2gce ( double a, double f, double elong, double phi,
+                double height, double xyz[3] )
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double sp, cp, w, d, ac, as, r;
+
+
+/* Functions of geodetic latitude. */
+   sp = sin(phi);
+   cp = cos(phi);
+   w = 1.0 - f;
+   w = w * w;
+   d = cp*cp + w*sp*sp;
+   if ( d <= 0.0 ) return -1;
+   ac = a / sqrt(d);
+   as = w * ac;
+
+/* Geocentric vector. */
+   r = (ac + height) * cp;
+   xyz[0] = r * cos(elong);
+   xyz[1] = r * sin(elong);
+   xyz[2] = (as + height) * sp;
+
+/* Success. */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gmst00.c b/cextern/erfa/gmst00.c
new file mode 100644
index 0000000..8b3d51e
--- /dev/null
+++ b/cextern/erfa/gmst00.c
@@ -0,0 +1,154 @@
+#include "erfa.h"
+
+double eraGmst00(double uta, double utb, double tta, double ttb)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, gmst;
+
+
+/* TT Julian centuries since J2000.0. */
+   t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
+
+/* Greenwich Mean Sidereal Time, IAU 2000. */
+   gmst = eraAnp(eraEra00(uta, utb) +
+                   (     0.014506   +
+                   (  4612.15739966 +
+                   (     1.39667721 +
+                   (    -0.00009344 +
+                   (     0.00001882 )
+          * t) * t) * t) * t) * ERFA_DAS2R);
+
+   return gmst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gmst06.c b/cextern/erfa/gmst06.c
new file mode 100644
index 0000000..a79045d
--- /dev/null
+++ b/cextern/erfa/gmst06.c
@@ -0,0 +1,145 @@
+#include "erfa.h"
+
+double eraGmst06(double uta, double utb, double tta, double ttb)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, gmst;
+
+
+/* TT Julian centuries since J2000.0. */
+   t = ((tta - ERFA_DJ00) + ttb) / ERFA_DJC;
+
+/* Greenwich mean sidereal time, IAU 2006. */
+   gmst = eraAnp(eraEra00(uta, utb) +
+                  (    0.014506     +
+                  (  4612.156534    +
+                  (     1.3915817   +
+                  (    -0.00000044  +
+                  (    -0.000029956 +
+                  (    -0.0000000368 )
+          * t) * t) * t) * t) * t) * ERFA_DAS2R);
+
+   return gmst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gmst82.c b/cextern/erfa/gmst82.c
new file mode 100644
index 0000000..5ddf032
--- /dev/null
+++ b/cextern/erfa/gmst82.c
@@ -0,0 +1,160 @@
+#include "erfa.h"
+
+double eraGmst82(double dj1, double dj2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Coefficients of IAU 1982 GMST-UT1 model */
+   double A = 24110.54841  -  ERFA_DAYSEC / 2.0;
+   double B = 8640184.812866;
+   double C = 0.093104;
+   double D =  -6.2e-6;
+
+/* Note: the first constant, A, has to be adjusted by 12 hours */
+/* because the UT1 is supplied as a Julian date, which begins  */
+/* at noon.                                                    */
+
+   double d1, d2, t, f, gmst;
+
+
+/* Julian centuries since fundamental epoch. */
+   if (dj1 < dj2) {
+      d1 = dj1;
+      d2 = dj2;
+   } else {
+      d1 = dj2;
+      d2 = dj1;
+   }
+   t = (d1 + (d2 - ERFA_DJ00)) / ERFA_DJC;
+
+/* Fractional part of JD(UT1), in seconds. */
+   f = ERFA_DAYSEC * (fmod(d1, 1.0) + fmod(d2, 1.0));
+
+/* GMST at this UT1. */
+   gmst = eraAnp(ERFA_DS2R * ((A + (B + (C + D * t) * t) * t) + f));
+
+   return gmst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gst00a.c b/cextern/erfa/gst00a.c
new file mode 100644
index 0000000..e54bb0b
--- /dev/null
+++ b/cextern/erfa/gst00a.c
@@ -0,0 +1,147 @@
+#include "erfa.h"
+
+double eraGst00a(double uta, double utb, double tta, double ttb)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gmst00, ee00a, gst;
+
+
+   gmst00 = eraGmst00(uta, utb, tta, ttb);
+   ee00a = eraEe00a(tta, ttb);
+   gst = eraAnp(gmst00 + ee00a);
+
+   return gst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gst00b.c b/cextern/erfa/gst00b.c
new file mode 100644
index 0000000..d34ae67
--- /dev/null
+++ b/cextern/erfa/gst00b.c
@@ -0,0 +1,155 @@
+#include "erfa.h"
+
+double eraGst00b(double uta, double utb)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gmst00, ee00b, gst;
+
+
+   gmst00 = eraGmst00(uta, utb, uta, utb);
+   ee00b = eraEe00b(uta, utb);
+   gst = eraAnp(gmst00 + ee00b);
+
+   return gst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gst06.c b/cextern/erfa/gst06.c
new file mode 100644
index 0000000..79a1c37
--- /dev/null
+++ b/cextern/erfa/gst06.c
@@ -0,0 +1,149 @@
+#include "erfa.h"
+
+double eraGst06(double uta, double utb, double tta, double ttb,
+                double rnpb[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y, s, era, eors, gst;
+
+
+/* Extract CIP coordinates. */
+   eraBpn2xy(rnpb, &x, &y);
+
+/* The CIO locator, s. */
+   s = eraS06(tta, ttb, x, y);
+
+/* Greenwich apparent sidereal time. */
+   era = eraEra00(uta, utb);
+   eors = eraEors(rnpb, s);
+   gst = eraAnp(era - eors);
+
+   return gst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gst06a.c b/cextern/erfa/gst06a.c
new file mode 100644
index 0000000..fb38999
--- /dev/null
+++ b/cextern/erfa/gst06a.c
@@ -0,0 +1,140 @@
+#include "erfa.h"
+
+double eraGst06a(double uta, double utb, double tta, double ttb)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rnpb[3][3], gst;
+
+
+/* Classical nutation x precession x bias matrix, IAU 2000A. */
+   eraPnm06a(tta, ttb, rnpb);
+
+/* Greenwich apparent sidereal time. */
+   gst = eraGst06(uta, utb, tta, ttb, rnpb);
+
+   return gst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/gst94.c b/cextern/erfa/gst94.c
new file mode 100644
index 0000000..79f7ba8
--- /dev/null
+++ b/cextern/erfa/gst94.c
@@ -0,0 +1,140 @@
+#include "erfa.h"
+
+double eraGst94(double uta, double utb)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gmst82, eqeq94, gst;
+
+
+   gmst82 = eraGmst82(uta, utb);
+   eqeq94 = eraEqeq94(uta, utb);
+   gst = eraAnp(gmst82  + eqeq94);
+
+   return gst;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/h2fk5.c b/cextern/erfa/h2fk5.c
new file mode 100644
index 0000000..f7132f4
--- /dev/null
+++ b/cextern/erfa/h2fk5.c
@@ -0,0 +1,157 @@
+#include "erfa.h"
+
+void eraH2fk5(double rh, double dh,
+              double drh, double ddh, double pxh, double rvh,
+              double *r5, double *d5,
+              double *dr5, double *dd5, double *px5, double *rv5)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i;
+   double pvh[2][3], r5h[3][3], s5h[3], sh[3], wxp[3], vv[3], pv5[2][3];
+
+
+/* Hipparcos barycentric position/velocity pv-vector (normalized). */
+   eraStarpv(rh, dh, drh, ddh, pxh, rvh, pvh);
+
+/* FK5 to Hipparcos orientation matrix and spin vector. */
+   eraFk5hip(r5h, s5h);
+
+/* Make spin units per day instead of per year. */
+   for ( i = 0; i < 3; s5h[i++] /= 365.25 );
+
+/* Orient the spin into the Hipparcos system. */
+   eraRxp(r5h, s5h, sh);
+
+/* De-orient the Hipparcos position into the FK5 system. */
+   eraTrxp(r5h, pvh[0], pv5[0]);
+
+/* Apply spin to the position giving an extra space motion component. */
+   eraPxp(pvh[0], sh, wxp);
+
+/* Subtract this component from the Hipparcos space motion. */
+   eraPmp(pvh[1], wxp, vv);
+
+/* De-orient the Hipparcos space motion into the FK5 system. */
+   eraTrxp(r5h, vv, pv5[1]);
+
+/* FK5 pv-vector to spherical. */
+   eraPvstar(pv5, r5, d5, dr5, dd5, px5, rv5);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/hfk5z.c b/cextern/erfa/hfk5z.c
new file mode 100644
index 0000000..d2c442e
--- /dev/null
+++ b/cextern/erfa/hfk5z.c
@@ -0,0 +1,184 @@
+#include "erfa.h"
+
+void eraHfk5z(double rh, double dh, double date1, double date2,
+              double *r5, double *d5, double *dr5, double *dd5)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, ph[3], r5h[3][3], s5h[3], sh[3], vst[3],
+   rst[3][3], r5ht[3][3], pv5e[2][3], vv[3],
+   w, r, v;
+
+
+/* Time interval from fundamental epoch J2000.0 to given date (JY). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJY;
+
+/* Hipparcos barycentric position vector (normalized). */
+   eraS2c(rh, dh, ph);
+
+/* FK5 to Hipparcos orientation matrix and spin vector. */
+   eraFk5hip(r5h, s5h);
+
+/* Rotate the spin into the Hipparcos system. */
+   eraRxp(r5h, s5h, sh);
+
+/* Accumulated Hipparcos wrt FK5 spin over that interval. */
+   eraSxp(t, s5h, vst);
+
+/* Express the accumulated spin as a rotation matrix. */
+   eraRv2m(vst, rst);
+
+/* Rotation matrix:  accumulated spin, then FK5 to Hipparcos. */
+   eraRxr(r5h, rst, r5ht);
+
+/* De-orient & de-spin the Hipparcos position into FK5 J2000.0. */
+   eraTrxp(r5ht, ph, pv5e[0]);
+
+/* Apply spin to the position giving a space motion. */
+   eraPxp(sh, ph, vv);
+
+/* De-orient & de-spin the Hipparcos space motion into FK5 J2000.0. */
+   eraTrxp(r5ht, vv, pv5e[1]);
+
+/* FK5 position/velocity pv-vector to spherical. */
+   eraPv2s(pv5e, &w, d5, &r, dr5, dd5, &v);
+   *r5 = eraAnp(w);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ir.c b/cextern/erfa/ir.c
new file mode 100644
index 0000000..ea077d6
--- /dev/null
+++ b/cextern/erfa/ir.c
@@ -0,0 +1,92 @@
+#include "erfa.h"
+
+void eraIr(double r[3][3])
+/*
+**  - - - - - -
+**   e r a I r
+**  - - - - - -
+**
+**  Initialize an r-matrix to the identity matrix.
+**
+**  Returned:
+**     r       double[3][3]    r-matrix
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   r[0][0] = 1.0;
+   r[0][1] = 0.0;
+   r[0][2] = 0.0;
+   r[1][0] = 0.0;
+   r[1][1] = 1.0;
+   r[1][2] = 0.0;
+   r[2][0] = 0.0;
+   r[2][1] = 0.0;
+   r[2][2] = 1.0;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/jd2cal.c b/cextern/erfa/jd2cal.c
new file mode 100644
index 0000000..16c73c6
--- /dev/null
+++ b/cextern/erfa/jd2cal.c
@@ -0,0 +1,164 @@
+#include "erfa.h"
+
+int eraJd2cal(double dj1, double dj2,
+              int *iy, int *im, int *id, double *fd)
+/*
+**  - - - - - - - - - -
+**   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 3)
+**
+**  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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Minimum and maximum allowed JD */
+   const double DJMIN = -68569.5;
+   const double DJMAX = 1e9;
+
+   long jd, l, n, i, k;
+   double dj, d1, d2, f1, f2, f, d;
+
+
+/* Verify date is acceptable. */
+   dj = dj1 + dj2;
+   if (dj < DJMIN || dj > DJMAX) return -1;
+
+/* Copy the date, big then small, and re-align to midnight. */
+   if (dj1 >= dj2) {
+      d1 = dj1;
+      d2 = dj2;
+   } else {
+      d1 = dj2;
+      d2 = dj1;
+   }
+   d2 -= 0.5;
+
+/* Separate day and fraction. */
+   f1 = fmod(d1, 1.0);
+   f2 = fmod(d2, 1.0);
+   f = fmod(f1 + f2, 1.0);
+   if (f < 0.0) f += 1.0;
+   d = floor(d1 - f1) + floor(d2 - f2) + floor(f1 + f2 - f);
+   jd = (long) floor(d) + 1L;
+
+/* Express day in Gregorian calendar. */
+   l = jd + 68569L;
+   n = (4L * l) / 146097L;
+   l -= (146097L * n + 3L) / 4L;
+   i = (4000L * (l + 1L)) / 1461001L;
+   l -= (1461L * i) / 4L - 31L;
+   k = (80L * l) / 2447L;
+   *id = (int) (l - (2447L * k) / 80L);
+   l = k / 11L;
+   *im = (int) (k + 2L - 12L * l);
+   *iy = (int) (100L * (n - 49L) + i + l);
+   *fd = f;
+
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/jdcalf.c b/cextern/erfa/jdcalf.c
new file mode 100644
index 0000000..3bd54ab
--- /dev/null
+++ b/cextern/erfa/jdcalf.c
@@ -0,0 +1,170 @@
+#include "erfa.h"
+
+int eraJdcalf(int ndp, double dj1, double dj2, int iymdf[4])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int j, js;
+   double denom, d1, d2, f1, f2, f;
+
+
+/* Denominator of fraction (e.g. 100 for 2 decimal places). */
+   if ((ndp >= 0) && (ndp <= 9)) {
+      j = 0;
+      denom = pow(10.0, ndp);
+   } else {
+      j = 1;
+      denom = 1.0;
+   }
+
+/* Copy the date, big then small, and realign to midnight. */
+   if (dj1 >= dj2) {
+      d1 = dj1;
+      d2 = dj2;
+   } else {
+      d1 = dj2;
+      d2 = dj1;
+   }
+   d2 -= 0.5;
+
+/* Separate days and fractions. */
+   f1 = fmod(d1, 1.0);
+   f2 = fmod(d2, 1.0);
+   d1 = floor(d1 - f1);
+   d2 = floor(d2 - f2);
+
+/* Round the total fraction to the specified number of places. */
+   f = floor((f1+f2)*denom + 0.5) / denom;
+
+/* Re-assemble the rounded date and re-align to noon. */
+   d2 += f + 0.5;
+
+/* Convert to Gregorian calendar. */
+   js = eraJd2cal(d1, d2, &iymdf[0], &iymdf[1], &iymdf[2], &f);
+   if (js == 0) {
+      iymdf[3] = (int) (f * denom);
+   } else {
+      j = js;
+   }
+
+/* Return the status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ld.c b/cextern/erfa/ld.c
new file mode 100644
index 0000000..c732ab7
--- /dev/null
+++ b/cextern/erfa/ld.c
@@ -0,0 +1,161 @@
+#include "erfa.h"
+
+void eraLd(double bm, double p[3], double q[3], double e[3],
+           double em, double dlim, double p1[3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i;
+   double qpe[3], qdqpe, w, eq[3], peq[3];
+
+
+/* q . (q + e). */
+   for (i = 0; i < 3; i++) {
+      qpe[i] = q[i] + e[i];
+   }
+   qdqpe = eraPdp(q, qpe);
+
+/* 2 x G x bm / ( em x c^2 x ( q . (q + e) ) ). */
+   w = bm * ERFA_SRS / em / ERFA_GMAX(qdqpe,dlim);
+
+/* p x (e x q). */
+   eraPxp(e, q, eq);
+   eraPxp(p, eq, peq);
+
+/* Apply the deflection. */
+   for (i = 0; i < 3; i++) {
+      p1[i] = p[i] + w*peq[i];
+   }
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ldn.c b/cextern/erfa/ldn.c
new file mode 100644
index 0000000..cd56f48
--- /dev/null
+++ b/cextern/erfa/ldn.c
@@ -0,0 +1,183 @@
+#include "erfa.h"
+
+void eraLdn(int n, eraLDBODY b[], double ob[3], double sc[3],
+            double sn[3])
+/*+
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Light time for 1 AU (days) */
+   const double CR = ERFA_AULT/ERFA_DAYSEC;
+
+   int i;
+   double  v[3], dt, ev[3], em, e[3];
+
+
+/* Star direction prior to deflection. */
+   eraCp(sc, sn);
+
+/* Body by body. */
+   for ( i = 0; i < n; i++ ) {
+
+   /* Body to observer vector at epoch of observation (au). */
+      eraPmp ( ob, b[i].pv[0], v );
+
+   /* Minus the time since the light passed the body (days). */
+      dt = eraPdp(sn,v) * CR;
+
+   /* Neutralize if the star is "behind" the observer. */
+      dt = ERFA_GMIN(dt, 0.0);
+
+   /* Backtrack the body to the time the light was passing the body. */
+      eraPpsp(v, -dt, b[i].pv[1], ev);
+
+   /* Body to observer vector as magnitude and direction. */
+      eraPn(ev, &em, e);
+
+   /* Apply light deflection for this body. */
+      eraLd ( b[i].bm, sn, sn, e, em, b[i].dl, sn );
+
+   /* Next body. */
+   }
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ldsun.c b/cextern/erfa/ldsun.c
new file mode 100644
index 0000000..9ace77e
--- /dev/null
+++ b/cextern/erfa/ldsun.c
@@ -0,0 +1,105 @@
+#include "erfa.h"
+
+void eraLdsun(double p[3], double e[3], double em, double p1[3])
+/*
+**  - - - - - - - - -
+**   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 about 9 arcsec, falling to
+**     zero for zero separation. (The chosen threshold is within the
+**     solar limb for all solar-system applications.)
+**
+**  3) The arguments p and p1 can be the same array.
+**
+**  Called:
+**     eraLd        light deflection by a solar-system body
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraLd(1.0, p, p, e, em, 1e-9, p1);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/num00a.c b/cextern/erfa/num00a.c
new file mode 100644
index 0000000..2cb19d4
--- /dev/null
+++ b/cextern/erfa/num00a.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+void eraNum00a(double date1, double date2, double rmatn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3];
+
+
+/* Obtain the required matrix (discarding other results). */
+   eraPn00a(date1, date2,
+            &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/num00b.c b/cextern/erfa/num00b.c
new file mode 100644
index 0000000..87e4361
--- /dev/null
+++ b/cextern/erfa/num00b.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+void eraNum00b(double date1, double date2, double rmatn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rbpn[3][3];
+
+
+/* Obtain the required matrix (discarding other results). */
+   eraPn00b(date1, date2,
+            &dpsi, &deps, &epsa, rb, rp, rbp, rmatn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/num06a.c b/cextern/erfa/num06a.c
new file mode 100644
index 0000000..824e487
--- /dev/null
+++ b/cextern/erfa/num06a.c
@@ -0,0 +1,134 @@
+#include "erfa.h"
+
+void eraNum06a(double date1, double date2, double rmatn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double eps, dp, de;
+
+
+/* Mean obliquity. */
+   eps = eraObl06(date1, date2);
+
+/* Nutation components. */
+   eraNut06a(date1, date2, &dp, &de);
+
+/* Nutation matrix. */
+   eraNumat(eps, dp, de, rmatn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/numat.c b/cextern/erfa/numat.c
new file mode 100644
index 0000000..6023271
--- /dev/null
+++ b/cextern/erfa/numat.c
@@ -0,0 +1,118 @@
+#include "erfa.h"
+
+void eraNumat(double epsa, double dpsi, double deps, double rmatn[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Build the rotation matrix. */
+   eraIr(rmatn);
+   eraRx(epsa, rmatn);
+   eraRz(-dpsi, rmatn);
+   eraRx(-(epsa + deps), rmatn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/nut00a.c b/cextern/erfa/nut00a.c
new file mode 100644
index 0000000..bb63d72
--- /dev/null
+++ b/cextern/erfa/nut00a.c
@@ -0,0 +1,2056 @@
+#include "erfa.h"
+
+void eraNut00a(double date1, double date2, double *dpsi, double *deps)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i;
+   double t, el, elp, f, d, om, arg, dp, de, sarg, carg,
+          al, af, ad, aom, alme, alve, alea, alma,
+          alju, alsa, alur, alne, apa, dpsils, depsls,
+          dpsipl, depspl;
+
+/* Units of 0.1 microarcsecond to radians */
+   const double U2R = ERFA_DAS2R / 1e7;
+
+/* ------------------------- */
+/* Luni-Solar nutation model */
+/* ------------------------- */
+
+/* The units for the sine and cosine coefficients are */
+/* 0.1 microarcsecond and the same per Julian century */
+
+   static const struct {
+      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
+      double sp,spt,cp;     /* longitude sin, t*sin, cos coefficients */
+      double ce,cet,se;     /* obliquity cos, t*cos, sin coefficients */
+   } xls[] = {
+
+   /* 1- 10 */
+      { 0, 0, 0, 0, 1,
+         -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0},
+      { 0, 0, 2,-2, 2,
+           -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0},
+      { 0, 0, 2, 0, 2,-2276413.0,-234.0,2796.0,978459.0,-485.0, 1374.0},
+      { 0, 0, 0, 0, 2,2074554.0, 207.0, -698.0,-897492.0,470.0, -291.0},
+      { 0, 1, 0, 0, 0,1475877.0,-3633.0,11817.0,73871.0,-184.0,-1924.0},
+      { 0, 1, 2,-2, 2,-516821.0,1226.0, -524.0,224386.0,-677.0, -174.0},
+      { 1, 0, 0, 0, 0, 711159.0,  73.0, -872.0,  -6750.0,  0.0,  358.0},
+      { 0, 0, 2, 0, 1,-387298.0,-367.0,  380.0, 200728.0, 18.0,  318.0},
+      { 1, 0, 2, 0, 2,-301461.0, -36.0,  816.0, 129025.0,-63.0,  367.0},
+      { 0,-1, 2,-2, 2, 215829.0,-494.0,  111.0, -95929.0,299.0,  132.0},
+
+   /* 11-20 */
+      { 0, 0, 2,-2, 1, 128227.0, 137.0,  181.0, -68982.0, -9.0,   39.0},
+      {-1, 0, 2, 0, 2, 123457.0,  11.0,   19.0, -53311.0, 32.0,   -4.0},
+      {-1, 0, 0, 2, 0, 156994.0,  10.0, -168.0,  -1235.0,  0.0,   82.0},
+      { 1, 0, 0, 0, 1,  63110.0,  63.0,   27.0, -33228.0,  0.0,   -9.0},
+      {-1, 0, 0, 0, 1, -57976.0, -63.0, -189.0,  31429.0,  0.0,  -75.0},
+      {-1, 0, 2, 2, 2, -59641.0, -11.0,  149.0,  25543.0,-11.0,   66.0},
+      { 1, 0, 2, 0, 1, -51613.0, -42.0,  129.0,  26366.0,  0.0,   78.0},
+      {-2, 0, 2, 0, 1,  45893.0,  50.0,   31.0, -24236.0,-10.0,   20.0},
+      { 0, 0, 0, 2, 0,  63384.0,  11.0, -150.0,  -1220.0,  0.0,   29.0},
+      { 0, 0, 2, 2, 2, -38571.0,  -1.0,  158.0,  16452.0,-11.0,   68.0},
+
+   /* 21-30 */
+      { 0,-2, 2,-2, 2,  32481.0,   0.0,    0.0, -13870.0,  0.0,    0.0},
+      {-2, 0, 0, 2, 0, -47722.0,   0.0,  -18.0,    477.0,  0.0,  -25.0},
+      { 2, 0, 2, 0, 2, -31046.0,  -1.0,  131.0,  13238.0,-11.0,   59.0},
+      { 1, 0, 2,-2, 2,  28593.0,   0.0,   -1.0, -12338.0, 10.0,   -3.0},
+      {-1, 0, 2, 0, 1,  20441.0,  21.0,   10.0, -10758.0,  0.0,   -3.0},
+      { 2, 0, 0, 0, 0,  29243.0,   0.0,  -74.0,   -609.0,  0.0,   13.0},
+      { 0, 0, 2, 0, 0,  25887.0,   0.0,  -66.0,   -550.0,  0.0,   11.0},
+      { 0, 1, 0, 0, 1, -14053.0, -25.0,   79.0,   8551.0, -2.0,  -45.0},
+      {-1, 0, 0, 2, 1,  15164.0,  10.0,   11.0,  -8001.0,  0.0,   -1.0},
+      { 0, 2, 2,-2, 2, -15794.0,  72.0,  -16.0,   6850.0,-42.0,   -5.0},
+
+   /* 31-40 */
+      { 0, 0,-2, 2, 0,  21783.0,   0.0,   13.0,   -167.0,  0.0,   13.0},
+      { 1, 0, 0,-2, 1, -12873.0, -10.0,  -37.0,   6953.0,  0.0,  -14.0},
+      { 0,-1, 0, 0, 1, -12654.0,  11.0,   63.0,   6415.0,  0.0,   26.0},
+      {-1, 0, 2, 2, 1, -10204.0,   0.0,   25.0,   5222.0,  0.0,   15.0},
+      { 0, 2, 0, 0, 0,  16707.0, -85.0,  -10.0,    168.0, -1.0,   10.0},
+      { 1, 0, 2, 2, 2,  -7691.0,   0.0,   44.0,   3268.0,  0.0,   19.0},
+      {-2, 0, 2, 0, 0, -11024.0,   0.0,  -14.0,    104.0,  0.0,    2.0},
+      { 0, 1, 2, 0, 2,   7566.0, -21.0,  -11.0,  -3250.0,  0.0,   -5.0},
+      { 0, 0, 2, 2, 1,  -6637.0, -11.0,   25.0,   3353.0,  0.0,   14.0},
+      { 0,-1, 2, 0, 2,  -7141.0,  21.0,    8.0,   3070.0,  0.0,    4.0},
+
+   /* 41-50 */
+      { 0, 0, 0, 2, 1,  -6302.0, -11.0,    2.0,   3272.0,  0.0,    4.0},
+      { 1, 0, 2,-2, 1,   5800.0,  10.0,    2.0,  -3045.0,  0.0,   -1.0},
+      { 2, 0, 2,-2, 2,   6443.0,   0.0,   -7.0,  -2768.0,  0.0,   -4.0},
+      {-2, 0, 0, 2, 1,  -5774.0, -11.0,  -15.0,   3041.0,  0.0,   -5.0},
+      { 2, 0, 2, 0, 1,  -5350.0,   0.0,   21.0,   2695.0,  0.0,   12.0},
+      { 0,-1, 2,-2, 1,  -4752.0, -11.0,   -3.0,   2719.0,  0.0,   -3.0},
+      { 0, 0, 0,-2, 1,  -4940.0, -11.0,  -21.0,   2720.0,  0.0,   -9.0},
+      {-1,-1, 0, 2, 0,   7350.0,   0.0,   -8.0,    -51.0,  0.0,    4.0},
+      { 2, 0, 0,-2, 1,   4065.0,   0.0,    6.0,  -2206.0,  0.0,    1.0},
+      { 1, 0, 0, 2, 0,   6579.0,   0.0,  -24.0,   -199.0,  0.0,    2.0},
+
+   /* 51-60 */
+      { 0, 1, 2,-2, 1,   3579.0,   0.0,    5.0,  -1900.0,  0.0,    1.0},
+      { 1,-1, 0, 0, 0,   4725.0,   0.0,   -6.0,    -41.0,  0.0,    3.0},
+      {-2, 0, 2, 0, 2,  -3075.0,   0.0,   -2.0,   1313.0,  0.0,   -1.0},
+      { 3, 0, 2, 0, 2,  -2904.0,   0.0,   15.0,   1233.0,  0.0,    7.0},
+      { 0,-1, 0, 2, 0,   4348.0,   0.0,  -10.0,    -81.0,  0.0,    2.0},
+      { 1,-1, 2, 0, 2,  -2878.0,   0.0,    8.0,   1232.0,  0.0,    4.0},
+      { 0, 0, 0, 1, 0,  -4230.0,   0.0,    5.0,    -20.0,  0.0,   -2.0},
+      {-1,-1, 2, 2, 2,  -2819.0,   0.0,    7.0,   1207.0,  0.0,    3.0},
+      {-1, 0, 2, 0, 0,  -4056.0,   0.0,    5.0,     40.0,  0.0,   -2.0},
+      { 0,-1, 2, 2, 2,  -2647.0,   0.0,   11.0,   1129.0,  0.0,    5.0},
+
+   /* 61-70 */
+      {-2, 0, 0, 0, 1,  -2294.0,   0.0,  -10.0,   1266.0,  0.0,   -4.0},
+      { 1, 1, 2, 0, 2,   2481.0,   0.0,   -7.0,  -1062.0,  0.0,   -3.0},
+      { 2, 0, 0, 0, 1,   2179.0,   0.0,   -2.0,  -1129.0,  0.0,   -2.0},
+      {-1, 1, 0, 1, 0,   3276.0,   0.0,    1.0,     -9.0,  0.0,    0.0},
+      { 1, 1, 0, 0, 0,  -3389.0,   0.0,    5.0,     35.0,  0.0,   -2.0},
+      { 1, 0, 2, 0, 0,   3339.0,   0.0,  -13.0,   -107.0,  0.0,    1.0},
+      {-1, 0, 2,-2, 1,  -1987.0,   0.0,   -6.0,   1073.0,  0.0,   -2.0},
+      { 1, 0, 0, 0, 2,  -1981.0,   0.0,    0.0,    854.0,  0.0,    0.0},
+      {-1, 0, 0, 1, 0,   4026.0,   0.0, -353.0,   -553.0,  0.0, -139.0},
+      { 0, 0, 2, 1, 2,   1660.0,   0.0,   -5.0,   -710.0,  0.0,   -2.0},
+
+   /* 71-80 */
+      {-1, 0, 2, 4, 2,  -1521.0,   0.0,    9.0,    647.0,  0.0,    4.0},
+      {-1, 1, 0, 1, 1,   1314.0,   0.0,    0.0,   -700.0,  0.0,    0.0},
+      { 0,-2, 2,-2, 1,  -1283.0,   0.0,    0.0,    672.0,  0.0,    0.0},
+      { 1, 0, 2, 2, 1,  -1331.0,   0.0,    8.0,    663.0,  0.0,    4.0},
+      {-2, 0, 2, 2, 2,   1383.0,   0.0,   -2.0,   -594.0,  0.0,   -2.0},
+      {-1, 0, 0, 0, 2,   1405.0,   0.0,    4.0,   -610.0,  0.0,    2.0},
+      { 1, 1, 2,-2, 2,   1290.0,   0.0,    0.0,   -556.0,  0.0,    0.0},
+      {-2, 0, 2, 4, 2,  -1214.0,   0.0,    5.0,    518.0,  0.0,    2.0},
+      {-1, 0, 4, 0, 2,   1146.0,   0.0,   -3.0,   -490.0,  0.0,   -1.0},
+      { 2, 0, 2,-2, 1,   1019.0,   0.0,   -1.0,   -527.0,  0.0,   -1.0},
+
+   /* 81-90 */
+      { 2, 0, 2, 2, 2,  -1100.0,   0.0,    9.0,    465.0,  0.0,    4.0},
+      { 1, 0, 0, 2, 1,   -970.0,   0.0,    2.0,    496.0,  0.0,    1.0},
+      { 3, 0, 0, 0, 0,   1575.0,   0.0,   -6.0,    -50.0,  0.0,    0.0},
+      { 3, 0, 2,-2, 2,    934.0,   0.0,   -3.0,   -399.0,  0.0,   -1.0},
+      { 0, 0, 4,-2, 2,    922.0,   0.0,   -1.0,   -395.0,  0.0,   -1.0},
+      { 0, 1, 2, 0, 1,    815.0,   0.0,   -1.0,   -422.0,  0.0,   -1.0},
+      { 0, 0,-2, 2, 1,    834.0,   0.0,    2.0,   -440.0,  0.0,    1.0},
+      { 0, 0, 2,-2, 3,   1248.0,   0.0,    0.0,   -170.0,  0.0,    1.0},
+      {-1, 0, 0, 4, 0,   1338.0,   0.0,   -5.0,    -39.0,  0.0,    0.0},
+      { 2, 0,-2, 0, 1,    716.0,   0.0,   -2.0,   -389.0,  0.0,   -1.0},
+
+   /* 91-100 */
+      {-2, 0, 0, 4, 0,   1282.0,   0.0,   -3.0,    -23.0,  0.0,    1.0},
+      {-1,-1, 0, 2, 1,    742.0,   0.0,    1.0,   -391.0,  0.0,    0.0},
+      {-1, 0, 0, 1, 1,   1020.0,   0.0,  -25.0,   -495.0,  0.0,  -10.0},
+      { 0, 1, 0, 0, 2,    715.0,   0.0,   -4.0,   -326.0,  0.0,    2.0},
+      { 0, 0,-2, 0, 1,   -666.0,   0.0,   -3.0,    369.0,  0.0,   -1.0},
+      { 0,-1, 2, 0, 1,   -667.0,   0.0,    1.0,    346.0,  0.0,    1.0},
+      { 0, 0, 2,-1, 2,   -704.0,   0.0,    0.0,    304.0,  0.0,    0.0},
+      { 0, 0, 2, 4, 2,   -694.0,   0.0,    5.0,    294.0,  0.0,    2.0},
+      {-2,-1, 0, 2, 0,  -1014.0,   0.0,   -1.0,      4.0,  0.0,   -1.0},
+      { 1, 1, 0,-2, 1,   -585.0,   0.0,   -2.0,    316.0,  0.0,   -1.0},
+
+   /* 101-110 */
+      {-1, 1, 0, 2, 0,   -949.0,   0.0,    1.0,      8.0,  0.0,   -1.0},
+      {-1, 1, 0, 1, 2,   -595.0,   0.0,    0.0,    258.0,  0.0,    0.0},
+      { 1,-1, 0, 0, 1,    528.0,   0.0,    0.0,   -279.0,  0.0,    0.0},
+      { 1,-1, 2, 2, 2,   -590.0,   0.0,    4.0,    252.0,  0.0,    2.0},
+      {-1, 1, 2, 2, 2,    570.0,   0.0,   -2.0,   -244.0,  0.0,   -1.0},
+      { 3, 0, 2, 0, 1,   -502.0,   0.0,    3.0,    250.0,  0.0,    2.0},
+      { 0, 1,-2, 2, 0,   -875.0,   0.0,    1.0,     29.0,  0.0,    0.0},
+      {-1, 0, 0,-2, 1,   -492.0,   0.0,   -3.0,    275.0,  0.0,   -1.0},
+      { 0, 1, 2, 2, 2,    535.0,   0.0,   -2.0,   -228.0,  0.0,   -1.0},
+      {-1,-1, 2, 2, 1,   -467.0,   0.0,    1.0,    240.0,  0.0,    1.0},
+
+   /* 111-120 */
+      { 0,-1, 0, 0, 2,    591.0,   0.0,    0.0,   -253.0,  0.0,    0.0},
+      { 1, 0, 2,-4, 1,   -453.0,   0.0,   -1.0,    244.0,  0.0,   -1.0},
+      {-1, 0,-2, 2, 0,    766.0,   0.0,    1.0,      9.0,  0.0,    0.0},
+      { 0,-1, 2, 2, 1,   -446.0,   0.0,    2.0,    225.0,  0.0,    1.0},
+      { 2,-1, 2, 0, 2,   -488.0,   0.0,    2.0,    207.0,  0.0,    1.0},
+      { 0, 0, 0, 2, 2,   -468.0,   0.0,    0.0,    201.0,  0.0,    0.0},
+      { 1,-1, 2, 0, 1,   -421.0,   0.0,    1.0,    216.0,  0.0,    1.0},
+      {-1, 1, 2, 0, 2,    463.0,   0.0,    0.0,   -200.0,  0.0,    0.0},
+      { 0, 1, 0, 2, 0,   -673.0,   0.0,    2.0,     14.0,  0.0,    0.0},
+      { 0,-1,-2, 2, 0,    658.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 121-130 */
+      { 0, 3, 2,-2, 2,   -438.0,   0.0,    0.0,    188.0,  0.0,    0.0},
+      { 0, 0, 0, 1, 1,   -390.0,   0.0,    0.0,    205.0,  0.0,    0.0},
+      {-1, 0, 2, 2, 0,    639.0, -11.0,   -2.0,    -19.0,  0.0,    0.0},
+      { 2, 1, 2, 0, 2,    412.0,   0.0,   -2.0,   -176.0,  0.0,   -1.0},
+      { 1, 1, 0, 0, 1,   -361.0,   0.0,    0.0,    189.0,  0.0,    0.0},
+      { 1, 1, 2, 0, 1,    360.0,   0.0,   -1.0,   -185.0,  0.0,   -1.0},
+      { 2, 0, 0, 2, 0,    588.0,   0.0,   -3.0,    -24.0,  0.0,    0.0},
+      { 1, 0,-2, 2, 0,   -578.0,   0.0,    1.0,      5.0,  0.0,    0.0},
+      {-1, 0, 0, 2, 2,   -396.0,   0.0,    0.0,    171.0,  0.0,    0.0},
+      { 0, 1, 0, 1, 0,    565.0,   0.0,   -1.0,     -6.0,  0.0,    0.0},
+
+   /* 131-140 */
+      { 0, 1, 0,-2, 1,   -335.0,   0.0,   -1.0,    184.0,  0.0,   -1.0},
+      {-1, 0, 2,-2, 2,    357.0,   0.0,    1.0,   -154.0,  0.0,    0.0},
+      { 0, 0, 0,-1, 1,    321.0,   0.0,    1.0,   -174.0,  0.0,    0.0},
+      {-1, 1, 0, 0, 1,   -301.0,   0.0,   -1.0,    162.0,  0.0,    0.0},
+      { 1, 0, 2,-1, 2,   -334.0,   0.0,    0.0,    144.0,  0.0,    0.0},
+      { 1,-1, 0, 2, 0,    493.0,   0.0,   -2.0,    -15.0,  0.0,    0.0},
+      { 0, 0, 0, 4, 0,    494.0,   0.0,   -2.0,    -19.0,  0.0,    0.0},
+      { 1, 0, 2, 1, 2,    337.0,   0.0,   -1.0,   -143.0,  0.0,   -1.0},
+      { 0, 0, 2, 1, 1,    280.0,   0.0,   -1.0,   -144.0,  0.0,    0.0},
+      { 1, 0, 0,-2, 2,    309.0,   0.0,    1.0,   -134.0,  0.0,    0.0},
+
+   /* 141-150 */
+      {-1, 0, 2, 4, 1,   -263.0,   0.0,    2.0,    131.0,  0.0,    1.0},
+      { 1, 0,-2, 0, 1,    253.0,   0.0,    1.0,   -138.0,  0.0,    0.0},
+      { 1, 1, 2,-2, 1,    245.0,   0.0,    0.0,   -128.0,  0.0,    0.0},
+      { 0, 0, 2, 2, 0,    416.0,   0.0,   -2.0,    -17.0,  0.0,    0.0},
+      {-1, 0, 2,-1, 1,   -229.0,   0.0,    0.0,    128.0,  0.0,    0.0},
+      {-2, 0, 2, 2, 1,    231.0,   0.0,    0.0,   -120.0,  0.0,    0.0},
+      { 4, 0, 2, 0, 2,   -259.0,   0.0,    2.0,    109.0,  0.0,    1.0},
+      { 2,-1, 0, 0, 0,    375.0,   0.0,   -1.0,     -8.0,  0.0,    0.0},
+      { 2, 1, 2,-2, 2,    252.0,   0.0,    0.0,   -108.0,  0.0,    0.0},
+      { 0, 1, 2, 1, 2,   -245.0,   0.0,    1.0,    104.0,  0.0,    0.0},
+
+   /* 151-160 */
+      { 1, 0, 4,-2, 2,    243.0,   0.0,   -1.0,   -104.0,  0.0,    0.0},
+      {-1,-1, 0, 0, 1,    208.0,   0.0,    1.0,   -112.0,  0.0,    0.0},
+      { 0, 1, 0, 2, 1,    199.0,   0.0,    0.0,   -102.0,  0.0,    0.0},
+      {-2, 0, 2, 4, 1,   -208.0,   0.0,    1.0,    105.0,  0.0,    0.0},
+      { 2, 0, 2, 0, 0,    335.0,   0.0,   -2.0,    -14.0,  0.0,    0.0},
+      { 1, 0, 0, 1, 0,   -325.0,   0.0,    1.0,      7.0,  0.0,    0.0},
+      {-1, 0, 0, 4, 1,   -187.0,   0.0,    0.0,     96.0,  0.0,    0.0},
+      {-1, 0, 4, 0, 1,    197.0,   0.0,   -1.0,   -100.0,  0.0,    0.0},
+      { 2, 0, 2, 2, 1,   -192.0,   0.0,    2.0,     94.0,  0.0,    1.0},
+      { 0, 0, 2,-3, 2,   -188.0,   0.0,    0.0,     83.0,  0.0,    0.0},
+
+   /* 161-170 */
+      {-1,-2, 0, 2, 0,    276.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 1, 0, 0, 0,   -286.0,   0.0,    1.0,      6.0,  0.0,    0.0},
+      { 0, 0, 4, 0, 2,    186.0,   0.0,   -1.0,    -79.0,  0.0,    0.0},
+      { 0, 0, 0, 0, 3,   -219.0,   0.0,    0.0,     43.0,  0.0,    0.0},
+      { 0, 3, 0, 0, 0,    276.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 2,-4, 1,   -153.0,   0.0,   -1.0,     84.0,  0.0,    0.0},
+      { 0,-1, 0, 2, 1,   -156.0,   0.0,    0.0,     81.0,  0.0,    0.0},
+      { 0, 0, 0, 4, 1,   -154.0,   0.0,    1.0,     78.0,  0.0,    0.0},
+      {-1,-1, 2, 4, 2,   -174.0,   0.0,    1.0,     75.0,  0.0,    0.0},
+      { 1, 0, 2, 4, 2,   -163.0,   0.0,    2.0,     69.0,  0.0,    1.0},
+
+   /* 171-180 */
+      {-2, 2, 0, 2, 0,   -228.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-2,-1, 2, 0, 1,     91.0,   0.0,   -4.0,    -54.0,  0.0,   -2.0},
+      {-2, 0, 0, 2, 2,    175.0,   0.0,    0.0,    -75.0,  0.0,    0.0},
+      {-1,-1, 2, 0, 2,   -159.0,   0.0,    0.0,     69.0,  0.0,    0.0},
+      { 0, 0, 4,-2, 1,    141.0,   0.0,    0.0,    -72.0,  0.0,    0.0},
+      { 3, 0, 2,-2, 1,    147.0,   0.0,    0.0,    -75.0,  0.0,    0.0},
+      {-2,-1, 0, 2, 1,   -132.0,   0.0,    0.0,     69.0,  0.0,    0.0},
+      { 1, 0, 0,-1, 1,    159.0,   0.0,  -28.0,    -54.0,  0.0,   11.0},
+      { 0,-2, 0, 2, 0,    213.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      {-2, 0, 0, 4, 1,    123.0,   0.0,    0.0,    -64.0,  0.0,    0.0},
+
+   /* 181-190 */
+      {-3, 0, 0, 0, 1,   -118.0,   0.0,   -1.0,     66.0,  0.0,    0.0},
+      { 1, 1, 2, 2, 2,    144.0,   0.0,   -1.0,    -61.0,  0.0,    0.0},
+      { 0, 0, 2, 4, 1,   -121.0,   0.0,    1.0,     60.0,  0.0,    0.0},
+      { 3, 0, 2, 2, 2,   -134.0,   0.0,    1.0,     56.0,  0.0,    1.0},
+      {-1, 1, 2,-2, 1,   -105.0,   0.0,    0.0,     57.0,  0.0,    0.0},
+      { 2, 0, 0,-4, 1,   -102.0,   0.0,    0.0,     56.0,  0.0,    0.0},
+      { 0, 0, 0,-2, 2,    120.0,   0.0,    0.0,    -52.0,  0.0,    0.0},
+      { 2, 0, 2,-4, 1,    101.0,   0.0,    0.0,    -54.0,  0.0,    0.0},
+      {-1, 1, 0, 2, 1,   -113.0,   0.0,    0.0,     59.0,  0.0,    0.0},
+      { 0, 0, 2,-1, 1,   -106.0,   0.0,    0.0,     61.0,  0.0,    0.0},
+
+   /* 191-200 */
+      { 0,-2, 2, 2, 2,   -129.0,   0.0,    1.0,     55.0,  0.0,    0.0},
+      { 2, 0, 0, 2, 1,   -114.0,   0.0,    0.0,     57.0,  0.0,    0.0},
+      { 4, 0, 2,-2, 2,    113.0,   0.0,   -1.0,    -49.0,  0.0,    0.0},
+      { 2, 0, 0,-2, 2,   -102.0,   0.0,    0.0,     44.0,  0.0,    0.0},
+      { 0, 2, 0, 0, 1,    -94.0,   0.0,    0.0,     51.0,  0.0,    0.0},
+      { 1, 0, 0,-4, 1,   -100.0,   0.0,   -1.0,     56.0,  0.0,    0.0},
+      { 0, 2, 2,-2, 1,     87.0,   0.0,    0.0,    -47.0,  0.0,    0.0},
+      {-3, 0, 0, 4, 0,    161.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-1, 1, 2, 0, 1,     96.0,   0.0,    0.0,    -50.0,  0.0,    0.0},
+      {-1,-1, 0, 4, 0,    151.0,   0.0,   -1.0,     -5.0,  0.0,    0.0},
+
+   /* 201-210 */
+      {-1,-2, 2, 2, 2,   -104.0,   0.0,    0.0,     44.0,  0.0,    0.0},
+      {-2,-1, 2, 4, 2,   -110.0,   0.0,    0.0,     48.0,  0.0,    0.0},
+      { 1,-1, 2, 2, 1,   -100.0,   0.0,    1.0,     50.0,  0.0,    0.0},
+      {-2, 1, 0, 2, 0,     92.0,   0.0,   -5.0,     12.0,  0.0,   -2.0},
+      {-2, 1, 2, 0, 1,     82.0,   0.0,    0.0,    -45.0,  0.0,    0.0},
+      { 2, 1, 0,-2, 1,     82.0,   0.0,    0.0,    -45.0,  0.0,    0.0},
+      {-3, 0, 2, 0, 1,    -78.0,   0.0,    0.0,     41.0,  0.0,    0.0},
+      {-2, 0, 2,-2, 1,    -77.0,   0.0,    0.0,     43.0,  0.0,    0.0},
+      {-1, 1, 0, 2, 2,      2.0,   0.0,    0.0,     54.0,  0.0,    0.0},
+      { 0,-1, 2,-1, 2,     94.0,   0.0,    0.0,    -40.0,  0.0,    0.0},
+
+   /* 211-220 */
+      {-1, 0, 4,-2, 2,    -93.0,   0.0,    0.0,     40.0,  0.0,    0.0},
+      { 0,-2, 2, 0, 2,    -83.0,   0.0,   10.0,     40.0,  0.0,   -2.0},
+      {-1, 0, 2, 1, 2,     83.0,   0.0,    0.0,    -36.0,  0.0,    0.0},
+      { 2, 0, 0, 0, 2,    -91.0,   0.0,    0.0,     39.0,  0.0,    0.0},
+      { 0, 0, 2, 0, 3,    128.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-2, 0, 4, 0, 2,    -79.0,   0.0,    0.0,     34.0,  0.0,    0.0},
+      {-1, 0,-2, 0, 1,    -83.0,   0.0,    0.0,     47.0,  0.0,    0.0},
+      {-1, 1, 2, 2, 1,     84.0,   0.0,    0.0,    -44.0,  0.0,    0.0},
+      { 3, 0, 0, 0, 1,     83.0,   0.0,    0.0,    -43.0,  0.0,    0.0},
+      {-1, 0, 2, 3, 2,     91.0,   0.0,    0.0,    -39.0,  0.0,    0.0},
+
+   /* 221-230 */
+      { 2,-1, 2, 0, 1,    -77.0,   0.0,    0.0,     39.0,  0.0,    0.0},
+      { 0, 1, 2, 2, 1,     84.0,   0.0,    0.0,    -43.0,  0.0,    0.0},
+      { 0,-1, 2, 4, 2,    -92.0,   0.0,    1.0,     39.0,  0.0,    0.0},
+      { 2,-1, 2, 2, 2,    -92.0,   0.0,    1.0,     39.0,  0.0,    0.0},
+      { 0, 2,-2, 2, 0,    -94.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 2,-1, 1,     68.0,   0.0,    0.0,    -36.0,  0.0,    0.0},
+      { 0,-2, 0, 0, 1,    -61.0,   0.0,    0.0,     32.0,  0.0,    0.0},
+      { 1, 0, 2,-4, 2,     71.0,   0.0,    0.0,    -31.0,  0.0,    0.0},
+      { 1,-1, 0,-2, 1,     62.0,   0.0,    0.0,    -34.0,  0.0,    0.0},
+      {-1,-1, 2, 0, 1,    -63.0,   0.0,    0.0,     33.0,  0.0,    0.0},
+
+   /* 231-240 */
+      { 1,-1, 2,-2, 2,    -73.0,   0.0,    0.0,     32.0,  0.0,    0.0},
+      {-2,-1, 0, 4, 0,    115.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 0, 0, 3, 0,   -103.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2,-1, 2, 2, 2,     63.0,   0.0,    0.0,    -28.0,  0.0,    0.0},
+      { 0, 2, 2, 0, 2,     74.0,   0.0,    0.0,    -32.0,  0.0,    0.0},
+      { 1, 1, 0, 2, 0,   -103.0,   0.0,   -3.0,      3.0,  0.0,   -1.0},
+      { 2, 0, 2,-1, 2,    -69.0,   0.0,    0.0,     30.0,  0.0,    0.0},
+      { 1, 0, 2, 1, 1,     57.0,   0.0,    0.0,    -29.0,  0.0,    0.0},
+      { 4, 0, 0, 0, 0,     94.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 2, 1, 2, 0, 1,     64.0,   0.0,    0.0,    -33.0,  0.0,    0.0},
+
+   /* 241-250 */
+      { 3,-1, 2, 0, 2,    -63.0,   0.0,    0.0,     26.0,  0.0,    0.0},
+      {-2, 2, 0, 2, 1,    -38.0,   0.0,    0.0,     20.0,  0.0,    0.0},
+      { 1, 0, 2,-3, 1,    -43.0,   0.0,    0.0,     24.0,  0.0,    0.0},
+      { 1, 1, 2,-4, 1,    -45.0,   0.0,    0.0,     23.0,  0.0,    0.0},
+      {-1,-1, 2,-2, 1,     47.0,   0.0,    0.0,    -24.0,  0.0,    0.0},
+      { 0,-1, 0,-1, 1,    -48.0,   0.0,    0.0,     25.0,  0.0,    0.0},
+      { 0,-1, 0,-2, 1,     45.0,   0.0,    0.0,    -26.0,  0.0,    0.0},
+      {-2, 0, 0, 0, 2,     56.0,   0.0,    0.0,    -25.0,  0.0,    0.0},
+      {-2, 0,-2, 2, 0,     88.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 0,-2, 4, 0,    -75.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 251-260 */
+      { 1,-2, 0, 0, 0,     85.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 0, 1, 1,     49.0,   0.0,    0.0,    -26.0,  0.0,    0.0},
+      {-1, 2, 0, 2, 0,    -74.0,   0.0,   -3.0,     -1.0,  0.0,   -1.0},
+      { 1,-1, 2,-2, 1,    -39.0,   0.0,    0.0,     21.0,  0.0,    0.0},
+      { 1, 2, 2,-2, 2,     45.0,   0.0,    0.0,    -20.0,  0.0,    0.0},
+      { 2,-1, 2,-2, 2,     51.0,   0.0,    0.0,    -22.0,  0.0,    0.0},
+      { 1, 0, 2,-1, 1,    -40.0,   0.0,    0.0,     21.0,  0.0,    0.0},
+      { 2, 1, 2,-2, 1,     41.0,   0.0,    0.0,    -21.0,  0.0,    0.0},
+      {-2, 0, 0,-2, 1,    -42.0,   0.0,    0.0,     24.0,  0.0,    0.0},
+      { 1,-2, 2, 0, 2,    -51.0,   0.0,    0.0,     22.0,  0.0,    0.0},
+
+   /* 261-270 */
+      { 0, 1, 2, 1, 1,    -42.0,   0.0,    0.0,     22.0,  0.0,    0.0},
+      { 1, 0, 4,-2, 1,     39.0,   0.0,    0.0,    -21.0,  0.0,    0.0},
+      {-2, 0, 4, 2, 2,     46.0,   0.0,    0.0,    -18.0,  0.0,    0.0},
+      { 1, 1, 2, 1, 2,    -53.0,   0.0,    0.0,     22.0,  0.0,    0.0},
+      { 1, 0, 0, 4, 0,     82.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 1, 0, 2, 2, 0,     81.0,   0.0,   -1.0,     -4.0,  0.0,    0.0},
+      { 2, 0, 2, 1, 2,     47.0,   0.0,    0.0,    -19.0,  0.0,    0.0},
+      { 3, 1, 2, 0, 2,     53.0,   0.0,    0.0,    -23.0,  0.0,    0.0},
+      { 4, 0, 2, 0, 1,    -45.0,   0.0,    0.0,     22.0,  0.0,    0.0},
+      {-2,-1, 2, 0, 0,    -44.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 271-280 */
+      { 0, 1,-2, 2, 1,    -33.0,   0.0,    0.0,     16.0,  0.0,    0.0},
+      { 1, 0,-2, 1, 0,    -61.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 0,-1,-2, 2, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
+      { 2,-1, 0,-2, 1,    -38.0,   0.0,    0.0,     19.0,  0.0,    0.0},
+      {-1, 0, 2,-1, 2,    -33.0,   0.0,    0.0,     21.0,  0.0,    0.0},
+      { 1, 0, 2,-3, 2,    -60.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 2,-2, 3,     48.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
+      { 0, 0, 2,-3, 1,     27.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
+      {-1, 0,-2, 2, 1,     38.0,   0.0,    0.0,    -20.0,  0.0,    0.0},
+      { 0, 0, 2,-4, 2,     31.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
+
+   /* 281-290 */
+      {-2, 1, 0, 0, 1,    -29.0,   0.0,    0.0,     15.0,  0.0,    0.0},
+      {-1, 0, 0,-1, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
+      { 2, 0, 2,-4, 2,    -32.0,   0.0,    0.0,     15.0,  0.0,    0.0},
+      { 0, 0, 4,-4, 4,     45.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
+      { 0, 0, 4,-4, 2,    -44.0,   0.0,    0.0,     19.0,  0.0,    0.0},
+      {-1,-2, 0, 2, 1,     28.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
+      {-2, 0, 0, 3, 0,    -51.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0,-2, 2, 1,    -36.0,   0.0,    0.0,     20.0,  0.0,    0.0},
+      {-3, 0, 2, 2, 2,     44.0,   0.0,    0.0,    -19.0,  0.0,    0.0},
+      {-3, 0, 2, 2, 1,     26.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
+
+   /* 291-300 */
+      {-2, 0, 2, 2, 0,    -60.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2,-1, 0, 0, 1,     35.0,   0.0,    0.0,    -18.0,  0.0,    0.0},
+      {-2, 1, 2, 2, 2,    -27.0,   0.0,    0.0,     11.0,  0.0,    0.0},
+      { 1, 1, 0, 1, 0,     47.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0, 1, 4,-2, 2,     36.0,   0.0,    0.0,    -15.0,  0.0,    0.0},
+      {-1, 1, 0,-2, 1,    -36.0,   0.0,    0.0,     20.0,  0.0,    0.0},
+      { 0, 0, 0,-4, 1,    -35.0,   0.0,    0.0,     19.0,  0.0,    0.0},
+      { 1,-1, 0, 2, 1,    -37.0,   0.0,    0.0,     19.0,  0.0,    0.0},
+      { 1, 1, 0, 2, 1,     32.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
+      {-1, 2, 2, 2, 2,     35.0,   0.0,    0.0,    -14.0,  0.0,    0.0},
+
+   /* 301-310 */
+      { 3, 1, 2,-2, 2,     32.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
+      { 0,-1, 0, 4, 0,     65.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2,-1, 0, 2, 0,     47.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0, 0, 4, 0, 1,     32.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
+      { 2, 0, 4,-2, 2,     37.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
+      {-1,-1, 2, 4, 1,    -30.0,   0.0,    0.0,     15.0,  0.0,    0.0},
+      { 1, 0, 0, 4, 1,    -32.0,   0.0,    0.0,     16.0,  0.0,    0.0},
+      { 1,-2, 2, 2, 2,    -31.0,   0.0,    0.0,     13.0,  0.0,    0.0},
+      { 0, 0, 2, 3, 2,     37.0,   0.0,    0.0,    -16.0,  0.0,    0.0},
+      {-1, 1, 2, 4, 2,     31.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
+
+   /* 311-320 */
+      { 3, 0, 0, 2, 0,     49.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 0, 4, 2, 2,     32.0,   0.0,    0.0,    -13.0,  0.0,    0.0},
+      { 1, 1, 2, 2, 1,     23.0,   0.0,    0.0,    -12.0,  0.0,    0.0},
+      {-2, 0, 2, 6, 2,    -43.0,   0.0,    0.0,     18.0,  0.0,    0.0},
+      { 2, 1, 2, 2, 2,     26.0,   0.0,    0.0,    -11.0,  0.0,    0.0},
+      {-1, 0, 2, 6, 2,    -32.0,   0.0,    0.0,     14.0,  0.0,    0.0},
+      { 1, 0, 2, 4, 1,    -29.0,   0.0,    0.0,     14.0,  0.0,    0.0},
+      { 2, 0, 2, 4, 2,    -27.0,   0.0,    0.0,     12.0,  0.0,    0.0},
+      { 1, 1,-2, 1, 0,     30.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3, 1, 2, 1, 2,    -11.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+
+   /* 321-330 */
+      { 2, 0,-2, 0, 2,    -21.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      {-1, 0, 0, 1, 2,    -34.0,   0.0,    0.0,     15.0,  0.0,    0.0},
+      {-4, 0, 2, 2, 1,    -10.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      {-1,-1, 0, 1, 0,    -36.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0,-2, 2, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 1, 0, 0,-1, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 0,-1, 2,-2, 3,    -21.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      {-2, 1, 2, 0, 0,    -29.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0, 0, 2,-2, 4,    -15.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-2,-2, 0, 2, 0,    -20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 331-340 */
+      {-2, 0,-2, 4, 0,     28.0,   0.0,    0.0,      0.0,  0.0,   -2.0},
+      { 0,-2,-2, 2, 0,     17.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 2, 0,-2, 1,    -22.0,   0.0,    0.0,     12.0,  0.0,    0.0},
+      { 3, 0, 0,-4, 1,    -14.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+      {-1, 1, 2,-2, 2,     24.0,   0.0,    0.0,    -11.0,  0.0,    0.0},
+      { 1,-1, 2,-4, 1,     11.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      { 1, 1, 0,-2, 2,     14.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      {-3, 0, 2, 0, 0,     24.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3, 0, 2, 0, 2,     18.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
+      {-2, 0, 0, 1, 0,    -38.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 341-350 */
+      { 0, 0,-2, 1, 0,    -31.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3, 0, 0, 2, 1,    -16.0,   0.0,    0.0,      8.0,  0.0,    0.0},
+      {-1,-1,-2, 2, 0,     29.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 2,-4, 1,    -18.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      { 2, 1, 0,-4, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 0, 2, 0,-2, 1,    -17.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      { 1, 0, 0,-3, 1,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      {-2, 0, 2,-2, 2,     16.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      {-2,-1, 0, 0, 1,     22.0,   0.0,    0.0,    -12.0,  0.0,    0.0},
+      {-4, 0, 0, 2, 0,     20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 351-360 */
+      { 1, 1, 0,-4, 1,    -13.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      {-1, 0, 2,-4, 1,    -17.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      { 0, 0, 4,-4, 1,    -14.0,   0.0,    0.0,      8.0,  0.0,    0.0},
+      { 0, 3, 2,-2, 2,      0.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
+      {-3,-1, 0, 4, 0,     14.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3, 0, 0, 4, 1,     19.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
+      { 1,-1,-2, 2, 0,    -34.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 0, 2, 2,    -20.0,   0.0,    0.0,      8.0,  0.0,    0.0},
+      { 1,-2, 0, 0, 1,      9.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+      { 1,-1, 0, 0, 2,    -18.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+
+   /* 361-370 */
+      { 0, 0, 0, 1, 2,     13.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      {-1,-1, 2, 0, 0,     17.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1,-2, 2,-2, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 0,-1, 2,-1, 1,     15.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
+      {-1, 0, 2, 0, 3,    -11.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 1, 1, 0, 0, 2,     13.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+      {-1, 1, 2, 0, 0,    -18.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 2, 0, 0, 0,    -35.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 2, 2, 0, 2,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      {-1, 0, 4,-2, 1,    -19.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+
+   /* 371-380 */
+      { 3, 0, 2,-4, 2,    -26.0,   0.0,    0.0,     11.0,  0.0,    0.0},
+      { 1, 2, 2,-2, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 1, 0, 4,-4, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      {-2,-1, 0, 4, 1,     10.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      { 0,-1, 0, 2, 2,    -21.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      {-2, 1, 0, 4, 0,    -15.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2,-1, 2, 2, 1,      9.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+      { 2, 0,-2, 2, 0,    -29.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 0, 1, 1,    -19.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      { 0, 1, 0, 2, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+
+   /* 381-390 */
+      { 1,-1, 2,-1, 2,     22.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
+      {-2, 0, 4, 0, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 2, 1, 0, 0, 1,    -20.0,   0.0,    0.0,     11.0,  0.0,    0.0},
+      { 0, 1, 2, 0, 0,    -20.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0,-1, 4,-2, 2,    -17.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+      { 0, 0, 4,-2, 4,     15.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 0, 2, 2, 0, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      {-3, 0, 0, 6, 0,     14.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 0, 4, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      { 1,-2, 0, 2, 0,     25.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 391-400 */
+      {-1, 0, 0, 4, 2,    -13.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      {-1,-2, 2, 2, 1,    -14.0,   0.0,    0.0,      8.0,  0.0,    0.0},
+      {-1, 0, 0,-2, 2,     13.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+      { 1, 0,-2,-2, 1,    -17.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      { 0, 0,-2,-2, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      {-2, 0,-2, 0, 1,    -10.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 0, 0, 0, 3, 1,     10.0,   0.0,    0.0,     -6.0,  0.0,    0.0},
+      { 0, 0, 0, 3, 0,    -15.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 1, 0, 4, 0,    -22.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 2, 2, 0,     28.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+
+   /* 401-410 */
+      {-2, 0, 2, 3, 2,     15.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
+      { 1, 0, 0, 2, 2,     23.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
+      { 0,-1, 2, 1, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+      { 3,-1, 0, 0, 0,     29.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 2, 0, 0, 1, 0,    -25.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 1,-1, 2, 0, 0,     22.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0, 2, 1, 0,    -18.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 2, 0, 3,     15.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 3, 1, 0, 0, 0,    -23.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 3,-1, 2,-2, 2,     12.0,   0.0,    0.0,     -5.0,  0.0,    0.0},
+
+   /* 411-420 */
+      { 2, 0, 2,-1, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 1, 1, 2, 0, 0,    -19.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0, 4,-1, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 1, 2, 2, 0, 2,     21.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
+      {-2, 0, 0, 6, 0,     23.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0,-1, 0, 4, 1,    -16.0,   0.0,    0.0,      8.0,  0.0,    0.0},
+      {-2,-1, 2, 4, 1,    -19.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      { 0,-2, 2, 2, 1,    -22.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      { 0,-1, 2, 2, 0,     27.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-1, 0, 2, 3, 1,     16.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
+
+   /* 421-430 */
+      {-2, 1, 2, 4, 2,     19.0,   0.0,    0.0,     -8.0,  0.0,    0.0},
+      { 2, 0, 0, 2, 2,      9.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 2,-2, 2, 0, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      {-1, 1, 2, 3, 2,     -9.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 3, 0, 2,-1, 2,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 4, 0, 2,-2, 1,     18.0,   0.0,    0.0,     -9.0,  0.0,    0.0},
+      {-1, 0, 0, 6, 0,     16.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-1,-2, 2, 4, 2,    -10.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      {-3, 0, 2, 6, 2,    -23.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      {-1, 0, 2, 4, 0,     16.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+
+   /* 431-440 */
+      { 3, 0, 0, 2, 1,    -12.0,   0.0,    0.0,      6.0,  0.0,    0.0},
+      { 3,-1, 2, 0, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 3, 0, 2, 0, 0,     30.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 1, 0, 4, 0, 2,     24.0,   0.0,    0.0,    -10.0,  0.0,    0.0},
+      { 5, 0, 2,-2, 2,     10.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 0,-1, 2, 4, 1,    -16.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+      { 2,-1, 2, 2, 1,    -16.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+      { 0, 1, 2, 4, 2,     17.0,   0.0,    0.0,     -7.0,  0.0,    0.0},
+      { 1,-1, 2, 4, 2,    -24.0,   0.0,    0.0,     10.0,  0.0,    0.0},
+      { 3,-1, 2, 2, 2,    -12.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+
+   /* 441-450 */
+      { 3, 0, 2, 2, 1,    -24.0,   0.0,    0.0,     11.0,  0.0,    0.0},
+      { 5, 0, 2, 0, 2,    -23.0,   0.0,    0.0,      9.0,  0.0,    0.0},
+      { 0, 0, 2, 6, 2,    -13.0,   0.0,    0.0,      5.0,  0.0,    0.0},
+      { 4, 0, 2, 2, 2,    -15.0,   0.0,    0.0,      7.0,  0.0,    0.0},
+      { 0,-1, 1,-1, 1,      0.0,   0.0,-1988.0,      0.0,  0.0,-1679.0},
+      {-1, 0, 1, 0, 3,      0.0,   0.0,  -63.0,      0.0,  0.0,  -27.0},
+      { 0,-2, 2,-2, 3,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0,-1, 0, 1,      0.0,   0.0,    5.0,      0.0,  0.0,    4.0},
+      { 2,-2, 0,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-1, 0, 1, 0, 2,      0.0,   0.0,  364.0,      0.0,  0.0,  176.0},
+
+   /* 451-460 */
+      {-1, 0, 1, 0, 1,      0.0,   0.0,-1044.0,      0.0,  0.0, -891.0},
+      {-1,-1, 2,-1, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-2, 2, 0, 2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 0, 1, 0, 0,      0.0,   0.0,  330.0,      0.0,  0.0,    0.0},
+      {-4, 1, 2, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-3, 0, 2, 1, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-2,-1, 2, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 1, 0,-2, 1, 1,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2,-1,-2, 0, 1,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-4, 0, 2, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 461-470 */
+      {-3, 1, 0, 3, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 0,-1, 2, 0,      0.0,   0.0,    5.0,      0.0,  0.0,    0.0},
+      { 0,-2, 0, 0, 2,      0.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 0,-2, 0, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-3, 0, 0, 3, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2,-1, 0, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 0,-2, 3, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-4, 0, 0, 4, 0,    -12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 1,-2, 0, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 2,-1, 0,-2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+
+   /* 471-480 */
+      { 0, 0, 1,-1, 0,     -5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 2, 0, 1, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 1, 2, 0, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 1, 1, 0,-1, 1,      7.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 1, 0, 1,-2, 1,      0.0,   0.0,  -12.0,      0.0,  0.0,  -10.0},
+      { 0, 2, 0, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 1,-1, 2,-3, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 1, 2,-1, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2, 0, 4,-2, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-2, 0, 4,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+
+   /* 481-490 */
+      {-2,-2, 0, 2, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-2, 0,-2, 4, 0,      0.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 2, 2,-4, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 1, 1, 2,-4, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-1, 2, 2,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2, 0, 0,-3, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 2, 0, 0, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 0, 0, 0,-2, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 2,-2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 1, 0, 0, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 491-500 */
+      { 0, 0, 0,-1, 2,     -8.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-2, 1, 0, 1, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1,-2, 0,-2, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 1, 0,-2, 0, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-3, 1, 0, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 1,-2, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 0, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-3, 0, 0, 2, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3,-1, 0, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 0, 2,-6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+
+   /* 501-510 */
+      { 0, 1, 2,-4, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 0, 0,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-2, 1, 2,-2, 1,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0,-1, 2,-4, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 0, 1, 0,-2, 2,      9.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-1, 0, 0,-2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 0,-2,-2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-4, 0, 2, 0, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1,-1, 0,-1, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0,-2, 0, 2,      9.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+
+   /* 511-520 */
+      {-3, 0, 0, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 0,-2, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 0,-2, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 0, 0,-4, 2, 0,      8.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2,-1,-2, 2, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 2,-6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 0, 2,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 1, 0, 0,-4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 2, 1, 2,-4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 2, 1, 2,-4, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+
+   /* 521-530 */
+      { 0, 1, 4,-4, 4,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 4,-4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-1,-1,-2, 4, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-3, 0, 2, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 0,-2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2,-1, 0, 3, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0,-2, 3, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 0, 0, 3, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 0,-1, 0, 1, 0,    -13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3, 0, 2, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 531-540 */
+      { 1, 1,-2, 2, 0,     10.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 1, 0, 2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 1,-2, 2,-2, 1,     10.0,   0.0,   13.0,      6.0,  0.0,   -5.0},
+      { 0, 0, 1, 0, 2,      0.0,   0.0,   30.0,      0.0,  0.0,   14.0},
+      { 0, 0, 1, 0, 1,      0.0,   0.0, -162.0,      0.0,  0.0, -138.0},
+      { 0, 0, 1, 0, 0,      0.0,   0.0,   75.0,      0.0,  0.0,    0.0},
+      {-1, 2, 0, 2, 1,     -7.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      { 0, 0, 2, 0, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2, 0, 2, 0, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 0, 0,-1, 1,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 541-550 */
+      { 3, 0, 0,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 1, 0, 2,-2, 3,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 2, 0, 0, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2, 0, 2,-3, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 1, 4,-2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2,-2, 0, 4, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0,-3, 0, 2, 0,      9.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0,-2, 4, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 0, 3, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 0, 0, 4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+
+   /* 551-560 */
+      {-1, 0, 0, 3, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2,-2, 0, 0, 0,      7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1,-1, 0, 1, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 0, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0,-2, 2, 0, 1,     -6.0,   0.0,   -3.0,      3.0,  0.0,    1.0},
+      {-1, 0, 1, 2, 1,      0.0,   0.0,   -3.0,      0.0,  0.0,   -2.0},
+      {-1, 1, 0, 3, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-1, 2, 1, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0,-1, 2, 0, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 1, 2, 2, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+
+   /* 561-570 */
+      { 2,-2, 2,-2, 2,     -1.0,   0.0,    3.0,      3.0,  0.0,   -1.0},
+      { 1, 1, 0, 1, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 1, 0, 1, 0, 1,      0.0,   0.0,  -13.0,      0.0,  0.0,  -11.0},
+      { 1, 0, 1, 0, 0,      3.0,   0.0,    6.0,      0.0,  0.0,    0.0},
+      { 0, 2, 0, 2, 0,     -7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2,-1, 2,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 0,-1, 4,-2, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 0, 0, 4,-2, 3,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 4,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 4, 0, 2,-4, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+
+   /* 571-580 */
+      { 2, 2, 2,-2, 2,      8.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 2, 0, 4,-4, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1,-2, 0, 4, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1,-3, 2, 2, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-3, 0, 2, 4, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-3, 0, 2,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1,-1, 0,-2, 1,      8.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      {-3, 0, 0, 0, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-3, 0,-2, 2, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 0,-4, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+
+   /* 581-590 */
+      {-2, 1, 0,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-4, 0, 0, 0, 1,     -8.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+      {-1, 0, 0,-4, 1,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-3, 0, 0,-2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 0, 3, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-1, 1, 0, 4, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 1,-2, 2, 0, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 0, 1, 0, 3, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-1, 0, 2, 2, 3,      6.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 0, 0, 2, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 591-600 */
+      {-2, 0, 2, 2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 1, 2, 2, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 3, 0, 0, 0, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2, 1, 0, 1, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2,-1, 2,-1, 2,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 0, 0, 2, 0, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 3, 0, 3,      0.0,   0.0,  -26.0,      0.0,  0.0,  -11.0},
+      { 0, 0, 3, 0, 2,      0.0,   0.0,  -10.0,      0.0,  0.0,   -5.0},
+      {-1, 2, 2, 2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-1, 0, 4, 0, 0,    -13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 601-610 */
+      { 1, 2, 2, 0, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 3, 1, 2,-2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 1, 1, 4,-2, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-2,-1, 0, 6, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0,-2, 0, 4, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-2, 0, 0, 6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2,-2, 2, 4, 2,     -6.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0,-3, 2, 2, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 0, 4, 2,     -7.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-1,-1, 2, 3, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 611-620 */
+      {-2, 0, 2, 4, 0,     13.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2,-1, 0, 2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 1, 0, 0, 3, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 0, 4, 1,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 0, 1, 0, 4, 0,    -11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1,-1, 2, 1, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 0, 0, 2, 2, 3,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 2, 2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-1, 0, 2, 2, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-2, 0, 4, 2, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+
+   /* 621-630 */
+      { 2, 1, 0, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 1, 0, 2, 0,    -12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2,-1, 2, 0, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 2, 1, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 1, 2, 2, 0,     -4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 0, 2, 0, 3,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 3, 0, 2, 0, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 1, 0, 2, 0, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 1, 0, 3, 0, 3,      0.0,   0.0,   -5.0,      0.0,  0.0,   -2.0},
+      { 1, 1, 2, 1, 1,     -7.0,   0.0,    0.0,      4.0,  0.0,    0.0},
+
+   /* 631-640 */
+      { 0, 2, 2, 2, 2,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 2, 1, 2, 0, 0,     -3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 0, 4,-2, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 4, 1, 2,-2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      {-1,-1, 0, 6, 0,      3.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      {-3,-1, 2, 6, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      {-1, 0, 0, 6, 1,     -5.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-3, 0, 2, 6, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 1,-1, 0, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 1,-1, 0, 4, 0,     12.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 641-650 */
+      {-2, 0, 2, 5, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 1,-2, 2, 2, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 3,-1, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1,-1, 2, 2, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0, 2, 3, 1,      5.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      {-1, 1, 2, 4, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 0, 1, 2, 3, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-1, 0, 4, 2, 1,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 0, 2, 1, 1,      6.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 5, 0, 0, 0, 0,      6.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 651-660 */
+      { 2, 1, 2, 1, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 1, 0, 4, 0, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 3, 1, 2, 0, 1,      7.0,   0.0,    0.0,     -4.0,  0.0,    0.0},
+      { 3, 0, 4,-2, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      {-2,-1, 2, 6, 2,     -5.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 0, 6, 0,      5.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0,-2, 2, 4, 2,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      {-2, 0, 2, 6, 1,     -6.0,   0.0,    0.0,      3.0,  0.0,    0.0},
+      { 2, 0, 0, 4, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 2, 0, 0, 4, 0,     10.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+
+   /* 661-670 */
+      { 2,-2, 2, 2, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 0, 0, 2, 4, 0,      7.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 1, 0, 2, 3, 2,      7.0,   0.0,    0.0,     -3.0,  0.0,    0.0},
+      { 4, 0, 0, 2, 0,      4.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 2, 0, 2, 2, 0,     11.0,   0.0,    0.0,      0.0,  0.0,    0.0},
+      { 0, 0, 4, 2, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 4,-1, 2, 0, 2,     -6.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 3, 0, 2, 1, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 2, 1, 2, 2, 1,      3.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 4, 1, 2, 0, 2,      5.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+
+   /* 671-678 */
+      {-1,-1, 2, 6, 2,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      {-1, 0, 2, 6, 1,     -4.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 1,-1, 2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0},
+      { 1, 1, 2, 4, 2,      4.0,   0.0,    0.0,     -2.0,  0.0,    0.0},
+      { 3, 1, 2, 2, 2,      3.0,   0.0,    0.0,     -1.0,  0.0,    0.0},
+      { 5, 0, 2, 0, 1,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 2,-1, 2, 4, 2,     -3.0,   0.0,    0.0,      1.0,  0.0,    0.0},
+      { 2, 0, 2, 4, 1,     -3.0,   0.0,    0.0,      2.0,  0.0,    0.0}
+   };
+
+/* Number of terms in the luni-solar nutation model */
+   const int NLS = (int) (sizeof xls / sizeof xls[0]);
+
+/* ------------------------ */
+/* Planetary nutation model */
+/* ------------------------ */
+
+/* The units for the sine and cosine coefficients are */
+/* 0.1 microarcsecond                                 */
+
+   static const struct {
+      int nl,               /* coefficients of l, F, D and Omega */
+          nf,
+          nd,
+          nom,
+          nme,              /* coefficients of planetary longitudes */
+          nve,
+          nea,
+          nma,
+          nju,
+          nsa,
+          nur,
+          nne,
+          npa;              /* coefficient of general precession */
+      int sp,cp;            /* longitude sin, cos coefficients */
+      int se,ce;            /* obliquity sin, cos coefficients */
+   } xpl[] = {
+
+   /* 1-10 */
+      { 0, 0, 0, 0, 0,  0,  8,-16, 4, 5, 0, 0, 0, 1440,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -8, 16,-4,-5, 0, 0, 2,   56,-117,  -42, -40},
+      { 0, 0, 0, 0, 0,  0,  8,-16, 4, 5, 0, 0, 2,  125, -43,    0, -54},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0,-1, 2, 2,    0,   5,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -4,  8,-1,-5, 0, 0, 2,    3,  -7,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 1,    3,   0,    0,  -2},
+      { 0, 1,-1, 1, 0,  0,  3, -8, 3, 0, 0, 0, 0, -114,   0,    0,  61},
+      {-1, 0, 0, 0, 0, 10, -3,  0, 0, 0, 0, 0, 0, -219,  89,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 6,-3, 0, 2,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0, -462,1604,    0,   0},
+
+   /* 11-20 */
+      { 0, 1,-1, 1, 0,  0, -5,  8,-3, 0, 0, 0, 0,   99,   0,    0, -53},
+      { 0, 0, 0, 0, 0,  0, -4,  8,-3, 0, 0, 0, 1,   -3,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  4, -8, 1, 5, 0, 0, 2,    0,   6,    2,   0},
+      { 0, 0, 0, 0, 0, -5,  6,  4, 0, 0, 0, 0, 2,    3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 2,  -12,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 1,   14,-218,  117,   8},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 2,-5, 0, 0, 0,   31,-481, -257, -17},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-5, 0, 0, 0, -491, 128,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0,-2, 5, 0, 0, 0,-3084,5123, 2735,1647},
+      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 5, 0, 0, 1,-1444,2409,-1286,-771},
+
+   /* 21-30 */
+      { 0, 0, 0, 0, 0,  0,  0,  0,-2, 5, 0, 0, 2,   11, -24,  -11,  -9},
+      { 2,-1,-1, 0, 0,  0,  3, -7, 0, 0, 0, 0, 0,   26,  -9,    0,   0},
+      { 1, 0,-2, 0, 0, 19,-21,  3, 0, 0, 0, 0, 0,  103, -60,    0,   0},
+      { 0, 1,-1, 1, 0,  2, -4,  0,-3, 0, 0, 0, 0,    0, -13,   -7,   0},
+      { 1, 0,-1, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,  -26, -29,  -16,  14},
+      { 0, 1,-1, 1, 0,  0, -1,  0,-4,10, 0, 0, 0,    9, -27,  -14,  -5},
+      {-2, 0, 2, 1, 0,  0,  2,  0, 0,-5, 0, 0, 0,   12,   0,    0,  -6},
+      { 0, 0, 0, 0, 0,  3, -7,  4, 0, 0, 0, 0, 0,   -7,   0,    0,   0},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 1,-1, 0, 0, 0,    0,  24,    0,   0},
+      {-2, 0, 2, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,  284,   0,    0,-151},
+
+   /* 31-40 */
+      {-1, 0, 0, 0, 0, 18,-16,  0, 0, 0, 0, 0, 0,  226, 101,    0,   0},
+      {-2, 1, 1, 2, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -8,   -2,   0},
+      {-1, 1,-1, 1, 0, 18,-17,  0, 0, 0, 0, 0, 0,    0,  -6,   -3,   0},
+      {-1, 0, 1, 1, 0,  0,  2, -2, 0, 0, 0, 0, 0,    5,   0,    0,  -3},
+      { 0, 0, 0, 0, 0, -8, 13,  0, 0, 0, 0, 0, 2,  -41, 175,   76,  17},
+      { 0, 2,-2, 2, 0, -8, 11,  0, 0, 0, 0, 0, 0,    0,  15,    6,   0},
+      { 0, 0, 0, 0, 0, -8, 13,  0, 0, 0, 0, 0, 1,  425, 212, -133, 269},
+      { 0, 1,-1, 1, 0, -8, 12,  0, 0, 0, 0, 0, 0, 1200, 598,  319,-641},
+      { 0, 0, 0, 0, 0,  8,-13,  0, 0, 0, 0, 0, 0,  235, 334,    0,   0},
+      { 0, 1,-1, 1, 0,  8,-14,  0, 0, 0, 0, 0, 0,   11, -12,   -7,  -6},
+
+   /* 41-50 */
+      { 0, 0, 0, 0, 0,  8,-13,  0, 0, 0, 0, 0, 1,    5,  -6,    3,   3},
+      {-2, 0, 2, 1, 0,  0,  2,  0,-4, 5, 0, 0, 0,   -5,   0,    0,   3},
+      {-2, 0, 2, 2, 0,  3, -3,  0, 0, 0, 0, 0, 0,    6,   0,    0,  -3},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-3, 1, 0, 0, 0,   15,   0,    0,   0},
+      { 0, 0, 0, 1, 0,  3, -5,  0, 2, 0, 0, 0, 0,   13,   0,    0,  -7},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-4, 3, 0, 0, 0,   -6,  -9,    0,   0},
+      { 0,-1, 1, 0, 0,  0,  0,  2, 0, 0, 0, 0, 0,  266, -78,    0,   0},
+      { 0, 0, 0, 1, 0,  0, -1,  2, 0, 0, 0, 0, 0, -460,-435, -232, 246},
+      { 0, 1,-1, 2, 0,  0, -2,  2, 0, 0, 0, 0, 0,    0,  15,    7,   0},
+      {-1, 1, 0, 1, 0,  3, -5,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
+
+   /* 51-60 */
+      {-1, 0, 1, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0, 131,    0,   0},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-2,-2, 0, 0, 0,    4,   0,    0,   0},
+      {-2, 2, 0, 2, 0,  0, -5,  9, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0,-1, 0, 0,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 1, 0, 0,    0,   3,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 2, 0,  -17, -19,  -10,   9},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 2, 1,   -9, -11,    6,  -5},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 2, 2,   -6,   0,    0,   3},
+      {-1, 0, 1, 0, 0,  0,  3, -4, 0, 0, 0, 0, 0,  -16,   8,    0,   0},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 0, 2, 0, 0, 0,    0,   3,    0,   0},
+
+   /* 61-70 */
+      { 0, 1,-1, 2, 0,  0, -1,  0, 0, 2, 0, 0, 0,   11,  24,   11,  -5},
+      { 0, 0, 0, 1, 0,  0, -9, 17, 0, 0, 0, 0, 0,   -3,  -4,   -2,   1},
+      { 0, 0, 0, 2, 0, -3,  5,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 2, 0, 0, 0,    0,  -8,   -4,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 1,-2, 0, 0, 0,    0,   3,    0,   0},
+      { 1, 0,-2, 0, 0, 17,-16,  0,-2, 0, 0, 0, 0,    0,   5,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 1,-3, 0, 0, 0,    0,   3,    2,   0},
+      {-2, 0, 2, 1, 0,  0,  5, -6, 0, 0, 0, 0, 0,   -6,   4,    2,   3},
+      { 0,-2, 2, 0, 0,  0,  9,-13, 0, 0, 0, 0, 0,   -3,  -5,    0,   0},
+      { 0, 1,-1, 2, 0,  0, -1,  0, 0, 1, 0, 0, 0,   -5,   0,    0,   2},
+
+   /* 71-80 */
+      { 0, 0, 0, 1, 0,  0,  0,  0, 0, 1, 0, 0, 0,    4,  24,   13,  -2},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 0, 1, 0, 0, 0,  -42,  20,    0,   0},
+      { 0,-2, 2, 0, 0,  5, -6,  0, 0, 0, 0, 0, 0,  -10, 233,    0,   0},
+      { 0,-1, 1, 1, 0,  5, -7,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+      {-2, 0, 2, 0, 0,  6, -8,  0, 0, 0, 0, 0, 0,   78, -18,    0,   0},
+      { 2, 1,-3, 1, 0, -6,  7,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 0, 0, 2, 0,  0,  0,  0, 1, 0, 0, 0, 0,    0,  -3,   -1,   0},
+      { 0,-1, 1, 1, 0,  0,  1,  0, 1, 0, 0, 0, 0,    0,  -4,   -2,   1},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 0, 2, 0, 0,    0,  -8,   -4,  -1},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 2, 0, 1,    0,  -5,    3,   0},
+
+   /* 81-90 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 2, 0, 2,   -7,   0,    0,   3},
+      { 0, 0, 0, 0, 0,  0, -8, 15, 0, 0, 0, 0, 2,  -14,   8,    3,   6},
+      { 0, 0, 0, 0, 0,  0, -8, 15, 0, 0, 0, 0, 1,    0,   8,   -4,   0},
+      { 0, 1,-1, 1, 0,  0, -9, 15, 0, 0, 0, 0, 0,    0,  19,   10,   0},
+      { 0, 0, 0, 0, 0,  0,  8,-15, 0, 0, 0, 0, 0,   45, -22,    0,   0},
+      { 1,-1,-1, 0, 0,  0,  8,-15, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 2, 0,-2, 0, 0,  2, -5,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-5, 5, 0, 0, 0,    0,   3,    0,   0},
+      { 2, 0,-2, 1, 0,  0, -6,  8, 0, 0, 0, 0, 0,    3,   5,    3,  -2},
+      { 2, 0,-2, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,   89, -16,   -9, -48},
+
+   /* 91-100 */
+      {-2, 1, 1, 0, 0,  0,  1,  0,-3, 0, 0, 0, 0,    0,   3,    0,   0},
+      {-2, 1, 1, 1, 0,  0,  1,  0,-3, 0, 0, 0, 0,   -3,   7,    4,   2},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0, -349, -62,    0,   0},
+      {-2, 0, 2, 0, 0,  0,  6, -8, 0, 0, 0, 0, 0,  -15,  22,    0,   0},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-1,-5, 0, 0, 0,   -3,   0,    0,   0},
+      {-1, 0, 1, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,  -53,   0,    0,   0},
+      {-1, 1, 1, 1, 0,-20, 20,  0, 0, 0, 0, 0, 0,    5,   0,    0,  -3},
+      { 1, 0,-2, 0, 0, 20,-21,  0, 0, 0, 0, 0, 0,    0,  -8,    0,   0},
+      { 0, 0, 0, 1, 0,  0,  8,-15, 0, 0, 0, 0, 0,   15,  -7,   -4,  -8},
+      { 0, 2,-2, 1, 0,  0,-10, 15, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+
+   /* 101-110 */
+      { 0,-1, 1, 0, 0,  0,  1,  0, 1, 0, 0, 0, 0,  -21, -78,    0,   0},
+      { 0, 0, 0, 1, 0,  0,  0,  0, 1, 0, 0, 0, 0,   20, -70,  -37, -11},
+      { 0, 1,-1, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    0,   6,    3,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0,-2, 4, 0, 0, 0,    5,   3,    2,  -2},
+      { 2, 0,-2, 1, 0, -6,  8,  0, 0, 0, 0, 0, 0,  -17,  -4,   -2,   9},
+      { 0,-2, 2, 1, 0,  5, -6,  0, 0, 0, 0, 0, 0,    0,   6,    3,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0,-1, 0, 0, 1,   32,  15,   -8,  17},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0,-1, 0, 0, 0,  174,  84,   45, -93},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 0,   11,  56,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 1, 0, 0, 0,  -66, -12,   -6,  35},
+
+   /* 111-120 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 1,   47,   8,    4, -25},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 1, 0, 0, 2,    0,   8,    4,   0},
+      { 0, 2,-2, 1, 0,  0, -9, 13, 0, 0, 0, 0, 0,   10, -22,  -12,  -5},
+      { 0, 0, 0, 1, 0,  0,  7,-13, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
+      {-2, 0, 2, 0, 0,  0,  5, -6, 0, 0, 0, 0, 0,  -24,  12,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  9,-17, 0, 0, 0, 0, 0,    5,  -6,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -9, 17, 0, 0, 0, 0, 2,    3,   0,    0,  -2},
+      { 1, 0,-1, 1, 0,  0, -3,  4, 0, 0, 0, 0, 0,    4,   3,    1,  -2},
+      { 1, 0,-1, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,  29,   15,   0},
+      { 0, 0, 0, 2, 0,  0, -1,  2, 0, 0, 0, 0, 0,   -5,  -4,   -2,   2},
+
+   /* 121-130 */
+      { 0,-1, 1, 1, 0,  0,  0,  2, 0, 0, 0, 0, 0,    8,  -3,   -1,  -5},
+      { 0,-2, 2, 0, 1,  0, -2,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
+      { 0, 0, 0, 0, 0,  3, -5,  0, 2, 0, 0, 0, 0,   10,   0,    0,   0},
+      {-2, 0, 2, 1, 0,  0,  2,  0,-3, 1, 0, 0, 0,    3,   0,    0,  -2},
+      {-2, 0, 2, 1, 0,  3, -3,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   3},
+      { 0, 0, 0, 1, 0,  8,-13,  0, 0, 0, 0, 0, 0,   46,  66,   35, -25},
+      { 0,-1, 1, 0, 0,  8,-12,  0, 0, 0, 0, 0, 0,  -14,   7,    0,   0},
+      { 0, 2,-2, 1, 0, -8, 11,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
+      {-1, 0, 1, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
+      {-1, 0, 0, 1, 0, 18,-16,  0, 0, 0, 0, 0, 0,  -68, -34,  -18,  36},
+
+   /* 131-140 */
+      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 1, 0, 0, 0,    0,  14,    7,   0},
+      { 0, 0, 0, 1, 0,  3, -7,  4, 0, 0, 0, 0, 0,   10,  -6,   -3,  -5},
+      {-2, 1, 1, 1, 0,  0, -3,  7, 0, 0, 0, 0, 0,   -5,  -4,   -2,   3},
+      { 0, 1,-1, 2, 0,  0, -1,  0,-2, 5, 0, 0, 0,   -3,   5,    2,   1},
+      { 0, 0, 0, 1, 0,  0,  0,  0,-2, 5, 0, 0, 0,   76,  17,    9, -41},
+      { 0, 0, 0, 1, 0,  0, -4,  8,-3, 0, 0, 0, 0,   84, 298,  159, -45},
+      { 1, 0, 0, 1, 0,-10,  3,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 2,-2, 1, 0,  0, -2,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
+      {-1, 0, 0, 1, 0, 10, -3,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+      { 0, 0, 0, 1, 0,  0,  4, -8, 3, 0, 0, 0, 0,  -82, 292,  156,  44},
+
+   /* 141-150 */
+      { 0, 0, 0, 1, 0,  0,  0,  0, 2,-5, 0, 0, 0,  -73,  17,    9,  39},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 2,-5, 0, 0, 0,   -9, -16,    0,   0},
+      { 2,-1,-1, 1, 0,  0,  3, -7, 0, 0, 0, 0, 0,    3,   0,   -1,  -2},
+      {-2, 0, 2, 0, 0,  0,  2,  0, 0,-5, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 1, 0, -3,  7, -4, 0, 0, 0, 0, 0,   -9,  -5,   -3,   5},
+      {-2, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0, -439,   0,    0,   0},
+      { 1, 0, 0, 1, 0,-18, 16,  0, 0, 0, 0, 0, 0,   57, -28,  -15, -30},
+      {-2, 1, 1, 1, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -6,   -3,   0},
+      { 0, 1,-1, 2, 0, -8, 12,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   2},
+      { 0, 0, 0, 1, 0, -8, 13,  0, 0, 0, 0, 0, 0,  -40,  57,   30,  21},
+
+   /* 151-160 */
+      { 0, 0, 0, 0, 0,  0,  1, -2, 0, 0, 0, 0, 1,   23,   7,    3, -13},
+      { 0, 1,-1, 1, 0,  0,  0, -2, 0, 0, 0, 0, 0,  273,  80,   43,-146},
+      { 0, 0, 0, 0, 0,  0,  1, -2, 0, 0, 0, 0, 0, -449, 430,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -2,  2, 0, 0, 0, 0, 0,   -8, -47,  -25,   4},
+      { 0, 0, 0, 0, 0,  0, -1,  2, 0, 0, 0, 0, 1,    6,  47,   25,  -3},
+      {-1, 0, 1, 1, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  23,   13,   0},
+      {-1, 0, 1, 1, 0,  0,  3, -4, 0, 0, 0, 0, 0,   -3,   0,    0,   2},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0,-2, 0, 0, 0,    3,  -4,   -2,  -2},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 2, 0, 0, 0,  -48,-110,  -59,  26},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 2, 0, 0, 1,   51, 114,   61, -27},
+
+   /* 161-170 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 2, 0, 0, 2, -133,   0,    0,  57},
+      { 0, 1,-1, 0, 0,  3, -6,  0, 0, 0, 0, 0, 0,    0,   4,    0,   0},
+      { 0, 0, 0, 1, 0, -3,  5,  0, 0, 0, 0, 0, 0,  -21,  -6,   -3,  11},
+      { 0, 1,-1, 2, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,  -3,   -1,   0},
+      { 0, 0, 0, 1, 0,  0, -2,  4, 0, 0, 0, 0, 0,  -11, -21,  -11,   6},
+      { 0, 2,-2, 1, 0, -5,  6,  0, 0, 0, 0, 0, 0,  -18,-436, -233,   9},
+      { 0,-1, 1, 0, 0,  5, -7,  0, 0, 0, 0, 0, 0,   35,  -7,    0,   0},
+      { 0, 0, 0, 1, 0,  5, -8,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
+      {-2, 0, 2, 1, 0,  6, -8,  0, 0, 0, 0, 0, 0,   11,  -3,   -1,  -6},
+      { 0, 0, 0, 1, 0,  0, -8, 15, 0, 0, 0, 0, 0,   -5,  -3,   -1,   3},
+
+   /* 171-180 */
+      {-2, 0, 2, 1, 0,  0,  2,  0,-3, 0, 0, 0, 0,  -53,  -9,   -5,  28},
+      {-2, 0, 2, 1, 0,  0,  6, -8, 0, 0, 0, 0, 0,    0,   3,    2,   1},
+      { 1, 0,-1, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,    4,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 3,-5, 0, 0, 0,    0,  -4,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0,-1, 0, 0, 0, 0,  -50, 194,  103,  27},
+      { 0, 0, 0, 0, 0,  0,  0,  0,-1, 0, 0, 0, 1,  -13,  52,   28,   7},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 0,  -91, 248,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 1,    6,  49,   26,  -3},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,   -6, -47,  -25,   3},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 1,    0,   5,    3,   0},
+
+   /* 181-190 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 1, 0, 0, 0, 2,   52,  23,   10, -23},
+      { 0, 1,-1, 2, 0,  0, -1,  0, 0,-1, 0, 0, 0,   -3,   0,    0,   1},
+      { 0, 0, 0, 1, 0,  0,  0,  0, 0,-1, 0, 0, 0,    0,   5,    3,   0},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 0,-1, 0, 0, 0,   -4,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -7, 13, 0, 0, 0, 0, 2,   -4,   8,    3,   2},
+      { 0, 0, 0, 0, 0,  0,  7,-13, 0, 0, 0, 0, 0,   10,   0,    0,   0},
+      { 2, 0,-2, 1, 0,  0, -5,  6, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
+      { 0, 2,-2, 1, 0,  0, -8, 11, 0, 0, 0, 0, 0,    0,   8,    4,   0},
+      { 0, 2,-2, 1,-1,  0,  2,  0, 0, 0, 0, 0, 0,    0,   8,    4,   1},
+      {-2, 0, 2, 0, 0,  0,  4, -4, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
+
+   /* 191-200 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2,-2, 0, 0, 0,   -4,   0,    0,   0},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 0, 3, 0, 0, 0,   -8,   4,    2,   4},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 3, 0, 0, 1,    8,  -4,   -2,  -4},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 3, 0, 0, 2,    0,  15,    7,   0},
+      {-2, 0, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0, -138,   0,    0,   0},
+      { 0, 0, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,  -7,   -3,   0},
+      { 0, 0, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -7,   -3,   0},
+      { 2, 0,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,   54,   0,    0, -29},
+      { 0, 1,-1, 2, 0,  0, -1,  0, 2, 0, 0, 0, 0,    0,  10,    4,   0},
+      { 0, 1,-1, 2, 0,  0,  0, -2, 0, 0, 0, 0, 0,   -7,   0,    0,   3},
+
+   /* 201-210 */
+      { 0, 0, 0, 1, 0,  0,  1, -2, 0, 0, 0, 0, 0,  -37,  35,   19,  20},
+      { 0,-1, 1, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0,    0,   4,    0,   0},
+      { 0,-1, 1, 0, 0,  0,  1,  0, 0,-2, 0, 0, 0,   -4,   9,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -2,  0, 0, 2, 0, 0, 0,    8,   0,    0,  -4},
+      { 0, 1,-1, 1, 0,  3, -6,  0, 0, 0, 0, 0, 0,   -9, -14,   -8,   5},
+      { 0, 0, 0, 0, 0,  3, -5,  0, 0, 0, 0, 0, 1,   -3,  -9,   -5,   3},
+      { 0, 0, 0, 0, 0,  3, -5,  0, 0, 0, 0, 0, 0, -145,  47,    0,   0},
+      { 0, 1,-1, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,  -10,  40,   21,   5},
+      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 1,   11, -49,  -26,  -7},
+      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 2,-2150,   0,    0, 932},
+
+   /* 211-220 */
+      { 0, 2,-2, 2, 0, -3,  3,  0, 0, 0, 0, 0, 0,  -12,   0,    0,   5},
+      { 0, 0, 0, 0, 0, -3,  5,  0, 0, 0, 0, 0, 2,   85,   0,    0, -37},
+      { 0, 0, 0, 0, 0,  0,  2, -4, 0, 0, 0, 0, 1,    4,   0,    0,  -2},
+      { 0, 1,-1, 1, 0,  0,  1, -4, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  2, -4, 0, 0, 0, 0, 0,  -86, 153,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 1,   -6,   9,    5,   3},
+      { 0, 1,-1, 1, 0,  0, -3,  4, 0, 0, 0, 0, 0,    9, -13,   -7,  -5},
+      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 1,   -8,  12,    6,   4},
+      { 0, 0, 0, 0, 0,  0, -2,  4, 0, 0, 0, 0, 2,  -51,   0,    0,  22},
+      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 2,  -11,-268, -116,   5},
+
+   /* 221-230 */
+      { 0, 2,-2, 2, 0, -5,  6,  0, 0, 0, 0, 0, 0,    0,  12,    5,   0},
+      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 2,    0,   7,    3,   0},
+      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 1,   31,   6,    3, -17},
+      { 0, 1,-1, 1, 0, -5,  7,  0, 0, 0, 0, 0, 0,  140,  27,   14, -75},
+      { 0, 0, 0, 0, 0, -5,  8,  0, 0, 0, 0, 0, 1,   57,  11,    6, -30},
+      { 0, 0, 0, 0, 0,  5, -8,  0, 0, 0, 0, 0, 0,  -14, -39,    0,   0},
+      { 0, 1,-1, 2, 0,  0, -1,  0,-1, 0, 0, 0, 0,    0,  -6,   -2,   0},
+      { 0, 0, 0, 1, 0,  0,  0,  0,-1, 0, 0, 0, 0,    4,  15,    8,  -2},
+      { 0,-1, 1, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    0,   4,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -2,  0, 1, 0, 0, 0, 0,   -3,   0,    0,   1},
+
+   /* 231-240 */
+      { 0, 0, 0, 0, 0,  0, -6, 11, 0, 0, 0, 0, 2,    0,  11,    5,   0},
+      { 0, 0, 0, 0, 0,  0,  6,-11, 0, 0, 0, 0, 0,    9,   6,    0,   0},
+      { 0, 0, 0, 0,-1,  0,  4,  0, 0, 0, 0, 0, 2,   -4,  10,    4,   2},
+      { 0, 0, 0, 0, 1,  0, -4,  0, 0, 0, 0, 0, 0,    5,   3,    0,   0},
+      { 2, 0,-2, 1, 0, -3,  3,  0, 0, 0, 0, 0, 0,   16,   0,    0,  -9},
+      {-2, 0, 2, 0, 0,  0,  2,  0, 0,-2, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -7,  9, 0, 0, 0, 0, 0,    0,   3,    2,  -1},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 4,-5, 0, 0, 2,    7,   0,    0,  -3},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 0,  -25,  22,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 1,   42, 223,  119, -22},
+
+   /* 241-250 */
+      { 0, 1,-1, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,  -27,-143,  -77,  14},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 1,    9,  49,   26,  -5},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 2, 0, 0, 0, 2,-1166,   0,    0, 505},
+      { 0, 2,-2, 2, 0,  0, -2,  0, 2, 0, 0, 0, 0,   -5,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 5, 0, 0, 2,   -6,   0,    0,   3},
+      { 0, 0, 0, 1, 0,  3, -5,  0, 0, 0, 0, 0, 0,   -8,   0,    1,   4},
+      { 0,-1, 1, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
+      { 0, 2,-2, 1, 0, -3,  3,  0, 0, 0, 0, 0, 0,  117,   0,    0, -63},
+      { 0, 0, 0, 1, 0,  0,  2, -4, 0, 0, 0, 0, 0,   -4,   8,    4,   2},
+      { 0, 2,-2, 1, 0,  0, -4,  4, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
+
+   /* 251-260 */
+      { 0, 1,-1, 2, 0, -5,  7,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  3, -6, 0, 0, 0, 0, 0,    0,  31,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 1,   -5,   0,    1,   3},
+      { 0, 1,-1, 1, 0,  0, -4,  6, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0, -3,  6, 0, 0, 0, 0, 2,  -24, -13,   -6,  10},
+      { 0,-1, 1, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    3,   0,    0,   0},
+      { 0, 0, 0, 1, 0,  2, -3,  0, 0, 0, 0, 0, 0,    0, -32,  -17,   0},
+      { 0, 0, 0, 0, 0,  0, -5,  9, 0, 0, 0, 0, 2,    8,  12,    5,  -3},
+      { 0, 0, 0, 0, 0,  0, -5,  9, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
+
+   /* 261-270 */
+      { 0, 0, 0, 0, 0,  0,  5, -9, 0, 0, 0, 0, 0,    7,  13,    0,   0},
+      { 0,-1, 1, 0, 0,  0,  1,  0,-2, 0, 0, 0, 0,   -3,  16,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,   50,   0,    0, -27},
+      {-2, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -5,   -3,   0},
+      { 0,-2, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,   13,   0,    0,   0},
+      { 0, 0, 0, 0, 0, -6, 10,  0, 0, 0, 0, 0, 1,    0,   5,    3,   1},
+      { 0, 0, 0, 0, 0, -6, 10,  0, 0, 0, 0, 0, 2,   24,   5,    2, -11},
+      { 0, 0, 0, 0, 0, -2,  3,  0, 0, 0, 0, 0, 2,    5, -11,   -5,  -2},
+      { 0, 0, 0, 0, 0, -2,  3,  0, 0, 0, 0, 0, 1,   30,  -3,   -2, -16},
+      { 0, 1,-1, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,   18,   0,    0,  -9},
+
+   /* 271-280 */
+      { 0, 0, 0, 0, 0,  2, -3,  0, 0, 0, 0, 0, 0,    8, 614,    0,   0},
+      { 0, 0, 0, 0, 0,  2, -3,  0, 0, 0, 0, 0, 1,    3,  -3,   -1,  -2},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 1,    6,  17,    9,  -3},
+      { 0, 1,-1, 1, 0,  0, -1,  0, 3, 0, 0, 0, 0,   -3,  -9,   -5,   2},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 1,    0,   6,    3,  -1},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 3, 0, 0, 0, 2, -127,  21,    9,  55},
+      { 0, 0, 0, 0, 0,  0,  4, -8, 0, 0, 0, 0, 0,    3,   5,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -4,  8, 0, 0, 0, 0, 2,   -6, -10,   -4,   3},
+      { 0,-2, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,    5,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -4,  7, 0, 0, 0, 0, 2,   16,   9,    4,  -7},
+
+   /* 281-290 */
+      { 0, 0, 0, 0, 0,  0, -4,  7, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  4, -7, 0, 0, 0, 0, 0,    0,  22,    0,   0},
+      { 0, 0, 0, 1, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,  19,   10,   0},
+      { 0, 2,-2, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,    7,   0,    0,  -4},
+      { 0, 0, 0, 0, 0,  0, -5, 10, 0, 0, 0, 0, 2,    0,  -5,   -2,   0},
+      { 0, 0, 0, 1, 0, -1,  2,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  0, 4, 0, 0, 0, 2,   -9,   3,    1,   4},
+      { 0, 0, 0, 0, 0,  0, -3,  5, 0, 0, 0, 0, 2,   17,   0,    0,  -7},
+      { 0, 0, 0, 0, 0,  0, -3,  5, 0, 0, 0, 0, 1,    0,  -3,   -2,  -1},
+      { 0, 0, 0, 0, 0,  0,  3, -5, 0, 0, 0, 0, 0,  -20,  34,    0,   0},
+
+   /* 291-300 */
+      { 0, 0, 0, 0, 0,  1, -2,  0, 0, 0, 0, 0, 1,  -10,   0,    1,   5},
+      { 0, 1,-1, 1, 0,  1, -3,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  1, -2,  0, 0, 0, 0, 0, 0,   22, -87,    0,   0},
+      { 0, 0, 0, 0, 0, -1,  2,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0, -1,  2,  0, 0, 0, 0, 0, 2,   -3,  -6,   -2,   1},
+      { 0, 0, 0, 0, 0, -7, 11,  0, 0, 0, 0, 0, 2,  -16,  -3,   -1,   7},
+      { 0, 0, 0, 0, 0, -7, 11,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
+      { 0,-2, 2, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  2, -3, 0, 0, 0, 0, 0,  -68,  39,    0,   0},
+      { 0, 2,-2, 1, 0, -4,  4,  0, 0, 0, 0, 0, 0,   27,   0,    0, -14},
+
+   /* 301-310 */
+      { 0,-1, 1, 0, 0,  4, -5,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1, -1, 0, 0, 0, 0, 0,  -25,   0,    0,   0},
+      { 0, 0, 0, 0, 0, -4,  7,  0, 0, 0, 0, 0, 1,  -12,  -3,   -2,   6},
+      { 0, 1,-1, 1, 0, -4,  6,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0, -4,  7,  0, 0, 0, 0, 0, 2,    3,  66,   29,  -1},
+      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 2,  490,   0,    0,-213},
+      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 1,  -22,  93,   49,  12},
+      { 0, 1,-1, 1, 0, -4,  5,  0, 0, 0, 0, 0, 0,   -7,  28,   15,   4},
+      { 0, 0, 0, 0, 0, -4,  6,  0, 0, 0, 0, 0, 1,   -3,  13,    7,   2},
+      { 0, 0, 0, 0, 0,  4, -6,  0, 0, 0, 0, 0, 0,  -46,  14,    0,   0},
+
+   /* 311-320 */
+      {-2, 0, 2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  1, 0, 0, 0, 0, 0,    2,   1,    0,   0},
+      { 0,-1, 1, 0, 0,  1,  0,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
+      { 0, 0, 0, 1, 0,  1, -1,  0, 0, 0, 0, 0, 0,  -28,   0,    0,  15},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 5, 0, 0, 0, 2,    5,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  1, -3, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -1,  3, 0, 0, 0, 0, 2,  -11,   0,    0,   5},
+      { 0, 0, 0, 0, 0,  0, -7, 12, 0, 0, 0, 0, 2,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0, -1,  1,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0, -1,  1,  0, 0, 0, 0, 0, 1,   25, 106,   57, -13},
+
+   /* 321-330 */
+      { 0, 1,-1, 1, 0, -1,  0,  0, 0, 0, 0, 0, 0,    5,  21,   11,  -3},
+      { 0, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0, 1485,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 1,   -7, -32,  -17,   4},
+      { 0, 1,-1, 1, 0,  1, -2,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
+      { 0, 0, 0, 0, 0,  0, -2,  5, 0, 0, 0, 0, 2,   -6,  -3,   -2,   3},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 4, 0, 0, 0, 2,   30,  -6,   -2, -13},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-4, 0, 0, 0, 0,   -4,   4,    0,   0},
+      { 0, 0, 0, 1, 0, -1,  1,  0, 0, 0, 0, 0, 0,  -19,   0,    0,  10},
+      { 0, 0, 0, 0, 0,  0, -6, 10, 0, 0, 0, 0, 2,    0,   4,    2,  -1},
+      { 0, 0, 0, 0, 0,  0, -6, 10, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+
+   /* 331-340 */
+      { 0, 2,-2, 1, 0,  0, -3,  0, 3, 0, 0, 0, 0,    4,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0, -3,  7, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
+      {-2, 0, 2, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -5,  8, 0, 0, 0, 0, 2,    5,   3,    1,  -2},
+      { 0, 0, 0, 0, 0,  0,  5, -8, 0, 0, 0, 0, 0,    0,  11,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 3, 0, 0, 0, 2,  118,   0,    0, -52},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 3, 0, 0, 0, 1,    0,  -5,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-3, 0, 0, 0, 0,  -28,  36,    0,   0},
+      { 0, 0, 0, 0, 0,  2, -4,  0, 0, 0, 0, 0, 0,    5,  -5,    0,   0},
+      { 0, 0, 0, 0, 0, -2,  4,  0, 0, 0, 0, 0, 1,   14, -59,  -31,  -8},
+
+   /* 341-350 */
+      { 0, 1,-1, 1, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,   9,    5,   1},
+      { 0, 0, 0, 0, 0, -2,  4,  0, 0, 0, 0, 0, 2, -458,   0,    0, 198},
+      { 0, 0, 0, 0, 0, -6,  9,  0, 0, 0, 0, 0, 2,    0, -45,  -20,   0},
+      { 0, 0, 0, 0, 0, -6,  9,  0, 0, 0, 0, 0, 1,    9,   0,    0,  -5},
+      { 0, 0, 0, 0, 0,  6, -9,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
+      { 0, 0, 0, 1, 0,  0,  1,  0,-2, 0, 0, 0, 0,    0,  -4,   -2,  -1},
+      { 0, 2,-2, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,   11,   0,    0,  -6},
+      { 0, 0, 0, 0, 0,  0, -4,  6, 0, 0, 0, 0, 2,    6,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  4, -6, 0, 0, 0, 0, 0,  -16,  23,    0,   0},
+      { 0, 0, 0, 1, 0,  3, -4,  0, 0, 0, 0, 0, 0,    0,  -4,   -2,   0},
+
+   /* 351-360 */
+      { 0, 0, 0, 0, 0,  0, -1,  0, 2, 0, 0, 0, 2,   -5,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-2, 0, 0, 0, 0, -166, 269,    0,   0},
+      { 0, 0, 0, 1, 0,  0,  1,  0,-1, 0, 0, 0, 0,   15,   0,    0,  -8},
+      { 0, 0, 0, 0, 0, -5,  9,  0, 0, 0, 0, 0, 2,   10,   0,    0,  -4},
+      { 0, 0, 0, 0, 0,  0,  3, -4, 0, 0, 0, 0, 0,  -78,  45,    0,   0},
+      { 0, 0, 0, 0, 0, -3,  4,  0, 0, 0, 0, 0, 2,    0,  -5,   -2,   0},
+      { 0, 0, 0, 0, 0, -3,  4,  0, 0, 0, 0, 0, 1,    7,   0,    0,  -4},
+      { 0, 0, 0, 0, 0,  3, -4,  0, 0, 0, 0, 0, 0,   -5, 328,    0,   0},
+      { 0, 0, 0, 0, 0,  3, -4,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
+      { 0, 0, 0, 1, 0,  0,  2, -2, 0, 0, 0, 0, 0,    5,   0,    0,  -2},
+
+   /* 361-370 */
+      { 0, 0, 0, 1, 0,  0, -1,  0, 2, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-3, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 1,-5, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 1, 0, 0, 0, 1,    0,  -4,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,-1223, -26,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 1,    0,   7,    3,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-3, 5, 0, 0, 0,    3,   0,    0,   0},
+      { 0, 0, 0, 1, 0, -3,  4,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-2, 0, 0, 0,   -6,  20,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  2, -2, 0, 0, 0, 0, 0, -368,   0,    0,   0},
+
+   /* 371-380 */
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0,-1, 0, 0, 0,  -75,   0,    0,   0},
+      { 0, 0, 0, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,   11,   0,    0,  -6},
+      { 0, 0, 0, 1, 0,  0, -2,  2, 0, 0, 0, 0, 0,    3,   0,    0,  -2},
+      { 0, 0, 0, 0, 0, -8, 14,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 2,-5, 0, 0, 0,  -13, -30,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -8, 3, 0, 0, 0, 0,   21,   3,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -8, 3, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    8, -27,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  3, -8, 3, 0, 0, 0, 0,  -19, -11,    0,   0},
+
+   /* 381-390 */
+      { 0, 0, 0, 0, 0,  0, -3,  8,-3, 0, 0, 0, 2,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  1,  0,-2, 5, 0, 0, 2,    0,   5,    2,   0},
+      { 0, 0, 0, 0, 0, -8, 12,  0, 0, 0, 0, 0, 2,   -6,   0,    0,   2},
+      { 0, 0, 0, 0, 0, -8, 12,  0, 0, 0, 0, 0, 0,   -8,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 1,-2, 0, 0, 0,   -1,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 1, 0, 0, 2,  -14,   0,    0,   6},
+      { 0, 0, 0, 0, 0,  0,  0,  2, 0, 0, 0, 0, 0,    6,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  0,  2, 0, 0, 0, 0, 2,  -74,   0,    0,  32},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 0, 2, 0, 0, 2,    0,  -3,   -1,   0},
+      { 0, 2,-2, 1, 0, -5,  5,  0, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
+
+   /* 391-400 */
+      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 0,    8,  11,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 1,    0,   3,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 1, 0, 0, 0, 2, -262,   0,    0, 114},
+      { 0, 0, 0, 0, 0,  3, -6,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
+      { 0, 0, 0, 0, 0, -3,  6,  0, 0, 0, 0, 0, 1,   -7,   0,    0,   4},
+      { 0, 0, 0, 0, 0, -3,  6,  0, 0, 0, 0, 0, 2,    0, -27,  -12,   0},
+      { 0, 0, 0, 0, 0,  0, -1,  4, 0, 0, 0, 0, 2,  -19,  -8,   -4,   8},
+      { 0, 0, 0, 0, 0, -5,  7,  0, 0, 0, 0, 0, 2,  202,   0,    0, -87},
+      { 0, 0, 0, 0, 0, -5,  7,  0, 0, 0, 0, 0, 1,   -8,  35,   19,   5},
+      { 0, 1,-1, 1, 0, -5,  6,  0, 0, 0, 0, 0, 0,    0,   4,    2,   0},
+
+   /* 401-410 */
+      { 0, 0, 0, 0, 0,  5, -7,  0, 0, 0, 0, 0, 0,   16,  -5,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -1,  0, 1, 0, 0, 0, 0,    5,   0,    0,  -3},
+      { 0, 0, 0, 0, 0,  0, -1,  0, 1, 0, 0, 0, 0,    0,  -3,    0,   0},
+      { 0, 0, 0, 0,-1,  0,  3,  0, 0, 0, 0, 0, 2,    1,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 2, 0, 0, 0, 2,  -35, -48,  -21,  15},
+      { 0, 0, 0, 0, 0,  0, -2,  6, 0, 0, 0, 0, 2,   -3,  -5,   -2,   1},
+      { 0, 0, 0, 1, 0,  2, -2,  0, 0, 0, 0, 0, 0,    6,   0,    0,  -3},
+      { 0, 0, 0, 0, 0,  0, -6,  9, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  0,  6, -9, 0, 0, 0, 0, 0,    0,  -5,    0,   0},
+      { 0, 0, 0, 0, 0, -2,  2,  0, 0, 0, 0, 0, 1,   12,  55,   29,  -6},
+
+   /* 411-420 */
+      { 0, 1,-1, 1, 0, -2,  1,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
+      { 0, 0, 0, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0, -598,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  2, -2,  0, 0, 0, 0, 0, 1,   -3, -13,   -7,   1},
+      { 0, 0, 0, 0, 0,  0,  1,  0, 3, 0, 0, 0, 2,   -5,  -7,   -3,   2},
+      { 0, 0, 0, 0, 0,  0, -5,  7, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  0,  5, -7, 0, 0, 0, 0, 0,    5,  -7,    0,   0},
+      { 0, 0, 0, 1, 0, -2,  2,  0, 0, 0, 0, 0, 0,    4,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  4, -5, 0, 0, 0, 0, 0,   16,  -6,    0,   0},
+      { 0, 0, 0, 0, 0,  1, -3,  0, 0, 0, 0, 0, 0,    8,  -3,    0,   0},
+      { 0, 0, 0, 0, 0, -1,  3,  0, 0, 0, 0, 0, 1,    8, -31,  -16,  -4},
+
+   /* 421-430 */
+      { 0, 1,-1, 1, 0, -1,  2,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0, -1,  3,  0, 0, 0, 0, 0, 2,  113,   0,    0, -49},
+      { 0, 0, 0, 0, 0, -7, 10,  0, 0, 0, 0, 0, 2,    0, -24,  -10,   0},
+      { 0, 0, 0, 0, 0, -7, 10,  0, 0, 0, 0, 0, 1,    4,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  3, -3, 0, 0, 0, 0, 0,   27,   0,    0,   0},
+      { 0, 0, 0, 0, 0, -4,  8,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0, -4,  5,  0, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
+      { 0, 0, 0, 0, 0, -4,  5,  0, 0, 0, 0, 0, 1,    5,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  4, -5,  0, 0, 0, 0, 0, 0,    0,  -3,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  1, 0, 0, 0, 0, 2,  -13,   0,    0,   6},
+
+   /* 431-440 */
+      { 0, 0, 0, 0, 0,  0, -2,  0, 5, 0, 0, 0, 2,    5,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  0,  0,  3, 0, 0, 0, 0, 2,  -18, -10,   -4,   8},
+      { 0, 0, 0, 0, 0,  1,  0,  0, 0, 0, 0, 0, 0,   -4, -28,    0,   0},
+      { 0, 0, 0, 0, 0,  1,  0,  0, 0, 0, 0, 0, 2,   -5,   6,    3,   2},
+      { 0, 0, 0, 0, 0, -9, 13,  0, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0,  0, -1,  5, 0, 0, 0, 0, 2,   -5,  -9,   -4,   2},
+      { 0, 0, 0, 0, 0,  0, -2,  0, 4, 0, 0, 0, 2,   17,   0,    0,  -7},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-4, 0, 0, 0, 0,   11,   4,    0,   0},
+      { 0, 0, 0, 0, 0,  0, -2,  7, 0, 0, 0, 0, 2,    0,  -6,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   83,  15,    0,   0},
+
+   /* 441-450 */
+      { 0, 0, 0, 0, 0, -2,  5,  0, 0, 0, 0, 0, 1,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0, -2,  5,  0, 0, 0, 0, 0, 2,    0,-114,  -49,   0},
+      { 0, 0, 0, 0, 0, -6,  8,  0, 0, 0, 0, 0, 2,  117,   0,    0, -51},
+      { 0, 0, 0, 0, 0, -6,  8,  0, 0, 0, 0, 0, 1,   -5,  19,   10,   2},
+      { 0, 0, 0, 0, 0,  6, -8,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0, -3,  9, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -6, 0, 0, 0, 0, 0,    3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -6, 0, 0, 0, 0, 2,    0,  -6,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,  393,   3,    0,   0},
+
+   /* 451-460 */
+      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 1,   -4,  21,   11,   2},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 2,   -6,   0,   -1,   3},
+      { 0, 0, 0, 0, 0, -5, 10,  0, 0, 0, 0, 0, 2,   -3,   8,    4,   1},
+      { 0, 0, 0, 0, 0,  0,  4, -4, 0, 0, 0, 0, 0,    8,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  4, -4, 0, 0, 0, 0, 2,   18, -29,  -13,  -8},
+      { 0, 0, 0, 0, 0, -3,  3,  0, 0, 0, 0, 0, 1,    8,  34,   18,  -4},
+      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,   89,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 1,    3,  12,    6,  -1},
+      { 0, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 2,   54, -15,   -7, -24},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-3, 0, 0, 0,    0,   3,    0,   0},
+
+   /* 461-470 */
+      { 0, 0, 0, 0, 0,  0, -5, 13, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-1, 0, 0, 0, 0,    0,  35,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-1, 0, 0, 0, 2, -154, -30,  -13,  67},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-2, 0, 0, 0,   15,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-2, 0, 0, 1,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  3, -2, 0, 0, 0, 0, 0,    0,   9,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  3, -2, 0, 0, 0, 0, 2,   80, -71,  -31, -35},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0,-1, 0, 0, 2,    0, -20,   -9,   0},
+      { 0, 0, 0, 0, 0,  0, -6, 15, 0, 0, 0, 0, 2,   11,   5,    2,  -5},
+      { 0, 0, 0, 0, 0, -8, 15,  0, 0, 0, 0, 0, 2,   61, -96,  -42, -27},
+
+   /* 471-480 */
+      { 0, 0, 0, 0, 0, -3,  9, -4, 0, 0, 0, 0, 2,   14,   9,    4,  -6},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 2,-5, 0, 0, 2,  -11,  -6,   -3,   5},
+      { 0, 0, 0, 0, 0,  0, -2,  8,-1,-5, 0, 0, 2,    0,  -3,   -1,   0},
+      { 0, 0, 0, 0, 0,  0,  6, -8, 3, 0, 0, 0, 2,  123,-415, -180, -53},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 0,    0,   0,    0, -35},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 1,    7, -32,  -17,  -4},
+      { 0, 1,-1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -9,   -5,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 1,    0,  -4,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 0, 0, 0, 2,  -89,   0,    0,  38},
+
+   /* 481-490 */
+      { 0, 0, 0, 0, 0,  0, -6, 16,-4,-5, 0, 0, 2,    0, -86,  -19,  -6},
+      { 0, 0, 0, 0, 0,  0, -2,  8,-3, 0, 0, 0, 2,    0,   0,  -19,   6},
+      { 0, 0, 0, 0, 0,  0, -2,  8,-3, 0, 0, 0, 2, -123,-416, -180,  53},
+      { 0, 0, 0, 0, 0,  0,  6, -8, 1, 5, 0, 0, 2,    0,  -3,   -1,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 5, 0, 0, 2,   12,  -6,   -3,  -5},
+      { 0, 0, 0, 0, 0,  3, -5,  4, 0, 0, 0, 0, 2,  -13,   9,    4,   6},
+      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 2,    0, -15,   -7,   0},
+      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0, -8, 11,  0, 0, 0, 0, 0, 2,  -62, -97,  -42,  27},
+      { 0, 0, 0, 0, 0,  0, 11,  0, 0, 0, 0, 0, 2,  -11,   5,    2,   5},
+
+   /* 491-500 */
+      { 0, 0, 0, 0, 0,  0,  2,  0, 0, 1, 0, 0, 2,    0, -19,   -8,   0},
+      { 0, 0, 0, 0, 0,  3, -3,  0, 2, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 2,-2, 1, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   4,    2,   0},
+      { 0, 1,-1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+      { 0, 2,-2, 1, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  1,  2, 0, 0, 0, 0, 2,  -85, -70,  -31,  37},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 1, 0, 0, 0, 2,  163, -12,   -5, -72},
+      { 0, 0, 0, 0, 0, -3,  7,  0, 0, 0, 0, 0, 2,  -63, -16,   -7,  28},
+      { 0, 0, 0, 0, 0,  0,  0,  4, 0, 0, 0, 0, 2,  -21, -32,  -14,   9},
+      { 0, 0, 0, 0, 0, -5,  6,  0, 0, 0, 0, 0, 2,    0,  -3,   -1,   0},
+
+   /* 501-510 */
+      { 0, 0, 0, 0, 0, -5,  6,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -2},
+      { 0, 0, 0, 0, 0,  5, -6,  0, 0, 0, 0, 0, 0,    0,   8,    0,   0},
+      { 0, 0, 0, 0, 0,  5, -6,  0, 0, 0, 0, 0, 2,    3,  10,    4,  -1},
+      { 0, 0, 0, 0, 0,  0,  2,  0, 2, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  0, -1,  6, 0, 0, 0, 0, 2,    0,  -7,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  7, -9, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
+      { 0, 0, 0, 0, 0,  2, -1,  0, 0, 0, 0, 0, 0,    6,  19,    0,   0},
+      { 0, 0, 0, 0, 0,  2, -1,  0, 0, 0, 0, 0, 2,    5,-173,  -75,  -2},
+      { 0, 0, 0, 0, 0,  0,  6, -7, 0, 0, 0, 0, 2,    0,  -7,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -5, 0, 0, 0, 0, 2,    7, -12,   -5,  -3},
+
+   /* 511-520 */
+      { 0, 0, 0, 0, 0, -1,  4,  0, 0, 0, 0, 0, 1,   -3,   0,    0,   2},
+      { 0, 0, 0, 0, 0, -1,  4,  0, 0, 0, 0, 0, 2,    3,  -4,   -2,  -1},
+      { 0, 0, 0, 0, 0, -7,  9,  0, 0, 0, 0, 0, 2,   74,   0,    0, -32},
+      { 0, 0, 0, 0, 0, -7,  9,  0, 0, 0, 0, 0, 1,   -3,  12,    6,   2},
+      { 0, 0, 0, 0, 0,  0,  4, -3, 0, 0, 0, 0, 2,   26, -14,   -6, -11},
+      { 0, 0, 0, 0, 0,  0,  3, -1, 0, 0, 0, 0, 2,   19,   0,    0,  -8},
+      { 0, 0, 0, 0, 0, -4,  4,  0, 0, 0, 0, 0, 1,    6,  24,   13,  -3},
+      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 0,   83,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 1,    0, -10,   -5,   0},
+      { 0, 0, 0, 0, 0,  4, -4,  0, 0, 0, 0, 0, 2,   11,  -3,   -1,  -5},
+
+   /* 521-530 */
+      { 0, 0, 0, 0, 0,  0,  2,  1, 0, 0, 0, 0, 2,    3,   0,    1,  -1},
+      { 0, 0, 0, 0, 0,  0, -3,  0, 5, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 1,    5, -23,  -12,  -3},
+      { 0, 0, 0, 0, 0,  1,  1,  0, 0, 0, 0, 0, 2, -339,   0,    0, 147},
+      { 0, 0, 0, 0, 0, -9, 12,  0, 0, 0, 0, 0, 2,    0, -10,   -5,   0},
+      { 0, 0, 0, 0, 0,  0,  3,  0,-4, 0, 0, 0, 0,    5,   0,    0,   0},
+      { 0, 2,-2, 1, 0,  1, -1,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  0,  7, -8, 0, 0, 0, 0, 2,    0,  -4,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  3,  0,-3, 0, 0, 0, 0,   18,  -3,    0,   0},
+
+   /* 531-540 */
+      { 0, 0, 0, 0, 0,  0,  3,  0,-3, 0, 0, 0, 2,    9, -11,   -5,  -4},
+      { 0, 0, 0, 0, 0, -2,  6,  0, 0, 0, 0, 0, 2,   -8,   0,    0,   4},
+      { 0, 0, 0, 0, 0, -6,  7,  0, 0, 0, 0, 0, 1,    3,   0,    0,  -1},
+      { 0, 0, 0, 0, 0,  6, -7,  0, 0, 0, 0, 0, 0,    0,   9,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  6, -6, 0, 0, 0, 0, 2,    6,  -9,   -4,  -2},
+      { 0, 0, 0, 0, 0,  0,  3,  0,-2, 0, 0, 0, 0,   -4, -12,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  3,  0,-2, 0, 0, 0, 2,   67, -91,  -39, -29},
+      { 0, 0, 0, 0, 0,  0,  5, -4, 0, 0, 0, 0, 2,   30, -18,   -8, -13},
+      { 0, 0, 0, 0, 0,  3, -2,  0, 0, 0, 0, 0, 0,    0,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  3, -2,  0, 0, 0, 0, 0, 2,    0,-114,  -50,   0},
+
+   /* 541-550 */
+      { 0, 0, 0, 0, 0,  0,  3,  0,-1, 0, 0, 0, 2,    0,   0,    0,  23},
+      { 0, 0, 0, 0, 0,  0,  3,  0,-1, 0, 0, 0, 2,  517,  16,    7,-224},
+      { 0, 0, 0, 0, 0,  0,  3,  0, 0,-2, 0, 0, 2,    0,  -7,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  4, -2, 0, 0, 0, 0, 2,  143,  -3,   -1, -62},
+      { 0, 0, 0, 0, 0,  0,  3,  0, 0,-1, 0, 0, 2,   29,   0,    0, -13},
+      { 0, 2,-2, 1, 0,  0,  1,  0,-1, 0, 0, 0, 0,   -4,   0,    0,   2},
+      { 0, 0, 0, 0, 0, -8, 16,  0, 0, 0, 0, 0, 2,   -6,   0,    0,   3},
+      { 0, 0, 0, 0, 0,  0,  3,  0, 2,-5, 0, 0, 2,    5,  12,    5,  -2},
+      { 0, 0, 0, 0, 0,  0,  7, -8, 3, 0, 0, 0, 2,  -25,   0,    0,  11},
+      { 0, 0, 0, 0, 0,  0, -5, 16,-4,-5, 0, 0, 2,   -3,   0,    0,   1},
+
+   /* 551-560 */
+      { 0, 0, 0, 0, 0,  0,  3,  0, 0, 0, 0, 0, 2,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0,  0, -1,  8,-3, 0, 0, 0, 2,  -22,  12,    5,  10},
+      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 2,   50,   0,    0, -22},
+      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 1,    0,   7,    4,   0},
+      { 0, 0, 0, 0, 0, -8, 10,  0, 0, 0, 0, 0, 2,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0,  0,  2,  2, 0, 0, 0, 0, 2,   -4,   4,    2,   2},
+      { 0, 0, 0, 0, 0,  0,  3,  0, 1, 0, 0, 0, 2,   -5, -11,   -5,   2},
+      { 0, 0, 0, 0, 0, -3,  8,  0, 0, 0, 0, 0, 2,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0, -5,  5,  0, 0, 0, 0, 0, 1,    4,  17,    9,  -2},
+      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 0,   59,   0,    0,   0},
+
+   /* 561-570 */
+      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 1,    0,  -4,   -2,   0},
+      { 0, 0, 0, 0, 0,  5, -5,  0, 0, 0, 0, 0, 2,   -8,   0,    0,   4},
+      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 1,    4, -15,   -8,  -2},
+      { 0, 0, 0, 0, 0,  2,  0,  0, 0, 0, 0, 0, 2,  370,  -8,    0,-160},
+      { 0, 0, 0, 0, 0,  0,  7, -7, 0, 0, 0, 0, 2,    0,   0,   -3,   0},
+      { 0, 0, 0, 0, 0,  0,  7, -7, 0, 0, 0, 0, 2,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0,  0,  6, -5, 0, 0, 0, 0, 2,   -6,   3,    1,   3},
+      { 0, 0, 0, 0, 0,  7, -8,  0, 0, 0, 0, 0, 0,    0,   6,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  5, -3, 0, 0, 0, 0, 2,  -10,   0,    0,   4},
+
+   /* 571-580 */
+      { 0, 0, 0, 0, 0,  4, -3,  0, 0, 0, 0, 0, 2,    0,   9,    4,   0},
+      { 0, 0, 0, 0, 0,  1,  2,  0, 0, 0, 0, 0, 2,    4,  17,    7,  -2},
+      { 0, 0, 0, 0, 0, -9, 11,  0, 0, 0, 0, 0, 2,   34,   0,    0, -15},
+      { 0, 0, 0, 0, 0, -9, 11,  0, 0, 0, 0, 0, 1,    0,   5,    3,   0},
+      { 0, 0, 0, 0, 0,  0,  4,  0,-4, 0, 0, 0, 2,   -5,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  4,  0,-3, 0, 0, 0, 2,  -37,  -7,   -3,  16},
+      { 0, 0, 0, 0, 0, -6,  6,  0, 0, 0, 0, 0, 1,    3,  13,    7,  -2},
+      { 0, 0, 0, 0, 0,  6, -6,  0, 0, 0, 0, 0, 0,   40,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  6, -6,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  4,  0,-2, 0, 0, 0, 2, -184,  -3,   -1,  80},
+
+   /* 581-590 */
+      { 0, 0, 0, 0, 0,  0,  6, -4, 0, 0, 0, 0, 2,   -3,   0,    0,   1},
+      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 1,    0, -10,   -6,  -1},
+      { 0, 0, 0, 0, 0,  3, -1,  0, 0, 0, 0, 0, 2,   31,  -6,    0, -13},
+      { 0, 0, 0, 0, 0,  0,  4,  0,-1, 0, 0, 0, 2,   -3, -32,  -14,   1},
+      { 0, 0, 0, 0, 0,  0,  4,  0, 0,-2, 0, 0, 2,   -7,   0,    0,   3},
+      { 0, 0, 0, 0, 0,  0,  5, -2, 0, 0, 0, 0, 2,    0,  -8,   -4,   0},
+      { 0, 0, 0, 0, 0,  0,  4,  0, 0, 0, 0, 0, 0,    3,  -4,    0,   0},
+      { 0, 0, 0, 0, 0,  8, -9,  0, 0, 0, 0, 0, 0,    0,   4,    0,   0},
+      { 0, 0, 0, 0, 0,  5, -4,  0, 0, 0, 0, 0, 2,    0,   3,    1,   0},
+
+   /* 591-600 */
+      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 2,   19, -23,  -10,   2},
+      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 1,    0,   0,    0, -10},
+      { 0, 0, 0, 0, 0,  2,  1,  0, 0, 0, 0, 0, 1,    0,   3,    2,   0},
+      { 0, 0, 0, 0, 0, -7,  7,  0, 0, 0, 0, 0, 1,    0,   9,    5,  -1},
+      { 0, 0, 0, 0, 0,  7, -7,  0, 0, 0, 0, 0, 0,   28,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 1,    0,  -7,   -4,   0},
+      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 2,    8,  -4,    0,  -4},
+      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 0,    0,   0,   -2,   0},
+      { 0, 0, 0, 0, 0,  4, -2,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  5,  0,-4, 0, 0, 0, 2,   -3,   0,    0,   1},
+
+   /* 601-610 */
+      { 0, 0, 0, 0, 0,  0,  5,  0,-3, 0, 0, 0, 2,   -9,   0,    1,   4},
+      { 0, 0, 0, 0, 0,  0,  5,  0,-2, 0, 0, 0, 2,    3,  12,    5,  -1},
+      { 0, 0, 0, 0, 0,  3,  0,  0, 0, 0, 0, 0, 2,   17,  -3,   -1,   0},
+      { 0, 0, 0, 0, 0, -8,  8,  0, 0, 0, 0, 0, 1,    0,   7,    4,   0},
+      { 0, 0, 0, 0, 0,  8, -8,  0, 0, 0, 0, 0, 0,   19,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  5, -3,  0, 0, 0, 0, 0, 1,    0,  -5,   -3,   0},
+      { 0, 0, 0, 0, 0,  5, -3,  0, 0, 0, 0, 0, 2,   14,  -3,    0,  -1},
+      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   0,   -1,   0},
+      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   0,    0,  -5},
+      { 0, 0, 0, 0, 0, -9,  9,  0, 0, 0, 0, 0, 1,    0,   5,    3,   0},
+
+   /* 611-620 */
+      { 0, 0, 0, 0, 0,  9, -9,  0, 0, 0, 0, 0, 0,   13,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  6, -4,  0, 0, 0, 0, 0, 1,    0,  -3,   -2,   0},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    2,   9,    4,   3},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    0,   0,    0,  -4},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    8,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 1,    0,   4,    2,   0},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    6,   0,    0,  -3},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 0,    6,   0,    0,   0},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 1,    0,   3,    1,   0},
+      { 0, 0, 0, 0, 0,  0,  6,  0, 0, 0, 0, 0, 2,    5,   0,    0,  -2},
+
+   /* 621-630 */
+      { 0, 0, 0, 0, 0,  0,  0,  0, 0, 0, 0, 0, 2,    3,   0,    0,  -1},
+      { 1, 0,-2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 1, 0,-2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    6,   0,    0,   0},
+      { 1, 0,-2, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    7,   0,    0,   0},
+      { 1, 0,-2, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
+      {-1, 0, 0, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
+      {-1, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,    6,   0,    0,   0},
+      {-1, 0, 2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -4,    0,   0},
+      { 1, 0,-2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -4,    0,   0},
+      {-2, 0, 2, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    5,   0,    0,   0},
+
+   /* 631-640 */
+      {-1, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   -3,   0,    0,   0},
+      {-1, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    4,   0,    0,   0},
+      {-1, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -5,   0,    0,   0},
+      {-1, 0, 2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    4,   0,    0,   0},
+      { 1,-1, 1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    0,   0},
+      {-1, 0, 2, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   13,   0,    0,   0},
+      {-2, 0, 0, 0, 0,  0,  2,  0,-3, 0, 0, 0, 0,   21,  11,    0,   0},
+      { 1, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -5,    0,   0},
+      {-1, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 0, 0,    0,  -5,   -2,   0},
+      { 1, 1,-1, 1, 0,  0, -1,  0, 0, 0, 0, 0, 0,    0,   5,    3,   0},
+
+   /* 641-650 */
+      {-1, 0, 0, 0, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,  -5,    0,   0},
+      {-1, 0, 2, 1, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   2},
+      { 0, 0, 0, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   20,  10,    0,   0},
+      {-1, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,  -34,   0,    0,   0},
+      {-1, 0, 2, 0, 0,  3, -3,  0, 0, 0, 0, 0, 0,  -19,   0,    0,   0},
+      { 1, 0,-2, 1, 0,  0, -2,  0, 2, 0, 0, 0, 0,    3,   0,    0,  -2},
+      { 1, 2,-2, 2, 0, -3,  3,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+      { 1, 2,-2, 2, 0,  0, -2,  0, 2, 0, 0, 0, 0,   -6,   0,    0,   3},
+      { 1, 0, 0, 0, 0,  1, -1,  0, 0, 0, 0, 0, 0,   -4,   0,    0,   0},
+      { 1, 0, 0, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    3,   0,    0,   0},
+
+   /* 651-660 */
+      { 0, 0,-2, 0, 0,  2, -2,  0, 0, 0, 0, 0, 0,    3,   0,    0,   0},
+      { 0, 0,-2, 0, 0,  0,  1,  0,-1, 0, 0, 0, 0,    4,   0,    0,   0},
+      { 0, 2, 0, 2, 0, -2,  2,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 2, 0, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    6,   0,    0,  -3},
+      { 0, 2, 0, 2, 0, -1,  1,  0, 0, 0, 0, 0, 0,   -8,   0,    0,   3},
+      { 0, 2, 0, 2, 0, -2,  3,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 0, 2, 0, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   0},
+      { 0, 1, 1, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -3,   -2,   0},
+      { 1, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,  126, -63,  -27, -55},
+      {-1, 2, 0, 2, 0, 10, -3,  0, 0, 0, 0, 0, 0,   -5,   0,    1,   2},
+
+   /* 661-670 */
+      { 0, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,   -3,  28,   15,   2},
+      { 1, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,    5,   0,    1,  -2},
+      { 0, 2, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   9,    4,   1},
+      { 0, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   9,    4,  -1},
+      {-1, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0, -126, -63,  -27,  55},
+      { 2, 2,-2, 2, 0,  0, -2,  0, 3, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 1, 2, 0, 1, 0,  0, -2,  0, 3, 0, 0, 0, 0,   21, -11,   -6, -11},
+      { 0, 1, 1, 0, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,  -4,    0,   0},
+      {-1, 2, 0, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,  -21, -11,   -6,  11},
+      {-2, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,   -3,   0,    0,   1},
+
+   /* 671-680 */
+      { 0, 2, 0, 2, 0,  2, -3,  0, 0, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 0, 2, 0, 2, 0,  1, -1,  0, 0, 0, 0, 0, 0,    8,   0,    0,  -4},
+      { 0, 2, 0, 2, 0,  0,  1,  0,-1, 0, 0, 0, 0,   -6,   0,    0,   3},
+      { 0, 2, 0, 2, 0,  2, -2,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+      {-1, 2, 2, 2, 0,  0, -1,  0, 1, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 1, 2, 0, 2, 0, -1,  1,  0, 0, 0, 0, 0, 0,   -3,   0,    0,   1},
+      {-1, 2, 2, 2, 0,  0,  2,  0,-3, 0, 0, 0, 0,   -5,   0,    0,   2},
+      { 2, 2, 0, 2, 0,  0,  2,  0,-3, 0, 0, 0, 0,   24, -12,   -5, -11},
+      { 1, 2, 0, 2, 0,  0, -4,  8,-3, 0, 0, 0, 0,    0,   3,    1,   0},
+      { 1, 2, 0, 2, 0,  0,  4, -8, 3, 0, 0, 0, 0,    0,   3,    1,   0},
+
+   /* 681-687 */
+      { 1, 1, 1, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    0,   3,    2,   0},
+      { 0, 2, 0, 2, 0,  0,  1,  0, 0, 0, 0, 0, 0,  -24, -12,   -5,  10},
+      { 2, 2, 0, 1, 0,  0,  1,  0, 0, 0, 0, 0, 0,    4,   0,   -1,  -2},
+      {-1, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,   13,   0,    0,  -6},
+      {-1, 2, 2, 2, 0,  3, -3,  0, 0, 0, 0, 0, 0,    7,   0,    0,  -3},
+      { 1, 2, 0, 2, 0,  1, -1,  0, 0, 0, 0, 0, 0,    3,   0,    0,  -1},
+      { 0, 2, 2, 2, 0,  0,  2,  0,-2, 0, 0, 0, 0,    3,   0,    0,  -1}
+   };
+
+/* Number of terms in the planetary nutation model */
+   const int NPL = (int) (sizeof xpl / sizeof xpl[0]);
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* ------------------- */
+/* LUNI-SOLAR NUTATION */
+/* ------------------- */
+
+/* Fundamental (Delaunay) arguments */
+
+/* Mean anomaly of the Moon (IERS 2003). */
+   el = eraFal03(t);
+
+/* Mean anomaly of the Sun (MHB2000). */
+   elp = fmod(1287104.79305  +
+            t * (129596581.0481  +
+            t * (-0.5532  +
+            t * (0.000136  +
+            t * (-0.00001149)))), ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean longitude of the Moon minus that of the ascending node */
+/* (IERS 2003. */
+   f = eraFaf03(t);
+
+/* Mean elongation of the Moon from the Sun (MHB2000). */
+   d = fmod(1072260.70369  +
+          t * (1602961601.2090  +
+          t * (-6.3706  +
+          t * (0.006593  +
+          t * (-0.00003169)))), ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean longitude of the ascending node of the Moon (IERS 2003). */
+   om = eraFaom03(t);
+
+/* Initialize the nutation values. */
+   dp = 0.0;
+   de = 0.0;
+
+/* Summation of luni-solar nutation series (in reverse order). */
+   for (i = NLS-1; i >= 0; i--) {
+
+   /* Argument and functions. */
+      arg = fmod((double)xls[i].nl  * el +
+                 (double)xls[i].nlp * elp +
+                 (double)xls[i].nf  * f +
+                 (double)xls[i].nd  * d +
+                 (double)xls[i].nom * om, ERFA_D2PI);
+      sarg = sin(arg);
+      carg = cos(arg);
+
+   /* Term. */
+      dp += (xls[i].sp + xls[i].spt * t) * sarg + xls[i].cp * carg;
+      de += (xls[i].ce + xls[i].cet * t) * carg + xls[i].se * sarg;
+   }
+
+/* Convert from 0.1 microarcsec units to radians. */
+   dpsils = dp * U2R;
+   depsls = de * U2R;
+
+/* ------------------ */
+/* PLANETARY NUTATION */
+/* ------------------ */
+
+/* n.b.  The MHB2000 code computes the luni-solar and planetary nutation */
+/* in different functions, using slightly different Delaunay */
+/* arguments in the two cases.  This behaviour is faithfully */
+/* reproduced here.  Use of the IERS 2003 expressions for both */
+/* cases leads to negligible changes, well below */
+/* 0.1 microarcsecond. */
+
+/* Mean anomaly of the Moon (MHB2000). */
+   al = fmod(2.35555598 + 8328.6914269554 * t, ERFA_D2PI);
+
+/* Mean longitude of the Moon minus that of the ascending node */
+/*(MHB2000). */
+   af = fmod(1.627905234 + 8433.466158131 * t, ERFA_D2PI);
+
+/* Mean elongation of the Moon from the Sun (MHB2000). */
+   ad = fmod(5.198466741 + 7771.3771468121 * t, ERFA_D2PI);
+
+/* Mean longitude of the ascending node of the Moon (MHB2000). */
+   aom = fmod(2.18243920 - 33.757045 * t, ERFA_D2PI);
+
+/* General accumulated precession in longitude (IERS 2003). */
+   apa = eraFapa03(t);
+
+/* Planetary longitudes, Mercury through Uranus (IERS 2003). */
+   alme = eraFame03(t);
+   alve = eraFave03(t);
+   alea = eraFae03(t);
+   alma = eraFama03(t);
+   alju = eraFaju03(t);
+   alsa = eraFasa03(t);
+   alur = eraFaur03(t);
+
+/* Neptune longitude (MHB2000). */
+   alne = fmod(5.321159000 + 3.8127774000 * t, ERFA_D2PI);
+
+/* Initialize the nutation values. */
+   dp = 0.0;
+   de = 0.0;
+
+/* Summation of planetary nutation series (in reverse order). */
+   for (i = NPL-1; i >= 0; i--) {
+
+   /* Argument and functions. */
+      arg = fmod((double)xpl[i].nl  * al   +
+                 (double)xpl[i].nf  * af   +
+                 (double)xpl[i].nd  * ad   +
+                 (double)xpl[i].nom * aom  +
+                 (double)xpl[i].nme * alme +
+                 (double)xpl[i].nve * alve +
+                 (double)xpl[i].nea * alea +
+                 (double)xpl[i].nma * alma +
+                 (double)xpl[i].nju * alju +
+                 (double)xpl[i].nsa * alsa +
+                 (double)xpl[i].nur * alur +
+                 (double)xpl[i].nne * alne +
+                 (double)xpl[i].npa * apa, ERFA_D2PI);
+      sarg = sin(arg);
+      carg = cos(arg);
+
+   /* Term. */
+      dp += (double)xpl[i].sp * sarg + (double)xpl[i].cp * carg;
+      de += (double)xpl[i].se * sarg + (double)xpl[i].ce * carg;
+
+   }
+
+/* Convert from 0.1 microarcsec units to radians. */
+   dpsipl = dp * U2R;
+   depspl = de * U2R;
+
+/* ------- */
+/* RESULTS */
+/* ------- */
+
+/* Add luni-solar and planetary components. */
+   *dpsi = dpsils + dpsipl;
+   *deps = depsls + depspl;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/nut00b.c b/cextern/erfa/nut00b.c
new file mode 100644
index 0000000..ec82bad
--- /dev/null
+++ b/cextern/erfa/nut00b.c
@@ -0,0 +1,381 @@
+#include "erfa.h"
+
+void eraNut00b(double date1, double date2, double *dpsi, double *deps)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, el, elp, f, d, om, arg, dp, de, sarg, carg,
+          dpsils, depsls, dpsipl, depspl;
+   int i;
+
+/* Units of 0.1 microarcsecond to radians */
+   static const double U2R = ERFA_DAS2R / 1e7;
+
+/* ---------------------------------------- */
+/* Fixed offsets in lieu of planetary terms */
+/* ---------------------------------------- */
+
+   static const double DPPLAN = -0.135 * ERFA_DMAS2R;
+   static const double DEPLAN =  0.388 * ERFA_DMAS2R;
+
+/* --------------------------------------------------- */
+/* Luni-solar nutation: argument and term coefficients */
+/* --------------------------------------------------- */
+
+/* The units for the sine and cosine coefficients are */
+/* 0.1 microarcsec and the same per Julian century    */
+
+   static const struct {
+      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
+      double ps,pst,pc;     /* longitude sin, t*sin, cos coefficients */
+      double ec,ect,es;     /* obliquity cos, t*cos, sin coefficients */
+
+   } x[] = {
+
+   /* 1-10 */
+      { 0, 0, 0, 0,1,
+         -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0},
+      { 0, 0, 2,-2,2,
+           -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0},
+      { 0, 0, 2, 0,2,-2276413.0,-234.0, 2796.0, 978459.0,-485.0,1374.0},
+      { 0, 0, 0, 0,2,2074554.0,  207.0, -698.0,-897492.0, 470.0,-291.0},
+      { 0, 1, 0, 0,0,1475877.0,-3633.0,11817.0, 73871.0,-184.0,-1924.0},
+      { 0, 1, 2,-2,2,-516821.0, 1226.0, -524.0, 224386.0,-677.0,-174.0},
+      { 1, 0, 0, 0,0, 711159.0,   73.0, -872.0,  -6750.0,   0.0, 358.0},
+      { 0, 0, 2, 0,1,-387298.0, -367.0,  380.0, 200728.0,  18.0, 318.0},
+      { 1, 0, 2, 0,2,-301461.0,  -36.0,  816.0, 129025.0, -63.0, 367.0},
+      { 0,-1, 2,-2,2, 215829.0, -494.0,  111.0, -95929.0, 299.0, 132.0},
+
+   /* 11-20 */
+      { 0, 0, 2,-2,1, 128227.0,  137.0,  181.0, -68982.0,  -9.0,  39.0},
+      {-1, 0, 2, 0,2, 123457.0,   11.0,   19.0, -53311.0,  32.0,  -4.0},
+      {-1, 0, 0, 2,0, 156994.0,   10.0, -168.0,  -1235.0,   0.0,  82.0},
+      { 1, 0, 0, 0,1,  63110.0,   63.0,   27.0, -33228.0,   0.0,  -9.0},
+      {-1, 0, 0, 0,1, -57976.0,  -63.0, -189.0,  31429.0,   0.0, -75.0},
+      {-1, 0, 2, 2,2, -59641.0,  -11.0,  149.0,  25543.0, -11.0,  66.0},
+      { 1, 0, 2, 0,1, -51613.0,  -42.0,  129.0,  26366.0,   0.0,  78.0},
+      {-2, 0, 2, 0,1,  45893.0,   50.0,   31.0, -24236.0, -10.0,  20.0},
+      { 0, 0, 0, 2,0,  63384.0,   11.0, -150.0,  -1220.0,   0.0,  29.0},
+      { 0, 0, 2, 2,2, -38571.0,   -1.0,  158.0,  16452.0, -11.0,  68.0},
+
+   /* 21-30 */
+      { 0,-2, 2,-2,2,  32481.0,    0.0,    0.0, -13870.0,   0.0,   0.0},
+      {-2, 0, 0, 2,0, -47722.0,    0.0,  -18.0,    477.0,   0.0, -25.0},
+      { 2, 0, 2, 0,2, -31046.0,   -1.0,  131.0,  13238.0, -11.0,  59.0},
+      { 1, 0, 2,-2,2,  28593.0,    0.0,   -1.0, -12338.0,  10.0,  -3.0},
+      {-1, 0, 2, 0,1,  20441.0,   21.0,   10.0, -10758.0,   0.0,  -3.0},
+      { 2, 0, 0, 0,0,  29243.0,    0.0,  -74.0,   -609.0,   0.0,  13.0},
+      { 0, 0, 2, 0,0,  25887.0,    0.0,  -66.0,   -550.0,   0.0,  11.0},
+      { 0, 1, 0, 0,1, -14053.0,  -25.0,   79.0,   8551.0,  -2.0, -45.0},
+      {-1, 0, 0, 2,1,  15164.0,   10.0,   11.0,  -8001.0,   0.0,  -1.0},
+      { 0, 2, 2,-2,2, -15794.0,   72.0,  -16.0,   6850.0, -42.0,  -5.0},
+
+   /* 31-40 */
+      { 0, 0,-2, 2,0,  21783.0,    0.0,   13.0,   -167.0,   0.0,  13.0},
+      { 1, 0, 0,-2,1, -12873.0,  -10.0,  -37.0,   6953.0,   0.0, -14.0},
+      { 0,-1, 0, 0,1, -12654.0,   11.0,   63.0,   6415.0,   0.0,  26.0},
+      {-1, 0, 2, 2,1, -10204.0,    0.0,   25.0,   5222.0,   0.0,  15.0},
+      { 0, 2, 0, 0,0,  16707.0,  -85.0,  -10.0,    168.0,  -1.0,  10.0},
+      { 1, 0, 2, 2,2,  -7691.0,    0.0,   44.0,   3268.0,   0.0,  19.0},
+      {-2, 0, 2, 0,0, -11024.0,    0.0,  -14.0,    104.0,   0.0,   2.0},
+      { 0, 1, 2, 0,2,   7566.0,  -21.0,  -11.0,  -3250.0,   0.0,  -5.0},
+      { 0, 0, 2, 2,1,  -6637.0,  -11.0,   25.0,   3353.0,   0.0,  14.0},
+      { 0,-1, 2, 0,2,  -7141.0,   21.0,    8.0,   3070.0,   0.0,   4.0},
+
+   /* 41-50 */
+      { 0, 0, 0, 2,1,  -6302.0,  -11.0,    2.0,   3272.0,   0.0,   4.0},
+      { 1, 0, 2,-2,1,   5800.0,   10.0,    2.0,  -3045.0,   0.0,  -1.0},
+      { 2, 0, 2,-2,2,   6443.0,    0.0,   -7.0,  -2768.0,   0.0,  -4.0},
+      {-2, 0, 0, 2,1,  -5774.0,  -11.0,  -15.0,   3041.0,   0.0,  -5.0},
+      { 2, 0, 2, 0,1,  -5350.0,    0.0,   21.0,   2695.0,   0.0,  12.0},
+      { 0,-1, 2,-2,1,  -4752.0,  -11.0,   -3.0,   2719.0,   0.0,  -3.0},
+      { 0, 0, 0,-2,1,  -4940.0,  -11.0,  -21.0,   2720.0,   0.0,  -9.0},
+      {-1,-1, 0, 2,0,   7350.0,    0.0,   -8.0,    -51.0,   0.0,   4.0},
+      { 2, 0, 0,-2,1,   4065.0,    0.0,    6.0,  -2206.0,   0.0,   1.0},
+      { 1, 0, 0, 2,0,   6579.0,    0.0,  -24.0,   -199.0,   0.0,   2.0},
+
+   /* 51-60 */
+      { 0, 1, 2,-2,1,   3579.0,    0.0,    5.0,  -1900.0,   0.0,   1.0},
+      { 1,-1, 0, 0,0,   4725.0,    0.0,   -6.0,    -41.0,   0.0,   3.0},
+      {-2, 0, 2, 0,2,  -3075.0,    0.0,   -2.0,   1313.0,   0.0,  -1.0},
+      { 3, 0, 2, 0,2,  -2904.0,    0.0,   15.0,   1233.0,   0.0,   7.0},
+      { 0,-1, 0, 2,0,   4348.0,    0.0,  -10.0,    -81.0,   0.0,   2.0},
+      { 1,-1, 2, 0,2,  -2878.0,    0.0,    8.0,   1232.0,   0.0,   4.0},
+      { 0, 0, 0, 1,0,  -4230.0,    0.0,    5.0,    -20.0,   0.0,  -2.0},
+      {-1,-1, 2, 2,2,  -2819.0,    0.0,    7.0,   1207.0,   0.0,   3.0},
+      {-1, 0, 2, 0,0,  -4056.0,    0.0,    5.0,     40.0,   0.0,  -2.0},
+      { 0,-1, 2, 2,2,  -2647.0,    0.0,   11.0,   1129.0,   0.0,   5.0},
+
+   /* 61-70 */
+      {-2, 0, 0, 0,1,  -2294.0,    0.0,  -10.0,   1266.0,   0.0,  -4.0},
+      { 1, 1, 2, 0,2,   2481.0,    0.0,   -7.0,  -1062.0,   0.0,  -3.0},
+      { 2, 0, 0, 0,1,   2179.0,    0.0,   -2.0,  -1129.0,   0.0,  -2.0},
+      {-1, 1, 0, 1,0,   3276.0,    0.0,    1.0,     -9.0,   0.0,   0.0},
+      { 1, 1, 0, 0,0,  -3389.0,    0.0,    5.0,     35.0,   0.0,  -2.0},
+      { 1, 0, 2, 0,0,   3339.0,    0.0,  -13.0,   -107.0,   0.0,   1.0},
+      {-1, 0, 2,-2,1,  -1987.0,    0.0,   -6.0,   1073.0,   0.0,  -2.0},
+      { 1, 0, 0, 0,2,  -1981.0,    0.0,    0.0,    854.0,   0.0,   0.0},
+      {-1, 0, 0, 1,0,   4026.0,    0.0, -353.0,   -553.0,   0.0,-139.0},
+      { 0, 0, 2, 1,2,   1660.0,    0.0,   -5.0,   -710.0,   0.0,  -2.0},
+
+   /* 71-77 */
+      {-1, 0, 2, 4,2,  -1521.0,    0.0,    9.0,    647.0,   0.0,   4.0},
+      {-1, 1, 0, 1,1,   1314.0,    0.0,    0.0,   -700.0,   0.0,   0.0},
+      { 0,-2, 2,-2,1,  -1283.0,    0.0,    0.0,    672.0,   0.0,   0.0},
+      { 1, 0, 2, 2,1,  -1331.0,    0.0,    8.0,    663.0,   0.0,   4.0},
+      {-2, 0, 2, 2,2,   1383.0,    0.0,   -2.0,   -594.0,   0.0,  -2.0},
+      {-1, 0, 0, 0,2,   1405.0,    0.0,    4.0,   -610.0,   0.0,   2.0},
+      { 1, 1, 2,-2,2,   1290.0,    0.0,    0.0,   -556.0,   0.0,   0.0}
+   };
+
+/* Number of terms in the series */
+   const int NLS = (int) (sizeof x / sizeof x[0]);
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental epoch J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* --------------------*/
+/* LUNI-SOLAR NUTATION */
+/* --------------------*/
+
+/* Fundamental (Delaunay) arguments from Simon et al. (1994) */
+
+/* Mean anomaly of the Moon. */
+   el = fmod(485868.249036 + (1717915923.2178) * t, ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean anomaly of the Sun. */
+   elp = fmod(1287104.79305 + (129596581.0481) * t, ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean argument of the latitude of the Moon. */
+   f = fmod(335779.526232 + (1739527262.8478) * t, ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean elongation of the Moon from the Sun. */
+   d = fmod(1072260.70369 + (1602961601.2090) * t, ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Mean longitude of the ascending node of the Moon. */
+   om = fmod(450160.398036 + (-6962890.5431) * t, ERFA_TURNAS) * ERFA_DAS2R;
+
+/* Initialize the nutation values. */
+   dp = 0.0;
+   de = 0.0;
+
+/* Summation of luni-solar nutation series (smallest terms first). */
+   for (i = NLS-1; i >= 0; i--) {
+
+   /* Argument and functions. */
+      arg = fmod( (double)x[i].nl  * el  +
+                  (double)x[i].nlp * elp +
+                  (double)x[i].nf  * f   +
+                  (double)x[i].nd  * d   +
+                  (double)x[i].nom * om, ERFA_D2PI  );
+      sarg = sin(arg);
+      carg = cos(arg);
+
+   /* Term. */
+      dp += (x[i].ps + x[i].pst * t) * sarg + x[i].pc * carg;
+      de += (x[i].ec + x[i].ect * t) * carg + x[i].es * sarg;
+   }
+
+/* Convert from 0.1 microarcsec units to radians. */
+   dpsils = dp * U2R;
+   depsls = de * U2R;
+
+/* ------------------------------*/
+/* IN LIEU OF PLANETARY NUTATION */
+/* ------------------------------*/
+
+/* Fixed offset to correct for missing terms in truncated series. */
+   dpsipl = DPPLAN;
+   depspl = DEPLAN;
+
+/* --------*/
+/* RESULTS */
+/* --------*/
+
+/* Add luni-solar and planetary components. */
+   *dpsi = dpsils + dpsipl;
+   *deps = depsls + depspl;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/nut06a.c b/cextern/erfa/nut06a.c
new file mode 100644
index 0000000..8936277
--- /dev/null
+++ b/cextern/erfa/nut06a.c
@@ -0,0 +1,162 @@
+#include "erfa.h"
+
+void eraNut06a(double date1, double date2, double *dpsi, double *deps)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, fj2, dp, de;
+
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Factor correcting for secular variation of J2. */
+   fj2 = -2.7774e-6 * t;
+
+/* Obtain IAU 2000A nutation. */
+   eraNut00a(date1, date2, &dp, &de);
+
+/* Apply P03 adjustments (Wallace & Capitaine, 2006, Eqs.5). */
+   *dpsi = dp + dp * (0.4697e-6 + fj2);
+   *deps = de + de * fj2;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/nut80.c b/cextern/erfa/nut80.c
new file mode 100644
index 0000000..c0da4ef
--- /dev/null
+++ b/cextern/erfa/nut80.c
@@ -0,0 +1,334 @@
+#include "erfa.h"
+
+void eraNut80(double date1, double date2, double *dpsi, double *deps)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, el, elp, f, d, om, dp, de, arg, s, c;
+   int j;
+
+/* Units of 0.1 milliarcsecond to radians */
+   const double U2R = ERFA_DAS2R / 1e4;
+
+/* ------------------------------------------------ */
+/* Table of multiples of arguments and coefficients */
+/* ------------------------------------------------ */
+
+/* The units for the sine and cosine coefficients are 0.1 mas and */
+/* the same per Julian century */
+
+   static const struct {
+      int nl,nlp,nf,nd,nom; /* coefficients of l,l',F,D,Om */
+      double sp,spt;        /* longitude sine, 1 and t coefficients */
+      double ce,cet;        /* obliquity cosine, 1 and t coefficients */
+   } x[] = {
+
+   /* 1-10 */
+      {  0,  0,  0,  0,  1, -171996.0, -174.2,  92025.0,    8.9 },
+      {  0,  0,  0,  0,  2,    2062.0,    0.2,   -895.0,    0.5 },
+      { -2,  0,  2,  0,  1,      46.0,    0.0,    -24.0,    0.0 },
+      {  2,  0, -2,  0,  0,      11.0,    0.0,      0.0,    0.0 },
+      { -2,  0,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
+      {  1, -1,  0, -1,  0,      -3.0,    0.0,      0.0,    0.0 },
+      {  0, -2,  2, -2,  1,      -2.0,    0.0,      1.0,    0.0 },
+      {  2,  0, -2,  0,  1,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  2, -2,  2,  -13187.0,   -1.6,   5736.0,   -3.1 },
+      {  0,  1,  0,  0,  0,    1426.0,   -3.4,     54.0,   -0.1 },
+
+   /* 11-20 */
+      {  0,  1,  2, -2,  2,    -517.0,    1.2,    224.0,   -0.6 },
+      {  0, -1,  2, -2,  2,     217.0,   -0.5,    -95.0,    0.3 },
+      {  0,  0,  2, -2,  1,     129.0,    0.1,    -70.0,    0.0 },
+      {  2,  0,  0, -2,  0,      48.0,    0.0,      1.0,    0.0 },
+      {  0,  0,  2, -2,  0,     -22.0,    0.0,      0.0,    0.0 },
+      {  0,  2,  0,  0,  0,      17.0,   -0.1,      0.0,    0.0 },
+      {  0,  1,  0,  0,  1,     -15.0,    0.0,      9.0,    0.0 },
+      {  0,  2,  2, -2,  2,     -16.0,    0.1,      7.0,    0.0 },
+      {  0, -1,  0,  0,  1,     -12.0,    0.0,      6.0,    0.0 },
+      { -2,  0,  0,  2,  1,      -6.0,    0.0,      3.0,    0.0 },
+
+   /* 21-30 */
+      {  0, -1,  2, -2,  1,      -5.0,    0.0,      3.0,    0.0 },
+      {  2,  0,  0, -2,  1,       4.0,    0.0,     -2.0,    0.0 },
+      {  0,  1,  2, -2,  1,       4.0,    0.0,     -2.0,    0.0 },
+      {  1,  0,  0, -1,  0,      -4.0,    0.0,      0.0,    0.0 },
+      {  2,  1,  0, -2,  0,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  0, -2,  2,  1,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  1, -2,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  0,  0,  2,       1.0,    0.0,      0.0,    0.0 },
+      { -1,  0,  0,  1,  1,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
+
+   /* 31-40 */
+      {  0,  0,  2,  0,  2,   -2274.0,   -0.2,    977.0,   -0.5 },
+      {  1,  0,  0,  0,  0,     712.0,    0.1,     -7.0,    0.0 },
+      {  0,  0,  2,  0,  1,    -386.0,   -0.4,    200.0,    0.0 },
+      {  1,  0,  2,  0,  2,    -301.0,    0.0,    129.0,   -0.1 },
+      {  1,  0,  0, -2,  0,    -158.0,    0.0,     -1.0,    0.0 },
+      { -1,  0,  2,  0,  2,     123.0,    0.0,    -53.0,    0.0 },
+      {  0,  0,  0,  2,  0,      63.0,    0.0,     -2.0,    0.0 },
+      {  1,  0,  0,  0,  1,      63.0,    0.1,    -33.0,    0.0 },
+      { -1,  0,  0,  0,  1,     -58.0,   -0.1,     32.0,    0.0 },
+      { -1,  0,  2,  2,  2,     -59.0,    0.0,     26.0,    0.0 },
+
+   /* 41-50 */
+      {  1,  0,  2,  0,  1,     -51.0,    0.0,     27.0,    0.0 },
+      {  0,  0,  2,  2,  2,     -38.0,    0.0,     16.0,    0.0 },
+      {  2,  0,  0,  0,  0,      29.0,    0.0,     -1.0,    0.0 },
+      {  1,  0,  2, -2,  2,      29.0,    0.0,    -12.0,    0.0 },
+      {  2,  0,  2,  0,  2,     -31.0,    0.0,     13.0,    0.0 },
+      {  0,  0,  2,  0,  0,      26.0,    0.0,     -1.0,    0.0 },
+      { -1,  0,  2,  0,  1,      21.0,    0.0,    -10.0,    0.0 },
+      { -1,  0,  0,  2,  1,      16.0,    0.0,     -8.0,    0.0 },
+      {  1,  0,  0, -2,  1,     -13.0,    0.0,      7.0,    0.0 },
+      { -1,  0,  2,  2,  1,     -10.0,    0.0,      5.0,    0.0 },
+
+   /* 51-60 */
+      {  1,  1,  0, -2,  0,      -7.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  2,  0,  2,       7.0,    0.0,     -3.0,    0.0 },
+      {  0, -1,  2,  0,  2,      -7.0,    0.0,      3.0,    0.0 },
+      {  1,  0,  2,  2,  2,      -8.0,    0.0,      3.0,    0.0 },
+      {  1,  0,  0,  2,  0,       6.0,    0.0,      0.0,    0.0 },
+      {  2,  0,  2, -2,  2,       6.0,    0.0,     -3.0,    0.0 },
+      {  0,  0,  0,  2,  1,      -6.0,    0.0,      3.0,    0.0 },
+      {  0,  0,  2,  2,  1,      -7.0,    0.0,      3.0,    0.0 },
+      {  1,  0,  2, -2,  1,       6.0,    0.0,     -3.0,    0.0 },
+      {  0,  0,  0, -2,  1,      -5.0,    0.0,      3.0,    0.0 },
+
+   /* 61-70 */
+      {  1, -1,  0,  0,  0,       5.0,    0.0,      0.0,    0.0 },
+      {  2,  0,  2,  0,  1,      -5.0,    0.0,      3.0,    0.0 },
+      {  0,  1,  0, -2,  0,      -4.0,    0.0,      0.0,    0.0 },
+      {  1,  0, -2,  0,  0,       4.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  0,  1,  0,      -4.0,    0.0,      0.0,    0.0 },
+      {  1,  1,  0,  0,  0,      -3.0,    0.0,      0.0,    0.0 },
+      {  1,  0,  2,  0,  0,       3.0,    0.0,      0.0,    0.0 },
+      {  1, -1,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
+      { -1, -1,  2,  2,  2,      -3.0,    0.0,      1.0,    0.0 },
+      { -2,  0,  0,  0,  1,      -2.0,    0.0,      1.0,    0.0 },
+
+   /* 71-80 */
+      {  3,  0,  2,  0,  2,      -3.0,    0.0,      1.0,    0.0 },
+      {  0, -1,  2,  2,  2,      -3.0,    0.0,      1.0,    0.0 },
+      {  1,  1,  2,  0,  2,       2.0,    0.0,     -1.0,    0.0 },
+      { -1,  0,  2, -2,  1,      -2.0,    0.0,      1.0,    0.0 },
+      {  2,  0,  0,  0,  1,       2.0,    0.0,     -1.0,    0.0 },
+      {  1,  0,  0,  0,  2,      -2.0,    0.0,      1.0,    0.0 },
+      {  3,  0,  0,  0,  0,       2.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  2,  1,  2,       2.0,    0.0,     -1.0,    0.0 },
+      { -1,  0,  0,  0,  2,       1.0,    0.0,     -1.0,    0.0 },
+      {  1,  0,  0, -4,  0,      -1.0,    0.0,      0.0,    0.0 },
+
+   /* 81-90 */
+      { -2,  0,  2,  2,  2,       1.0,    0.0,     -1.0,    0.0 },
+      { -1,  0,  2,  4,  2,      -2.0,    0.0,      1.0,    0.0 },
+      {  2,  0,  0, -4,  0,      -1.0,    0.0,      0.0,    0.0 },
+      {  1,  1,  2, -2,  2,       1.0,    0.0,     -1.0,    0.0 },
+      {  1,  0,  2,  2,  1,      -1.0,    0.0,      1.0,    0.0 },
+      { -2,  0,  2,  4,  2,      -1.0,    0.0,      1.0,    0.0 },
+      { -1,  0,  4,  0,  2,       1.0,    0.0,      0.0,    0.0 },
+      {  1, -1,  0, -2,  0,       1.0,    0.0,      0.0,    0.0 },
+      {  2,  0,  2, -2,  1,       1.0,    0.0,     -1.0,    0.0 },
+      {  2,  0,  2,  2,  2,      -1.0,    0.0,      0.0,    0.0 },
+
+   /* 91-100 */
+      {  1,  0,  0,  2,  1,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  4, -2,  2,       1.0,    0.0,      0.0,    0.0 },
+      {  3,  0,  2, -2,  2,       1.0,    0.0,      0.0,    0.0 },
+      {  1,  0,  2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  2,  0,  1,       1.0,    0.0,      0.0,    0.0 },
+      { -1, -1,  0,  2,  1,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  0, -2,  0,  1,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  2, -1,  2,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  0,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
+      {  1,  0, -2, -2,  0,      -1.0,    0.0,      0.0,    0.0 },
+
+   /* 101-106 */
+      {  0, -1,  2,  0,  1,      -1.0,    0.0,      0.0,    0.0 },
+      {  1,  1,  0, -2,  1,      -1.0,    0.0,      0.0,    0.0 },
+      {  1,  0, -2,  2,  0,      -1.0,    0.0,      0.0,    0.0 },
+      {  2,  0,  0,  2,  0,       1.0,    0.0,      0.0,    0.0 },
+      {  0,  0,  2,  4,  2,      -1.0,    0.0,      0.0,    0.0 },
+      {  0,  1,  0,  1,  0,       1.0,    0.0,      0.0,    0.0 }
+   };
+
+/* Number of terms in the series */
+   const int NT = (int) (sizeof x / sizeof x[0]);
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental epoch J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* --------------------- */
+/* Fundamental arguments */
+/* --------------------- */
+
+/* Mean longitude of Moon minus mean longitude of Moon's perigee. */
+   el = eraAnpm(
+        (485866.733 + (715922.633 + (31.310 + 0.064 * t) * t) * t)
+        * ERFA_DAS2R + fmod(1325.0 * t, 1.0) * ERFA_D2PI);
+
+/* Mean longitude of Sun minus mean longitude of Sun's perigee. */
+   elp = eraAnpm(
+         (1287099.804 + (1292581.224 + (-0.577 - 0.012 * t) * t) * t)
+         * ERFA_DAS2R + fmod(99.0 * t, 1.0) * ERFA_D2PI);
+
+/* Mean longitude of Moon minus mean longitude of Moon's node. */
+   f = eraAnpm(
+       (335778.877 + (295263.137 + (-13.257 + 0.011 * t) * t) * t)
+       * ERFA_DAS2R + fmod(1342.0 * t, 1.0) * ERFA_D2PI);
+
+/* Mean elongation of Moon from Sun. */
+   d = eraAnpm(
+       (1072261.307 + (1105601.328 + (-6.891 + 0.019 * t) * t) * t)
+       * ERFA_DAS2R + fmod(1236.0 * t, 1.0) * ERFA_D2PI);
+
+/* Longitude of the mean ascending node of the lunar orbit on the */
+/* ecliptic, measured from the mean equinox of date. */
+   om = eraAnpm(
+        (450160.280 + (-482890.539 + (7.455 + 0.008 * t) * t) * t)
+        * ERFA_DAS2R + fmod(-5.0 * t, 1.0) * ERFA_D2PI);
+
+/* --------------- */
+/* Nutation series */
+/* --------------- */
+
+/* Initialize nutation components. */
+   dp = 0.0;
+   de = 0.0;
+
+/* Sum the nutation terms, ending with the biggest. */
+   for (j = NT-1; j >= 0; j--) {
+
+   /* Form argument for current term. */
+      arg = (double)x[j].nl  * el
+          + (double)x[j].nlp * elp
+          + (double)x[j].nf  * f
+          + (double)x[j].nd  * d
+          + (double)x[j].nom * om;
+
+   /* Accumulate current nutation term. */
+      s = x[j].sp + x[j].spt * t;
+      c = x[j].ce + x[j].cet * t;
+      if (s != 0.0) dp += s * sin(arg);
+      if (c != 0.0) de += c * cos(arg);
+   }
+
+/* Convert results from 0.1 mas units to radians. */
+   *dpsi = dp * U2R;
+   *deps = de * U2R;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/nutm80.c b/cextern/erfa/nutm80.c
new file mode 100644
index 0000000..37612d3
--- /dev/null
+++ b/cextern/erfa/nutm80.c
@@ -0,0 +1,126 @@
+#include "erfa.h"
+
+void eraNutm80(double date1, double date2, double rmatn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsi, deps, epsa;
+
+
+/* Nutation components and mean obliquity. */
+   eraNut80(date1, date2, &dpsi, &deps);
+   epsa = eraObl80(date1, date2);
+
+/* Build the rotation matrix. */
+   eraNumat(epsa, dpsi, deps, rmatn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/obl06.c b/cextern/erfa/obl06.c
new file mode 100644
index 0000000..d1dad56
--- /dev/null
+++ b/cextern/erfa/obl06.c
@@ -0,0 +1,127 @@
+#include "erfa.h"
+
+double eraObl06(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, eps0;
+
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Mean obliquity. */
+   eps0 = (84381.406     +
+          (-46.836769    +
+          ( -0.0001831   +
+          (  0.00200340  +
+          ( -0.000000576 +
+          ( -0.0000000434) * t) * t) * t) * t) * t) * ERFA_DAS2R;
+
+   return eps0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/obl80.c b/cextern/erfa/obl80.c
new file mode 100644
index 0000000..c8fbb96
--- /dev/null
+++ b/cextern/erfa/obl80.c
@@ -0,0 +1,127 @@
+#include "erfa.h"
+
+double eraObl80(double date1, double date2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, eps0;
+
+
+/* Interval between fundamental epoch J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Mean obliquity of date. */
+   eps0 = ERFA_DAS2R * (84381.448  +
+                  (-46.8150   +
+                  (-0.00059   +
+                  ( 0.001813) * t) * t) * t);
+
+   return eps0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/p06e.c b/cextern/erfa/p06e.c
new file mode 100644
index 0000000..d8a3d69
--- /dev/null
+++ b/cextern/erfa/p06e.c
@@ -0,0 +1,330 @@
+#include "erfa.h"
+
+void eraP06e(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)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t;
+
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Obliquity at J2000.0. */
+
+   *eps0 = 84381.406 * ERFA_DAS2R;
+
+/* Luni-solar precession. */
+
+   *psia = ( 5038.481507     +
+           (   -1.0790069    +
+           (   -0.00114045   +
+           (    0.000132851  +
+           (   -0.0000000951 )
+           * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Inclination of mean equator with respect to the J2000.0 ecliptic. */
+
+   *oma = *eps0 + ( -0.025754     +
+                  (  0.0512623    +
+                  ( -0.00772503   +
+                  ( -0.000000467  +
+                  (  0.0000003337 )
+                  * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Ecliptic pole x, J2000.0 ecliptic triad. */
+
+   *bpa = (  4.199094     +
+          (  0.1939873    +
+          ( -0.00022466   +
+          ( -0.000000912  +
+          (  0.0000000120 )
+          * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Ecliptic pole -y, J2000.0 ecliptic triad. */
+
+   *bqa = ( -46.811015     +
+          (   0.0510283    +
+          (   0.00052413   +
+          (  -0.000000646  +
+          (  -0.0000000172 )
+          * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Angle between moving and J2000.0 ecliptics. */
+
+   *pia = ( 46.998973     +
+          ( -0.0334926    +
+          ( -0.00012559   +
+          (  0.000000113  +
+          ( -0.0000000022 )
+          * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Longitude of ascending node of the moving ecliptic. */
+
+   *bpia = ( 629546.7936      +
+           (   -867.95758     +
+           (      0.157992    +
+           (     -0.0005371   +
+           (     -0.00004797  +
+           (      0.000000072 )
+           * t) * t) * t) * t) * t) * ERFA_DAS2R;
+
+/* Mean obliquity of the ecliptic. */
+
+   *epsa = eraObl06(date1, date2);
+
+/* Planetary precession. */
+
+   *chia = ( 10.556403     +
+           ( -2.3814292    +
+           ( -0.00121197   +
+           (  0.000170663  +
+           ( -0.0000000560 )
+           * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Equatorial precession: minus the third of the 323 Euler angles. */
+
+   *za = (   -2.650545     +
+         ( 2306.077181     +
+         (    1.0927348    +
+         (    0.01826837   +
+         (   -0.000028596  +
+         (   -0.0000002904 )
+         * t) * t) * t) * t) * t) * ERFA_DAS2R;
+
+/* Equatorial precession: minus the first of the 323 Euler angles. */
+
+   *zetaa = (    2.650545     +
+            ( 2306.083227     +
+            (    0.2988499    +
+            (    0.01801828   +
+            (   -0.000005971  +
+            (   -0.0000003173 )
+            * t) * t) * t) * t) * t) * ERFA_DAS2R;
+
+/* Equatorial precession: second of the 323 Euler angles. */
+
+   *thetaa = ( 2004.191903     +
+             (   -0.4294934    +
+             (   -0.04182264   +
+             (   -0.000007089  +
+             (   -0.0000001274 )
+             * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* General precession. */
+
+   *pa = ( 5028.796195     +
+         (    1.1054348    +
+         (    0.00007964   +
+         (   -0.000023857  +
+         (    0.0000000383 )
+         * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+/* Fukushima-Williams angles for precession. */
+
+   *gam = ( 10.556403     +
+          (  0.4932044    +
+          ( -0.00031238   +
+          ( -0.000002788  +
+          (  0.0000000260 )
+          * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+   *phi = *eps0 + ( -46.811015     +
+                  (   0.0511269    +
+                  (   0.00053289   +
+                  (  -0.000000440  +
+                  (  -0.0000000176 )
+                  * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+   *psi = ( 5038.481507     +
+          (    1.5584176    +
+          (   -0.00018522   +
+          (   -0.000026452  +
+          (   -0.0000000148 )
+          * t) * t) * t) * t) * t * ERFA_DAS2R;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/p2pv.c b/cextern/erfa/p2pv.c
new file mode 100644
index 0000000..6ec1388
--- /dev/null
+++ b/cextern/erfa/p2pv.c
@@ -0,0 +1,92 @@
+#include "erfa.h"
+
+void eraP2pv(double p[3], double pv[2][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraCp(p, pv[0]);
+   eraZp(pv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/p2s.c b/cextern/erfa/p2s.c
new file mode 100644
index 0000000..2821b49
--- /dev/null
+++ b/cextern/erfa/p2s.c
@@ -0,0 +1,100 @@
+#include "erfa.h"
+
+void eraP2s(double p[3], double *theta, double *phi, double *r)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraC2s(p, theta, phi);
+   *r = eraPm(p);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pap.c b/cextern/erfa/pap.c
new file mode 100644
index 0000000..94c17c2
--- /dev/null
+++ b/cextern/erfa/pap.c
@@ -0,0 +1,148 @@
+#include "erfa.h"
+
+double eraPap(double a[3], double b[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double am, au[3], bm, st, ct, xa, ya, za, eta[3], xi[3], a2b[3], pa;
+
+
+/* Modulus and direction of the a vector. */
+   eraPn(a, &am, au);
+
+/* Modulus of the b vector. */
+   bm = eraPm(b);
+
+/* Deal with the case of a null vector. */
+   if ((am == 0.0) || (bm == 0.0)) {
+      st = 0.0;
+      ct = 1.0;
+   } else {
+
+   /* The "north" axis tangential from a (arbitrary length). */
+      xa = a[0];
+      ya = a[1];
+      za = a[2];
+      eta[0] = -xa * za;
+      eta[1] = -ya * za;
+      eta[2] =  xa*xa + ya*ya;
+
+   /* The "east" axis tangential from a (same length). */
+      eraPxp(eta, au, xi);
+
+   /* The vector from a to b. */
+      eraPmp(b, a, a2b);
+
+   /* Resolve into components along the north and east axes. */
+      st = eraPdp(a2b, xi);
+      ct = eraPdp(a2b, eta);
+
+   /* Deal with degenerate cases. */
+      if ((st == 0.0) && (ct == 0.0)) ct = 1.0;
+   }
+
+/* Position angle. */
+   pa = atan2(st, ct);
+
+   return pa;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pas.c b/cextern/erfa/pas.c
new file mode 100644
index 0000000..a71da1b
--- /dev/null
+++ b/cextern/erfa/pas.c
@@ -0,0 +1,105 @@
+#include "erfa.h"
+
+double eraPas(double al, double ap, double bl, double bp)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dl, x, y, pa;
+
+
+   dl = bl - al;
+   y = sin(dl) * cos(bp);
+   x = sin(bp) * cos(ap) - cos(bp) * sin(ap) * cos(dl);
+   pa = ((x != 0.0) || (y != 0.0)) ? atan2(y, x) : 0.0;
+
+   return pa;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pb06.c b/cextern/erfa/pb06.c
new file mode 100644
index 0000000..dc8d60d
--- /dev/null
+++ b/cextern/erfa/pb06.c
@@ -0,0 +1,153 @@
+#include "erfa.h"
+
+void eraPb06(double date1, double date2,
+             double *bzeta, double *bz, double *btheta)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r[3][3], r31, r32;
+
+
+/* Precession matrix via Fukushima-Williams angles. */
+   eraPmat06(date1, date2, r);
+
+/* Solve for z. */
+   *bz = atan2(r[1][2], r[0][2]);
+
+/* Remove it from the matrix. */
+   eraRz(*bz, r);
+
+/* Solve for the remaining two angles. */
+   *bzeta = atan2 (r[1][0], r[1][1]);
+   r31 = r[2][0];
+   r32 = r[2][1];
+   *btheta = atan2(-ERFA_DSIGN(sqrt(r31 * r31 + r32 * r32), r[0][2]),
+                   r[2][2]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pdp.c b/cextern/erfa/pdp.c
new file mode 100644
index 0000000..2b55422
--- /dev/null
+++ b/cextern/erfa/pdp.c
@@ -0,0 +1,93 @@
+#include "erfa.h"
+
+double eraPdp(double a[3], double b[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double w;
+
+
+   w  = a[0] * b[0]
+      + a[1] * b[1]
+      + a[2] * b[2];
+
+   return w;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pfw06.c b/cextern/erfa/pfw06.c
new file mode 100644
index 0000000..645dd5c
--- /dev/null
+++ b/cextern/erfa/pfw06.c
@@ -0,0 +1,174 @@
+#include "erfa.h"
+
+void eraPfw06(double date1, double date2,
+              double *gamb, double *phib, double *psib, double *epsa)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t;
+
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* P03 bias+precession angles. */
+   *gamb = (    -0.052928     +
+           (    10.556378     +
+           (     0.4932044    +
+           (    -0.00031238   +
+           (    -0.000002788  +
+           (     0.0000000260 )
+           * t) * t) * t) * t) * t) * ERFA_DAS2R;
+   *phib = ( 84381.412819     +
+           (   -46.811016     +
+           (     0.0511268    +
+           (     0.00053289   +
+           (    -0.000000440  +
+           (    -0.0000000176 )
+           * t) * t) * t) * t) * t) * ERFA_DAS2R;
+   *psib = (    -0.041775     +
+           (  5038.481484     +
+           (     1.5584175    +
+           (    -0.00018522   +
+           (    -0.000026452  +
+           (    -0.0000000148 )
+           * t) * t) * t) * t) * t) * ERFA_DAS2R;
+   *epsa =  eraObl06(date1, date2);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/plan94.c b/cextern/erfa/plan94.c
new file mode 100644
index 0000000..7191204
--- /dev/null
+++ b/cextern/erfa/plan94.c
@@ -0,0 +1,523 @@
+#include "erfa.h"
+
+int eraPlan94(double date1, double date2, int np, double pv[2][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Gaussian constant */
+   static const double GK = 0.017202098950;
+
+/* Sin and cos of J2000.0 mean obliquity (IAU 1976) */
+   static const double SINEPS = 0.3977771559319137;
+   static const double COSEPS = 0.9174820620691818;
+
+/* Maximum number of iterations allowed to solve Kepler's equation */
+   static const int KMAX = 10;
+
+   int jstat, i, k;
+   double t, da, dl, de, dp, di, dom, dmu, arga, argl, am,
+          ae, dae, ae2, at, r, v, si2, xq, xp, tl, xsw,
+          xcw, xm2, xf, ci2, xms, xmc, xpxq2, x, y, z;
+
+/* Planetary inverse masses */
+   static const double amas[] = { 6023600.0,       /* Mercury */
+                                   408523.5,       /* Venus   */
+                                   328900.5,       /* EMB     */
+                                  3098710.0,       /* Mars    */
+                                     1047.355,     /* Jupiter */
+                                     3498.5,       /* Saturn  */
+                                    22869.0,       /* Uranus  */
+                                    19314.0 };     /* Neptune */
+
+/*
+** Tables giving the mean Keplerian elements, limited to t^2 terms:
+**
+**   a       semi-major axis (AU)
+**   dlm     mean longitude (degree and arcsecond)
+**   e       eccentricity
+**   pi      longitude of the perihelion (degree and arcsecond)
+**   dinc    inclination (degree and arcsecond)
+**   omega   longitude of the ascending node (degree and arcsecond)
+*/
+
+   static const double a[][3] = {
+       {  0.3870983098,           0.0,     0.0 },  /* Mercury */
+       {  0.7233298200,           0.0,     0.0 },  /* Venus   */
+       {  1.0000010178,           0.0,     0.0 },  /* EMB     */
+       {  1.5236793419,         3e-10,     0.0 },  /* Mars    */
+       {  5.2026032092,     19132e-10, -39e-10 },  /* Jupiter */
+       {  9.5549091915, -0.0000213896, 444e-10 },  /* Saturn  */
+       { 19.2184460618,     -3716e-10, 979e-10 },  /* Uranus  */
+       { 30.1103868694,    -16635e-10, 686e-10 }   /* Neptune */
+   };
+
+   static const double dlm[][3] = {
+       { 252.25090552, 5381016286.88982,  -1.92789 },
+       { 181.97980085, 2106641364.33548,   0.59381 },
+       { 100.46645683, 1295977422.83429,  -2.04411 },
+       { 355.43299958,  689050774.93988,   0.94264 },
+       {  34.35151874,  109256603.77991, -30.60378 },
+       {  50.07744430,   43996098.55732,  75.61614 },
+       { 314.05500511,   15424811.93933,  -1.75083 },
+       { 304.34866548,    7865503.20744,   0.21103 }
+   };
+
+   static const double e[][3] = {
+       { 0.2056317526,  0.0002040653,    -28349e-10 },
+       { 0.0067719164, -0.0004776521,     98127e-10 },
+       { 0.0167086342, -0.0004203654, -0.0000126734 },
+       { 0.0934006477,  0.0009048438,    -80641e-10 },
+       { 0.0484979255,  0.0016322542, -0.0000471366 },
+       { 0.0555481426, -0.0034664062, -0.0000643639 },
+       { 0.0463812221, -0.0002729293,  0.0000078913 },
+       { 0.0094557470,  0.0000603263,           0.0 }
+   };
+
+   static const double pi[][3] = {
+       {  77.45611904,  5719.11590,   -4.83016 },
+       { 131.56370300,   175.48640, -498.48184 },
+       { 102.93734808, 11612.35290,   53.27577 },
+       { 336.06023395, 15980.45908,  -62.32800 },
+       {  14.33120687,  7758.75163,  259.95938 },
+       {  93.05723748, 20395.49439,  190.25952 },
+       { 173.00529106,  3215.56238,  -34.09288 },
+       {  48.12027554,  1050.71912,   27.39717 }
+   };
+
+   static const double dinc[][3] = {
+       { 7.00498625, -214.25629,   0.28977 },
+       { 3.39466189,  -30.84437, -11.67836 },
+       {        0.0,  469.97289,  -3.35053 },
+       { 1.84972648, -293.31722,  -8.11830 },
+       { 1.30326698,  -71.55890,  11.95297 },
+       { 2.48887878,   91.85195, -17.66225 },
+       { 0.77319689,  -60.72723,   1.25759 },
+       { 1.76995259,    8.12333,   0.08135 }
+   };
+
+   static const double omega[][3] = {
+       {  48.33089304,  -4515.21727,  -31.79892 },
+       {  76.67992019, -10008.48154,  -51.32614 },
+       { 174.87317577,  -8679.27034,   15.34191 },
+       {  49.55809321, -10620.90088, -230.57416 },
+       { 100.46440702,   6362.03561,  326.52178 },
+       { 113.66550252,  -9240.19942,  -66.23743 },
+       {  74.00595701,   2669.15033,  145.93964 },
+       { 131.78405702,   -221.94322,   -0.78728 }
+   };
+
+/* Tables for trigonometric terms to be added to the mean elements of */
+/* the semi-major axes */
+
+   static const double kp[][9] = {
+    {   69613, 75645, 88306, 59899, 15746, 71087, 142173,  3086,    0 },
+    {   21863, 32794, 26934, 10931, 26250, 43725,  53867, 28939,    0 },
+    {   16002, 21863, 32004, 10931, 14529, 16368,  15318, 32794,    0 },
+    {    6345,  7818, 15636,  7077,  8184, 14163,   1107,  4872,    0 },
+    {    1760,  1454,  1167,   880,   287,  2640,     19,  2047, 1454 },
+    {     574,     0,   880,   287,    19,  1760,   1167,   306,  574 },
+    {     204,     0,   177,  1265,     4,   385,    200,   208,  204 },
+    {       0,   102,   106,     4,    98,  1367,    487,   204,    0 }
+   };
+
+   static const double ca[][9] = {
+    {       4,    -13,    11,   -9,    -9,   -3,     -1,     4,     0 },
+    {    -156,     59,   -42,    6,    19,  -20,    -10,   -12,     0 },
+    {      64,   -152,    62,   -8,    32,  -41,     19,   -11,     0 },
+    {     124,    621,  -145,  208,    54,  -57,     30,    15,     0 },
+    {  -23437,  -2634,  6601, 6259, -1507,-1821,   2620, -2115, -1489 },
+    {   62911,-119919, 79336,17814,-24241,12068,   8306, -4893,  8902 },
+    {  389061,-262125,-44088, 8387,-22976,-2093,   -615, -9720,  6633 },
+    { -412235,-157046,-31430,37817, -9740,  -13,  -7449,  9644,     0 }
+   };
+
+   static const double sa[][9] = {
+    {     -29,    -1,     9,     6,    -6,     5,     4,     0,     0 },
+    {     -48,  -125,   -26,   -37,    18,   -13,   -20,    -2,     0 },
+    {    -150,   -46,    68,    54,    14,    24,   -28,    22,     0 },
+    {    -621,   532,  -694,   -20,   192,   -94,    71,   -73,     0 },
+    {  -14614,-19828, -5869,  1881, -4372, -2255,   782,   930,   913 },
+    {  139737,     0, 24667, 51123, -5102,  7429, -4095, -1976, -9566 },
+    { -138081,     0, 37205,-49039,-41901,-33872,-27037,-12474, 18797 },
+    {       0, 28492,133236, 69654, 52322,-49577,-26430, -3593,     0 }
+   };
+
+/* Tables giving the trigonometric terms to be added to the mean */
+/* elements of the mean longitudes */
+
+   static const double kq[][10] = {
+    {   3086,15746,69613,59899,75645,88306, 12661,  2658,    0,     0 },
+    {  21863,32794,10931,   73, 4387,26934,  1473,  2157,    0,     0 },
+    {     10,16002,21863,10931, 1473,32004,  4387,    73,    0,     0 },
+    {     10, 6345, 7818, 1107,15636, 7077,  8184,   532,   10,     0 },
+    {     19, 1760, 1454,  287, 1167,  880,   574,  2640,   19,  1454 },
+    {     19,  574,  287,  306, 1760,   12,    31,    38,   19,   574 },
+    {      4,  204,  177,    8,   31,  200,  1265,   102,    4,   204 },
+    {      4,  102,  106,    8,   98, 1367,   487,   204,    4,   102 }
+   };
+
+   static const double cl[][10] = {
+    {      21,   -95, -157,   41,   -5,   42,  23,  30,      0,     0 },
+    {    -160,  -313, -235,   60,  -74,  -76, -27,  34,      0,     0 },
+    {    -325,  -322,  -79,  232,  -52,   97,  55, -41,      0,     0 },
+    {    2268,  -979,  802,  602, -668,  -33, 345, 201,    -55,     0 },
+    {    7610, -4997,-7689,-5841,-2617, 1115,-748,-607,   6074,   354 },
+    {  -18549, 30125,20012, -730,  824,   23,1289,-352, -14767, -2062 },
+    { -135245,-14594, 4197,-4030,-5630,-2898,2540,-306,   2939,  1986 },
+    {   89948,  2103, 8963, 2695, 3682, 1648, 866,-154,  -1963,  -283 }
+   };
+
+   static const double sl[][10] = {
+    {   -342,   136,  -23,   62,   66,  -52, -33,    17,     0,     0 },
+    {    524,  -149,  -35,  117,  151,  122, -71,   -62,     0,     0 },
+    {   -105,  -137,  258,   35, -116,  -88,-112,   -80,     0,     0 },
+    {    854,  -205, -936, -240,  140, -341, -97,  -232,   536,     0 },
+    { -56980,  8016, 1012, 1448,-3024,-3710, 318,   503,  3767,   577 },
+    { 138606,-13478,-4964, 1441,-1319,-1482, 427,  1236, -9167, -1918 },
+    {  71234,-41116, 5334,-4935,-1848,   66, 434, -1748,  3780,  -701 },
+    { -47645, 11647, 2166, 3194,  679,    0,-244,  -419, -2531,    48 }
+   };
+
+/*--------------------------------------------------------------------*/
+
+/* Validate the planet number. */
+   if ((np < 1) || (np > 8)) {
+      jstat = -1;
+
+   /* Reset the result in case of failure. */
+      for (k = 0; k < 2; k++) {
+         for (i = 0; i < 3; i++) {
+            pv[k][i] = 0.0;
+         }
+      }
+
+   } else {
+
+   /* Decrement the planet number to start at zero. */
+      np--;
+
+   /* Time: Julian millennia since J2000.0. */
+      t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJM;
+
+   /* OK status unless remote date. */
+      jstat = fabs(t) <= 1.0 ? 0 : 1;
+
+   /* Compute the mean elements. */
+      da = a[np][0] +
+          (a[np][1] +
+           a[np][2] * t) * t;
+      dl = (3600.0 * dlm[np][0] +
+                    (dlm[np][1] +
+                     dlm[np][2] * t) * t) * ERFA_DAS2R;
+      de = e[np][0] +
+         ( e[np][1] +
+           e[np][2] * t) * t;
+      dp = eraAnpm((3600.0 * pi[np][0] +
+                            (pi[np][1] +
+                             pi[np][2] * t) * t) * ERFA_DAS2R);
+      di = (3600.0 * dinc[np][0] +
+                    (dinc[np][1] +
+                     dinc[np][2] * t) * t) * ERFA_DAS2R;
+      dom = eraAnpm((3600.0 * omega[np][0] +
+                             (omega[np][1] +
+                              omega[np][2] * t) * t) * ERFA_DAS2R);
+
+   /* Apply the trigonometric terms. */
+      dmu = 0.35953620 * t;
+      for (k = 0; k < 8; k++) {
+         arga = kp[np][k] * dmu;
+         argl = kq[np][k] * dmu;
+         da += (ca[np][k] * cos(arga) +
+                sa[np][k] * sin(arga)) * 1e-7;
+         dl += (cl[np][k] * cos(argl) +
+                sl[np][k] * sin(argl)) * 1e-7;
+      }
+      arga = kp[np][8] * dmu;
+      da += t * (ca[np][8] * cos(arga) +
+                 sa[np][8] * sin(arga)) * 1e-7;
+      for (k = 8; k < 10; k++) {
+         argl = kq[np][k] * dmu;
+         dl += t * (cl[np][k] * cos(argl) +
+                    sl[np][k] * sin(argl)) * 1e-7;
+      }
+      dl = fmod(dl, ERFA_D2PI);
+
+   /* Iterative soln. of Kepler's equation to get eccentric anomaly. */
+      am = dl - dp;
+      ae = am + de * sin(am);
+      k = 0;
+      dae = 1.0;
+      while (k < KMAX && fabs(dae) > 1e-12) {
+         dae = (am - ae + de * sin(ae)) / (1.0 - de * cos(ae));
+         ae += dae;
+         k++;
+         if (k == KMAX-1) jstat = 2;
+      }
+
+   /* True anomaly. */
+      ae2 = ae / 2.0;
+      at = 2.0 * atan2(sqrt((1.0 + de) / (1.0 - de)) * sin(ae2),
+                                                       cos(ae2));
+
+   /* Distance (AU) and speed (radians per day). */
+      r = da * (1.0 - de * cos(ae));
+      v = GK * sqrt((1.0 + 1.0 / amas[np]) / (da * da * da));
+
+      si2 = sin(di / 2.0);
+      xq = si2 * cos(dom);
+      xp = si2 * sin(dom);
+      tl = at + dp;
+      xsw = sin(tl);
+      xcw = cos(tl);
+      xm2 = 2.0 * (xp * xcw - xq * xsw);
+      xf = da / sqrt(1  -  de * de);
+      ci2 = cos(di / 2.0);
+      xms = (de * sin(dp) + xsw) * xf;
+      xmc = (de * cos(dp) + xcw) * xf;
+      xpxq2 = 2 * xp * xq;
+
+   /* Position (J2000.0 ecliptic x,y,z in AU). */
+      x = r * (xcw - xm2 * xp);
+      y = r * (xsw + xm2 * xq);
+      z = r * (-xm2 * ci2);
+
+   /* Rotate to equatorial. */
+      pv[0][0] = x;
+      pv[0][1] = y * COSEPS - z * SINEPS;
+      pv[0][2] = y * SINEPS + z * COSEPS;
+
+   /* Velocity (J2000.0 ecliptic xdot,ydot,zdot in AU/d). */
+      x = v * (( -1.0 + 2.0 * xp * xp) * xms + xpxq2 * xmc);
+      y = v * ((  1.0 - 2.0 * xq * xq) * xmc - xpxq2 * xms);
+      z = v * (2.0 * ci2 * (xp * xms + xq * xmc));
+
+   /* Rotate to equatorial. */
+      pv[1][0] = x;
+      pv[1][1] = y * COSEPS - z * SINEPS;
+      pv[1][2] = y * SINEPS + z * COSEPS;
+
+   }
+
+/* Return the status. */
+   return jstat;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pm.c b/cextern/erfa/pm.c
new file mode 100644
index 0000000..3ad503a
--- /dev/null
+++ b/cextern/erfa/pm.c
@@ -0,0 +1,85 @@
+#include "erfa.h"
+
+double eraPm(double p[3])
+/*
+**  - - - - - -
+**   e r a P m
+**  - - - - - -
+**
+**  Modulus of p-vector.
+**
+**  Given:
+**     p      double[3]     p-vector
+**
+**  Returned (function value):
+**            double        modulus
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   return sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmat00.c b/cextern/erfa/pmat00.c
new file mode 100644
index 0000000..275184a
--- /dev/null
+++ b/cextern/erfa/pmat00.c
@@ -0,0 +1,127 @@
+#include "erfa.h"
+
+void eraPmat00(double date1, double date2, double rbp[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rb[3][3], rp[3][3];
+
+
+/* Obtain the required matrix (discarding others). */
+   eraBp00(date1, date2, rb, rp, rbp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmat06.c b/cextern/erfa/pmat06.c
new file mode 100644
index 0000000..28d48f7
--- /dev/null
+++ b/cextern/erfa/pmat06.c
@@ -0,0 +1,131 @@
+#include "erfa.h"
+
+void eraPmat06(double date1, double date2, double rbp[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gamb, phib, psib, epsa;
+
+
+/* Bias-precession Fukushima-Williams angles. */
+   eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa);
+
+/* Form the matrix. */
+   eraFw2m(gamb, phib, psib, epsa, rbp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmat76.c b/cextern/erfa/pmat76.c
new file mode 100644
index 0000000..eeeecd2
--- /dev/null
+++ b/cextern/erfa/pmat76.c
@@ -0,0 +1,150 @@
+#include "erfa.h"
+
+void eraPmat76(double date1, double date2, double rmatp[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double zeta, z, theta, wmat[3][3];
+
+
+/* Precession Euler angles, J2000.0 to specified date. */
+   eraPrec76(ERFA_DJ00, 0.0, date1, date2, &zeta, &z, &theta);
+
+/* Form the rotation matrix. */
+   eraIr(  wmat);
+   eraRz( -zeta, wmat);
+   eraRy(  theta, wmat);
+   eraRz( -z, wmat);
+   eraCr( wmat, rmatp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmp.c b/cextern/erfa/pmp.c
new file mode 100644
index 0000000..d5c1f83
--- /dev/null
+++ b/cextern/erfa/pmp.c
@@ -0,0 +1,94 @@
+#include "erfa.h"
+
+void eraPmp(double a[3], double b[3], double amb[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   amb[0] = a[0] - b[0];
+   amb[1] = a[1] - b[1];
+   amb[2] = a[2] - b[2];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmpx.c b/cextern/erfa/pmpx.c
new file mode 100644
index 0000000..1659edc
--- /dev/null
+++ b/cextern/erfa/pmpx.c
@@ -0,0 +1,153 @@
+#include "erfa.h"
+
+void eraPmpx(double rc, double dc, double pr, double pd,
+             double px, double rv, double pmt, double pob[3],
+             double pco[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Km/s to au/year */
+   const double VF = ERFA_DAYSEC*ERFA_DJM/ERFA_DAU;
+
+/* Light time for 1 au, Julian years */
+   const double AULTY = ERFA_AULT/ERFA_DAYSEC/ERFA_DJY;
+
+   int i;
+   double sr, cr, sd, cd, x, y, z, p[3], dt, pxr, w, pdz, pm[3];
+
+
+/* Spherical coordinates to unit vector (and useful functions). */
+   sr = sin(rc);
+   cr = cos(rc);
+   sd = sin(dc);
+   cd = cos(dc);
+   p[0] = x = cr*cd;
+   p[1] = y = sr*cd;
+   p[2] = z = sd;
+
+/* Proper motion time interval (y) including Roemer effect. */
+   dt = pmt + eraPdp(p,pob)*AULTY;
+
+/* Space motion (radians per year). */
+   pxr = px * ERFA_DAS2R;
+   w = VF * rv * pxr;
+   pdz = pd * z;
+   pm[0] = - pr*y - pdz*cr + w*x;
+   pm[1] =   pr*x - pdz*sr + w*y;
+   pm[2] =   pd*cd + w*z;
+
+/* Coordinate direction of star (unit vector, BCRS). */
+   for (i = 0; i < 3; i++) {
+      p[i] += dt*pm[i] - pxr*pob[i];
+   }
+   eraPn(p, &w, pco);
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pmsafe.c b/cextern/erfa/pmsafe.c
new file mode 100644
index 0000000..3e405f6
--- /dev/null
+++ b/cextern/erfa/pmsafe.c
@@ -0,0 +1,206 @@
+#include "erfa.h"
+
+int eraPmsafe(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Minimum allowed parallax (arcsec) */
+   const double PXMIN = 5e-7;
+
+/* Factor giving maximum allowed transverse speed of about 1% c */
+   const double F = 326.0;
+
+   int jpx, j;
+   double pm, px1a;
+
+
+/* Proper motion in one year (radians). */
+   pm = eraSeps(ra1, dec1, ra1+pmr1, dec1+pmd1);
+
+/* Override the parallax to reduce the chances of a warning status. */
+   jpx = 0;
+   px1a = px1;
+   pm *= F;
+   if (px1a < pm) {jpx = 1; px1a = pm;}
+   if (px1a < PXMIN) {jpx = 1; px1a = PXMIN;}
+
+/* Carry out the transformation using the modified parallax. */
+   j = eraStarpm(ra1, dec1, pmr1, pmd1, px1a, rv1,
+                 ep1a, ep1b, ep2a, ep2b,
+                 ra2, dec2, pmr2, pmd2, px2, rv2);
+
+/* Revise and return the status. */
+   if ( !(j%2) ) j += jpx;
+   return j;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn.c b/cextern/erfa/pn.c
new file mode 100644
index 0000000..d8e27b4
--- /dev/null
+++ b/cextern/erfa/pn.c
@@ -0,0 +1,118 @@
+#include "erfa.h"
+
+void eraPn(double p[3], double *r, double u[3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double w;
+
+
+/* Obtain the modulus and test for zero. */
+   w = eraPm(p);
+   if (w == 0.0) {
+
+   /* Null vector. */
+      eraZp(u);
+
+   } else {
+
+   /* Unit vector. */
+      eraSxp(1.0/w, p, u);
+   }
+
+/* Return the modulus. */
+   *r = w;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn00.c b/cextern/erfa/pn00.c
new file mode 100644
index 0000000..9063aba
--- /dev/null
+++ b/cextern/erfa/pn00.c
@@ -0,0 +1,186 @@
+#include "erfa.h"
+
+void eraPn00(double date1, double date2, double dpsi, double deps,
+             double *epsa,
+             double rb[3][3], double rp[3][3], double rbp[3][3],
+             double rn[3][3], double rbpn[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsipr, depspr, rbpw[3][3], rnw[3][3];
+
+
+/* IAU 2000 precession-rate adjustments. */
+   eraPr00(date1, date2, &dpsipr, &depspr);
+
+/* Mean obliquity, consistent with IAU 2000 precession-nutation. */
+   *epsa = eraObl80(date1, date2) + depspr;
+
+/* Frame bias and precession matrices and their product. */
+   eraBp00(date1, date2, rb, rp, rbpw);
+   eraCr(rbpw, rbp);
+
+/* Nutation matrix. */
+   eraNumat(*epsa, dpsi, deps, rnw);
+   eraCr(rnw, rn);
+
+/* Bias-precession-nutation matrix (classical). */
+   eraRxr(rnw, rbpw, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn00a.c b/cextern/erfa/pn00a.c
new file mode 100644
index 0000000..8544cec
--- /dev/null
+++ b/cextern/erfa/pn00a.c
@@ -0,0 +1,172 @@
+#include "erfa.h"
+
+void eraPn00a(double date1, double date2,
+              double *dpsi, double *deps, double *epsa,
+              double rb[3][3], double rp[3][3], double rbp[3][3],
+              double rn[3][3], double rbpn[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Nutation. */
+   eraNut00a(date1, date2, dpsi, deps);
+
+/* Remaining results. */
+   eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn00b.c b/cextern/erfa/pn00b.c
new file mode 100644
index 0000000..959d6d4
--- /dev/null
+++ b/cextern/erfa/pn00b.c
@@ -0,0 +1,172 @@
+#include "erfa.h"
+
+void eraPn00b(double date1, double date2,
+              double *dpsi, double *deps, double *epsa,
+              double rb[3][3], double rp[3][3], double rbp[3][3],
+              double rn[3][3], double rbpn[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Nutation. */
+   eraNut00b(date1, date2, dpsi, deps);
+
+/* Remaining results. */
+   eraPn00(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn06.c b/cextern/erfa/pn06.c
new file mode 100644
index 0000000..0d23528
--- /dev/null
+++ b/cextern/erfa/pn06.c
@@ -0,0 +1,196 @@
+#include "erfa.h"
+
+void eraPn06(double date1, double date2, double dpsi, double deps,
+             double *epsa,
+             double rb[3][3], double rp[3][3], double rbp[3][3],
+             double rn[3][3], double rbpn[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gamb, phib, psib, eps, r1[3][3], r2[3][3], rt[3][3];
+
+
+/* Bias-precession Fukushima-Williams angles of J2000.0 = frame bias. */
+   eraPfw06(ERFA_DJM0, ERFA_DJM00, &gamb, &phib, &psib, &eps);
+
+/* B matrix. */
+   eraFw2m(gamb, phib, psib, eps, r1);
+   eraCr(r1, rb);
+
+/* Bias-precession Fukushima-Williams angles of date. */
+   eraPfw06(date1, date2, &gamb, &phib, &psib, &eps);
+
+/* Bias-precession matrix. */
+   eraFw2m(gamb, phib, psib, eps, r2);
+   eraCr(r2, rbp);
+
+/* Solve for precession matrix. */
+   eraTr(r1, rt);
+   eraRxr(r2, rt, rp);
+
+/* Equinox-based bias-precession-nutation matrix. */
+   eraFw2m(gamb, phib, psib + dpsi, eps + deps, r1);
+   eraCr(r1, rbpn);
+
+/* Solve for nutation matrix. */
+   eraTr(r2, rt);
+   eraRxr(r1, rt, rn);
+
+/* Obliquity, mean of date. */
+   *epsa = eps;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pn06a.c b/cextern/erfa/pn06a.c
new file mode 100644
index 0000000..5a7f958
--- /dev/null
+++ b/cextern/erfa/pn06a.c
@@ -0,0 +1,162 @@
+#include "erfa.h"
+
+void eraPn06a(double date1, double date2,
+              double *dpsi, double *deps, double *epsa,
+              double rb[3][3], double rp[3][3], double rbp[3][3],
+              double rn[3][3], double rbpn[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Nutation. */
+   eraNut06a(date1, date2, dpsi, deps);
+
+/* Remaining results. */
+   eraPn06(date1, date2, *dpsi, *deps, epsa, rb, rp, rbp, rn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pnm00a.c b/cextern/erfa/pnm00a.c
new file mode 100644
index 0000000..a53b3c7
--- /dev/null
+++ b/cextern/erfa/pnm00a.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+void eraPnm00a(double date1, double date2, double rbpn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3];
+
+
+/* Obtain the required matrix (discarding other results). */
+   eraPn00a(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pnm00b.c b/cextern/erfa/pnm00b.c
new file mode 100644
index 0000000..9acecbe
--- /dev/null
+++ b/cextern/erfa/pnm00b.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+void eraPnm00b(double date1, double date2, double rbpn[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dpsi, deps, epsa, rb[3][3], rp[3][3], rbp[3][3], rn[3][3];
+
+
+/* Obtain the required matrix (discarding other results). */
+   eraPn00b(date1, date2, &dpsi, &deps, &epsa, rb, rp, rbp, rn, rbpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pnm06a.c b/cextern/erfa/pnm06a.c
new file mode 100644
index 0000000..7801234
--- /dev/null
+++ b/cextern/erfa/pnm06a.c
@@ -0,0 +1,133 @@
+#include "erfa.h"
+
+void eraPnm06a(double date1, double date2, double rnpb[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double gamb, phib, psib, epsa, dp, de;
+
+
+/* Fukushima-Williams angles for frame bias and precession. */
+   eraPfw06(date1, date2, &gamb, &phib, &psib, &epsa);
+
+/* Nutation components. */
+   eraNut06a(date1, date2, &dp, &de);
+
+/* Equinox based nutation x precession x bias matrix. */
+   eraFw2m(gamb, phib, psib + dp, epsa + de, rnpb);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pnm80.c b/cextern/erfa/pnm80.c
new file mode 100644
index 0000000..ced1834
--- /dev/null
+++ b/cextern/erfa/pnm80.c
@@ -0,0 +1,135 @@
+#include "erfa.h"
+
+void eraPnm80(double date1, double date2, double rmatpn[3][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rmatp[3][3], rmatn[3][3];
+
+
+/* Precession matrix, J2000.0 to date. */
+   eraPmat76(date1, date2, rmatp);
+
+/* Nutation matrix. */
+   eraNutm80(date1, date2, rmatn);
+
+/* Combine the matrices:  PN = N x P. */
+   eraRxr(rmatn, rmatp, rmatpn);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pom00.c b/cextern/erfa/pom00.c
new file mode 100644
index 0000000..3606a90
--- /dev/null
+++ b/cextern/erfa/pom00.c
@@ -0,0 +1,124 @@
+#include "erfa.h"
+
+void eraPom00(double xp, double yp, double sp, double rpom[3][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Construct the matrix. */
+   eraIr(rpom);
+   eraRz(sp, rpom);
+   eraRy(-xp, rpom);
+   eraRx(-yp, rpom);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ppp.c b/cextern/erfa/ppp.c
new file mode 100644
index 0000000..87ff430
--- /dev/null
+++ b/cextern/erfa/ppp.c
@@ -0,0 +1,94 @@
+#include "erfa.h"
+
+void eraPpp(double a[3], double b[3], double apb[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   apb[0] = a[0] + b[0];
+   apb[1] = a[1] + b[1];
+   apb[2] = a[2] + b[2];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ppsp.c b/cextern/erfa/ppsp.c
new file mode 100644
index 0000000..fa86b00
--- /dev/null
+++ b/cextern/erfa/ppsp.c
@@ -0,0 +1,103 @@
+#include "erfa.h"
+
+void eraPpsp(double a[3], double s, double b[3], double apsb[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double sb[3];
+
+
+/* s*b. */
+   eraSxp(s, b, sb);
+
+/* a + s*b. */
+   eraPpp(a, sb, apsb);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pr00.c b/cextern/erfa/pr00.c
new file mode 100644
index 0000000..3477ad3
--- /dev/null
+++ b/cextern/erfa/pr00.c
@@ -0,0 +1,151 @@
+#include "erfa.h"
+
+void eraPr00(double date1, double date2, double *dpsipr, double *depspr)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t;
+
+/* Precession and obliquity corrections (radians per century) */
+   static const double PRECOR = -0.29965 * ERFA_DAS2R,
+                       OBLCOR = -0.02524 * ERFA_DAS2R;
+
+
+/* Interval between fundamental epoch J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Precession rate contributions with respect to IAU 1976/80. */
+   *dpsipr = PRECOR * t;
+   *depspr = OBLCOR * t;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/prec76.c b/cextern/erfa/prec76.c
new file mode 100644
index 0000000..ef6cc96
--- /dev/null
+++ b/cextern/erfa/prec76.c
@@ -0,0 +1,157 @@
+#include "erfa.h"
+
+void eraPrec76(double date01, double date02, double date11, double date12,
+               double *zeta, double *z, double *theta)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t0, t, tas2r, w;
+
+
+/* Interval between fundamental epoch J2000.0 and start date (JC). */
+   t0 = ((date01 - ERFA_DJ00) + date02) / ERFA_DJC;
+
+/* Interval over which precession required (JC). */
+   t = ((date11 - date01) + (date12 - date02)) / ERFA_DJC;
+
+/* Euler angles. */
+   tas2r = t * ERFA_DAS2R;
+   w = 2306.2181 + (1.39656 - 0.000139 * t0) * t0;
+
+   *zeta = (w + ((0.30188 - 0.000344 * t0) + 0.017998 * t) * t) * tas2r;
+
+   *z = (w + ((1.09468 + 0.000066 * t0) + 0.018203 * t) * t) * tas2r;
+
+   *theta = ((2004.3109 + (-0.85330 - 0.000217 * t0) * t0)
+          + ((-0.42665 - 0.000217 * t0) - 0.041833 * t) * t) * tas2r;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pv2p.c b/cextern/erfa/pv2p.c
new file mode 100644
index 0000000..4218ee0
--- /dev/null
+++ b/cextern/erfa/pv2p.c
@@ -0,0 +1,90 @@
+#include "erfa.h"
+
+void eraPv2p(double pv[2][3], double p[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraCp(pv[0], p);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pv2s.c b/cextern/erfa/pv2s.c
new file mode 100644
index 0000000..7ed8db2
--- /dev/null
+++ b/cextern/erfa/pv2s.c
@@ -0,0 +1,153 @@
+#include "erfa.h"
+
+void eraPv2s(double pv[2][3],
+             double *theta, double *phi, double *r,
+             double *td, double *pd, double *rd)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y, z, xd, yd, zd, rxy2, rxy, r2, rtrue, rw, xyp;
+
+
+/* Components of position/velocity vector. */
+   x  = pv[0][0];
+   y  = pv[0][1];
+   z  = pv[0][2];
+   xd = pv[1][0];
+   yd = pv[1][1];
+   zd = pv[1][2];
+
+/* Component of r in XY plane squared. */
+   rxy2 = x*x + y*y;
+
+/* Modulus squared. */
+   r2 = rxy2 + z*z;
+
+/* Modulus. */
+   rtrue = sqrt(r2);
+
+/* If null vector, move the origin along the direction of movement. */
+   rw = rtrue;
+   if (rtrue == 0.0) {
+       x = xd;
+       y = yd;
+       z = zd;
+       rxy2 = x*x + y*y;
+       r2 = rxy2 + z*z;
+       rw = sqrt(r2);
+   }
+
+/* Position and velocity in spherical coordinates. */
+   rxy = sqrt(rxy2);
+   xyp = x*xd + y*yd;
+   if (rxy2 != 0.0) {
+       *theta = atan2(y, x);
+       *phi = atan2(z, rxy);
+       *td = (x*yd - y*xd) / rxy2;
+       *pd = (zd*rxy2 - z*xyp) / (r2*rxy);
+   } else {
+       *theta = 0.0;
+       *phi = (z != 0.0) ? atan2(z, rxy) : 0.0;
+       *td = 0.0;
+       *pd = 0.0;
+   }
+   *r = rtrue;
+   *rd = (rw != 0.0) ? (xyp + z*zd) / rw : 0.0;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvdpv.c b/cextern/erfa/pvdpv.c
new file mode 100644
index 0000000..2f01707
--- /dev/null
+++ b/cextern/erfa/pvdpv.c
@@ -0,0 +1,111 @@
+#include "erfa.h"
+
+void eraPvdpv(double a[2][3], double b[2][3], double adb[2])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double adbd, addb;
+
+
+/* a . b = constant part of result. */
+   adb[0] = eraPdp(a[0], b[0]);
+
+/* a . bdot */
+   adbd = eraPdp(a[0], b[1]);
+
+/* adot . b */
+   addb = eraPdp(a[1], b[0]);
+
+/* Velocity part of result. */
+   adb[1] = adbd + addb;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvm.c b/cextern/erfa/pvm.c
new file mode 100644
index 0000000..cfd9c3e
--- /dev/null
+++ b/cextern/erfa/pvm.c
@@ -0,0 +1,95 @@
+#include "erfa.h"
+
+void eraPvm(double pv[2][3], double *r, double *s)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Distance. */
+   *r = eraPm(pv[0]);
+
+/* Speed. */
+   *s = eraPm(pv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvmpv.c b/cextern/erfa/pvmpv.c
new file mode 100644
index 0000000..f91f5fe
--- /dev/null
+++ b/cextern/erfa/pvmpv.c
@@ -0,0 +1,96 @@
+#include "erfa.h"
+
+void eraPvmpv(double a[2][3], double b[2][3], double amb[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraPmp(a[0], b[0], amb[0]);
+   eraPmp(a[1], b[1], amb[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvppv.c b/cextern/erfa/pvppv.c
new file mode 100644
index 0000000..4ab89a7
--- /dev/null
+++ b/cextern/erfa/pvppv.c
@@ -0,0 +1,96 @@
+#include "erfa.h"
+
+void eraPvppv(double a[2][3], double b[2][3], double apb[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraPpp(a[0], b[0], apb[0]);
+   eraPpp(a[1], b[1], apb[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvstar.c b/cextern/erfa/pvstar.c
new file mode 100644
index 0000000..49b1b67
--- /dev/null
+++ b/cextern/erfa/pvstar.c
@@ -0,0 +1,216 @@
+#include "erfa.h"
+
+int eraPvstar(double pv[2][3], double *ra, double *dec,
+              double *pmr, double *pmd, double *px, double *rv)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double r, x[3], vr, ur[3], vt, ut[3], bett, betr, d, w, del,
+          usr[3], ust[3], a, rad, decd, rd;
+
+
+/* Isolate the radial component of the velocity (AU/day, inertial). */
+   eraPn(pv[0], &r, x);
+   vr = eraPdp(x, pv[1]);
+   eraSxp(vr, x, ur);
+
+/* Isolate the transverse component of the velocity (AU/day, inertial). */
+   eraPmp(pv[1], ur, ut);
+   vt = eraPm(ut);
+
+/* Special-relativity dimensionless parameters. */
+   bett = vt / ERFA_DC;
+   betr = vr / ERFA_DC;
+
+/* The inertial-to-observed correction terms. */
+   d = 1.0 + betr;
+   w = 1.0 - betr*betr - bett*bett;
+   if (d == 0.0 || w < 0) return -1;
+   del = sqrt(w) - 1.0;
+
+/* Apply relativistic correction factor to radial velocity component. */
+   w = (betr != 0) ? (betr - del) / (betr * d) : 1.0;
+   eraSxp(w, ur, usr);
+
+/* Apply relativistic correction factor to tangential velocity */
+/* component.                                                  */
+   eraSxp(1.0/d, ut, ust);
+
+/* Combine the two to obtain the observed velocity vector (AU/day). */
+   eraPpp(usr, ust, pv[1]);
+
+/* Cartesian to spherical. */
+   eraPv2s(pv, &a, dec, &r, &rad, &decd, &rd);
+   if (r == 0.0) return -2;
+
+/* Return RA in range 0 to 2pi. */
+   *ra = eraAnp(a);
+
+/* Return proper motions in radians per year. */
+   *pmr = rad * ERFA_DJY;
+   *pmd = decd * ERFA_DJY;
+
+/* Return parallax in arcsec. */
+   *px = ERFA_DR2AS / r;
+
+/* Return radial velocity in km/s. */
+   *rv = 1e-3 * rd * ERFA_DAU / ERFA_DAYSEC;
+
+/* OK status. */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvtob.c b/cextern/erfa/pvtob.c
new file mode 100644
index 0000000..f808be7
--- /dev/null
+++ b/cextern/erfa/pvtob.c
@@ -0,0 +1,162 @@
+#include "erfa.h"
+
+void eraPvtob(double elong, double phi, double hm,
+              double xp, double yp, double sp, double theta,
+              double pv[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Earth rotation rate in radians per UT1 second */
+   const double OM = 1.00273781191135448 * ERFA_D2PI / ERFA_DAYSEC;
+
+   double xyzm[3], rpm[3][3], xyz[3], x, y, z, s, c;
+
+
+/* Geodetic to geocentric transformation (ERFA_WGS84). */
+   (void) eraGd2gc(1, elong, phi, hm, xyzm);
+
+/* Polar motion and TIO position. */
+   eraPom00(xp, yp, sp, rpm);
+   eraTrxp(rpm, xyzm, xyz);
+   x = xyz[0];
+   y = xyz[1];
+   z = xyz[2];
+
+/* Functions of ERA. */
+   s = sin(theta);
+   c = cos(theta);
+
+/* Position. */
+   pv[0][0] = c*x - s*y;
+   pv[0][1] = s*x + c*y;
+   pv[0][2] = z;
+
+/* Velocity. */
+   pv[1][0] = OM * ( -s*x - c*y );
+   pv[1][1] = OM * (  c*x - s*y );
+   pv[1][2] = 0.0;
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvu.c b/cextern/erfa/pvu.c
new file mode 100644
index 0000000..8b469d0
--- /dev/null
+++ b/cextern/erfa/pvu.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+void eraPvu(double dt, double pv[2][3], double upv[2][3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraPpsp(pv[0], dt, pv[1], upv[0]);
+   eraCp(pv[1], upv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvup.c b/cextern/erfa/pvup.c
new file mode 100644
index 0000000..d820be8
--- /dev/null
+++ b/cextern/erfa/pvup.c
@@ -0,0 +1,97 @@
+#include "erfa.h"
+
+void eraPvup(double dt, double pv[2][3], double p[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   p[0] = pv[0][0] + dt * pv[1][0];
+   p[1] = pv[0][1] + dt * pv[1][1];
+   p[2] = pv[0][2] + dt * pv[1][2];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pvxpv.c b/cextern/erfa/pvxpv.c
new file mode 100644
index 0000000..fcea173
--- /dev/null
+++ b/cextern/erfa/pvxpv.c
@@ -0,0 +1,116 @@
+#include "erfa.h"
+
+void eraPvxpv(double a[2][3], double b[2][3], double axb[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double wa[2][3], wb[2][3], axbd[3], adxb[3];
+
+
+/* Make copies of the inputs. */
+   eraCpv(a, wa);
+   eraCpv(b, wb);
+
+/* a x b = position part of result. */
+   eraPxp(wa[0], wb[0], axb[0]);
+
+/* a x bdot + adot x b = velocity part of result. */
+   eraPxp(wa[0], wb[1], axbd);
+   eraPxp(wa[1], wb[0], adxb);
+   eraPpp(axbd, adxb, axb[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/pxp.c b/cextern/erfa/pxp.c
new file mode 100644
index 0000000..32a224f
--- /dev/null
+++ b/cextern/erfa/pxp.c
@@ -0,0 +1,103 @@
+#include "erfa.h"
+
+void eraPxp(double a[3], double b[3], double axb[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double xa, ya, za, xb, yb, zb;
+
+
+   xa = a[0];
+   ya = a[1];
+   za = a[2];
+   xb = b[0];
+   yb = b[1];
+   zb = b[2];
+   axb[0] = ya*zb - za*yb;
+   axb[1] = za*xb - xa*zb;
+   axb[2] = xa*yb - ya*xb;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/refco.c b/cextern/erfa/refco.c
new file mode 100644
index 0000000..8c228d1
--- /dev/null
+++ b/cextern/erfa/refco.c
@@ -0,0 +1,262 @@
+#include "erfa.h"
+
+void eraRefco(double phpa, double tc, double rh, double wl,
+              double *refa, double *refb)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int optic;
+   double p, t, r, w, ps, pw, tk, wlsq, gamma, beta;
+
+
+/* Decide whether optical/IR or radio case:  switch at 100 microns. */
+   optic = ( wl <= 100.0 );
+
+/* Restrict parameters to safe values. */
+   t = ERFA_GMAX ( tc, -150.0 );
+   t = ERFA_GMIN ( t, 200.0 );
+   p = ERFA_GMAX ( phpa, 0.0 );
+   p = ERFA_GMIN ( p, 10000.0 );
+   r = ERFA_GMAX ( rh, 0.0 );
+   r = ERFA_GMIN ( r, 1.0 );
+   w = ERFA_GMAX ( wl, 0.1 );
+   w = ERFA_GMIN ( w, 1e6 );
+
+/* Water vapour pressure at the observer. */
+   if ( p > 0.0 ) {
+      ps = pow ( 10.0, ( 0.7859 + 0.03477*t ) /
+                          ( 1.0 + 0.00412*t ) ) *
+                 ( 1.0 + p * ( 4.5e-6 + 6e-10*t*t )  );
+      pw = r * ps / ( 1.0 - (1.0-r)*ps/p );
+   } else {
+      pw = 0.0;
+   }
+
+/* Refractive index minus 1 at the observer. */
+   tk = t + 273.15;
+   if ( optic ) {
+      wlsq = w * w;
+      gamma = ( ( 77.53484e-6 +
+                 ( 4.39108e-7 + 3.666e-9/wlsq ) / wlsq ) * p
+                    - 11.2684e-6*pw ) / tk;
+   } else {
+      gamma = ( 77.6890e-6*p - ( 6.3938e-6 - 0.375463/tk ) * pw ) / tk;
+   }
+
+/* Formula for beta from Stone, with empirical adjustments. */
+   beta = 4.4474e-6 * tk;
+   if ( ! optic ) beta -= 0.0074 * pw * beta;
+
+/* Refraction constants from Green. */
+   *refa = gamma * ( 1.0 - beta );
+   *refb = - gamma * ( beta - gamma / 2.0 );
+
+/* Finished. */
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rm2v.c b/cextern/erfa/rm2v.c
new file mode 100644
index 0000000..7cf27db
--- /dev/null
+++ b/cextern/erfa/rm2v.c
@@ -0,0 +1,120 @@
+#include "erfa.h"
+
+void eraRm2v(double r[3][3], double w[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y, z, s2, c2, phi, f;
+
+
+   x = r[1][2] - r[2][1];
+   y = r[2][0] - r[0][2];
+   z = r[0][1] - r[1][0];
+   s2 = sqrt(x*x + y*y + z*z);
+   if (s2 != 0) {
+      c2 = r[0][0] + r[1][1] + r[2][2] - 1.0;
+      phi = atan2(s2, c2);
+      f =  phi / s2;
+      w[0] = x * f;
+      w[1] = y * f;
+      w[2] = z * f;
+   } else {
+      w[0] = 0.0;
+      w[1] = 0.0;
+      w[2] = 0.0;
+   }
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rv2m.c b/cextern/erfa/rv2m.c
new file mode 100644
index 0000000..22eeff8
--- /dev/null
+++ b/cextern/erfa/rv2m.c
@@ -0,0 +1,127 @@
+#include "erfa.h"
+
+void eraRv2m(double w[3], double r[3][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double x, y, z, phi, s, c, f;
+
+
+/* Euler angle (magnitude of rotation vector) and functions. */
+   x = w[0];
+   y = w[1];
+   z = w[2];
+   phi = sqrt(x*x + y*y + z*z);
+   s = sin(phi);
+   c = cos(phi);
+   f = 1.0 - c;
+
+/* Euler axis (direction of rotation vector), perhaps null. */
+   if (phi != 0.0) {
+       x /= phi;
+       y /= phi;
+       z /= phi;
+   }
+
+/* Form the rotation matrix. */
+   r[0][0] = x*x*f + c;
+   r[0][1] = x*y*f + z*s;
+   r[0][2] = x*z*f - y*s;
+   r[1][0] = y*x*f - z*s;
+   r[1][1] = y*y*f + c;
+   r[1][2] = y*z*f + x*s;
+   r[2][0] = z*x*f + y*s;
+   r[2][1] = z*y*f - x*s;
+   r[2][2] = z*z*f + c;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rx.c b/cextern/erfa/rx.c
new file mode 100644
index 0000000..2cfa460
--- /dev/null
+++ b/cextern/erfa/rx.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+void eraRx(double phi, double r[3][3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double s, c, a10, a11, a12, a20, a21, a22;
+
+
+   s = sin(phi);
+   c = cos(phi);
+
+   a10 =   c*r[1][0] + s*r[2][0];
+   a11 =   c*r[1][1] + s*r[2][1];
+   a12 =   c*r[1][2] + s*r[2][2];
+   a20 = - s*r[1][0] + c*r[2][0];
+   a21 = - s*r[1][1] + c*r[2][1];
+   a22 = - s*r[1][2] + c*r[2][2];
+
+   r[1][0] = a10;
+   r[1][1] = a11;
+   r[1][2] = a12;
+   r[2][0] = a20;
+   r[2][1] = a21;
+   r[2][2] = a22;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rxp.c b/cextern/erfa/rxp.c
new file mode 100644
index 0000000..124ca30
--- /dev/null
+++ b/cextern/erfa/rxp.c
@@ -0,0 +1,108 @@
+#include "erfa.h"
+
+void eraRxp(double r[3][3], double p[3], double rp[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double w, wrp[3];
+   int i, j;
+
+
+/* Matrix r * vector p. */
+   for (j = 0; j < 3; j++) {
+       w = 0.0;
+       for (i = 0; i < 3; i++) {
+           w += r[j][i] * p[i];
+       }
+       wrp[j] = w;
+   }
+
+/* Return the result. */
+   eraCp(wrp, rp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rxpv.c b/cextern/erfa/rxpv.c
new file mode 100644
index 0000000..fee78ca
--- /dev/null
+++ b/cextern/erfa/rxpv.c
@@ -0,0 +1,95 @@
+#include "erfa.h"
+
+void eraRxpv(double r[3][3], double pv[2][3], double rpv[2][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraRxp(r, pv[0], rpv[0]);
+   eraRxp(r, pv[1], rpv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rxr.c b/cextern/erfa/rxr.c
new file mode 100644
index 0000000..db01937
--- /dev/null
+++ b/cextern/erfa/rxr.c
@@ -0,0 +1,108 @@
+#include "erfa.h"
+
+void eraRxr(double a[3][3], double b[3][3], double atb[3][3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int i, j, k;
+   double w, wm[3][3];
+
+
+   for (i = 0; i < 3; i++) {
+      for (j = 0; j < 3; j++) {
+         w = 0.0;
+         for (k = 0; k < 3; k++) {
+            w +=  a[i][k] * b[k][j];
+         }
+         wm[i][j] = w;
+      }
+   }
+   eraCr(wm, atb);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ry.c b/cextern/erfa/ry.c
new file mode 100644
index 0000000..8259496
--- /dev/null
+++ b/cextern/erfa/ry.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+void eraRy(double theta, double r[3][3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double s, c, a00, a01, a02, a20, a21, a22;
+
+
+   s = sin(theta);
+   c = cos(theta);
+
+   a00 = c*r[0][0] - s*r[2][0];
+   a01 = c*r[0][1] - s*r[2][1];
+   a02 = c*r[0][2] - s*r[2][2];
+   a20 = s*r[0][0] + c*r[2][0];
+   a21 = s*r[0][1] + c*r[2][1];
+   a22 = s*r[0][2] + c*r[2][2];
+
+   r[0][0] = a00;
+   r[0][1] = a01;
+   r[0][2] = a02;
+   r[2][0] = a20;
+   r[2][1] = a21;
+   r[2][2] = a22;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/rz.c b/cextern/erfa/rz.c
new file mode 100644
index 0000000..f511503
--- /dev/null
+++ b/cextern/erfa/rz.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+void eraRz(double psi, double r[3][3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double s, c, a00, a01, a02, a10, a11, a12;
+
+
+   s = sin(psi);
+   c = cos(psi);
+
+   a00 =   c*r[0][0] + s*r[1][0];
+   a01 =   c*r[0][1] + s*r[1][1];
+   a02 =   c*r[0][2] + s*r[1][2];
+   a10 = - s*r[0][0] + c*r[1][0];
+   a11 = - s*r[0][1] + c*r[1][1];
+   a12 = - s*r[0][2] + c*r[1][2];
+
+   r[0][0] = a00;
+   r[0][1] = a01;
+   r[0][2] = a02;
+   r[1][0] = a10;
+   r[1][1] = a11;
+   r[1][2] = a12;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s00.c b/cextern/erfa/s00.c
new file mode 100644
index 0000000..46f3386
--- /dev/null
+++ b/cextern/erfa/s00.c
@@ -0,0 +1,380 @@
+#include "erfa.h"
+
+double eraS00(double date1, double date2, double x, double y)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Time since J2000.0, in Julian centuries */
+   double t;
+
+/* Miscellaneous */
+   int i, j;
+   double a, w0, w1, w2, w3, w4, w5;
+
+/* Fundamental arguments */
+   double fa[8];
+
+/* Returned value */
+   double s;
+
+/* --------------------- */
+/* The series for s+XY/2 */
+/* --------------------- */
+
+   typedef struct {
+      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
+      double s, c;     /* sine and cosine coefficients */
+   } TERM;
+
+/* Polynomial coefficients */
+   static const double sp[] = {
+
+   /* 1-6 */
+          94.00e-6,
+        3808.35e-6,
+        -119.94e-6,
+      -72574.09e-6,
+          27.70e-6,
+          15.61e-6
+   };
+
+/* Terms of order t^0 */
+   static const TERM s0[] = {
+
+   /* 1-10 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0}, -2640.73e-6,   0.39e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},   -63.53e-6,   0.02e-6 },
+      {{ 0,  0,  2, -2,  3,  0,  0,  0},   -11.75e-6,  -0.01e-6 },
+      {{ 0,  0,  2, -2,  1,  0,  0,  0},   -11.21e-6,  -0.01e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},     4.57e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  3,  0,  0,  0},    -2.02e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  1,  0,  0,  0},    -1.98e-6,   0.00e-6 },
+      {{ 0,  0,  0,  0,  3,  0,  0,  0},     1.72e-6,   0.00e-6 },
+      {{ 0,  1,  0,  0,  1,  0,  0,  0},     1.41e-6,   0.01e-6 },
+      {{ 0,  1,  0,  0, -1,  0,  0,  0},     1.26e-6,   0.01e-6 },
+
+   /* 11-20 */
+      {{ 1,  0,  0,  0, -1,  0,  0,  0},     0.63e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0,  1,  0,  0,  0},     0.63e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  3,  0,  0,  0},    -0.46e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  1,  0,  0,  0},    -0.45e-6,   0.00e-6 },
+      {{ 0,  0,  4, -4,  4,  0,  0,  0},    -0.36e-6,   0.00e-6 },
+      {{ 0,  0,  1, -1,  1, -8, 12,  0},     0.24e-6,   0.12e-6 },
+      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.32e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.28e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  3,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  1,  0,  0,  0},    -0.26e-6,   0.00e-6 },
+
+   /* 21-30 */
+      {{ 0,  0,  2, -2,  0,  0,  0,  0},     0.21e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -3,  0,  0,  0},    -0.19e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -1,  0,  0,  0},    -0.18e-6,   0.00e-6 },
+      {{ 0,  0,  0,  0,  0,  8,-13, -1},     0.10e-6,  -0.05e-6 },
+      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.15e-6,   0.00e-6 },
+      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.14e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  2,  0,  0,  0},     0.14e-6,   0.00e-6 },
+      {{ 1,  0,  0, -2,  1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
+      {{ 1,  0,  0, -2, -1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
+      {{ 0,  0,  4, -2,  4,  0,  0,  0},    -0.13e-6,   0.00e-6 },
+
+   /* 31-33 */
+      {{ 0,  0,  2, -2,  4,  0,  0,  0},     0.11e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -3,  0,  0,  0},    -0.11e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -1,  0,  0,  0},    -0.11e-6,   0.00e-6 }
+   };
+
+/* Terms of order t^1 */
+   static const TERM s1[] ={
+
+   /* 1-3 */
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -0.07e-6,   3.57e-6 },
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},     1.71e-6,  -0.03e-6 },
+      {{ 0,  0,  2, -2,  3,  0,  0,  0},     0.00e-6,   0.48e-6 }
+   };
+
+/* Terms of order t^2 */
+   static const TERM s2[] ={
+
+   /* 1-10 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},   743.53e-6,  -0.17e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},    56.91e-6,   0.06e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},     9.84e-6,  -0.01e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -8.85e-6,   0.01e-6 },
+      {{ 0,  1,  0,  0,  0,  0,  0,  0},    -6.38e-6,  -0.05e-6 },
+      {{ 1,  0,  0,  0,  0,  0,  0,  0},    -3.07e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  2,  0,  0,  0},     2.23e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  1,  0,  0,  0},     1.67e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  2,  0,  0,  0},     1.30e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -2,  0,  0,  0},     0.93e-6,   0.00e-6 },
+
+   /* 11-20 */
+      {{ 1,  0,  0, -2,  0,  0,  0,  0},     0.68e-6,   0.00e-6 },
+      {{ 0,  0,  2, -2,  1,  0,  0,  0},    -0.55e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -2,  0,  0,  0},     0.53e-6,   0.00e-6 },
+      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0,  1,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0, -2, -2, -2,  0,  0,  0},    -0.26e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0, -1,  0,  0,  0},    -0.25e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  1,  0,  0,  0},     0.22e-6,   0.00e-6 },
+      {{ 2,  0,  0, -2,  0,  0,  0,  0},    -0.21e-6,   0.00e-6 },
+      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.20e-6,   0.00e-6 },
+
+   /* 21-25 */
+      {{ 0,  0,  2,  2,  2,  0,  0,  0},     0.17e-6,   0.00e-6 },
+      {{ 2,  0,  2,  0,  2,  0,  0,  0},     0.13e-6,   0.00e-6 },
+      {{ 2,  0,  0,  0,  0,  0,  0,  0},    -0.13e-6,   0.00e-6 },
+      {{ 1,  0,  2, -2,  2,  0,  0,  0},    -0.12e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.11e-6,   0.00e-6 }
+   };
+
+/* Terms of order t^3 */
+   static const TERM s3[] ={
+
+   /* 1-4 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},     0.30e-6, -23.51e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},    -0.03e-6,  -1.39e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.01e-6,  -0.24e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},     0.00e-6,   0.22e-6 }
+   };
+
+/* Terms of order t^4 */
+   static const TERM s4[] ={
+
+   /* 1-1 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.26e-6,  -0.01e-6 }
+   };
+
+/* Number of terms in the series */
+   const int NS0 = (int) (sizeof s0 / sizeof (TERM));
+   const int NS1 = (int) (sizeof s1 / sizeof (TERM));
+   const int NS2 = (int) (sizeof s2 / sizeof (TERM));
+   const int NS3 = (int) (sizeof s3 / sizeof (TERM));
+   const int NS4 = (int) (sizeof s4 / sizeof (TERM));
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental epoch J2000.0 and current date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Fundamental Arguments (from IERS Conventions 2003) */
+
+/* Mean anomaly of the Moon. */
+   fa[0] = eraFal03(t);
+
+/* Mean anomaly of the Sun. */
+   fa[1] = eraFalp03(t);
+
+/* Mean longitude of the Moon minus that of the ascending node. */
+   fa[2] = eraFaf03(t);
+
+/* Mean elongation of the Moon from the Sun. */
+   fa[3] = eraFad03(t);
+
+/* Mean longitude of the ascending node of the Moon. */
+   fa[4] = eraFaom03(t);
+
+/* Mean longitude of Venus. */
+   fa[5] = eraFave03(t);
+
+/* Mean longitude of Earth. */
+   fa[6] = eraFae03(t);
+
+/* General precession in longitude. */
+   fa[7] = eraFapa03(t);
+
+/* Evaluate s. */
+   w0 = sp[0];
+   w1 = sp[1];
+   w2 = sp[2];
+   w3 = sp[3];
+   w4 = sp[4];
+   w5 = sp[5];
+
+   for (i = NS0-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+       a += (double)s0[i].nfa[j] * fa[j];
+   }
+   w0 += s0[i].s * sin(a) + s0[i].c * cos(a);
+   }
+
+   for (i = NS1-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+       a += (double)s1[i].nfa[j] * fa[j];
+   }
+   w1 += s1[i].s * sin(a) + s1[i].c * cos(a);
+   }
+
+   for (i = NS2-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+       a += (double)s2[i].nfa[j] * fa[j];
+   }
+   w2 += s2[i].s * sin(a) + s2[i].c * cos(a);
+   }
+
+   for (i = NS3-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+       a += (double)s3[i].nfa[j] * fa[j];
+   }
+   w3 += s3[i].s * sin(a) + s3[i].c * cos(a);
+   }
+
+   for (i = NS4-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+       a += (double)s4[i].nfa[j] * fa[j];
+   }
+   w4 += s4[i].s * sin(a) + s4[i].c * cos(a);
+   }
+
+   s = (w0 +
+       (w1 +
+       (w2 +
+       (w3 +
+       (w4 +
+        w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0;
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s00a.c b/cextern/erfa/s00a.c
new file mode 100644
index 0000000..39376df
--- /dev/null
+++ b/cextern/erfa/s00a.c
@@ -0,0 +1,152 @@
+#include "erfa.h"
+
+double eraS00a(double date1, double date2)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3], x, y, s;
+
+
+/* Bias-precession-nutation-matrix, IAU 2000A. */
+   eraPnm00a(date1, date2, rbpn);
+
+/* Extract the CIP coordinates. */
+   eraBpn2xy(rbpn, &x, &y);
+
+/* Compute the CIO locator s, given the CIP coordinates. */
+   s = eraS00(date1, date2, x, y);
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s00b.c b/cextern/erfa/s00b.c
new file mode 100644
index 0000000..21aecf4
--- /dev/null
+++ b/cextern/erfa/s00b.c
@@ -0,0 +1,152 @@
+#include "erfa.h"
+
+double eraS00b(double date1, double date2)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3], x, y, s;
+
+
+/* Bias-precession-nutation-matrix, IAU 2000B. */
+   eraPnm00b(date1, date2, rbpn);
+
+/* Extract the CIP coordinates. */
+   eraBpn2xy(rbpn, &x, &y);
+
+/* Compute the CIO locator s, given the CIP coordinates. */
+   s = eraS00(date1, date2, x, y);
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s06.c b/cextern/erfa/s06.c
new file mode 100644
index 0000000..e92b501
--- /dev/null
+++ b/cextern/erfa/s06.c
@@ -0,0 +1,377 @@
+#include "erfa.h"
+
+double eraS06(double date1, double date2, double x, double y)
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Time since J2000.0, in Julian centuries */
+   double t;
+
+/* Miscellaneous */
+   int i, j;
+   double a, w0, w1, w2, w3, w4, w5;
+
+/* Fundamental arguments */
+   double fa[8];
+
+/* Returned value */
+   double s;
+
+/* --------------------- */
+/* The series for s+XY/2 */
+/* --------------------- */
+
+   typedef struct {
+      int nfa[8];      /* coefficients of l,l',F,D,Om,LVe,LE,pA */
+      double s, c;     /* sine and cosine coefficients */
+   } TERM;
+
+/* Polynomial coefficients */
+   static const double sp[] = {
+
+   /* 1-6 */
+          94.00e-6,
+        3808.65e-6,
+        -122.68e-6,
+      -72574.11e-6,
+          27.98e-6,
+          15.62e-6
+   };
+
+/* Terms of order t^0 */
+   static const TERM s0[] = {
+
+   /* 1-10 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0}, -2640.73e-6,   0.39e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},   -63.53e-6,   0.02e-6 },
+      {{ 0,  0,  2, -2,  3,  0,  0,  0},   -11.75e-6,  -0.01e-6 },
+      {{ 0,  0,  2, -2,  1,  0,  0,  0},   -11.21e-6,  -0.01e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},     4.57e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  3,  0,  0,  0},    -2.02e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  1,  0,  0,  0},    -1.98e-6,   0.00e-6 },
+      {{ 0,  0,  0,  0,  3,  0,  0,  0},     1.72e-6,   0.00e-6 },
+      {{ 0,  1,  0,  0,  1,  0,  0,  0},     1.41e-6,   0.01e-6 },
+      {{ 0,  1,  0,  0, -1,  0,  0,  0},     1.26e-6,   0.01e-6 },
+
+   /* 11-20 */
+      {{ 1,  0,  0,  0, -1,  0,  0,  0},     0.63e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0,  1,  0,  0,  0},     0.63e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  3,  0,  0,  0},    -0.46e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  1,  0,  0,  0},    -0.45e-6,   0.00e-6 },
+      {{ 0,  0,  4, -4,  4,  0,  0,  0},    -0.36e-6,   0.00e-6 },
+      {{ 0,  0,  1, -1,  1, -8, 12,  0},     0.24e-6,   0.12e-6 },
+      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.32e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.28e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  3,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  1,  0,  0,  0},    -0.26e-6,   0.00e-6 },
+
+   /* 21-30 */
+      {{ 0,  0,  2, -2,  0,  0,  0,  0},     0.21e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -3,  0,  0,  0},    -0.19e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -1,  0,  0,  0},    -0.18e-6,   0.00e-6 },
+      {{ 0,  0,  0,  0,  0,  8,-13, -1},     0.10e-6,  -0.05e-6 },
+      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.15e-6,   0.00e-6 },
+      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.14e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  2,  0,  0,  0},     0.14e-6,   0.00e-6 },
+      {{ 1,  0,  0, -2,  1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
+      {{ 1,  0,  0, -2, -1,  0,  0,  0},    -0.14e-6,   0.00e-6 },
+      {{ 0,  0,  4, -2,  4,  0,  0,  0},    -0.13e-6,   0.00e-6 },
+
+   /* 31-33 */
+      {{ 0,  0,  2, -2,  4,  0,  0,  0},     0.11e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -3,  0,  0,  0},    -0.11e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -1,  0,  0,  0},    -0.11e-6,   0.00e-6 }
+   };
+
+/* Terms of order t^1 */
+   static const TERM s1[] = {
+
+   /* 1 - 3 */
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -0.07e-6,   3.57e-6 },
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},     1.73e-6,  -0.03e-6 },
+      {{ 0,  0,  2, -2,  3,  0,  0,  0},     0.00e-6,   0.48e-6 }
+   };
+
+/* Terms of order t^2 */
+   static const TERM s2[] = {
+
+   /* 1-10 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},   743.52e-6,  -0.17e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},    56.91e-6,   0.06e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},     9.84e-6,  -0.01e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},    -8.85e-6,   0.01e-6 },
+      {{ 0,  1,  0,  0,  0,  0,  0,  0},    -6.38e-6,  -0.05e-6 },
+      {{ 1,  0,  0,  0,  0,  0,  0,  0},    -3.07e-6,   0.00e-6 },
+      {{ 0,  1,  2, -2,  2,  0,  0,  0},     2.23e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  1,  0,  0,  0},     1.67e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  2,  0,  0,  0},     1.30e-6,   0.00e-6 },
+      {{ 0,  1, -2,  2, -2,  0,  0,  0},     0.93e-6,   0.00e-6 },
+
+   /* 11-20 */
+      {{ 1,  0,  0, -2,  0,  0,  0,  0},     0.68e-6,   0.00e-6 },
+      {{ 0,  0,  2, -2,  1,  0,  0,  0},    -0.55e-6,   0.00e-6 },
+      {{ 1,  0, -2,  0, -2,  0,  0,  0},     0.53e-6,   0.00e-6 },
+      {{ 0,  0,  0,  2,  0,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0,  1,  0,  0,  0},    -0.27e-6,   0.00e-6 },
+      {{ 1,  0, -2, -2, -2,  0,  0,  0},    -0.26e-6,   0.00e-6 },
+      {{ 1,  0,  0,  0, -1,  0,  0,  0},    -0.25e-6,   0.00e-6 },
+      {{ 1,  0,  2,  0,  1,  0,  0,  0},     0.22e-6,   0.00e-6 },
+      {{ 2,  0,  0, -2,  0,  0,  0,  0},    -0.21e-6,   0.00e-6 },
+      {{ 2,  0, -2,  0, -1,  0,  0,  0},     0.20e-6,   0.00e-6 },
+
+   /* 21-25 */
+      {{ 0,  0,  2,  2,  2,  0,  0,  0},     0.17e-6,   0.00e-6 },
+      {{ 2,  0,  2,  0,  2,  0,  0,  0},     0.13e-6,   0.00e-6 },
+      {{ 2,  0,  0,  0,  0,  0,  0,  0},    -0.13e-6,   0.00e-6 },
+      {{ 1,  0,  2, -2,  2,  0,  0,  0},    -0.12e-6,   0.00e-6 },
+      {{ 0,  0,  2,  0,  0,  0,  0,  0},    -0.11e-6,   0.00e-6 }
+   };
+
+/* Terms of order t^3 */
+   static const TERM s3[] = {
+
+   /* 1-4 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},     0.30e-6, -23.42e-6 },
+      {{ 0,  0,  2, -2,  2,  0,  0,  0},    -0.03e-6,  -1.46e-6 },
+      {{ 0,  0,  2,  0,  2,  0,  0,  0},    -0.01e-6,  -0.25e-6 },
+      {{ 0,  0,  0,  0,  2,  0,  0,  0},     0.00e-6,   0.23e-6 }
+   };
+
+/* Terms of order t^4 */
+   static const TERM s4[] = {
+
+   /* 1-1 */
+      {{ 0,  0,  0,  0,  1,  0,  0,  0},    -0.26e-6,  -0.01e-6 }
+   };
+
+/* Number of terms in the series */
+   static const int NS0 = (int) (sizeof s0 / sizeof (TERM));
+   static const int NS1 = (int) (sizeof s1 / sizeof (TERM));
+   static const int NS2 = (int) (sizeof s2 / sizeof (TERM));
+   static const int NS3 = (int) (sizeof s3 / sizeof (TERM));
+   static const int NS4 = (int) (sizeof s4 / sizeof (TERM));
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental epoch J2000.0 and current date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Fundamental Arguments (from IERS Conventions 2003) */
+
+/* Mean anomaly of the Moon. */
+   fa[0] = eraFal03(t);
+
+/* Mean anomaly of the Sun. */
+   fa[1] = eraFalp03(t);
+
+/* Mean longitude of the Moon minus that of the ascending node. */
+   fa[2] = eraFaf03(t);
+
+/* Mean elongation of the Moon from the Sun. */
+   fa[3] = eraFad03(t);
+
+/* Mean longitude of the ascending node of the Moon. */
+   fa[4] = eraFaom03(t);
+
+/* Mean longitude of Venus. */
+   fa[5] = eraFave03(t);
+
+/* Mean longitude of Earth. */
+   fa[6] = eraFae03(t);
+
+/* General precession in longitude. */
+   fa[7] = eraFapa03(t);
+
+/* Evaluate s. */
+   w0 = sp[0];
+   w1 = sp[1];
+   w2 = sp[2];
+   w3 = sp[3];
+   w4 = sp[4];
+   w5 = sp[5];
+
+   for (i = NS0-1; i >= 0; i--) {
+   a = 0.0;
+   for (j = 0; j < 8; j++) {
+      a += (double)s0[i].nfa[j] * fa[j];
+   }
+   w0 += s0[i].s * sin(a) + s0[i].c * cos(a);
+   }
+
+   for (i = NS1-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)s1[i].nfa[j] * fa[j];
+      }
+      w1 += s1[i].s * sin(a) + s1[i].c * cos(a);
+   }
+
+   for (i = NS2-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)s2[i].nfa[j] * fa[j];
+      }
+      w2 += s2[i].s * sin(a) + s2[i].c * cos(a);
+   }
+
+   for (i = NS3-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)s3[i].nfa[j] * fa[j];
+      }
+      w3 += s3[i].s * sin(a) + s3[i].c * cos(a);
+   }
+
+   for (i = NS4-1; i >= 0; i--) {
+      a = 0.0;
+      for (j = 0; j < 8; j++) {
+         a += (double)s4[i].nfa[j] * fa[j];
+      }
+      w4 += s4[i].s * sin(a) + s4[i].c * cos(a);
+   }
+
+   s = (w0 +
+       (w1 +
+       (w2 +
+       (w3 +
+       (w4 +
+        w5 * t) * t) * t) * t) * t) * ERFA_DAS2R - x*y/2.0;
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s06a.c b/cextern/erfa/s06a.c
new file mode 100644
index 0000000..6fac640
--- /dev/null
+++ b/cextern/erfa/s06a.c
@@ -0,0 +1,154 @@
+#include "erfa.h"
+
+double eraS06a(double date1, double date2)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rnpb[3][3], x, y, s;
+
+
+/* Bias-precession-nutation-matrix, IAU 20006/2000A. */
+   eraPnm06a(date1, date2, rnpb);
+
+/* Extract the CIP coordinates. */
+   eraBpn2xy(rnpb, &x, &y);
+
+/* Compute the CIO locator s, given the CIP coordinates. */
+   s = eraS06(date1, date2, x, y);
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s2c.c b/cextern/erfa/s2c.c
new file mode 100644
index 0000000..6812fe2
--- /dev/null
+++ b/cextern/erfa/s2c.c
@@ -0,0 +1,94 @@
+#include "erfa.h"
+
+void eraS2c(double theta, double phi, double c[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double cp;
+
+
+   cp = cos(phi);
+   c[0] = cos(theta) * cp;
+   c[1] = sin(theta) * cp;
+   c[2] = sin(phi);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s2p.c b/cextern/erfa/s2p.c
new file mode 100644
index 0000000..69b0415
--- /dev/null
+++ b/cextern/erfa/s2p.c
@@ -0,0 +1,97 @@
+#include "erfa.h"
+
+void eraS2p(double theta, double phi, double r, double p[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double u[3];
+
+
+   eraS2c(theta, phi, u);
+   eraSxp(r, u, p);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s2pv.c b/cextern/erfa/s2pv.c
new file mode 100644
index 0000000..cb9b8d2
--- /dev/null
+++ b/cextern/erfa/s2pv.c
@@ -0,0 +1,112 @@
+#include "erfa.h"
+
+void eraS2pv(double theta, double phi, double r,
+             double td, double pd, double rd,
+             double pv[2][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double st, ct, sp, cp, rcp, x, y, rpd, w;
+
+
+   st = sin(theta);
+   ct = cos(theta);
+   sp = sin(phi);
+   cp = cos(phi);
+   rcp = r * cp;
+   x = rcp * ct;
+   y = rcp * st;
+   rpd = r * pd;
+   w = rpd*sp - cp*rd;
+
+   pv[0][0] = x;
+   pv[0][1] = y;
+   pv[0][2] = r * sp;
+   pv[1][0] = -y*td - w*ct;
+   pv[1][1] =  x*td - w*st;
+   pv[1][2] = rpd*cp + sp*rd;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/s2xpv.c b/cextern/erfa/s2xpv.c
new file mode 100644
index 0000000..909e2ee
--- /dev/null
+++ b/cextern/erfa/s2xpv.c
@@ -0,0 +1,96 @@
+#include "erfa.h"
+
+void eraS2xpv(double s1, double s2, double pv[2][3], double spv[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraSxp(s1, pv[0], spv[0]);
+   eraSxp(s2, pv[1], spv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/sepp.c b/cextern/erfa/sepp.c
new file mode 100644
index 0000000..04993fa
--- /dev/null
+++ b/cextern/erfa/sepp.c
@@ -0,0 +1,114 @@
+#include "erfa.h"
+
+double eraSepp(double a[3], double b[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double axb[3], ss, cs, s;
+
+
+/* Sine of angle between the vectors, multiplied by the two moduli. */
+   eraPxp(a, b, axb);
+   ss = eraPm(axb);
+
+/* Cosine of the angle, multiplied by the two moduli. */
+   cs = eraPdp(a, b);
+
+/* The angle. */
+   s = ((ss != 0.0) || (cs != 0.0)) ? atan2(ss, cs) : 0.0;
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/seps.c b/cextern/erfa/seps.c
new file mode 100644
index 0000000..46dd412
--- /dev/null
+++ b/cextern/erfa/seps.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+double eraSeps(double al, double ap, double bl, double bp)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double ac[3], bc[3], s;
+
+
+/* Spherical to Cartesian. */
+   eraS2c(al, ap, ac);
+   eraS2c(bl, bp, bc);
+
+/* Angle between the vectors. */
+   s = eraSepp(ac, bc);
+
+   return s;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/sp00.c b/cextern/erfa/sp00.c
new file mode 100644
index 0000000..c586ce0
--- /dev/null
+++ b/cextern/erfa/sp00.c
@@ -0,0 +1,127 @@
+#include "erfa.h"
+
+double eraSp00(double date1, double date2)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double t, sp;
+
+
+/* Interval between fundamental epoch J2000.0 and current date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Approximate s'. */
+   sp = -47e-6 * t * ERFA_DAS2R;
+
+   return sp;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/starpm.c b/cextern/erfa/starpm.c
new file mode 100644
index 0000000..e82662a
--- /dev/null
+++ b/cextern/erfa/starpm.c
@@ -0,0 +1,214 @@
+#include "erfa.h"
+
+int eraStarpm(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)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double pv1[2][3], tl1, dt, pv[2][3], r2, rdv, v2, c2mv2, tl2,
+          pv2[2][3];
+   int j1, j2, j;
+
+
+/* RA,Dec etc. at the "before" epoch to space motion pv-vector. */
+   j1 = eraStarpv(ra1, dec1, pmr1, pmd1, px1, rv1, pv1);
+
+/* Light time when observed (days). */
+   tl1 = eraPm(pv1[0]) / ERFA_DC;
+
+/* Time interval, "before" to "after" (days). */
+   dt = (ep2a - ep1a) + (ep2b - ep1b);
+
+/* Move star along track from the "before" observed position to the */
+/* "after" geometric position. */
+   eraPvu(dt + tl1, pv1, pv);
+
+/* From this geometric position, deduce the observed light time (days) */
+/* at the "after" epoch (with theoretically unneccessary error check). */
+   r2 = eraPdp(pv[0], pv[0]);
+   rdv = eraPdp(pv[0], pv[1]);
+   v2 = eraPdp(pv[1], pv[1]);
+   c2mv2 = ERFA_DC*ERFA_DC - v2;
+   if (c2mv2 <=  0) return -1;
+   tl2 = (-rdv + sqrt(rdv*rdv + c2mv2*r2)) / c2mv2;
+
+/* Move the position along track from the observed place at the */
+/* "before" epoch to the observed place at the "after" epoch. */
+   eraPvu(dt + (tl1 - tl2), pv1, pv2);
+
+/* Space motion pv-vector to RA,Dec etc. at the "after" epoch. */
+   j2 = eraPvstar(pv2, ra2, dec2, pmr2, pmd2, px2, rv2);
+
+/* Final status. */
+   j = (j2 == 0) ? j1 : -1;
+
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/starpv.c b/cextern/erfa/starpv.c
new file mode 100644
index 0000000..c79fe77
--- /dev/null
+++ b/cextern/erfa/starpv.c
@@ -0,0 +1,273 @@
+#include "erfa.h"
+
+int eraStarpv(double ra, double dec,
+              double pmr, double pmd, double px, double rv,
+              double pv[2][3])
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+/* Smallest allowed parallax */
+   static const double PXMIN = 1e-7;
+
+/* Largest allowed speed (fraction of c) */
+   static const double VMAX = 0.5;
+
+/* Maximum number of iterations for relativistic solution */
+   static const int IMAX = 100;
+
+   int i, iwarn;
+   double w, r, rd, rad, decd, v, x[3], usr[3], ust[3],
+          vsr, vst, betst, betsr, bett, betr,
+          dd, ddel, ur[3], ut[3],
+          d = 0.0, del = 0.0,       /* to prevent */
+          odd = 0.0, oddel = 0.0,   /* compiler   */
+          od = 0.0, odel = 0.0;     /* warnings   */
+
+
+/* Distance (AU). */
+   if (px >= PXMIN) {
+      w = px;
+      iwarn = 0;
+   } else {
+      w = PXMIN;
+      iwarn = 1;
+   }
+   r = ERFA_DR2AS / w;
+
+/* Radial velocity (AU/day). */
+   rd = ERFA_DAYSEC * rv * 1e3 / ERFA_DAU;
+
+/* Proper motion (radian/day). */
+   rad = pmr / ERFA_DJY;
+   decd = pmd / ERFA_DJY;
+
+/* To pv-vector (AU,AU/day). */
+   eraS2pv(ra, dec, r, rad, decd, rd, pv);
+
+/* If excessive velocity, arbitrarily set it to zero. */
+   v = eraPm(pv[1]);
+   if (v / ERFA_DC > VMAX) {
+      eraZp(pv[1]);
+      iwarn += 2;
+   }
+
+/* Isolate the radial component of the velocity (AU/day). */
+   eraPn(pv[0], &w, x);
+   vsr = eraPdp(x, pv[1]);
+   eraSxp(vsr, x, usr);
+
+/* Isolate the transverse component of the velocity (AU/day). */
+   eraPmp(pv[1], usr, ust);
+   vst = eraPm(ust);
+
+/* Special-relativity dimensionless parameters. */
+   betsr = vsr / ERFA_DC;
+   betst = vst / ERFA_DC;
+
+/* Determine the inertial-to-observed relativistic correction terms. */
+   bett = betst;
+   betr = betsr;
+   for (i = 0; i < IMAX; i++) {
+      d = 1.0 + betr;
+      del = sqrt(1.0 - betr*betr - bett*bett) - 1.0;
+      betr = d * betsr + del;
+      bett = d * betst;
+      if (i > 0) {
+         dd = fabs(d - od);
+         ddel = fabs(del - odel);
+         if ((i > 1) && (dd >= odd) && (ddel >= oddel)) break;
+         odd = dd;
+         oddel = ddel;
+      }
+      od = d;
+      odel = del;
+   }
+   if (i >= IMAX) iwarn += 4;
+
+/* Replace observed radial velocity with inertial value. */
+   w = (betsr != 0.0) ? d + del / betsr : 1.0;
+   eraSxp(w, usr, ur);
+
+/* Replace observed tangential velocity with inertial value. */
+   eraSxp(d, ust, ut);
+
+/* Combine the two to obtain the inertial space velocity. */
+   eraPpp(ur, ut, pv[1]);
+
+/* Return the status. */
+   return iwarn;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/sxp.c b/cextern/erfa/sxp.c
new file mode 100644
index 0000000..14e5b27
--- /dev/null
+++ b/cextern/erfa/sxp.c
@@ -0,0 +1,93 @@
+#include "erfa.h"
+
+void eraSxp(double s, double p[3], double sp[3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   sp[0] = s * p[0];
+   sp[1] = s * p[1];
+   sp[2] = s * p[2];
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/sxpv.c b/cextern/erfa/sxpv.c
new file mode 100644
index 0000000..0dcc03a
--- /dev/null
+++ b/cextern/erfa/sxpv.c
@@ -0,0 +1,94 @@
+#include "erfa.h"
+
+void eraSxpv(double s, double pv[2][3], double spv[2][3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraS2xpv(s, s, pv, spv);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/taitt.c b/cextern/erfa/taitt.c
new file mode 100644
index 0000000..fc0e1b6
--- /dev/null
+++ b/cextern/erfa/taitt.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+int eraTaitt(double tai1, double tai2, double *tt1, double *tt2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* TT minus TAI (days). */
+   static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC;
+
+
+/* Result, safeguarding precision. */
+   if ( tai1 > tai2 ) {
+      *tt1 = tai1;
+      *tt2 = tai2 + dtat;
+   } else {
+      *tt1 = tai1 + dtat;
+      *tt2 = tai2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/taiut1.c b/cextern/erfa/taiut1.c
new file mode 100644
index 0000000..45fbaff
--- /dev/null
+++ b/cextern/erfa/taiut1.c
@@ -0,0 +1,120 @@
+#include "erfa.h"
+
+int eraTaiut1(double tai1, double tai2, double dta,
+              double *ut11, double *ut12)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtad;
+
+
+/* Result, safeguarding precision. */
+   dtad = dta / ERFA_DAYSEC;
+   if ( tai1 > tai2 ) {
+      *ut11 = tai1;
+      *ut12 = tai2 + dtad;
+   } else {
+      *ut11 = tai1 + dtad;
+      *ut12 = tai2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/taiutc.c b/cextern/erfa/taiutc.c
new file mode 100644
index 0000000..c9f6958
--- /dev/null
+++ b/cextern/erfa/taiutc.c
@@ -0,0 +1,168 @@
+#include "erfa.h"
+
+int eraTaiutc(double tai1, double tai2, double *utc1, double *utc2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int big1;
+   int i, j;
+   double a1, a2, u1, u2, g1, g2;
+
+
+/* Put the two parts of the TAI into big-first order. */
+   big1 = ( tai1 >= tai2 );
+   if ( big1 ) {
+      a1 = tai1;
+      a2 = tai2;
+   } else {
+      a1 = tai2;
+      a2 = tai1;
+   }
+
+/* Initial guess for UTC. */
+   u1 = a1;
+   u2 = a2;
+
+/* Iterate (though in most cases just once is enough). */
+   for ( i = 0; i < 3; i++ ) {
+
+   /* Guessed UTC to TAI. */
+      j = eraUtctai(u1, u2, &g1, &g2);
+      if ( j < 0 ) return j;
+
+   /* Adjust guessed UTC. */
+      u2 += a1 - g1;
+      u2 += a2 - g2;
+   }
+
+/* Return the UTC result, preserving the TAI order. */
+   if ( big1 ) {
+      *utc1 = u1;
+      *utc2 = u2;
+   } else {
+      *utc1 = u2;
+      *utc2 = u1;
+   }
+
+/* Status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tcbtdb.c b/cextern/erfa/tcbtdb.c
new file mode 100644
index 0000000..2a76cf3
--- /dev/null
+++ b/cextern/erfa/tcbtdb.c
@@ -0,0 +1,141 @@
+#include "erfa.h"
+
+int eraTcbtdb(double tcb1, double tcb2, double *tdb1, double *tdb2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */
+   static const double t77td = ERFA_DJM0 + ERFA_DJM77;
+   static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC;
+
+/* TDB (days) at TAI 1977 Jan 1.0 */
+   static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC;
+
+   double d;
+
+
+/* Result, safeguarding precision. */
+   if ( tcb1 > tcb2 ) {
+      d = tcb1 - t77td;
+      *tdb1 = tcb1;
+      *tdb2 = tcb2 + tdb0 - ( d + ( tcb2 - t77tf ) ) * ERFA_ELB;
+   } else {
+      d = tcb2 - t77td;
+      *tdb1 = tcb1 + tdb0 - ( d + ( tcb1 - t77tf ) ) * ERFA_ELB;
+      *tdb2 = tcb2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tcgtt.c b/cextern/erfa/tcgtt.c
new file mode 100644
index 0000000..adc0c41
--- /dev/null
+++ b/cextern/erfa/tcgtt.c
@@ -0,0 +1,118 @@
+#include "erfa.h"
+
+int eraTcgtt(double tcg1, double tcg2, double *tt1, double *tt2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* 1977 Jan 1 00:00:32.184 TT, as MJD */
+   static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC;
+
+
+/* Result, safeguarding precision. */
+   if ( tcg1 > tcg2 ) {
+      *tt1 = tcg1;
+      *tt2 = tcg2 - ( ( tcg1 - ERFA_DJM0 ) + ( tcg2 - t77t ) ) * ERFA_ELG;
+   } else {
+      *tt1 = tcg1 - ( ( tcg2 - ERFA_DJM0 ) + ( tcg1 - t77t ) ) * ERFA_ELG;
+      *tt2 = tcg2;
+   }
+
+/* OK status. */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tdbtcb.c b/cextern/erfa/tdbtcb.c
new file mode 100644
index 0000000..aa57f5e
--- /dev/null
+++ b/cextern/erfa/tdbtcb.c
@@ -0,0 +1,146 @@
+#include "erfa.h"
+
+int eraTdbtcb(double tdb1, double tdb2, double *tcb1, double *tcb2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* 1977 Jan 1 00:00:32.184 TT, as two-part JD */
+   static const double t77td = ERFA_DJM0 + ERFA_DJM77;
+   static const double t77tf = ERFA_TTMTAI/ERFA_DAYSEC;
+
+/* TDB (days) at TAI 1977 Jan 1.0 */
+   static const double tdb0 = ERFA_TDB0/ERFA_DAYSEC;
+
+/* TDB to TCB rate */
+   static const double elbb = ERFA_ELB/(1.0-ERFA_ELB);
+
+   double d, f;
+
+
+/* Result, preserving date format but safeguarding precision. */
+   if ( tdb1 > tdb2 ) {
+      d = t77td - tdb1;
+      f  = tdb2 - tdb0;
+      *tcb1 = tdb1;
+      *tcb2 = f - ( d - ( f - t77tf ) ) * elbb;
+   } else {
+      d = t77td - tdb2;
+      f  = tdb1 - tdb0;
+      *tcb1 = f + ( d - ( f - t77tf ) ) * elbb;
+      *tcb2 = tdb2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tdbtt.c b/cextern/erfa/tdbtt.c
new file mode 100644
index 0000000..2b0d72e
--- /dev/null
+++ b/cextern/erfa/tdbtt.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+int eraTdbtt(double tdb1, double tdb2, double dtr,
+             double *tt1, double *tt2 )
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtrd;
+
+
+/* Result, safeguarding precision. */
+   dtrd = dtr / ERFA_DAYSEC;
+   if ( tdb1 > tdb2 ) {
+      *tt1 = tdb1;
+      *tt2 = tdb2 - dtrd;
+   } else {
+      *tt1 = tdb1 - dtrd;
+      *tt2 = tdb2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tf2a.c b/cextern/erfa/tf2a.c
new file mode 100644
index 0000000..3d3535e
--- /dev/null
+++ b/cextern/erfa/tf2a.c
@@ -0,0 +1,116 @@
+#include "erfa.h"
+#include <stdlib.h>
+
+int eraTf2a(char s, int ihour, int imin, double sec, double *rad)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Compute the interval. */
+   *rad  = ( s == '-' ? -1.0 : 1.0 ) *
+           ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) +
+                             ( (double) abs(imin) ) ) +
+                                        fabs(sec) ) * ERFA_DS2R;
+
+/* Validate arguments and return status. */
+   if ( ihour < 0 || ihour > 23 ) return 1;
+   if ( imin < 0 || imin > 59 ) return 2;
+   if ( sec < 0.0 || sec >= 60.0 ) return 3;
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tf2d.c b/cextern/erfa/tf2d.c
new file mode 100644
index 0000000..d61f0c8
--- /dev/null
+++ b/cextern/erfa/tf2d.c
@@ -0,0 +1,116 @@
+#include "erfa.h"
+#include <stdlib.h>
+
+int eraTf2d(char s, int ihour, int imin, double sec, double *days)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Compute the interval. */
+   *days  = ( s == '-' ? -1.0 : 1.0 ) *
+            ( 60.0 * ( 60.0 * ( (double) abs(ihour) ) +
+                              ( (double) abs(imin) ) ) +
+                                         fabs(sec) ) / ERFA_DAYSEC;
+
+/* Validate arguments and return status. */
+   if ( ihour < 0 || ihour > 23 ) return 1;
+   if ( imin < 0 || imin > 59 ) return 2;
+   if ( sec < 0.0 || sec >= 60.0 ) return 3;
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tr.c b/cextern/erfa/tr.c
new file mode 100644
index 0000000..7c97550
--- /dev/null
+++ b/cextern/erfa/tr.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+void eraTr(double r[3][3], double rt[3][3])
+/*
+**  - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double wm[3][3];
+   int i, j;
+
+
+   for (i = 0; i < 3; i++) {
+      for (j = 0; j < 3; j++) {
+         wm[i][j] = r[j][i];
+      }
+   }
+   eraCr(wm, rt);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/trxp.c b/cextern/erfa/trxp.c
new file mode 100644
index 0000000..82ff8c6
--- /dev/null
+++ b/cextern/erfa/trxp.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+void eraTrxp(double r[3][3], double p[3], double trp[3])
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double tr[3][3];
+
+
+/* Transpose of matrix r. */
+   eraTr(r, tr);
+
+/* Matrix tr * vector p -> vector trp. */
+   eraRxp(tr, p, trp);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/trxpv.c b/cextern/erfa/trxpv.c
new file mode 100644
index 0000000..ce071b1
--- /dev/null
+++ b/cextern/erfa/trxpv.c
@@ -0,0 +1,102 @@
+#include "erfa.h"
+
+void eraTrxpv(double r[3][3], double pv[2][3], double trpv[2][3])
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double tr[3][3];
+
+
+/* Transpose of matrix r. */
+   eraTr(r, tr);
+
+/* Matrix tr * vector pv -> vector trpv. */
+   eraRxpv(tr, pv, trpv);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tttai.c b/cextern/erfa/tttai.c
new file mode 100644
index 0000000..87edb10
--- /dev/null
+++ b/cextern/erfa/tttai.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+int eraTttai(double tt1, double tt2, double *tai1, double *tai2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* TT minus TAI (days). */
+   static const double dtat = ERFA_TTMTAI/ERFA_DAYSEC;
+
+
+/* Result, safeguarding precision. */
+   if ( tt1 > tt2 ) {
+      *tai1 = tt1;
+      *tai2 = tt2 - dtat;
+   } else {
+      *tai1 = tt1 - dtat;
+      *tai2 = tt2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tttcg.c b/cextern/erfa/tttcg.c
new file mode 100644
index 0000000..dab382f
--- /dev/null
+++ b/cextern/erfa/tttcg.c
@@ -0,0 +1,121 @@
+#include "erfa.h"
+
+int eraTttcg(double tt1, double tt2, double *tcg1, double *tcg2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* 1977 Jan 1 00:00:32.184 TT, as MJD */
+   static const double t77t = ERFA_DJM77 + ERFA_TTMTAI/ERFA_DAYSEC;
+
+/* TT to TCG rate */
+   static const double elgg = ERFA_ELG/(1.0-ERFA_ELG);
+
+
+/* Result, safeguarding precision. */
+   if ( tt1 > tt2 ) {
+      *tcg1 = tt1;
+      *tcg2 = tt2 + ( ( tt1 - ERFA_DJM0 ) + ( tt2 - t77t ) ) * elgg;
+   } else {
+      *tcg1 = tt1 + ( ( tt2 - ERFA_DJM0 ) + ( tt1 - t77t ) ) * elgg;
+      *tcg2 = tt2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/tttdb.c b/cextern/erfa/tttdb.c
new file mode 100644
index 0000000..c94c94d
--- /dev/null
+++ b/cextern/erfa/tttdb.c
@@ -0,0 +1,130 @@
+#include "erfa.h"
+
+int eraTttdb(double tt1, double tt2, double dtr,
+             double *tdb1, double *tdb2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtrd;
+
+
+/* Result, safeguarding precision. */
+   dtrd = dtr / ERFA_DAYSEC;
+   if ( tt1 > tt2 ) {
+      *tdb1 = tt1;
+      *tdb2 = tt2 + dtrd;
+   } else {
+      *tdb1 = tt1 + dtrd;
+      *tdb2 = tt2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ttut1.c b/cextern/erfa/ttut1.c
new file mode 100644
index 0000000..27dbac8
--- /dev/null
+++ b/cextern/erfa/ttut1.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+int eraTtut1(double tt1, double tt2, double dt,
+             double *ut11, double *ut12)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtd;
+
+
+/* Result, safeguarding precision. */
+   dtd = dt / ERFA_DAYSEC;
+   if ( tt1 > tt2 ) {
+      *ut11 = tt1;
+      *ut12 = tt2 - dtd;
+   } else {
+      *ut11 = tt1 - dtd;
+      *ut12 = tt2;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ut1tai.c b/cextern/erfa/ut1tai.c
new file mode 100644
index 0000000..c21df04
--- /dev/null
+++ b/cextern/erfa/ut1tai.c
@@ -0,0 +1,120 @@
+#include "erfa.h"
+
+int eraUt1tai(double ut11, double ut12, double dta,
+              double *tai1, double *tai2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtad;
+
+
+/* Result, safeguarding precision. */
+   dtad = dta / ERFA_DAYSEC;
+   if ( ut11 > ut12 ) {
+      *tai1 = ut11;
+      *tai2 = ut12 - dtad;
+   } else {
+      *tai1 = ut11 - dtad;
+      *tai2 = ut12;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ut1tt.c b/cextern/erfa/ut1tt.c
new file mode 100644
index 0000000..6beeb22
--- /dev/null
+++ b/cextern/erfa/ut1tt.c
@@ -0,0 +1,119 @@
+#include "erfa.h"
+
+int eraUt1tt(double ut11, double ut12, double dt,
+             double *tt1, double *tt2)
+/*
+**  - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double dtd;
+
+
+/* Result, safeguarding precision. */
+   dtd = dt / ERFA_DAYSEC;
+   if ( ut11 > ut12 ) {
+      *tt1 = ut11;
+      *tt2 = ut12 + dtd;
+   } else {
+      *tt1 = ut11 + dtd;
+      *tt2 = ut12;
+   }
+
+/* Status (always OK). */
+   return 0;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/ut1utc.c b/cextern/erfa/ut1utc.c
new file mode 100644
index 0000000..4788bb3
--- /dev/null
+++ b/cextern/erfa/ut1utc.c
@@ -0,0 +1,202 @@
+#include "erfa.h"
+
+int eraUt1utc(double ut11, double ut12, double dut1,
+              double *utc1, double *utc2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int big1;
+   int i, iy, im, id, js;
+   double duts, u1, u2, d1, dats1, d2, fd, dats2, ddats, us1, us2, du;
+
+
+/* UT1-UTC in seconds. */
+   duts = dut1;
+
+/* Put the two parts of the UT1 into big-first order. */
+   big1 = ( ut11 >= ut12 );
+   if ( big1 ) {
+      u1 = ut11;
+      u2 = ut12;
+   } else {
+      u1 = ut12;
+      u2 = ut11;
+   }
+
+/* See if the UT1 can possibly be in a leap-second day. */
+   d1 = u1;
+   dats1 = 0;
+   for ( i = -1; i <= 3; i++ ) {
+      d2 = u2 + (double) i;
+      if ( eraJd2cal(d1, d2, &iy, &im, &id, &fd) ) return -1;
+      js = eraDat(iy, im, id, 0.0, &dats2);
+      if ( js < 0 ) return -1;
+      if ( i == - 1 ) dats1 = dats2;
+      ddats = dats2 - dats1;
+      if ( fabs(ddats) >= 0.5 ) {
+
+      /* Yes, leap second nearby: ensure UT1-UTC is "before" value. */
+         if ( ddats * duts >= 0 ) duts -= ddats;
+
+      /* UT1 for the start of the UTC day that ends in a leap. */
+         if ( eraCal2jd(iy, im, id, &d1, &d2) ) return -1;
+         us1 = d1;
+         us2 = d2 - 1.0 + duts/ERFA_DAYSEC;
+
+      /* Is the UT1 after this point? */
+         du = u1 - us1;
+         du += u2 - us2;
+         if ( du > 0 ) {
+
+         /* Yes:  fraction of the current UTC day that has elapsed. */
+            fd = du * ERFA_DAYSEC / ( ERFA_DAYSEC + ddats );
+
+         /* Ramp UT1-UTC to bring about ERFA's JD(UTC) convention. */
+            duts += ddats * ( fd <= 1.0 ? fd : 1.0 );
+         }
+
+      /* Done. */
+         break;
+      }
+      dats1 = dats2;
+   }
+
+/* Subtract the (possibly adjusted) UT1-UTC from UT1 to give UTC. */
+   u2 -= duts / ERFA_DAYSEC;
+
+/* Result, safeguarding precision. */
+   if ( big1 ) {
+      *utc1 = u1;
+      *utc2 = u2;
+   } else {
+      *utc1 = u2;
+      *utc2 = u1;
+   }
+
+/* Status. */
+   return js;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/utctai.c b/cextern/erfa/utctai.c
new file mode 100644
index 0000000..44526f0
--- /dev/null
+++ b/cextern/erfa/utctai.c
@@ -0,0 +1,186 @@
+#include "erfa.h"
+
+int eraUtctai(double utc1, double utc2, double *tai1, double *tai2)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int big1;
+   int iy, im, id, j, iyt, imt, idt;
+   double u1, u2, fd, dat0, dat12, w, dat24, dlod, dleap, z1, z2, a2;
+
+
+/* Put the two parts of the UTC into big-first order. */
+   big1 = ( utc1 >= utc2 );
+   if ( big1 ) {
+      u1 = utc1;
+      u2 = utc2;
+   } else {
+      u1 = utc2;
+      u2 = utc1;
+   }
+
+/* Get TAI-UTC at 0h today. */
+   j = eraJd2cal(u1, u2, &iy, &im, &id, &fd);
+   if ( j ) return j;
+   j = eraDat(iy, im, id, 0.0, &dat0);
+   if ( j < 0 ) return j;
+
+/* Get TAI-UTC at 12h today (to detect drift). */
+   j = eraDat(iy, im, id, 0.5, &dat12);
+   if ( j < 0 ) return j;
+
+/* Get TAI-UTC at 0h tomorrow (to detect jumps). */
+   j = eraJd2cal(u1+1.5, u2-fd, &iyt, &imt, &idt, &w);
+   if ( j ) return j;
+   j = eraDat(iyt, imt, idt, 0.0, &dat24);
+   if ( j < 0 ) return j;
+
+/* Separate TAI-UTC change into per-day (DLOD) and any jump (DLEAP). */
+   dlod = 2.0 * (dat12 - dat0);
+   dleap = dat24 - (dat0 + dlod);
+
+/* Remove any scaling applied to spread leap into preceding day. */
+   fd *= (ERFA_DAYSEC+dleap)/ERFA_DAYSEC;
+
+/* Scale from (pre-1972) UTC seconds to SI seconds. */
+   fd *= (ERFA_DAYSEC+dlod)/ERFA_DAYSEC;
+
+/* Today's calendar date to 2-part JD. */
+   if ( eraCal2jd(iy, im, id, &z1, &z2) ) return -1;
+
+/* Assemble the TAI result, preserving the UTC split and order. */
+   a2 = z1 - u1;
+   a2 += z2;
+   a2 += fd + dat0/ERFA_DAYSEC;
+   if ( big1 ) {
+      *tai1 = u1;
+      *tai2 = a2;
+   } else {
+      *tai1 = a2;
+      *tai2 = u1;
+   }
+
+/* Status. */
+   return j;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/utcut1.c b/cextern/erfa/utcut1.c
new file mode 100644
index 0000000..0ba94bc
--- /dev/null
+++ b/cextern/erfa/utcut1.c
@@ -0,0 +1,156 @@
+#include "erfa.h"
+
+int eraUtcut1(double utc1, double utc2, double dut1,
+              double *ut11, double *ut12)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   int iy, im, id, js, jw;
+   double w, dat, dta, tai1, tai2;
+
+
+/* Look up TAI-UTC. */
+   if ( eraJd2cal(utc1, utc2, &iy, &im, &id, &w) ) return -1;
+   js = eraDat ( iy, im, id, 0.0, &dat);
+   if ( js < 0 ) return -1;
+
+/* Form UT1-TAI. */
+   dta = dut1 - dat;
+
+/* UTC to TAI to UT1. */
+   jw = eraUtctai(utc1, utc2, &tai1, &tai2);
+   if ( jw < 0 ) {
+      return -1;
+   } else if ( jw > 0 ) {
+      js = jw;
+   }
+   if ( eraTaiut1(tai1, tai2, dta, ut11, ut12) ) return -1;
+
+/* Status. */
+   return js;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/xy06.c b/cextern/erfa/xy06.c
new file mode 100644
index 0000000..ab7965a
--- /dev/null
+++ b/cextern/erfa/xy06.c
@@ -0,0 +1,2767 @@
+#include "erfa.h"
+
+void eraXy06(double date1, double date2, double *x, double *y)
+/*
+**  - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+
+/* Maximum power of T in the polynomials for X and Y */
+   enum { MAXPT = 5 };
+
+/* Polynomial coefficients (arcsec, X then Y). */
+   static const double xyp[2][MAXPT+1] = {
+
+      {    -0.016617,
+         2004.191898,
+           -0.4297829,
+           -0.19861834,
+            0.000007578,
+            0.0000059285
+      },
+      {    -0.006951,
+           -0.025896,
+          -22.4072747,
+            0.00190059,
+            0.001112526,
+            0.0000001358
+      }
+   };
+
+/* Fundamental-argument multipliers:  luni-solar terms */
+   static const int mfals[][5] = {
+
+   /* 1-10 */
+      {  0,   0,   0,   0,   1 },
+      {  0,   0,   2,  -2,   2 },
+      {  0,   0,   2,   0,   2 },
+      {  0,   0,   0,   0,   2 },
+      {  0,   1,   0,   0,   0 },
+      {  0,   1,   2,  -2,   2 },
+      {  1,   0,   0,   0,   0 },
+      {  0,   0,   2,   0,   1 },
+      {  1,   0,   2,   0,   2 },
+      {  0,   1,  -2,   2,  -2 },
+
+   /* 11-20 */
+      {  0,   0,   2,  -2,   1 },
+      {  1,   0,  -2,   0,  -2 },
+      {  1,   0,   0,  -2,   0 },
+      {  1,   0,   0,   0,   1 },
+      {  1,   0,   0,   0,  -1 },
+      {  1,   0,  -2,  -2,  -2 },
+      {  1,   0,   2,   0,   1 },
+      {  2,   0,  -2,   0,  -1 },
+      {  0,   0,   0,   2,   0 },
+      {  0,   0,   2,   2,   2 },
+
+   /* 21-30 */
+      {  2,   0,   0,  -2,   0 },
+      {  0,   2,  -2,   2,  -2 },
+      {  2,   0,   2,   0,   2 },
+      {  1,   0,   2,  -2,   2 },
+      {  1,   0,  -2,   0,  -1 },
+      {  2,   0,   0,   0,   0 },
+      {  0,   0,   2,   0,   0 },
+      {  0,   1,   0,   0,   1 },
+      {  1,   0,   0,  -2,  -1 },
+      {  0,   2,   2,  -2,   2 },
+
+   /* 31-40 */
+      {  0,   0,   2,  -2,   0 },
+      {  1,   0,   0,  -2,   1 },
+      {  0,   1,   0,   0,  -1 },
+      {  0,   2,   0,   0,   0 },
+      {  1,   0,  -2,  -2,  -1 },
+      {  1,   0,   2,   2,   2 },
+      {  0,   1,   2,   0,   2 },
+      {  2,   0,  -2,   0,   0 },
+      {  0,   0,   2,   2,   1 },
+      {  0,   1,  -2,   0,  -2 },
+
+   /* 41-50 */
+      {  0,   0,   0,   2,   1 },
+      {  1,   0,   2,  -2,   1 },
+      {  2,   0,   0,  -2,  -1 },
+      {  2,   0,   2,  -2,   2 },
+      {  2,   0,   2,   0,   1 },
+      {  0,   0,   0,   2,  -1 },
+      {  0,   1,  -2,   2,  -1 },
+      {  1,   1,   0,  -2,   0 },
+      {  2,   0,   0,  -2,   1 },
+      {  1,   0,   0,   2,   0 },
+
+   /* 51-60 */
+      {  0,   1,   2,  -2,   1 },
+      {  1,  -1,   0,   0,   0 },
+      {  0,   1,  -1,   1,  -1 },
+      {  2,   0,  -2,   0,  -2 },
+      {  0,   1,   0,  -2,   0 },
+      {  1,   0,   0,  -1,   0 },
+      {  3,   0,   2,   0,   2 },
+      {  0,   0,   0,   1,   0 },
+      {  1,  -1,   2,   0,   2 },
+      {  1,   1,  -2,  -2,  -2 },
+
+   /* 61-70 */
+      {  1,   0,  -2,   0,   0 },
+      {  2,   0,   0,   0,  -1 },
+      {  0,   1,  -2,  -2,  -2 },
+      {  1,   1,   2,   0,   2 },
+      {  2,   0,   0,   0,   1 },
+      {  1,   1,   0,   0,   0 },
+      {  1,   0,  -2,   2,  -1 },
+      {  1,   0,   2,   0,   0 },
+      {  1,  -1,   0,  -1,   0 },
+      {  1,   0,   0,   0,   2 },
+
+   /* 71-80 */
+      {  1,   0,  -1,   0,  -1 },
+      {  0,   0,   2,   1,   2 },
+      {  1,   0,  -2,  -4,  -2 },
+      {  1,  -1,   0,  -1,  -1 },
+      {  1,   0,   2,   2,   1 },
+      {  0,   2,  -2,   2,  -1 },
+      {  1,   0,   0,   0,  -2 },
+      {  2,   0,  -2,  -2,  -2 },
+      {  1,   1,   2,  -2,   2 },
+      {  2,   0,  -2,  -4,  -2 },
+
+   /* 81-90 */
+      {  1,   0,  -4,   0,  -2 },
+      {  2,   0,   2,  -2,   1 },
+      {  1,   0,   0,  -1,  -1 },
+      {  2,   0,   2,   2,   2 },
+      {  3,   0,   0,   0,   0 },
+      {  1,   0,   0,   2,   1 },
+      {  0,   0,   2,  -2,  -1 },
+      {  3,   0,   2,  -2,   2 },
+      {  0,   0,   4,  -2,   2 },
+      {  1,   0,   0,  -4,   0 },
+
+   /* 91-100 */
+      {  0,   1,   2,   0,   1 },
+      {  2,   0,   0,  -4,   0 },
+      {  1,   1,   0,  -2,  -1 },
+      {  2,   0,  -2,   0,   1 },
+      {  0,   0,   2,   0,  -1 },
+      {  0,   1,  -2,   0,  -1 },
+      {  0,   1,   0,   0,   2 },
+      {  0,   0,   2,  -1,   2 },
+      {  0,   0,   2,   4,   2 },
+      {  2,   1,   0,  -2,   0 },
+
+   /* 101-110 */
+      {  1,   1,   0,  -2,   1 },
+      {  1,  -1,   0,  -2,   0 },
+      {  1,  -1,   0,  -1,  -2 },
+      {  1,  -1,   0,   0,   1 },
+      {  0,   1,  -2,   2,   0 },
+      {  0,   1,   0,   0,  -2 },
+      {  1,  -1,   2,   2,   2 },
+      {  1,   0,   0,   2,  -1 },
+      {  1,  -1,  -2,  -2,  -2 },
+      {  3,   0,   2,   0,   1 },
+
+   /* 111-120 */
+      {  0,   1,   2,   2,   2 },
+      {  1,   0,   2,  -2,   0 },
+      {  1,   1,  -2,  -2,  -1 },
+      {  1,   0,   2,  -4,   1 },
+      {  0,   1,  -2,  -2,  -1 },
+      {  2,  -1,   2,   0,   2 },
+      {  0,   0,   0,   2,   2 },
+      {  1,  -1,   2,   0,   1 },
+      {  1,  -1,  -2,   0,  -2 },
+      {  0,   1,   0,   2,   0 },
+
+   /* 121-130 */
+      {  0,   1,   2,  -2,   0 },
+      {  0,   0,   0,   1,   1 },
+      {  1,   0,  -2,  -2,   0 },
+      {  0,   3,   2,  -2,   2 },
+      {  2,   1,   2,   0,   2 },
+      {  1,   1,   0,   0,   1 },
+      {  2,   0,   0,   2,   0 },
+      {  1,   1,   2,   0,   1 },
+      {  1,   0,   0,  -2,  -2 },
+      {  1,   0,  -2,   2,   0 },
+
+   /* 131-140 */
+      {  1,   0,  -1,   0,  -2 },
+      {  0,   1,   0,  -2,   1 },
+      {  0,   1,   0,   1,   0 },
+      {  0,   0,   0,   1,  -1 },
+      {  1,   0,  -2,   2,  -2 },
+      {  1,  -1,   0,   0,  -1 },
+      {  0,   0,   0,   4,   0 },
+      {  1,  -1,   0,   2,   0 },
+      {  1,   0,   2,   1,   2 },
+      {  1,   0,   2,  -1,   2 },
+
+   /* 141-150 */
+      {  0,   0,   2,   1,   1 },
+      {  1,   0,   0,  -2,   2 },
+      {  1,   0,  -2,   0,   1 },
+      {  1,   0,  -2,  -4,  -1 },
+      {  0,   0,   2,   2,   0 },
+      {  1,   1,   2,  -2,   1 },
+      {  1,   0,  -2,   1,  -1 },
+      {  0,   0,   1,   0,   1 },
+      {  2,   0,  -2,  -2,  -1 },
+      {  4,   0,   2,   0,   2 },
+
+   /* 151-160 */
+      {  2,  -1,   0,   0,   0 },
+      {  2,   1,   2,  -2,   2 },
+      {  0,   1,   2,   1,   2 },
+      {  1,   0,   4,  -2,   2 },
+      {  1,   1,   0,   0,  -1 },
+      {  2,   0,   2,   0,   0 },
+      {  2,   0,  -2,  -4,  -1 },
+      {  1,   0,  -1,   0,   0 },
+      {  1,   0,   0,   1,   0 },
+      {  0,   1,   0,   2,   1 },
+
+   /* 161-170 */
+      {  1,   0,  -4,   0,  -1 },
+      {  1,   0,   0,  -4,  -1 },
+      {  2,   0,   2,   2,   1 },
+      {  2,   1,   0,   0,   0 },
+      {  0,   0,   2,  -3,   2 },
+      {  1,   2,   0,  -2,   0 },
+      {  0,   3,   0,   0,   0 },
+      {  0,   0,   4,   0,   2 },
+      {  0,   0,   2,  -4,   1 },
+      {  2,   0,   0,  -2,  -2 },
+
+   /* 171-180 */
+      {  1,   1,  -2,  -4,  -2 },
+      {  0,   1,   0,  -2,  -1 },
+      {  0,   0,   0,   4,   1 },
+      {  3,   0,   2,  -2,   1 },
+      {  1,   0,   2,   4,   2 },
+      {  1,   1,  -2,   0,  -2 },
+      {  0,   0,   4,  -2,   1 },
+      {  2,  -2,   0,  -2,   0 },
+      {  2,   1,   0,  -2,  -1 },
+      {  0,   2,   0,  -2,   0 },
+
+   /* 181-190 */
+      {  1,   0,   0,  -1,   1 },
+      {  1,   1,   2,   2,   2 },
+      {  3,   0,   0,   0,  -1 },
+      {  2,   0,   0,  -4,  -1 },
+      {  3,   0,   2,   2,   2 },
+      {  0,   0,   2,   4,   1 },
+      {  0,   2,  -2,  -2,  -2 },
+      {  1,  -1,   0,  -2,  -1 },
+      {  0,   0,   2,  -1,   1 },
+      {  2,   0,   0,   2,   1 },
+
+   /* 191-200 */
+      {  1,  -1,  -2,   2,  -1 },
+      {  0,   0,   0,   2,  -2 },
+      {  2,   0,   0,  -4,   1 },
+      {  1,   0,   0,  -4,   1 },
+      {  2,   0,   2,  -4,   1 },
+      {  4,   0,   2,  -2,   2 },
+      {  2,   1,  -2,   0,  -1 },
+      {  2,   1,  -2,  -4,  -2 },
+      {  3,   0,   0,  -4,   0 },
+      {  1,  -1,   2,   2,   1 },
+
+   /* 201-210 */
+      {  1,  -1,  -2,   0,  -1 },
+      {  0,   2,   0,   0,   1 },
+      {  1,   2,  -2,  -2,  -2 },
+      {  1,   1,   0,  -4,   0 },
+      {  2,   0,   0,  -2,   2 },
+      {  0,   2,   2,  -2,   1 },
+      {  1,   0,   2,   0,  -1 },
+      {  2,   1,   0,  -2,   1 },
+      {  2,  -1,  -2,   0,  -1 },
+      {  1,  -1,  -2,  -2,  -1 },
+
+   /* 211-220 */
+      {  0,   1,  -2,   1,  -2 },
+      {  1,   0,  -4,   2,  -2 },
+      {  0,   1,   2,   2,   1 },
+      {  3,   0,   0,   0,   1 },
+      {  2,  -1,   2,   2,   2 },
+      {  0,   1,  -2,  -4,  -2 },
+      {  1,   0,  -2,  -3,  -2 },
+      {  2,   0,   0,   0,   2 },
+      {  1,  -1,   0,  -2,  -2 },
+      {  2,   0,  -2,   2,  -1 },
+
+   /* 221-230 */
+      {  0,   2,  -2,   0,  -2 },
+      {  3,   0,  -2,   0,  -1 },
+      {  2,  -1,   2,   0,   1 },
+      {  1,   0,  -2,  -1,  -2 },
+      {  0,   0,   2,   0,   3 },
+      {  2,   0,  -4,   0,  -2 },
+      {  2,   1,   0,  -4,   0 },
+      {  1,   1,  -2,   1,  -1 },
+      {  0,   2,   2,   0,   2 },
+      {  1,  -1,   2,  -2,   2 },
+
+   /* 231-240 */
+      {  1,  -1,   0,  -2,   1 },
+      {  2,   1,   2,   0,   1 },
+      {  1,   0,   2,  -4,   2 },
+      {  1,   1,  -2,   0,  -1 },
+      {  1,   1,   0,   2,   0 },
+      {  1,   0,   0,  -3,   0 },
+      {  2,   0,   2,  -1,   2 },
+      {  0,   2,   0,   0,  -1 },
+      {  2,  -1,   0,  -2,   0 },
+      {  4,   0,   0,   0,   0 },
+
+   /* 241-250 */
+      {  2,   1,  -2,  -2,  -2 },
+      {  0,   2,  -2,   2,   0 },
+      {  1,   0,   2,   1,   1 },
+      {  1,   0,  -1,   0,  -3 },
+      {  3,  -1,   2,   0,   2 },
+      {  2,   0,   2,  -2,   0 },
+      {  1,  -2,   0,   0,   0 },
+      {  2,   0,   0,   0,  -2 },
+      {  1,   0,   0,   4,   0 },
+      {  0,   1,   0,   1,   1 },
+
+   /* 251-260 */
+      {  1,   0,   2,   2,   0 },
+      {  0,   1,   0,   2,  -1 },
+      {  0,   1,   0,   1,  -1 },
+      {  0,   0,   2,  -2,   3 },
+      {  3,   1,   2,   0,   2 },
+      {  1,   1,   2,   1,   2 },
+      {  1,   1,  -2,   2,  -1 },
+      {  2,  -1,   2,  -2,   2 },
+      {  1,  -2,   2,   0,   2 },
+      {  1,   0,   2,  -4,   0 },
+
+   /* 261-270 */
+      {  0,   0,   1,   0,   0 },
+      {  1,   0,   2,  -3,   1 },
+      {  1,  -2,   0,  -2,   0 },
+      {  2,   0,   0,   2,  -1 },
+      {  1,   1,   2,  -4,   1 },
+      {  4,   0,   2,   0,   1 },
+      {  0,   1,   2,   1,   1 },
+      {  1,   2,   2,  -2,   2 },
+      {  2,   0,   2,   1,   2 },
+      {  2,   1,   2,  -2,   1 },
+
+   /* 271-280 */
+      {  1,   0,   2,  -1,   1 },
+      {  1,   0,   4,  -2,   1 },
+      {  1,  -1,   2,  -2,   1 },
+      {  0,   1,   0,  -4,   0 },
+      {  3,   0,  -2,  -2,  -2 },
+      {  0,   0,   4,  -4,   2 },
+      {  2,   0,  -4,  -2,  -2 },
+      {  2,  -2,   0,  -2,  -1 },
+      {  1,   0,   2,  -2,  -1 },
+      {  2,   0,  -2,  -6,  -2 },
+
+   /* 281-290 */
+      {  1,   0,  -2,   1,  -2 },
+      {  1,   0,  -2,   2,   1 },
+      {  1,  -1,   0,   2,  -1 },
+      {  1,   0,  -2,   1,   0 },
+      {  2,  -1,   0,  -2,   1 },
+      {  1,  -1,   0,   2,   1 },
+      {  2,   0,  -2,  -2,   0 },
+      {  1,   0,   2,  -3,   2 },
+      {  0,   0,   0,   4,  -1 },
+      {  2,  -1,   0,   0,   1 },
+
+   /* 291-300 */
+      {  2,   0,   4,  -2,   2 },
+      {  0,   0,   2,   3,   2 },
+      {  0,   1,   4,  -2,   2 },
+      {  0,   1,  -2,   2,   1 },
+      {  1,   1,   0,   2,   1 },
+      {  1,   0,   0,   4,   1 },
+      {  0,   0,   4,   0,   1 },
+      {  2,   0,   0,  -3,   0 },
+      {  1,   0,   0,  -1,  -2 },
+      {  1,  -2,  -2,  -2,  -2 },
+
+   /* 301-310 */
+      {  3,   0,   0,   2,   0 },
+      {  2,   0,   2,  -4,   2 },
+      {  1,   1,  -2,  -4,  -1 },
+      {  1,   0,  -2,  -6,  -2 },
+      {  2,  -1,   0,   0,  -1 },
+      {  2,  -1,   0,   2,   0 },
+      {  0,   1,   2,  -2,  -1 },
+      {  1,   1,   0,   1,   0 },
+      {  1,   2,   0,  -2,  -1 },
+      {  1,   0,   0,   1,  -1 },
+
+   /* 311-320 */
+      {  0,   0,   1,   0,   2 },
+      {  3,   1,   2,  -2,   2 },
+      {  1,   0,  -4,  -2,  -2 },
+      {  1,   0,   2,   4,   1 },
+      {  1,  -2,   2,   2,   2 },
+      {  1,  -1,  -2,  -4,  -2 },
+      {  0,   0,   2,  -4,   2 },
+      {  0,   0,   2,  -3,   1 },
+      {  2,   1,  -2,   0,   0 },
+      {  3,   0,  -2,  -2,  -1 },
+
+   /* 321-330 */
+      {  2,   0,   2,   4,   2 },
+      {  0,   0,   0,   0,   3 },
+      {  2,  -1,  -2,  -2,  -2 },
+      {  2,   0,   0,  -1,   0 },
+      {  3,   0,   2,  -4,   2 },
+      {  2,   1,   2,   2,   2 },
+      {  0,   0,   3,   0,   3 },
+      {  1,   1,   2,   2,   1 },
+      {  2,   1,   0,   0,  -1 },
+      {  1,   2,   0,  -2,   1 },
+
+   /* 331-340 */
+      {  3,   0,   2,   2,   1 },
+      {  1,  -1,  -2,   2,  -2 },
+      {  1,   1,   0,  -1,   0 },
+      {  1,   2,   0,   0,   0 },
+      {  1,   0,   4,   0,   2 },
+      {  1,  -1,   2,   4,   2 },
+      {  2,   1,   0,   0,   1 },
+      {  1,   0,   0,   2,   2 },
+      {  1,  -1,  -2,   2,   0 },
+      {  0,   2,  -2,  -2,  -1 },
+
+   /* 341-350 */
+      {  2,   0,  -2,   0,   2 },
+      {  5,   0,   2,   0,   2 },
+      {  3,   0,  -2,  -6,  -2 },
+      {  1,  -1,   2,  -1,   2 },
+      {  3,   0,   0,  -4,  -1 },
+      {  1,   0,   0,   1,   1 },
+      {  1,   0,  -4,   2,  -1 },
+      {  0,   1,   2,  -4,   1 },
+      {  1,   2,   2,   0,   2 },
+      {  0,   1,   0,  -2,  -2 },
+
+   /* 351-360 */
+      {  0,   0,   2,  -1,   0 },
+      {  1,   0,   1,   0,   1 },
+      {  0,   2,   0,  -2,   1 },
+      {  3,   0,   2,   0,   0 },
+      {  1,   1,  -2,   1,   0 },
+      {  2,   1,  -2,  -4,  -1 },
+      {  3,  -1,   0,   0,   0 },
+      {  2,  -1,  -2,   0,   0 },
+      {  4,   0,   2,  -2,   1 },
+      {  2,   0,  -2,   2,   0 },
+
+   /* 361-370 */
+      {  1,   1,   2,  -2,   0 },
+      {  1,   0,  -2,   4,  -1 },
+      {  1,   0,  -2,  -2,   1 },
+      {  2,   0,   2,  -4,   0 },
+      {  1,   1,   0,  -2,  -2 },
+      {  1,   1,  -2,  -2,   0 },
+      {  1,   0,   1,  -2,   1 },
+      {  2,  -1,  -2,  -4,  -2 },
+      {  3,   0,  -2,   0,  -2 },
+      {  0,   1,  -2,  -2,   0 },
+
+   /* 371-380 */
+      {  3,   0,   0,  -2,  -1 },
+      {  1,   0,  -2,  -3,  -1 },
+      {  0,   1,   0,  -4,  -1 },
+      {  1,  -2,   2,  -2,   1 },
+      {  0,   1,  -2,   1,  -1 },
+      {  1,  -1,   0,   0,   2 },
+      {  2,   0,   0,   1,   0 },
+      {  1,  -2,   0,   2,   0 },
+      {  1,   2,  -2,  -2,  -1 },
+      {  0,   0,   4,  -4,   1 },
+
+   /* 381-390 */
+      {  0,   1,   2,   4,   2 },
+      {  0,   1,  -4,   2,  -2 },
+      {  3,   0,  -2,   0,   0 },
+      {  2,  -1,   2,   2,   1 },
+      {  0,   1,  -2,  -4,  -1 },
+      {  4,   0,   2,   2,   2 },
+      {  2,   0,  -2,  -3,  -2 },
+      {  2,   0,   0,  -6,   0 },
+      {  1,   0,   2,   0,   3 },
+      {  3,   1,   0,   0,   0 },
+
+   /* 391-400 */
+      {  3,   0,   0,  -4,   1 },
+      {  1,  -1,   2,   0,   0 },
+      {  1,  -1,   0,  -4,   0 },
+      {  2,   0,  -2,   2,  -2 },
+      {  1,   1,   0,  -2,   2 },
+      {  4,   0,   0,  -2,   0 },
+      {  2,   2,   0,  -2,   0 },
+      {  0,   1,   2,   0,   0 },
+      {  1,   1,   0,  -4,   1 },
+      {  1,   0,   0,  -4,  -2 },
+
+   /* 401-410 */
+      {  0,   0,   0,   1,   2 },
+      {  3,   0,   0,   2,   1 },
+      {  1,   1,   0,  -4,  -1 },
+      {  0,   0,   2,   2,  -1 },
+      {  1,   1,   2,   0,   0 },
+      {  1,  -1,   2,  -4,   1 },
+      {  1,   1,   0,   0,   2 },
+      {  0,   0,   2,   6,   2 },
+      {  4,   0,  -2,  -2,  -1 },
+      {  2,   1,   0,  -4,  -1 },
+
+   /* 411-420 */
+      {  0,   0,   0,   3,   1 },
+      {  1,  -1,  -2,   0,   0 },
+      {  0,   0,   2,   1,   0 },
+      {  1,   0,   0,   2,  -2 },
+      {  3,  -1,   2,   2,   2 },
+      {  3,  -1,   2,  -2,   2 },
+      {  1,   0,   0,  -1,   2 },
+      {  1,  -2,   2,  -2,   2 },
+      {  0,   1,   0,   2,   2 },
+      {  0,   1,  -2,  -1,  -2 },
+
+   /* 421-430 */
+      {  1,   1,  -2,   0,   0 },
+      {  0,   2,   2,  -2,   0 },
+      {  3,  -1,  -2,  -1,  -2 },
+      {  1,   0,   0,  -6,   0 },
+      {  1,   0,  -2,  -4,   0 },
+      {  2,   1,   0,  -4,   1 },
+      {  2,   0,   2,   0,  -1 },
+      {  2,   0,  -4,   0,  -1 },
+      {  0,   0,   3,   0,   2 },
+      {  2,   1,  -2,  -2,  -1 },
+
+   /* 431-440 */
+      {  1,  -2,   0,   0,   1 },
+      {  2,  -1,   0,  -4,   0 },
+      {  0,   0,   0,   3,   0 },
+      {  5,   0,   2,  -2,   2 },
+      {  1,   2,  -2,  -4,  -2 },
+      {  1,   0,   4,  -4,   2 },
+      {  0,   0,   4,  -1,   2 },
+      {  3,   1,   0,  -4,   0 },
+      {  3,   0,   0,  -6,   0 },
+      {  2,   0,   0,   2,   2 },
+
+   /* 441-450 */
+      {  2,  -2,   2,   0,   2 },
+      {  1,   0,   0,  -3,   1 },
+      {  1,  -2,  -2,   0,  -2 },
+      {  1,  -1,  -2,  -3,  -2 },
+      {  0,   0,   2,  -2,  -2 },
+      {  2,   0,  -2,  -4,   0 },
+      {  1,   0,  -4,   0,   0 },
+      {  0,   1,   0,  -1,   0 },
+      {  4,   0,   0,   0,  -1 },
+      {  3,   0,   2,  -1,   2 },
+
+   /* 451-460 */
+      {  3,  -1,   2,   0,   1 },
+      {  2,   0,   2,  -1,   1 },
+      {  1,   2,   2,  -2,   1 },
+      {  1,   1,   0,   2,  -1 },
+      {  0,   2,   2,   0,   1 },
+      {  3,   1,   2,   0,   1 },
+      {  1,   1,   2,   1,   1 },
+      {  1,   1,   0,  -1,   1 },
+      {  1,  -2,   0,  -2,  -1 },
+      {  4,   0,   0,  -4,   0 },
+
+   /* 461-470 */
+      {  2,   1,   0,   2,   0 },
+      {  1,  -1,   0,   4,   0 },
+      {  0,   1,   0,  -2,   2 },
+      {  0,   0,   2,   0,  -2 },
+      {  1,   0,  -1,   0,   1 },
+      {  3,   0,   2,  -2,   0 },
+      {  2,   0,   2,   2,   0 },
+      {  1,   2,   0,  -4,   0 },
+      {  1,  -1,   0,  -3,   0 },
+      {  0,   1,   0,   4,   0 },
+
+   /* 471 - 480 */
+      {  0,   1,  -2,   0,   0 },
+      {  2,   2,   2,  -2,   2 },
+      {  0,   0,   0,   1,  -2 },
+      {  0,   2,  -2,   0,  -1 },
+      {  4,   0,   2,  -4,   2 },
+      {  2,   0,  -4,   2,  -2 },
+      {  2,  -1,  -2,   0,  -2 },
+      {  1,   1,   4,  -2,   2 },
+      {  1,   1,   2,  -4,   2 },
+      {  1,   0,   2,   3,   2 },
+
+   /* 481-490 */
+      {  1,   0,   0,   4,  -1 },
+      {  0,   0,   0,   4,   2 },
+      {  2,   0,   0,   4,   0 },
+      {  1,   1,  -2,   2,   0 },
+      {  2,   1,   2,   1,   2 },
+      {  2,   1,   2,  -4,   1 },
+      {  2,   0,   2,   1,   1 },
+      {  2,   0,  -4,  -2,  -1 },
+      {  2,   0,  -2,  -6,  -1 },
+      {  2,  -1,   2,  -1,   2 },
+
+   /* 491-500 */
+      {  1,  -2,   2,   0,   1 },
+      {  1,  -2,   0,  -2,   1 },
+      {  1,  -1,   0,  -4,  -1 },
+      {  0,   2,   2,   2,   2 },
+      {  0,   2,  -2,  -4,  -2 },
+      {  0,   1,   2,   3,   2 },
+      {  0,   1,   0,  -4,   1 },
+      {  3,   0,   0,  -2,   1 },
+      {  2,   1,  -2,   0,   1 },
+      {  2,   0,   4,  -2,   1 },
+
+   /* 501-510 */
+      {  2,   0,   0,  -3,  -1 },
+      {  2,  -2,   0,  -2,   1 },
+      {  2,  -1,   2,  -2,   1 },
+      {  1,   0,   0,  -6,  -1 },
+      {  1,  -2,   0,   0,  -1 },
+      {  1,  -2,  -2,  -2,  -1 },
+      {  0,   1,   4,  -2,   1 },
+      {  0,   0,   2,   3,   1 },
+      {  2,  -1,   0,  -1,   0 },
+      {  1,   3,   0,  -2,   0 },
+
+   /* 511-520 */
+      {  0,   3,   0,  -2,   0 },
+      {  2,  -2,   2,  -2,   2 },
+      {  0,   0,   4,  -2,   0 },
+      {  4,  -1,   2,   0,   2 },
+      {  2,   2,  -2,  -4,  -2 },
+      {  4,   1,   2,   0,   2 },
+      {  4,  -1,  -2,  -2,  -2 },
+      {  2,   1,   0,  -2,  -2 },
+      {  2,   1,  -2,  -6,  -2 },
+      {  2,   0,   0,  -1,   1 },
+
+   /* 521-530 */
+      {  2,  -1,  -2,   2,  -1 },
+      {  1,   1,  -2,   2,  -2 },
+      {  1,   1,  -2,  -3,  -2 },
+      {  1,   0,   3,   0,   3 },
+      {  1,   0,  -2,   1,   1 },
+      {  1,   0,  -2,   0,   2 },
+      {  1,  -1,   2,   1,   2 },
+      {  1,  -1,   0,   0,  -2 },
+      {  1,  -1,  -4,   2,  -2 },
+      {  0,   3,  -2,  -2,  -2 },
+
+   /* 531-540 */
+      {  0,   1,   0,   4,   1 },
+      {  0,   0,   4,   2,   2 },
+      {  3,   0,  -2,  -2,   0 },
+      {  2,  -2,   0,   0,   0 },
+      {  1,   1,   2,  -4,   0 },
+      {  1,   1,   0,  -3,   0 },
+      {  1,   0,   2,  -3,   0 },
+      {  1,  -1,   2,  -2,   0 },
+      {  0,   2,   0,   2,   0 },
+      {  0,   0,   2,   4,   0 },
+
+   /* 541-550 */
+      {  1,   0,   1,   0,   0 },
+      {  3,   1,   2,  -2,   1 },
+      {  3,   0,   4,  -2,   2 },
+      {  3,   0,   2,   1,   2 },
+      {  3,   0,   0,   2,  -1 },
+      {  3,   0,   0,   0,   2 },
+      {  3,   0,  -2,   2,  -1 },
+      {  2,   0,   4,  -4,   2 },
+      {  2,   0,   2,  -3,   2 },
+      {  2,   0,   0,   4,   1 },
+
+   /* 551-560 */
+      {  2,   0,   0,  -3,   1 },
+      {  2,   0,  -4,   2,  -1 },
+      {  2,   0,  -2,  -2,   1 },
+      {  2,  -2,   2,   2,   2 },
+      {  2,  -2,   0,  -2,  -2 },
+      {  2,  -1,   0,   2,   1 },
+      {  2,  -1,   0,   2,  -1 },
+      {  1,   1,   2,   4,   2 },
+      {  1,   1,   0,   1,   1 },
+      {  1,   1,   0,   1,  -1 },
+
+   /* 561-570 */
+      {  1,   1,  -2,  -6,  -2 },
+      {  1,   0,   0,  -3,  -1 },
+      {  1,   0,  -4,  -2,  -1 },
+      {  1,   0,  -2,  -6,  -1 },
+      {  1,  -2,   2,   2,   1 },
+      {  1,  -2,  -2,   2,  -1 },
+      {  1,  -1,  -2,  -4,  -1 },
+      {  0,   2,   0,   0,   2 },
+      {  0,   1,   2,  -4,   2 },
+      {  0,   1,  -2,   4,  -1 },
+
+   /* 571-580 */
+      {  5,   0,   0,   0,   0 },
+      {  3,   0,   0,  -3,   0 },
+      {  2,   2,   0,  -4,   0 },
+      {  1,  -1,   2,   2,   0 },
+      {  0,   1,   0,   3,   0 },
+      {  4,   0,  -2,   0,  -1 },
+      {  3,   0,  -2,  -6,  -1 },
+      {  3,   0,  -2,  -1,  -1 },
+      {  2,   1,   2,   2,   1 },
+      {  2,   1,   0,   2,   1 },
+
+   /* 581-590 */
+      {  2,   0,   2,   4,   1 },
+      {  2,   0,   2,  -6,   1 },
+      {  2,   0,   2,  -2,  -1 },
+      {  2,   0,   0,  -6,  -1 },
+      {  2,  -1,  -2,  -2,  -1 },
+      {  1,   2,   2,   0,   1 },
+      {  1,   2,   0,   0,   1 },
+      {  1,   0,   4,   0,   1 },
+      {  1,   0,   2,  -6,   1 },
+      {  1,   0,   2,  -4,  -1 },
+
+   /* 591-600 */
+      {  1,   0,  -1,  -2,  -1 },
+      {  1,  -1,   2,   4,   1 },
+      {  1,  -1,   2,  -3,   1 },
+      {  1,  -1,   0,   4,   1 },
+      {  1,  -1,  -2,   1,  -1 },
+      {  0,   1,   2,  -2,   3 },
+      {  3,   0,   0,  -2,   0 },
+      {  1,   0,   1,  -2,   0 },
+      {  0,   2,   0,  -4,   0 },
+      {  0,   0,   2,  -4,   0 },
+
+   /* 601-610 */
+      {  0,   0,   1,  -1,   0 },
+      {  0,   0,   0,   6,   0 },
+      {  0,   2,   0,   0,  -2 },
+      {  0,   1,  -2,   2,  -3 },
+      {  4,   0,   0,   2,   0 },
+      {  3,   0,   0,  -1,   0 },
+      {  3,  -1,   0,   2,   0 },
+      {  2,   1,   0,   1,   0 },
+      {  2,   1,   0,  -6,   0 },
+      {  2,  -1,   2,   0,   0 },
+
+   /* 611-620 */
+      {  1,   0,   2,  -1,   0 },
+      {  1,  -1,   0,   1,   0 },
+      {  1,  -1,  -2,  -2,   0 },
+      {  0,   1,   2,   2,   0 },
+      {  0,   0,   2,  -3,   0 },
+      {  2,   2,   0,  -2,  -1 },
+      {  2,  -1,  -2,   0,   1 },
+      {  1,   2,   2,  -4,   1 },
+      {  0,   1,   4,  -4,   2 },
+      {  0,   0,   0,   3,   2 },
+
+   /* 621-630 */
+      {  5,   0,   2,   0,   1 },
+      {  4,   1,   2,  -2,   2 },
+      {  4,   0,  -2,  -2,   0 },
+      {  3,   1,   2,   2,   2 },
+      {  3,   1,   0,  -2,   0 },
+      {  3,   1,  -2,  -6,  -2 },
+      {  3,   0,   0,   0,  -2 },
+      {  3,   0,  -2,  -4,  -2 },
+      {  3,  -1,   0,  -3,   0 },
+      {  3,  -1,   0,  -2,   0 },
+
+   /* 631-640 */
+      {  2,   1,   2,   0,   0 },
+      {  2,   1,   2,  -4,   2 },
+      {  2,   1,   2,  -2,   0 },
+      {  2,   1,   0,  -3,   0 },
+      {  2,   1,  -2,   0,  -2 },
+      {  2,   0,   0,  -4,   2 },
+      {  2,   0,   0,  -4,  -2 },
+      {  2,   0,  -2,  -5,  -2 },
+      {  2,  -1,   2,   4,   2 },
+      {  2,  -1,   0,  -2,   2 },
+
+   /* 641-650 */
+      {  1,   3,  -2,  -2,  -2 },
+      {  1,   1,   0,   0,  -2 },
+      {  1,   1,   0,  -6,   0 },
+      {  1,   1,  -2,   1,  -2 },
+      {  1,   1,  -2,  -1,  -2 },
+      {  1,   0,   2,   1,   0 },
+      {  1,   0,   0,   3,   0 },
+      {  1,   0,   0,  -4,   2 },
+      {  1,   0,  -2,   4,  -2 },
+      {  1,  -2,   0,  -1,   0 },
+
+   /* 651-NFLS */
+      {  0,   1,  -4,   2,  -1 },
+      {  1,   0,  -2,   0,  -3 },
+      {  0,   0,   4,  -4,   4 }
+   };
+
+/* Number of frequencies:  luni-solar */
+   static const int NFLS = (int) (sizeof mfals / sizeof (int) / 5);
+
+/* Fundamental-argument multipliers:  planetary terms */
+   static const int mfapl[][14] = {
+
+   /* 1-10 */
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -1,  2,  0,  0,  0,  0,  0 },
+
+   /* 11-20 */
+      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  2, -5,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -1,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -8,  3,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6, -8,  3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
+
+   /* 21-30 */
+      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  1,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  1, -1,  1,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  1 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+
+   /* 31-40 */
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  1 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
+
+   /* 41-50 */
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  0,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -2,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2, -1,  0,  0,  0,  0,  0,  2 },
+      {  1,  0,  0,  0,  0,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  1,  0,  0,  0,  2 },
+
+   /* 51-60 */
+      {  0,  0,  1, -1,  1,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -1,  0,  0,  0,  2 },
+      {  1,  0,  2,  0,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  1 },
+      {  1,  0, -2,  0, -2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+
+   /* 61-70 */
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0,  0,  3, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-11,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0 },
+
+   /* 71-80 */
+      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -2,  0,  0,  0,  2 },
+      {  0,  0,  1, -1,  1,  0,  0, -5,  8, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0,  0 },
+
+   /* 81-90 */
+      {  2,  0,  0, -2,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0, -1 },
+      {  2,  0,  0, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  8,-13,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0, -2,  5,  0,  0,  0 },
+      {  1,  0,  0, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2 },
+      {  1,  0,  0,  0, -1,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  2, -5,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
+
+   /* 91-100 */
+      {  1,  0,  0, -2,  0,  0, 19,-21,  3,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -8, 13,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2 },
+      {  1,  0,  0,  0,  1,  0,-18, 16,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-16,  4,  5,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  3, -7,  0,  0,  0,  0,  0, -2 },
+
+   /* 101-110 */
+      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1 },
+      {  2,  0,  0, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  2 },
+
+   /* 111-120 */
+      {  0,  0,  0,  0,  1,  0,  0,  1, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  2 },
+      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+
+   /* 121-130 */
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-10,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0, -2 },
+      {  1,  0,  0, -1,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+
+   /* 131-140 */
+      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  1,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
+
+   /* 141-150 */
+      {  1,  0,  0, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -4,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  9,-11,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -4,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -1,  0,  0,  0,  2 },
+
+   /* 151-160 */
+      {  1,  0,  0, -1,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1,  1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -4, 10,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0, -2 },
+      {  0,  0,  2, -2,  1,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
+
+   /* 161-170 */
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0, -1,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -3,  0,  0,  0,  0,  2 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  0,  2,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -9, 13,  0,  0,  0,  0,  0 },
+      {  2,  0,  2,  0,  2,  0,  0,  2,  0, -3,  0,  0,  0,  0 },
+
+   /* 171-180 */
+      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
+      {  1,  0,  0, -1, -1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  1 },
+      {  1,  0,  2,  0,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  1,  0, -2,  0, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -2,  4,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0 },
+
+   /* 181-190 */
+      {  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  2,  0,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -8,  3,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  7, -8,  3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  1,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -1,  0,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  1 },
+
+   /* 191-200 */
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7,-10,  0,  0,  0,  0,  0, -2 },
+      {  1,  0,  0, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  2, -5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1,  1,  0,  0, -9, 15,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0 },
+
+   /* 201-210 */
+      {  0,  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -1,  0,  0,  2 },
+      {  2,  0,  0, -2,  1,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1,  1,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  8,-14,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+
+   /* 211-220 */
+      {  0,  0,  0,  0,  1,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  1,  0,  0,  2 },
+      {  2,  0, -1, -1,  0,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
+
+   /* 221-230 */
+      {  2,  0,  0, -2,  0,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  1,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -9,  4,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0, -2 },
+
+   /* 231-240 */
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -4,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  1 },
+      {  0,  0,  0,  0,  0,  0,  7,-11,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  3, -5,  4,  0,  0,  0,  0,  2 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -1,  1,  0,  0,  0 },
+      {  2,  0,  0,  0,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  2,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0, -1 },
+
+   /* 241-250 */
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  2, -4,  0, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  3, -5,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -3,  0,  0,  0,  2 },
+      {  0,  0,  2, -2,  2,  0, -8, 11,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -2,  0,  0,  0 },
+
+   /* 251-260 */
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  2, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0, -2, -2, -2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  0,  0,  0,  0,  1 },
+
+   /* 261-270 */
+      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  2, -5,  0,  0,  2 },
+      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  0,  5,  0,  0,  0 },
+      {  2,  0,  0, -2, -1,  0, -6,  8,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8, -8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  2, -5,  0,  0,  2 },
+      {  0,  0,  0,  0,  1,  0,  3, -7,  4,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+
+   /* 271-280 */
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-15,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  1,  0,  0,  0,  2 },
+      {  1,  0,  0, -1,  0,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -3,  7, -4,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -2,  0,  0,  0,  2 },
+
+   /* 281-290 */
+      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  2, -2,  2,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-11,  0,  0,  0,  0, -2 },
+
+   /* 291-300 */
+      {  0,  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  9,-12,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  1, -1,  0,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0, -1 },
+
+   /* 301-310 */
+      {  0,  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1, -1,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -5,  0,  0,  0,  0, -2 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  3, -1,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0,  2 },
+
+   /* 311-320 */
+      {  0,  0,  0,  0,  0,  0,  9, -9,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  3,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  2, -4,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  1 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  2 },
+      {  0,  0,  2,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+
+   /* 321-330 */
+      {  0,  0,  2,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  0 },
+      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -3,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  5,-10,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  8,-13,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  2, -2,  1, -1,  0,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  2,  0,  0 },
+
+   /* 331-340 */
+      {  0,  0,  0,  0,  1,  0,  3, -5,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  9, -9,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -8, 11,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  0,  2,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -1,  2,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  2, -6,  0,  0,  0,  0,  0, -2 },
+
+   /* 341-350 */
+      {  0,  0,  0,  0,  0,  0,  0,  8,-15,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -2,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  7,-13,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  3,  0,  0,  0,  2 },
+      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8, -8,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  8,-10,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  1 },
+
+   /* 351-360 */
+      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -4,  0,  0,  0,  0 },
+      {  2,  0,  0, -2, -1,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0, -2 },
+      {  2,  0, -1, -1, -1,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
+
+   /* 361-370 */
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  4, -3,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-11,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  1,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  1,  5,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6, -5,  0,  0,  0,  0,  2 },
+      {  1,  0, -2, -2, -2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0,  0,  0, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  1 },
+
+   /* 371-380 */
+      {  0,  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0,  0, -2,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0, -2,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1, -6,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  3, -5,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  7,-13,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -2,  0,  0,  0,  2 },
+
+   /* 381-390 */
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0,  2,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -8, 15,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2, -2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  1,  0,  2, -2,  2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  1,  0, -1,  1, -1,  0,-18, 17,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  2, -2, -1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+
+   /* 391-400 */
+      {  0,  0,  0,  0,  1,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-16,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2 },
+      {  0,  0,  0,  0,  2,  0,  0, -1,  2,  0,  0,  0,  0,  0 },
+      {  2,  0, -1, -1, -2,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0, -2,  4,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  2 },
+      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  4, -5,  0,  0,  0 },
+
+   /* 401-410 */
+      {  2,  0,  0, -2, -1,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  2,  0, -1, -1, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -1, -1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+      {  1,  0, -1, -1, -1,  0, 20,-20,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  1, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -2,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  5, -8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, -1,  0,  0,  0 },
+
+   /* 411-420 */
+      {  0,  0,  0,  0,  0,  0,  9,-11,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  5, -3,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0, -2,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0, -2,  5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0,  0 },
+
+   /* 421-430 */
+      {  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -6,  0,  0,  0,  0, -2 },
+      {  1,  0,  0, -2,  0,  0, 20,-21,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-12,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -4,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  8,-12,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  9,-17,  0,  0,  0,  0,  0 },
+
+   /* 431-440 */
+      {  0,  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  1,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -6,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -7,  0,  0,  0,  0, -2 },
+      {  1,  0,  0, -1,  1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
+      {  1,  0, -2,  0, -2,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -9, 17,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0,  0, -2 },
+      {  1,  0, -2, -2, -2,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  1,  0, -1,  1, -1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+
+   /* 441-450 */
+      {  0,  0,  2, -2,  2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  2, -2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,-10,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0, -4,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0, -5,  0,  0,  0, -2 },
+
+   /* 451-460 */
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -5,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -2,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -3,  0,  0,  0,  0,  0,  1 },
+      {  1,  0,  0, -2,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -7,  4,  0,  0,  0,  0,  0 },
+      {  2,  0,  2,  0,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1, -1,  0,  0, -1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  1,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0, -2 },
+
+   /* 461-470 */
+      {  1,  0,  0, -1,  1,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -3,  0,  3,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0, -5,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  1, -3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -4,  6,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  0,  0, -1,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -5,  6,  0,  0,  0,  0,  0,  0 },
+
+   /* 471-480 */
+      {  0,  0,  0,  0,  1,  0,  3, -4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7,-10,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  5, -5,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  3, -8,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  2, -5,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  7, -9,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  7, -8,  0,  0,  0,  0,  2 },
+
+   /* 481-490 */
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -8,  3,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -4,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0, -1 },
+      {  2,  0,  0, -2, -1,  0,  0, -6,  8,  0,  0,  0,  0,  0 },
+      {  2,  0, -1, -1,  1,  0,  0,  3, -7,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -7,  9,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0,  0, -1 },
+
+   /* 491-500 */
+      {  0,  0,  1, -1,  2,  0, -8, 12,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7, -8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  1,  0,  0, -5,  6,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2, -1,  0,  0, -2,  0,  3, -1,  0,  0,  0 },
+      {  1,  0,  1,  1,  1,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  1,  0,  0, -2, -1,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+
+   /* 501-510 */
+      {  1,  0,  0, -1, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0 },
+      {  1,  0, -1,  0, -1,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -4,  4,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0, -8, 11,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0,  0,  0, -9, 13,  0,  0,  0,  0,  0 },
+      {  0,  0,  1,  1,  2,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0,  1, -4,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0,  0, -1,  0,  1, -3,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0,  7,-13,  0,  0,  0,  0,  0 },
+
+   /* 511-520 */
+      {  0,  0,  0,  0,  1,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  7,-11,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  6, -6,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  6, -4,  0,  0,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  4, -2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -4,  0,  0,  0,  0,  0,  1 },
+
+   /* 521-530 */
+      {  0,  0,  0,  0,  0,  0,  1, -4,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  9,-17,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  7, -7,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4, -7,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -4,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+
+   /* 531-540 */
+      {  2,  0,  0, -2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0, 17,-16,  0, -2,  0,  0,  0,  0 },
+      {  1,  0,  0, -1,  0,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -4,  0,  0,  0,  0 },
+
+   /* 541-550 */
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1, -2, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  1,  0,  0,  0,  0,  2 },
+      {  2,  0,  0, -2,  0,  0,  0, -4,  4,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  2,  2,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+
+   /* 551-560 */
+      {  1,  0,  0, -2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -2,  2,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0,  1,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0, -4,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  2,  0,  0,  0, -1,  0,  1,  0,  0,  0,  0 },
+
+   /* 561-570 */
+      {  0,  0,  0,  0,  0,  0,  8, -9,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, -5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  0 },
+      {  2,  0, -2, -2, -2,  0,  0, -2,  0,  2,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  1,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0, -1,  0,-10,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0,  2, -3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0,  2, -2,  0,  0,  0,  0,  0,  0 },
+
+   /* 571-580 */
+      {  0,  0,  2,  0,  2,  0, -2,  3,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  0,  2,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  2,  0,  0,  0,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0,  0, -1,  0,  2,  0,  0,  0,  0 },
+      {  2,  0,  2, -2,  2,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  2,  0,  1, -3,  1,  0, -6,  7,  0,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  2, -5,  0,  0,  0,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  5, -5,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  1,  5,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  0,  5,  0,  0,  0 },
+
+   /* 581-590 */
+      {  2,  0,  0, -2,  0,  0,  0, -2,  0,  0,  2,  0,  0,  0 },
+      {  2,  0,  0, -2,  0,  0, -4,  4,  0,  0,  0,  0,  0,  0 },
+      {  2,  0, -2,  0, -2,  0,  0,  5, -9,  0,  0,  0,  0,  0 },
+      {  2,  0, -1, -1,  0,  0,  0, -1,  0,  3,  0,  0,  0,  0 },
+      {  1,  0,  2,  0,  2,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  2,  0,  2,  0,  0,  4, -8,  3,  0,  0,  0,  0 },
+      {  1,  0,  2,  0,  2,  0,  0, -4,  8, -3,  0,  0,  0,  0 },
+      {  1,  0,  2,  0,  2,  0, -1,  1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  2, -2,  2,  0, -3,  3,  0,  0,  0,  0,  0,  0 },
+      {  1,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+
+   /* 591-600 */
+      {  1,  0,  0,  0,  0,  0,  0, -2,  0,  3,  0,  0,  0,  0 },
+      {  1,  0,  0, -2,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
+      {  1,  0, -2, -2, -2,  0,  0,  1,  0, -1,  0,  0,  0,  0 },
+      {  1,  0, -1,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  1,  0, -1, -1,  0,  0,  0,  8,-15,  0,  0,  0,  0,  0 },
+      {  0,  0,  2,  2,  2,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  1, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0, -2,  0,  1,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  1,  0,  0,-10, 15,  0,  0,  0,  0,  0 },
+      {  0,  0,  2, -2,  0, -1,  0,  2,  0,  0,  0,  0,  0,  0 },
+
+   /* 601-610 */
+      {  0,  0,  1, -1,  2,  0,  0, -1,  0,  0, -1,  0,  0,  0 },
+      {  0,  0,  1, -1,  2,  0, -3,  4,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -4,  6,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  1,  0, -1,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0,  0, -1,  0,  0, -2,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  1, -1, -1,  0, -5,  7,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  2,  0,  0,  0,  2,  0, -2,  0,  0,  0,  0 },
+
+   /* 611-620 */
+      {  0,  0,  0,  2,  0,  0, -2,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  2,  0, -3,  5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  1,  0, -1,  2,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  9,-13,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  8,-14,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  8,-11,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6, -8,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  6, -7,  0,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0, -2 },
+
+   /* 621-630 */
+      {  0,  0,  0,  0,  0,  0,  5, -6, -4,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  5, -4,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  4, -8,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  4, -5,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  3, -3,  0,  2,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  3, -1,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  7,-12,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6, -9,  0,  0,  0,  0, -2 },
+
+   /* 631-640 */
+      {  0,  0,  0,  0,  0,  0,  0,  6, -8,  1,  5,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6, -4,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  6,-10,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,  0, -4,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -9,  0,  0,  0,  0, -1 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -8,  3,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -7,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5, -6,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,-16,  4,  5,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  5,-13,  0,  0,  0,  0, -2 },
+
+   /* 641-650 */
+      {  0,  0,  0,  0,  0,  0,  0,  3,  0, -5,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -9,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  3, -7,  0,  0,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, -3,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  2, -8,  1,  5,  0,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  1, -5,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -3,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  1,  0, -3,  5,  0,  0,  0 },
+
+   /* 651-NFPL */
+      {  0,  0,  0,  0,  0,  0,  0,  1, -3,  0,  0,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, -6,  3,  0, -2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1, -2,  0,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2 },
+      {  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0 }
+   };
+
+/* Number of frequencies:  planetary */
+   static const int NFPL = (int) (sizeof mfapl / sizeof (int) / 14);
+
+/* Pointers into amplitudes array, one pointer per frequency */
+   static const int nc[] = {
+
+   /* 1-100 */
+       1,    21,    37,    51,    65,    79,    91,   103,   115,   127,
+     139,   151,   163,   172,   184,   196,   207,   219,   231,   240,
+     252,   261,   273,   285,   297,   309,   318,   327,   339,   351,
+     363,   372,   384,   396,   405,   415,   423,   435,   444,   452,
+     460,   467,   474,   482,   490,   498,   506,   513,   521,   528,
+     536,   543,   551,   559,   566,   574,   582,   590,   597,   605,
+     613,   620,   628,   636,   644,   651,   658,   666,   674,   680,
+     687,   695,   702,   710,   717,   725,   732,   739,   746,   753,
+     760,   767,   774,   782,   790,   798,   805,   812,   819,   826,
+     833,   840,   846,   853,   860,   867,   874,   881,   888,   895,
+
+   /* 101-200 */
+     901,   908,   914,   921,   928,   934,   941,   948,   955,   962,
+     969,   976,   982,   989,   996,  1003,  1010,  1017,  1024,  1031,
+    1037,  1043,  1050,  1057,  1064,  1071,  1078,  1084,  1091,  1098,
+    1104,  1112,  1118,  1124,  1131,  1138,  1145,  1151,  1157,  1164,
+    1171,  1178,  1185,  1192,  1199,  1205,  1212,  1218,  1226,  1232,
+    1239,  1245,  1252,  1259,  1266,  1272,  1278,  1284,  1292,  1298,
+    1304,  1310,  1316,  1323,  1329,  1335,  1341,  1347,  1353,  1359,
+    1365,  1371,  1377,  1383,  1389,  1396,  1402,  1408,  1414,  1420,
+    1426,  1434,  1440,  1446,  1452,  1459,  1465,  1471,  1477,  1482,
+    1488,  1493,  1499,  1504,  1509,  1514,  1520,  1527,  1532,  1538,
+
+   /* 201-300 */
+    1543,  1548,  1553,  1558,  1564,  1569,  1574,  1579,  1584,  1589,
+    1594,  1596,  1598,  1600,  1602,  1605,  1608,  1610,  1612,  1617,
+    1619,  1623,  1625,  1627,  1629,  1632,  1634,  1640,  1642,  1644,
+    1646,  1648,  1650,  1652,  1654,  1658,  1660,  1662,  1664,  1668,
+    1670,  1672,  1673,  1675,  1679,  1681,  1683,  1684,  1686,  1688,
+    1690,  1693,  1695,  1697,  1701,  1703,  1705,  1707,  1709,  1711,
+    1712,  1715,  1717,  1721,  1723,  1725,  1727,  1729,  1731,  1733,
+    1735,  1737,  1739,  1741,  1743,  1745,  1747,  1749,  1751,  1753,
+    1755,  1757,  1759,  1761,  1762,  1764,  1766,  1768,  1769,  1771,
+    1773,  1775,  1777,  1779,  1781,  1783,  1785,  1787,  1788,  1790,
+
+   /* 301-400 */
+    1792,  1794,  1796,  1798,  1800,  1802,  1804,  1806,  1807,  1809,
+    1811,  1815,  1817,  1819,  1821,  1823,  1825,  1827,  1829,  1831,
+    1833,  1835,  1837,  1839,  1840,  1842,  1844,  1848,  1850,  1852,
+    1854,  1856,  1858,  1859,  1860,  1862,  1864,  1866,  1868,  1869,
+    1871,  1873,  1875,  1877,  1879,  1881,  1883,  1885,  1887,  1889,
+    1891,  1892,  1896,  1898,  1900,  1901,  1903,  1905,  1907,  1909,
+    1910,  1911,  1913,  1915,  1919,  1921,  1923,  1927,  1929,  1931,
+    1933,  1935,  1937,  1939,  1943,  1945,  1947,  1948,  1949,  1951,
+    1953,  1955,  1957,  1958,  1960,  1962,  1964,  1966,  1968,  1970,
+    1971,  1973,  1974,  1975,  1977,  1979,  1980,  1981,  1982,  1984,
+
+   /* 401-500 */
+    1986,  1988,  1990,  1992,  1994,  1995,  1997,  1999,  2001,  2003,
+    2005,  2007,  2008,  2009,  2011,  2013,  2015,  2017,  2019,  2021,
+    2023,  2024,  2025,  2027,  2029,  2031,  2033,  2035,  2037,  2041,
+    2043,  2045,  2046,  2047,  2049,  2051,  2053,  2055,  2056,  2057,
+    2059,  2061,  2063,  2065,  2067,  2069,  2070,  2071,  2072,  2074,
+    2076,  2078,  2080,  2082,  2084,  2086,  2088,  2090,  2092,  2094,
+    2095,  2096,  2097,  2099,  2101,  2105,  2106,  2107,  2108,  2109,
+    2110,  2111,  2113,  2115,  2119,  2121,  2123,  2125,  2127,  2129,
+    2131,  2133,  2135,  2136,  2137,  2139,  2141,  2143,  2145,  2147,
+    2149,  2151,  2153,  2155,  2157,  2159,  2161,  2163,  2165,  2167,
+
+   /* 501-600 */
+    2169,  2171,  2173,  2175,  2177,  2179,  2181,  2183,  2185,  2186,
+    2187,  2188,  2192,  2193,  2195,  2197,  2199,  2201,  2203,  2205,
+    2207,  2209,  2211,  2213,  2217,  2219,  2221,  2223,  2225,  2227,
+    2229,  2231,  2233,  2234,  2235,  2236,  2237,  2238,  2239,  2240,
+    2241,  2244,  2246,  2248,  2250,  2252,  2254,  2256,  2258,  2260,
+    2262,  2264,  2266,  2268,  2270,  2272,  2274,  2276,  2278,  2280,
+    2282,  2284,  2286,  2288,  2290,  2292,  2294,  2296,  2298,  2300,
+    2302,  2303,  2304,  2305,  2306,  2307,  2309,  2311,  2313,  2315,
+    2317,  2319,  2321,  2323,  2325,  2327,  2329,  2331,  2333,  2335,
+    2337,  2341,  2343,  2345,  2347,  2349,  2351,  2352,  2355,  2356,
+
+   /* 601-700 */
+    2357,  2358,  2359,  2361,  2363,  2364,  2365,  2366,  2367,  2368,
+    2369,  2370,  2371,  2372,  2373,  2374,  2376,  2378,  2380,  2382,
+    2384,  2385,  2386,  2387,  2388,  2389,  2390,  2391,  2392,  2393,
+    2394,  2395,  2396,  2397,  2398,  2399,  2400,  2401,  2402,  2403,
+    2404,  2405,  2406,  2407,  2408,  2409,  2410,  2411,  2412,  2413,
+    2414,  2415,  2417,  2418,  2430,  2438,  2445,  2453,  2460,  2468,
+    2474,  2480,  2488,  2496,  2504,  2512,  2520,  2527,  2535,  2543,
+    2550,  2558,  2566,  2574,  2580,  2588,  2596,  2604,  2612,  2619,
+    2627,  2634,  2642,  2648,  2656,  2664,  2671,  2679,  2685,  2693,
+    2701,  2709,  2717,  2725,  2733,  2739,  2747,  2753,  2761,  2769,
+
+   /* 701-800 */
+    2777,  2785,  2793,  2801,  2809,  2817,  2825,  2833,  2841,  2848,
+    2856,  2864,  2872,  2878,  2884,  2892,  2898,  2906,  2914,  2922,
+    2930,  2938,  2944,  2952,  2958,  2966,  2974,  2982,  2988,  2996,
+    3001,  3009,  3017,  3025,  3032,  3039,  3045,  3052,  3059,  3067,
+    3069,  3076,  3083,  3090,  3098,  3105,  3109,  3111,  3113,  3120,
+    3124,  3128,  3132,  3136,  3140,  3144,  3146,  3150,  3158,  3161,
+    3165,  3166,  3168,  3172,  3176,  3180,  3182,  3185,  3189,  3193,
+    3194,  3197,  3200,  3204,  3208,  3212,  3216,  3219,  3221,  3222,
+    3226,  3230,  3234,  3238,  3242,  3243,  3247,  3251,  3254,  3258,
+    3262,  3266,  3270,  3274,  3275,  3279,  3283,  3287,  3289,  3293,
+
+   /* 801-900 */
+    3296,  3300,  3303,  3307,  3311,  3315,  3319,  3321,  3324,  3327,
+    3330,  3334,  3338,  3340,  3342,  3346,  3350,  3354,  3358,  3361,
+    3365,  3369,  3373,  3377,  3381,  3385,  3389,  3393,  3394,  3398,
+    3402,  3406,  3410,  3413,  3417,  3421,  3425,  3429,  3433,  3435,
+    3439,  3443,  3446,  3450,  3453,  3457,  3458,  3461,  3464,  3468,
+    3472,  3476,  3478,  3481,  3485,  3489,  3493,  3497,  3501,  3505,
+    3507,  3511,  3514,  3517,  3521,  3524,  3525,  3527,  3529,  3533,
+    3536,  3540,  3541,  3545,  3548,  3551,  3555,  3559,  3563,  3567,
+    3569,  3570,  3574,  3576,  3578,  3582,  3586,  3590,  3593,  3596,
+    3600,  3604,  3608,  3612,  3616,  3620,  3623,  3626,  3630,  3632,
+
+   /* 901-1000 */
+    3636,  3640,  3643,  3646,  3648,  3652,  3656,  3660,  3664,  3667,
+    3669,  3671,  3675,  3679,  3683,  3687,  3689,  3693,  3694,  3695,
+    3699,  3703,  3705,  3707,  3710,  3713,  3717,  3721,  3725,  3729,
+    3733,  3736,  3740,  3744,  3748,  3752,  3754,  3757,  3759,  3763,
+    3767,  3770,  3773,  3777,  3779,  3783,  3786,  3790,  3794,  3798,
+    3801,  3805,  3809,  3813,  3817,  3821,  3825,  3827,  3831,  3835,
+    3836,  3837,  3840,  3844,  3848,  3852,  3856,  3859,  3863,  3867,
+    3869,  3871,  3875,  3879,  3883,  3887,  3890,  3894,  3898,  3901,
+    3905,  3909,  3913,  3917,  3921,  3922,  3923,  3924,  3926,  3930,
+    3932,  3936,  3938,  3940,  3944,  3948,  3952,  3956,  3959,  3963,
+
+   /* 1001-1100 */
+    3965,  3969,  3973,  3977,  3979,  3981,  3982,  3986,  3989,  3993,
+    3997,  4001,  4004,  4006,  4009,  4012,  4016,  4020,  4024,  4026,
+    4028,  4032,  4036,  4040,  4044,  4046,  4050,  4054,  4058,  4060,
+    4062,  4063,  4064,  4068,  4071,  4075,  4077,  4081,  4083,  4087,
+    4089,  4091,  4095,  4099,  4101,  4103,  4105,  4107,  4111,  4115,
+    4119,  4123,  4127,  4129,  4131,  4135,  4139,  4141,  4143,  4145,
+    4149,  4153,  4157,  4161,  4165,  4169,  4173,  4177,  4180,  4183,
+    4187,  4191,  4195,  4198,  4201,  4205,  4209,  4212,  4213,  4216,
+    4217,  4221,  4223,  4226,  4230,  4234,  4236,  4240,  4244,  4248,
+    4252,  4256,  4258,  4262,  4264,  4266,  4268,  4270,  4272,  4276,
+
+   /* 1101-1200 */
+    4279,  4283,  4285,  4287,  4289,  4293,  4295,  4299,  4300,  4301,
+    4305,  4309,  4313,  4317,  4319,  4323,  4325,  4329,  4331,  4333,
+    4335,  4337,  4341,  4345,  4349,  4351,  4353,  4357,  4361,  4365,
+    4367,  4369,  4373,  4377,  4381,  4383,  4387,  4389,  4391,  4395,
+    4399,  4403,  4407,  4411,  4413,  4414,  4415,  4418,  4419,  4421,
+    4423,  4427,  4429,  4431,  4433,  4435,  4437,  4439,  4443,  4446,
+    4450,  4452,  4456,  4458,  4460,  4462,  4466,  4469,  4473,  4477,
+    4481,  4483,  4487,  4489,  4491,  4493,  4497,  4499,  4501,  4504,
+    4506,  4510,  4513,  4514,  4515,  4518,  4521,  4522,  4525,  4526,
+    4527,  4530,  4533,  4534,  4537,  4541,  4542,  4543,  4544,  4545,
+
+   /* 1201-1300 */
+    4546,  4547,  4550,  4553,  4554,  4555,  4558,  4561,  4564,  4567,
+    4568,  4571,  4574,  4575,  4578,  4581,  4582,  4585,  4586,  4588,
+    4590,  4592,  4596,  4598,  4602,  4604,  4608,  4612,  4613,  4616,
+    4619,  4622,  4623,  4624,  4625,  4626,  4629,  4632,  4633,  4636,
+    4639,  4640,  4641,  4642,  4643,  4644,  4645,  4648,  4649,  4650,
+    4651,  4652,  4653,  4656,  4657,  4660,  4661,  4664,  4667,  4670,
+    4671,  4674,  4675,  4676,  4677,  4678,  4681,  4682,  4683,  4684,
+    4687,  4688,  4689,  4692,  4693,  4696,  4697,  4700,  4701,  4702,
+    4703,  4704,  4707,  4708,  4711,  4712,  4715,  4716,  4717,  4718,
+    4719,  4720,  4721,  4722,  4723,  4726,  4729,  4730,  4733,  4736,
+
+   /* 1301-(NFLS+NFPL) */
+    4737,  4740,  4741,  4742,  4745,  4746,  4749,  4752,  4753
+   };
+
+/* Amplitude coefficients (microarcsec);  indexed using the nc array. */
+   static const double a[] = {
+
+   /* 1-105 */
+         -6844318.44,     9205236.26,1328.67,1538.18,      205833.11,
+           153041.79,       -3309.73, 853.32,2037.98,       -2301.27,
+       81.46, 120.56, -20.39, -15.22,   1.73,  -1.61,  -0.10,   0.11,
+       -0.02,  -0.02,     -523908.04,      573033.42,-544.75,-458.66,
+            12814.01,       11714.49, 198.97,-290.91, 155.74,-143.27,
+       -2.75,  -1.03,  -1.27,  -1.16,   0.00,  -0.01,      -90552.22,
+            97846.69, 111.23, 137.41,2187.91,2024.68,  41.44, -51.26,
+       26.92, -24.46,  -0.46,  -0.28,  -0.22,  -0.20,       82168.76,
+           -89618.24, -27.64, -29.05,       -2004.36,       -1837.32,
+      -36.07,  48.00, -24.43,  22.41,   0.47,   0.24,   0.20,   0.18,
+            58707.02,7387.02, 470.05,-192.40, 164.33,       -1312.21,
+     -179.73, -28.93, -17.36,  -1.83,  -0.50,   3.57,   0.00,   0.13,
+           -20557.78,       22438.42, -20.84, -17.40, 501.82, 459.68,
+       59.20, -67.30,   6.08,  -5.61,  -1.36,  -1.19,       28288.28,
+     -674.99, -34.69,  35.80, -15.07,-632.54, -11.19,   0.78,  -8.41,
+        0.17,   0.01,   0.07,      -15406.85,       20069.50,  15.12,
+
+   /* 106-219 */
+       31.80, 448.76, 344.50,  -5.77,   1.41,   4.59,  -5.02,   0.17,
+        0.24,      -11991.74,       12902.66,  32.46,  36.70, 288.49,
+      268.14,   5.70,  -7.06,   3.57,  -3.23,  -0.06,  -0.04,
+            -8584.95,       -9592.72,   4.42, -13.20,-214.50, 192.06,
+       23.87,  29.83,   2.54,   2.40,   0.60,  -0.48,5095.50,
+            -6918.22,   7.19,   3.92,-154.91,-113.94,   2.86,  -1.04,
+       -1.52,   1.73,  -0.07,  -0.10,       -4910.93,       -5331.13,
+        0.76,   0.40,-119.21, 109.81,   2.16,   3.20,   1.46,   1.33,
+        0.04,  -0.02,       -6245.02,-123.48,  -6.68,  -8.20,  -2.76,
+      139.64,   2.71,   0.15,   1.86,2511.85,       -3323.89,   1.07,
+       -0.90, -74.33, -56.17,   1.16,  -0.01,  -0.75,   0.83,  -0.02,
+       -0.04,2307.58,3143.98,  -7.52,   7.50,  70.31, -51.60,   1.46,
+        0.16,  -0.69,  -0.79,   0.02,  -0.05,2372.58,2554.51,   5.93,
+       -6.60,  57.12, -53.05,  -0.96,  -1.24,  -0.71,  -0.64,  -0.01,
+            -2053.16,2636.13,   5.13,   7.80,  58.94,  45.91,  -0.42,
+       -0.12,   0.61,  -0.66,   0.02,   0.03,       -1825.49,
+
+   /* 220-339 */
+            -2423.59,   1.23,  -2.00, -54.19,  40.82,  -1.07,  -1.02,
+        0.54,   0.61,  -0.04,   0.04,2521.07,-122.28,  -5.97,   2.90,
+       -2.73, -56.37,  -0.82,   0.13,  -0.75,       -1534.09,1645.01,
+        6.29,   6.80,  36.78,  34.30,   0.92,  -1.25,   0.46,  -0.41,
+       -0.02,  -0.01,1898.27,  47.70,  -0.72,   2.50,   1.07, -42.45,
+       -0.94,   0.02,  -0.56,       -1292.02,       -1387.00,   0.00,
+        0.00, -31.01,  28.89,   0.68,   0.00,   0.38,   0.35,  -0.01,
+       -0.01,       -1234.96,1323.81,   5.21,   5.90,  29.60,  27.61,
+        0.74,  -1.22,   0.37,  -0.33,  -0.02,  -0.01,1137.48,
+            -1233.89,  -0.04,  -0.30, -27.59, -25.43,  -0.61,   1.00,
+       -0.34,   0.31,   0.01,   0.01,-813.13,       -1075.60,   0.40,
+        0.30, -24.05,  18.18,  -0.40,  -0.01,   0.24,   0.27,  -0.01,
+        0.01,1163.22, -60.90,  -2.94,   1.30,  -1.36, -26.01,  -0.58,
+        0.07,  -0.35,1029.70, -55.55,  -2.63,   1.10,  -1.25, -23.02,
+       -0.52,   0.06,  -0.31,-556.26, 852.85,   3.16,  -4.48,  19.06,
+       12.44,  -0.81,  -0.27,   0.17,  -0.21,   0.00,   0.02,-603.52,
+
+   /* 340-467 */
+     -800.34,   0.44,   0.10, -17.90,  13.49,  -0.08,  -0.01,   0.18,
+        0.20,  -0.01,   0.01,-628.24, 684.99,  -0.64,  -0.50,  15.32,
+       14.05,   3.18,  -4.19,   0.19,  -0.17,  -0.09,  -0.07,-866.48,
+      -16.26,   0.52,  -1.30,  -0.36,  19.37,   0.43,  -0.01,   0.26,
+     -512.37, 695.54,  -1.47,  -1.40,  15.55,  11.46,  -0.16,   0.03,
+        0.15,  -0.17,   0.01,   0.01, 506.65, 643.75,   2.54,  -2.62,
+       14.40, -11.33,  -0.77,  -0.06,  -0.15,  -0.16,   0.00,   0.01,
+      664.57,  16.81,  -0.40,   1.00,   0.38, -14.86,  -3.71,  -0.09,
+       -0.20, 405.91, 522.11,   0.99,  -1.50,  11.67,  -9.08,  -0.25,
+       -0.02,  -0.12,  -0.13,-305.78, 326.60,   1.75,   1.90,   7.30,
+        6.84,   0.20,  -0.04, 300.99,-325.03,  -0.44,  -0.50,  -7.27,
+       -6.73,  -1.01,   0.01,   0.00,   0.08,   0.00,   0.02, 438.51,
+       10.47,  -0.56,  -0.20,   0.24,  -9.81,  -0.24,   0.01,  -0.13,
+     -264.02, 335.24,   0.99,   1.40,   7.49,   5.90,  -0.27,  -0.02,
+      284.09, 307.03,   0.32,  -0.40,   6.87,  -6.35,  -0.99,  -0.01,
+     -250.54, 327.11,   0.08,   0.40,   7.31,   5.60,  -0.30, 230.72,
+
+   /* 468-595 */
+     -304.46,   0.08,  -0.10,  -6.81,  -5.16,   0.27, 229.78, 304.17,
+       -0.60,   0.50,   6.80,  -5.14,   0.33,   0.01, 256.30,-276.81,
+       -0.28,  -0.40,  -6.19,  -5.73,  -0.14,   0.01,-212.82, 269.45,
+        0.84,   1.20,   6.02,   4.76,   0.14,  -0.02, 196.64, 272.05,
+       -0.84,   0.90,   6.08,  -4.40,   0.35,   0.02, 188.95, 272.22,
+       -0.12,   0.30,   6.09,  -4.22,   0.34,-292.37,  -5.10,  -0.32,
+       -0.40,  -0.11,   6.54,   0.14,   0.01, 161.79,-220.67,   0.24,
+        0.10,  -4.93,  -3.62,  -0.08, 261.54, -19.94,  -0.95,   0.20,
+       -0.45,  -5.85,  -0.13,   0.02, 142.16,-190.79,   0.20,   0.10,
+       -4.27,  -3.18,  -0.07, 187.95,  -4.11,  -0.24,   0.30,  -0.09,
+       -4.20,  -0.09,   0.01,   0.00,   0.00, -79.08, 167.90,   0.04,
+        0.00,   3.75,   1.77, 121.98, 131.04,  -0.08,   0.10,   2.93,
+       -2.73,  -0.06,-172.95,  -8.11,  -0.40,  -0.20,  -0.18,   3.87,
+        0.09,   0.01,-160.15, -55.30, -14.04,  13.90,  -1.23,   3.58,
+        0.40,   0.31,-115.40, 123.20,   0.60,   0.70,   2.75,   2.58,
+        0.08,  -0.01,-168.26,  -2.00,   0.20,  -0.20,  -0.04,   3.76,
+
+   /* 596-723 */
+        0.08,-114.49, 123.20,   0.32,   0.40,   2.75,   2.56,   0.07,
+       -0.01, 112.14, 120.70,   0.28,  -0.30,   2.70,  -2.51,  -0.07,
+       -0.01, 161.34,   4.03,   0.20,   0.20,   0.09,  -3.61,  -0.08,
+       91.31, 126.64,  -0.40,   0.40,   2.83,  -2.04,  -0.04,   0.01,
+      105.29, 112.90,   0.44,  -0.50,   2.52,  -2.35,  -0.07,  -0.01,
+       98.69,-106.20,  -0.28,  -0.30,  -2.37,  -2.21,  -0.06,   0.01,
+       86.74,-112.94,  -0.08,  -0.20,  -2.53,  -1.94,  -0.05,-134.81,
+        3.51,   0.20,  -0.20,   0.08,   3.01,   0.07,  79.03, 107.31,
+       -0.24,   0.20,   2.40,  -1.77,  -0.04,   0.01, 132.81, -10.77,
+       -0.52,   0.10,  -0.24,  -2.97,  -0.07,   0.01,-130.31,  -0.90,
+        0.04,   0.00,   0.00,   2.91, -78.56,  85.32,   0.00,   0.00,
+        1.91,   1.76,   0.04,   0.00,   0.00, -41.53,  89.10,   0.02,
+        0.00,   1.99,   0.93,  66.03, -71.00,  -0.20,  -0.20,  -1.59,
+       -1.48,  -0.04,  60.50,  64.70,   0.36,  -0.40,   1.45,  -1.35,
+       -0.04,  -0.01, -52.27, -70.01,   0.00,   0.00,  -1.57,   1.17,
+        0.03, -52.95,  66.29,   0.32,   0.40,   1.48,   1.18,   0.04,
+
+   /* 724-851 */
+       -0.01,  51.02,  67.25,   0.00,   0.00,   1.50,  -1.14,  -0.03,
+      -55.66, -60.92,   0.16,  -0.20,  -1.36,   1.24,   0.03, -54.81,
+      -59.20,  -0.08,   0.20,  -1.32,   1.23,   0.03,  51.32, -55.60,
+        0.00,   0.00,  -1.24,  -1.15,  -0.03,  48.29,  51.80,   0.20,
+       -0.20,   1.16,  -1.08,  -0.03, -45.59, -49.00,  -0.12,   0.10,
+       -1.10,   1.02,   0.03,  40.54, -52.69,  -0.04,  -0.10,  -1.18,
+       -0.91,  -0.02, -40.58, -49.51,  -1.00,   1.00,  -1.11,   0.91,
+        0.04,   0.02, -43.76,  46.50,   0.36,   0.40,   1.04,   0.98,
+        0.03,  -0.01,  62.65,  -5.00,  -0.24,   0.00,  -0.11,  -1.40,
+       -0.03,   0.01, -38.57,  49.59,   0.08,   0.10,   1.11,   0.86,
+        0.02, -33.22, -44.04,   0.08,  -0.10,  -0.98,   0.74,   0.02,
+       37.15, -39.90,  -0.12,  -0.10,  -0.89,  -0.83,  -0.02,  36.68,
+      -39.50,  -0.04,  -0.10,  -0.88,  -0.82,  -0.02, -53.22,  -3.91,
+       -0.20,   0.00,  -0.09,   1.19,   0.03,  32.43, -42.19,  -0.04,
+       -0.10,  -0.94,  -0.73,  -0.02, -51.00,  -2.30,  -0.12,  -0.10,
+        0.00,   1.14, -29.53, -39.11,   0.04,   0.00,  -0.87,   0.66,
+
+   /* 852-979 */
+        0.02,  28.50, -38.92,  -0.08,  -0.10,  -0.87,  -0.64,  -0.02,
+       26.54,  36.95,  -0.12,   0.10,   0.83,  -0.59,  -0.01,  26.54,
+       34.59,   0.04,  -0.10,   0.77,  -0.59,  -0.02,  28.35, -32.55,
+       -0.16,   0.20,  -0.73,  -0.63,  -0.01, -28.00,  30.40,   0.00,
+        0.00,   0.68,   0.63,   0.01, -27.61,  29.40,   0.20,   0.20,
+        0.66,   0.62,   0.02,  40.33,   0.40,  -0.04,   0.10,   0.00,
+       -0.90, -23.28,  31.61,  -0.08,  -0.10,   0.71,   0.52,   0.01,
+       37.75,   0.80,   0.04,   0.10,   0.00,  -0.84,  23.66,  25.80,
+        0.00,   0.00,   0.58,  -0.53,  -0.01,  21.01, -27.91,   0.00,
+        0.00,  -0.62,  -0.47,  -0.01, -34.81,   2.89,   0.04,   0.00,
+        0.00,   0.78, -23.49, -25.31,   0.00,   0.00,  -0.57,   0.53,
+        0.01, -23.47,  25.20,   0.16,   0.20,   0.56,   0.52,   0.02,
+       19.58,  27.50,  -0.12,   0.10,   0.62,  -0.44,  -0.01, -22.67,
+      -24.40,  -0.08,   0.10,  -0.55,   0.51,   0.01, -19.97,  25.00,
+        0.12,   0.20,   0.56,   0.45,   0.01,  21.28, -22.80,  -0.08,
+       -0.10,  -0.51,  -0.48,  -0.01, -30.47,   0.91,   0.04,   0.00,
+
+   /* 980-1107 */
+        0.00,   0.68,  18.58,  24.00,   0.04,  -0.10,   0.54,  -0.42,
+       -0.01, -18.02,  24.40,  -0.04,  -0.10,   0.55,   0.40,   0.01,
+       17.74,  22.50,   0.08,  -0.10,   0.50,  -0.40,  -0.01, -19.41,
+       20.70,   0.08,   0.10,   0.46,   0.43,   0.01, -18.64,  20.11,
+        0.00,   0.00,   0.45,   0.42,   0.01, -16.75,  21.60,   0.04,
+        0.10,   0.48,   0.37,   0.01, -18.42, -20.00,   0.00,   0.00,
+       -0.45,   0.41,   0.01, -26.77,   1.41,   0.08,   0.00,   0.00,
+        0.60, -26.17,  -0.19,   0.00,   0.00,   0.00,   0.59, -15.52,
+       20.51,   0.00,   0.00,   0.46,   0.35,   0.01, -25.42,  -1.91,
+       -0.08,   0.00,  -0.04,   0.57,   0.45, -17.42,  18.10,   0.00,
+        0.00,   0.40,   0.39,   0.01,  16.39, -17.60,  -0.08,  -0.10,
+       -0.39,  -0.37,  -0.01, -14.37,  18.91,   0.00,   0.00,   0.42,
+        0.32,   0.01,  23.39,  -2.40,  -0.12,   0.00,   0.00,  -0.52,
+       14.32, -18.50,  -0.04,  -0.10,  -0.41,  -0.32,  -0.01,  15.69,
+       17.08,   0.00,   0.00,   0.38,  -0.35,  -0.01, -22.99,   0.50,
+        0.04,   0.00,   0.00,   0.51,   0.00,   0.00,  14.47, -17.60,
+
+   /* 1108-1235 */
+       -0.01,   0.00,  -0.39,  -0.32, -13.33,  18.40,  -0.04,  -0.10,
+        0.41,   0.30,  22.47,  -0.60,  -0.04,   0.00,   0.00,  -0.50,
+      -12.78, -17.41,   0.04,   0.00,  -0.39,   0.29,   0.01, -14.10,
+      -15.31,   0.04,   0.00,  -0.34,   0.32,   0.01,  11.98,  16.21,
+       -0.04,   0.00,   0.36,  -0.27,  -0.01,  19.65,  -1.90,  -0.08,
+        0.00,   0.00,  -0.44,  19.61,  -1.50,  -0.08,   0.00,   0.00,
+       -0.44,  13.41, -14.30,  -0.04,  -0.10,  -0.32,  -0.30,  -0.01,
+      -13.29,  14.40,   0.00,   0.00,   0.32,   0.30,   0.01,  11.14,
+      -14.40,  -0.04,   0.00,  -0.32,  -0.25,  -0.01,  12.24, -13.38,
+        0.04,   0.00,  -0.30,  -0.27,  -0.01,  10.07, -13.81,   0.04,
+        0.00,  -0.31,  -0.23,  -0.01,  10.46,  13.10,   0.08,  -0.10,
+        0.29,  -0.23,  -0.01,  16.55,  -1.71,  -0.08,   0.00,   0.00,
+       -0.37,   9.75, -12.80,   0.00,   0.00,  -0.29,  -0.22,  -0.01,
+        9.11,  12.80,   0.00,   0.00,   0.29,  -0.20,   0.00,   0.00,
+       -6.44, -13.80,   0.00,   0.00,  -0.31,   0.14,  -9.19, -12.00,
+        0.00,   0.00,  -0.27,   0.21, -10.30,  10.90,   0.08,   0.10,
+
+   /* 1236-1363 */
+        0.24,   0.23,   0.01,  14.92,  -0.80,  -0.04,   0.00,   0.00,
+       -0.33,  10.02, -10.80,   0.00,   0.00,  -0.24,  -0.22,  -0.01,
+       -9.75,  10.40,   0.04,   0.00,   0.23,   0.22,   0.01,   9.67,
+      -10.40,  -0.04,   0.00,  -0.23,  -0.22,  -0.01,  -8.28, -11.20,
+        0.04,   0.00,  -0.25,   0.19,  13.32,  -1.41,  -0.08,   0.00,
+        0.00,  -0.30,   8.27,  10.50,   0.04,   0.00,   0.23,  -0.19,
+        0.00,   0.00,  13.13,   0.00,   0.00,   0.00,   0.00,  -0.29,
+      -12.93,   0.70,   0.04,   0.00,   0.00,   0.29,   7.91, -10.20,
+        0.00,   0.00,  -0.23,  -0.18,  -7.84, -10.00,  -0.04,   0.00,
+       -0.22,   0.18,   7.44,   9.60,   0.00,   0.00,   0.21,  -0.17,
+       -7.64,   9.40,   0.08,   0.10,   0.21,   0.17,   0.01, -11.38,
+        0.60,   0.04,   0.00,   0.00,   0.25,  -7.48,   8.30,   0.00,
+        0.00,   0.19,   0.17, -10.98,  -0.20,   0.00,   0.00,   0.00,
+        0.25,  10.98,   0.20,   0.00,   0.00,   0.00,  -0.25,   7.40,
+       -7.90,  -0.04,   0.00,  -0.18,  -0.17,  -6.09,   8.40,  -0.04,
+        0.00,   0.19,   0.14,  -6.94,  -7.49,   0.00,   0.00,  -0.17,
+
+   /* 1364-1491 */
+        0.16,   6.92,   7.50,   0.04,   0.00,   0.17,  -0.15,   6.20,
+        8.09,   0.00,   0.00,   0.18,  -0.14,  -6.12,   7.80,   0.04,
+        0.00,   0.17,   0.14,   5.85,  -7.50,   0.00,   0.00,  -0.17,
+       -0.13,  -6.48,   6.90,   0.08,   0.10,   0.15,   0.14,   0.01,
+        6.32,   6.90,   0.00,   0.00,   0.15,  -0.14,   5.61,  -7.20,
+        0.00,   0.00,  -0.16,  -0.13,   9.07,   0.00,   0.00,   0.00,
+        0.00,  -0.20,   5.25,   6.90,   0.00,   0.00,   0.15,  -0.12,
+       -8.47,  -0.40,   0.00,   0.00,   0.00,   0.19,   6.32,  -5.39,
+       -1.11,   1.10,  -0.12,  -0.14,   0.02,   0.02,   5.73,  -6.10,
+       -0.04,   0.00,  -0.14,  -0.13,   4.70,   6.60,  -0.04,   0.00,
+        0.15,  -0.11,  -4.90,  -6.40,   0.00,   0.00,  -0.14,   0.11,
+       -5.33,   5.60,   0.04,   0.10,   0.13,   0.12,   0.01,  -4.81,
+        6.00,   0.04,   0.00,   0.13,   0.11,   5.13,   5.50,   0.04,
+        0.00,   0.12,  -0.11,   4.50,   5.90,   0.00,   0.00,   0.13,
+       -0.10,  -4.22,   6.10,   0.00,   0.00,   0.14,  -4.53,   5.70,
+        0.00,   0.00,   0.13,   0.10,   4.18,   5.70,   0.00,   0.00,
+
+   /* 1492-1619 */
+        0.13,  -4.75,  -5.19,   0.00,   0.00,  -0.12,   0.11,  -4.06,
+        5.60,   0.00,   0.00,   0.13,  -3.98,   5.60,  -0.04,   0.00,
+        0.13,   4.02,  -5.40,   0.00,   0.00,  -0.12,   4.49,  -4.90,
+       -0.04,   0.00,  -0.11,  -0.10,  -3.62,  -5.40,  -0.16,   0.20,
+       -0.12,   0.00,   0.01,   4.38,   4.80,   0.00,   0.00,   0.11,
+       -6.40,  -0.10,   0.00,   0.00,   0.00,   0.14,  -3.98,   5.00,
+        0.04,   0.00,   0.11,  -3.82,  -5.00,   0.00,   0.00,  -0.11,
+       -3.71,   5.07,   0.00,   0.00,   0.11,   4.14,   4.40,   0.00,
+        0.00,   0.10,  -6.01,  -0.50,  -0.04,   0.00,   0.00,   0.13,
+       -4.04,   4.39,   0.00,   0.00,   0.10,   3.45,  -4.72,   0.00,
+        0.00,  -0.11,   3.31,   4.71,   0.00,   0.00,   0.11,   3.26,
+       -4.50,   0.00,   0.00,  -0.10,  -3.26,  -4.50,   0.00,   0.00,
+       -0.10,  -3.34,  -4.40,   0.00,   0.00,  -0.10,  -3.74,  -4.00,
+        3.70,   4.00,   3.34,  -4.30,   3.30,  -4.30,  -3.66,   3.90,
+        0.04,   3.66,   3.90,   0.04,  -3.62,  -3.90,  -3.61,   3.90,
+       -0.20,   5.30,   0.00,   0.00,   0.12,   3.06,   4.30,   3.30,
+
+   /* 1620-1747 */
+        4.00,   0.40,   0.20,   3.10,   4.10,  -3.06,   3.90,  -3.30,
+       -3.60,  -3.30,   3.36,   0.01,   3.14,   3.40,  -4.57,  -0.20,
+        0.00,   0.00,   0.00,   0.10,  -2.70,  -3.60,   2.94,  -3.20,
+       -2.90,   3.20,   2.47,  -3.40,   2.55,  -3.30,   2.80,  -3.08,
+        2.51,   3.30,  -4.10,   0.30,  -0.12,  -0.10,   4.10,   0.20,
+       -2.74,   3.00,   2.46,   3.23,  -3.66,   1.20,  -0.20,   0.20,
+        3.74,  -0.40,  -2.51,  -2.80,  -3.74,   2.27,  -2.90,   0.00,
+        0.00,  -2.50,   2.70,  -2.51,   2.60,  -3.50,   0.20,   3.38,
+       -2.22,  -2.50,   3.26,  -0.40,   1.95,  -2.60,   3.22,  -0.40,
+       -0.04,  -1.79,  -2.60,   1.91,   2.50,   0.74,   3.05,  -0.04,
+        0.08,   2.11,  -2.30,  -2.11,   2.20,  -1.87,  -2.40,   2.03,
+       -2.20,  -2.03,   2.20,   2.98,   0.00,   0.00,   2.98,  -1.71,
+        2.40,   2.94,  -0.10,  -0.12,   0.10,   1.67,   2.40,  -1.79,
+        2.30,  -1.79,   2.20,  -1.67,   2.20,   1.79,  -2.00,   1.87,
+       -1.90,   1.63,  -2.10,  -1.59,   2.10,   1.55,  -2.10,  -1.55,
+        2.10,  -2.59,  -0.20,  -1.75,  -1.90,  -1.75,   1.90,  -1.83,
+
+   /* 1748-1875 */
+       -1.80,   1.51,   2.00,  -1.51,  -2.00,   1.71,   1.80,   1.31,
+        2.10,  -1.43,   2.00,   1.43,   2.00,  -2.43,  -1.51,   1.90,
+       -1.47,   1.90,   2.39,   0.20,  -2.39,   1.39,   1.90,   1.39,
+       -1.80,   1.47,  -1.60,   1.47,  -1.60,   1.43,  -1.50,  -1.31,
+        1.60,   1.27,  -1.60,  -1.27,   1.60,   1.27,  -1.60,   2.03,
+        1.35,   1.50,  -1.39,  -1.40,   1.95,  -0.20,  -1.27,   1.49,
+        1.19,   1.50,   1.27,   1.40,   1.15,   1.50,   1.87,  -0.10,
+       -1.12,  -1.50,   1.87,  -1.11,  -1.50,  -1.11,  -1.50,   0.00,
+        0.00,   1.19,   1.40,   1.27,  -1.30,  -1.27,  -1.30,  -1.15,
+        1.40,  -1.23,   1.30,  -1.23,  -1.30,   1.22,  -1.29,   1.07,
+       -1.40,   1.75,  -0.20,  -1.03,  -1.40,  -1.07,   1.20,  -1.03,
+        1.15,   1.07,   1.10,   1.51,  -1.03,   1.10,   1.03,  -1.10,
+        0.00,   0.00,  -1.03,  -1.10,   0.91,  -1.20,  -0.88,  -1.20,
+       -0.88,   1.20,  -0.95,   1.10,  -0.95,  -1.10,   1.43,  -1.39,
+        0.95,  -1.00,  -0.95,   1.00,  -0.80,   1.10,   0.91,  -1.00,
+       -1.35,   0.88,   1.00,  -0.83,   1.00,  -0.91,   0.90,   0.91,
+
+   /* 1876-2003 */
+        0.90,   0.88,  -0.90,  -0.76,  -1.00,  -0.76,   1.00,   0.76,
+        1.00,  -0.72,   1.00,   0.84,  -0.90,   0.84,   0.90,   1.23,
+        0.00,   0.00,  -0.52,  -1.10,  -0.68,   1.00,   1.19,  -0.20,
+        1.19,   0.76,   0.90,   1.15,  -0.10,   1.15,  -0.10,   0.72,
+       -0.90,  -1.15,  -1.15,   0.68,   0.90,  -0.68,   0.90,  -1.11,
+        0.00,   0.00,   0.20,   0.79,   0.80,  -1.11,  -0.10,   0.00,
+        0.00,  -0.48,  -1.00,  -0.76,  -0.80,  -0.72,  -0.80,  -1.07,
+       -0.10,   0.64,   0.80,  -0.64,  -0.80,   0.64,   0.80,   0.40,
+        0.60,   0.52,  -0.50,  -0.60,  -0.80,  -0.71,   0.70,  -0.99,
+        0.99,   0.56,   0.80,  -0.56,   0.80,   0.68,  -0.70,   0.68,
+        0.70,  -0.95,  -0.64,   0.70,   0.64,   0.70,  -0.60,   0.70,
+       -0.60,  -0.70,  -0.91,  -0.10,  -0.51,   0.76,  -0.91,  -0.56,
+        0.70,   0.88,   0.88,  -0.63,  -0.60,   0.55,  -0.60,  -0.80,
+        0.80,  -0.80,  -0.52,   0.60,   0.52,   0.60,   0.52,  -0.60,
+       -0.48,   0.60,   0.48,   0.60,   0.48,   0.60,  -0.76,   0.44,
+       -0.60,   0.52,  -0.50,  -0.52,   0.50,   0.40,   0.60,  -0.40,
+
+   /* 2004-2131 */
+       -0.60,   0.40,  -0.60,   0.72,  -0.72,  -0.51,  -0.50,  -0.48,
+        0.50,   0.48,  -0.50,  -0.48,   0.50,  -0.48,   0.50,   0.48,
+       -0.50,  -0.48,  -0.50,  -0.68,  -0.68,   0.44,   0.50,  -0.64,
+       -0.10,  -0.64,  -0.10,  -0.40,   0.50,   0.40,   0.50,   0.40,
+        0.50,   0.00,   0.00,  -0.40,  -0.50,  -0.36,  -0.50,   0.36,
+       -0.50,   0.60,  -0.60,   0.40,  -0.40,   0.40,   0.40,  -0.40,
+        0.40,  -0.40,   0.40,  -0.56,  -0.56,   0.36,  -0.40,  -0.36,
+        0.40,   0.36,  -0.40,  -0.36,  -0.40,   0.36,   0.40,   0.36,
+        0.40,  -0.52,   0.52,   0.52,   0.32,   0.40,  -0.32,   0.40,
+       -0.32,   0.40,  -0.32,   0.40,   0.32,  -0.40,  -0.32,  -0.40,
+        0.32,  -0.40,   0.28,  -0.40,  -0.28,   0.40,   0.28,  -0.40,
+        0.28,   0.40,   0.48,  -0.48,   0.48,   0.36,  -0.30,  -0.36,
+       -0.30,   0.00,   0.00,   0.20,   0.40,  -0.44,   0.44,  -0.44,
+       -0.44,  -0.44,  -0.44,   0.32,  -0.30,   0.32,   0.30,   0.24,
+        0.30,  -0.12,  -0.10,  -0.28,   0.30,   0.28,   0.30,   0.28,
+        0.30,   0.28,  -0.30,   0.28,  -0.30,   0.28,  -0.30,   0.28,
+
+   /* 2132-2259 */
+        0.30,  -0.28,   0.30,   0.40,   0.40,  -0.24,   0.30,   0.24,
+       -0.30,   0.24,  -0.30,  -0.24,  -0.30,   0.24,   0.30,   0.24,
+       -0.30,  -0.24,   0.30,   0.24,  -0.30,  -0.24,  -0.30,   0.24,
+       -0.30,   0.24,   0.30,  -0.24,   0.30,  -0.24,   0.30,   0.20,
+       -0.30,   0.20,  -0.30,   0.20,  -0.30,   0.20,   0.30,   0.20,
+       -0.30,   0.20,  -0.30,   0.20,   0.30,   0.20,   0.30,  -0.20,
+       -0.30,   0.20,  -0.30,   0.20,  -0.30,  -0.36,  -0.36,  -0.36,
+       -0.04,   0.30,   0.12,  -0.10,  -0.32,  -0.24,   0.20,   0.24,
+        0.20,   0.20,  -0.20,  -0.20,  -0.20,  -0.20,  -0.20,   0.20,
+        0.20,   0.20,  -0.20,   0.20,   0.20,   0.20,   0.20,  -0.20,
+       -0.20,   0.00,   0.00,  -0.20,  -0.20,  -0.20,   0.20,  -0.20,
+        0.20,   0.20,  -0.20,  -0.20,  -0.20,   0.20,   0.20,   0.20,
+        0.20,   0.20,  -0.20,   0.20,  -0.20,   0.28,   0.28,   0.28,
+        0.28,   0.28,   0.28,  -0.28,   0.28,   0.12,   0.00,   0.24,
+        0.16,  -0.20,   0.16,  -0.20,   0.16,  -0.20,   0.16,   0.20,
+       -0.16,   0.20,   0.16,   0.20,  -0.16,   0.20,  -0.16,   0.20,
+
+   /* 2260-2387 */
+       -0.16,   0.20,   0.16,  -0.20,   0.16,   0.20,   0.16,  -0.20,
+       -0.16,   0.20,  -0.16,  -0.20,  -0.16,   0.20,   0.16,   0.20,
+        0.16,  -0.20,   0.16,  -0.20,   0.16,   0.20,   0.16,   0.20,
+        0.16,   0.20,  -0.16,  -0.20,   0.16,   0.20,  -0.16,   0.20,
+        0.16,   0.20,  -0.16,  -0.20,   0.16,  -0.20,   0.16,  -0.20,
+       -0.16,  -0.20,   0.24,  -0.24,  -0.24,   0.24,   0.24,   0.12,
+        0.20,   0.12,   0.20,  -0.12,  -0.20,   0.12,  -0.20,   0.12,
+       -0.20,  -0.12,   0.20,  -0.12,   0.20,  -0.12,  -0.20,   0.12,
+        0.20,   0.12,   0.20,   0.12,  -0.20,  -0.12,   0.20,   0.12,
+       -0.20,  -0.12,   0.20,   0.12,   0.20,   0.00,   0.00,  -0.12,
+        0.20,  -0.12,   0.20,   0.12,  -0.20,  -0.12,   0.20,   0.12,
+        0.20,   0.00,  -0.21,  -0.20,   0.00,   0.00,   0.20,  -0.20,
+       -0.20,  -0.20,   0.20,  -0.16,  -0.10,   0.00,   0.17,   0.16,
+        0.16,   0.16,   0.16,  -0.16,   0.16,   0.16,  -0.16,   0.16,
+       -0.16,   0.16,   0.12,   0.10,   0.12,  -0.10,  -0.12,   0.10,
+       -0.12,   0.10,   0.12,  -0.10,  -0.12,   0.12,  -0.12,   0.12,
+
+   /* 2388-2515 */
+       -0.12,   0.12,  -0.12,  -0.12,  -0.12,  -0.12,  -0.12,  -0.12,
+       -0.12,   0.12,   0.12,   0.12,   0.12,  -0.12,  -0.12,   0.12,
+        0.12,   0.12,  -0.12,   0.12,  -0.12,  -0.12,  -0.12,   0.12,
+       -0.12,  -0.12,   0.12,   0.00,   0.11,   0.11,-122.67, 164.70,
+      203.78, 273.50,   3.58,   2.74,   6.18,  -4.56,   0.00,  -0.04,
+        0.00,  -0.07,  57.44, -77.10,  95.82, 128.60,  -1.77,  -1.28,
+        2.85,  -2.14,  82.14,  89.50,   0.00,   0.00,   2.00,  -1.84,
+       -0.04,  47.73, -64.10,  23.79,  31.90,  -1.45,  -1.07,   0.69,
+       -0.53, -46.38,  50.50,   0.00,   0.00,   1.13,   1.04,   0.02,
+      -18.38,   0.00,  63.80,   0.00,   0.00,   0.41,   0.00,  -1.43,
+       59.07,   0.00,   0.00,   0.00,   0.00,  -1.32,  57.28,   0.00,
+        0.00,   0.00,   0.00,  -1.28, -48.65,   0.00,  -1.15,   0.00,
+        0.00,   1.09,   0.00,   0.03, -18.30,  24.60, -17.30, -23.20,
+        0.56,   0.41,  -0.51,   0.39, -16.91,  26.90,   8.43,  13.30,
+        0.60,   0.38,   0.31,  -0.19,   1.23,  -1.70, -19.13, -25.70,
+       -0.03,  -0.03,  -0.58,   0.43,  -0.72,   0.90, -17.34, -23.30,
+
+   /* 2516-2643 */
+        0.03,   0.02,  -0.52,   0.39, -19.49, -21.30,   0.00,   0.00,
+       -0.48,   0.44,   0.01,  20.57, -20.10,   0.64,   0.70,  -0.45,
+       -0.46,   0.00,  -0.01,   4.89,   5.90, -16.55,  19.90,   0.14,
+       -0.11,   0.44,   0.37,  18.22,  19.80,   0.00,   0.00,   0.44,
+       -0.41,  -0.01,   4.89,  -5.30, -16.51, -18.00,  -0.11,  -0.11,
+       -0.41,   0.37, -17.86,   0.00,  17.10,   0.00,   0.00,   0.40,
+        0.00,  -0.38,   0.32,   0.00,  24.42,   0.00,   0.00,  -0.01,
+        0.00,  -0.55, -23.79,   0.00,   0.00,   0.00,   0.00,   0.53,
+       14.72, -16.00,  -0.32,   0.00,  -0.36,  -0.33,  -0.01,   0.01,
+        3.34,  -4.50,  11.86,  15.90,  -0.11,  -0.07,   0.35,  -0.27,
+       -3.26,   4.40,  11.62,  15.60,   0.09,   0.07,   0.35,  -0.26,
+      -19.53,   0.00,   5.09,   0.00,   0.00,   0.44,   0.00,  -0.11,
+      -13.48,  14.70,   0.00,   0.00,   0.33,   0.30,   0.01,  10.86,
+      -14.60,   3.18,   4.30,  -0.33,  -0.24,   0.09,  -0.07, -11.30,
+      -15.10,   0.00,   0.00,  -0.34,   0.25,   0.01,   2.03,  -2.70,
+       10.82,  14.50,  -0.07,  -0.05,   0.32,  -0.24,  17.46,   0.00,
+
+   /* 2644-2771 */
+        0.00,   0.00,   0.00,  -0.39,  16.43,   0.00,   0.52,   0.00,
+        0.00,  -0.37,   0.00,  -0.01,   9.35,   0.00,  13.29,   0.00,
+        0.00,  -0.21,   0.00,  -0.30, -10.42,  11.40,   0.00,   0.00,
+        0.25,   0.23,   0.01,   0.44,   0.50, -10.38,  11.30,   0.02,
+       -0.01,   0.25,   0.23, -14.64,   0.00,   0.00,   0.00,   0.00,
+        0.33,   0.56,   0.80,  -8.67,  11.70,   0.02,  -0.01,   0.26,
+        0.19,  13.88,   0.00,  -2.47,   0.00,   0.00,  -0.31,   0.00,
+        0.06,  -1.99,   2.70,   7.72,  10.30,   0.06,   0.04,   0.23,
+       -0.17,  -0.20,   0.00,  13.05,   0.00,   0.00,   0.00,   0.00,
+       -0.29,   6.92,  -9.30,   3.34,   4.50,  -0.21,  -0.15,   0.10,
+       -0.07,  -6.60,   0.00,  10.70,   0.00,   0.00,   0.15,   0.00,
+       -0.24,  -8.04,  -8.70,   0.00,   0.00,  -0.19,   0.18, -10.58,
+        0.00,  -3.10,   0.00,   0.00,   0.24,   0.00,   0.07,  -7.32,
+        8.00,  -0.12,  -0.10,   0.18,   0.16,   1.63,   1.70,   6.96,
+       -7.60,   0.03,  -0.04,  -0.17,  -0.16,  -3.62,   0.00,   9.86,
+        0.00,   0.00,   0.08,   0.00,  -0.22,   0.20,  -0.20,  -6.88,
+
+   /* 2772-2899 */
+       -7.50,   0.00,   0.00,  -0.17,   0.15,  -8.99,   0.00,   4.02,
+        0.00,   0.00,   0.20,   0.00,  -0.09,  -1.07,   1.40,  -5.69,
+       -7.70,   0.03,   0.02,  -0.17,   0.13,   6.48,  -7.20,  -0.48,
+       -0.50,  -0.16,  -0.14,  -0.01,   0.01,   5.57,  -7.50,   1.07,
+        1.40,  -0.17,  -0.12,   0.03,  -0.02,   8.71,   0.00,   3.54,
+        0.00,   0.00,  -0.19,   0.00,  -0.08,   0.40,   0.00,   9.27,
+        0.00,   0.00,  -0.01,   0.00,  -0.21,  -6.13,   6.70,  -1.19,
+       -1.30,   0.15,   0.14,  -0.03,   0.03,   5.21,  -5.70,  -2.51,
+       -2.60,  -0.13,  -0.12,  -0.06,   0.06,   5.69,  -6.20,  -0.12,
+       -0.10,  -0.14,  -0.13,  -0.01,   2.03,  -2.70,   4.53,   6.10,
+       -0.06,  -0.05,   0.14,  -0.10,   5.01,   5.50,  -2.51,   2.70,
+        0.12,  -0.11,   0.06,   0.06,  -1.91,   2.60,  -4.38,  -5.90,
+        0.06,   0.04,  -0.13,   0.10,   4.65,  -6.30,   0.00,   0.00,
+       -0.14,  -0.10,  -5.29,   5.70,   0.00,   0.00,   0.13,   0.12,
+       -2.23,  -4.00,  -4.65,   4.20,  -0.09,   0.05,   0.10,   0.10,
+       -4.53,   6.10,   0.00,   0.00,   0.14,   0.10,   2.47,   2.70,
+
+   /* 2900-3027 */
+       -4.46,   4.90,   0.06,  -0.06,   0.11,   0.10,  -5.05,   5.50,
+        0.84,   0.90,   0.12,   0.11,   0.02,  -0.02,   4.97,  -5.40,
+       -1.71,   0.00,  -0.12,  -0.11,   0.00,   0.04,  -0.99,  -1.30,
+        4.22,  -5.70,  -0.03,   0.02,  -0.13,  -0.09,   0.99,   1.40,
+        4.22,  -5.60,   0.03,  -0.02,  -0.13,  -0.09,  -4.69,  -5.20,
+        0.00,   0.00,  -0.12,   0.10,  -3.42,   0.00,   6.09,   0.00,
+        0.00,   0.08,   0.00,  -0.14,  -4.65,  -5.10,   0.00,   0.00,
+       -0.11,   0.10,   0.00,   0.00,  -4.53,  -5.00,   0.00,   0.00,
+       -0.11,   0.10,  -2.43,  -2.70,  -3.82,   4.20,  -0.06,   0.05,
+        0.10,   0.09,   0.00,   0.00,  -4.53,   4.90,   0.00,   0.00,
+        0.11,   0.10,  -4.49,  -4.90,   0.00,   0.00,  -0.11,   0.10,
+        2.67,  -2.90,  -3.62,  -3.90,  -0.06,  -0.06,  -0.09,   0.08,
+        3.94,  -5.30,   0.00,   0.00,  -0.12,  -3.38,   3.70,  -2.78,
+       -3.10,   0.08,   0.08,  -0.07,   0.06,   3.18,  -3.50,  -2.82,
+       -3.10,  -0.08,  -0.07,  -0.07,   0.06,  -5.77,   0.00,   1.87,
+        0.00,   0.00,   0.13,   0.00,  -0.04,   3.54,  -4.80,  -0.64,
+
+   /* 3028-3155 */
+       -0.90,  -0.11,   0.00,  -0.02,  -3.50,  -4.70,   0.68,  -0.90,
+       -0.11,   0.00,  -0.02,   5.49,   0.00,   0.00,   0.00,   0.00,
+       -0.12,   1.83,  -2.50,   2.63,   3.50,  -0.06,   0.00,   0.08,
+        3.02,  -4.10,   0.68,   0.90,  -0.09,   0.00,   0.02,   0.00,
+        0.00,   5.21,   0.00,   0.00,   0.00,   0.00,  -0.12,  -3.54,
+        3.80,   2.70,   3.60,  -1.35,   1.80,   0.08,   0.00,   0.04,
+       -2.90,   3.90,   0.68,   0.90,   0.09,   0.00,   0.02,   0.80,
+       -1.10,  -2.78,  -3.70,  -0.02,   0.00,  -0.08,   4.10,   0.00,
+       -2.39,   0.00,   0.00,  -0.09,   0.00,   0.05,  -1.59,   2.10,
+        2.27,   3.00,   0.05,   0.00,   0.07,  -2.63,   3.50,  -0.48,
+       -0.60,  -2.94,  -3.20,  -2.94,   3.20,   2.27,  -3.00,  -1.11,
+       -1.50,  -0.07,   0.00,  -0.03,  -0.56,  -0.80,  -2.35,   3.10,
+        0.00,  -0.60,  -3.42,   1.90,  -0.12,  -0.10,   2.63,  -2.90,
+        2.51,   2.80,  -0.64,   0.70,  -0.48,  -0.60,   2.19,  -2.90,
+        0.24,  -0.30,   2.15,   2.90,   2.15,  -2.90,   0.52,   0.70,
+        2.07,  -2.80,  -3.10,   0.00,   1.79,   0.00,   0.00,   0.07,
+
+   /* 3156-3283 */
+        0.00,  -0.04,   0.88,   0.00,  -3.46,   2.11,   2.80,  -0.36,
+        0.50,   3.54,  -0.20,  -3.50,  -1.39,   1.50,  -1.91,  -2.10,
+       -1.47,   2.00,   1.39,   1.90,   2.07,  -2.30,   0.91,   1.00,
+        1.99,  -2.70,   3.30,   0.00,   0.60,  -0.44,  -0.70,  -1.95,
+        2.60,   2.15,  -2.40,  -0.60,  -0.70,   3.30,   0.84,   0.00,
+       -3.10,  -3.10,   0.00,  -0.72,  -0.32,   0.40,  -1.87,  -2.50,
+        1.87,  -2.50,   0.32,   0.40,  -0.24,   0.30,  -1.87,  -2.50,
+       -0.24,  -0.30,   1.87,  -2.50,  -2.70,   0.00,   1.55,   2.03,
+        2.20,  -2.98,  -1.99,  -2.20,   0.12,  -0.10,  -0.40,   0.50,
+        1.59,   2.10,   0.00,   0.00,  -1.79,   2.00,  -1.03,   1.40,
+       -1.15,  -1.60,   0.32,   0.50,   1.39,  -1.90,   2.35,  -1.27,
+        1.70,   0.60,   0.80,  -0.32,  -0.40,   1.35,  -1.80,   0.44,
+        0.00,   2.23,  -0.84,   0.90,  -1.27,  -1.40,  -1.47,   1.60,
+       -0.28,  -0.30,  -0.28,   0.40,  -1.27,  -1.70,   0.28,  -0.40,
+       -1.43,  -1.50,   0.00,   0.00,  -1.27,  -1.70,   2.11,  -0.32,
+       -0.40,  -1.23,   1.60,   1.19,  -1.30,  -0.72,  -0.80,   0.72,
+
+   /* 3284-3411 */
+       -0.80,  -1.15,  -1.30,  -1.35,  -1.50,  -1.19,  -1.60,  -0.12,
+        0.20,   1.79,   0.00,  -0.88,  -0.28,   0.40,   1.11,   1.50,
+       -1.83,   0.00,   0.56,  -0.12,   0.10,  -1.27,  -1.40,   0.00,
+        0.00,   1.15,   1.50,  -0.12,   0.20,   1.11,   1.50,   0.36,
+       -0.50,  -1.07,  -1.40,  -1.11,   1.50,   1.67,   0.00,   0.80,
+       -1.11,   0.00,   1.43,   1.23,  -1.30,  -0.24,  -1.19,  -1.30,
+       -0.24,   0.20,  -0.44,  -0.90,  -0.95,   1.10,   1.07,  -1.40,
+        1.15,  -1.30,   1.03,  -1.10,  -0.56,  -0.60,  -0.68,   0.90,
+       -0.76,  -1.00,  -0.24,  -0.30,   0.95,  -1.30,   0.56,   0.70,
+        0.84,  -1.10,  -0.56,   0.00,  -1.55,   0.91,  -1.30,   0.28,
+        0.30,   0.16,  -0.20,   0.95,   1.30,   0.40,  -0.50,  -0.88,
+       -1.20,   0.95,  -1.10,  -0.48,  -0.50,   0.00,   0.00,  -1.07,
+        1.20,   0.44,  -0.50,   0.95,   1.10,   0.00,   0.00,   0.92,
+       -1.30,   0.95,   1.00,  -0.52,   0.60,   1.59,   0.24,  -0.40,
+        0.91,   1.20,   0.84,  -1.10,  -0.44,  -0.60,   0.84,   1.10,
+       -0.44,   0.60,  -0.44,   0.60,  -0.84,  -1.10,  -0.80,   0.00,
+
+   /* 3412-3539 */
+        1.35,   0.76,   0.20,  -0.91,  -1.00,   0.20,  -0.30,  -0.91,
+       -1.20,  -0.95,   1.00,  -0.48,  -0.50,   0.88,   1.00,   0.48,
+       -0.50,  -0.95,  -1.10,   0.20,  -0.20,  -0.99,   1.10,  -0.84,
+        1.10,  -0.24,  -0.30,   0.20,  -0.30,   0.84,   1.10,  -1.39,
+        0.00,  -0.28,  -0.16,   0.20,   0.84,   1.10,   0.00,   0.00,
+        1.39,   0.00,   0.00,  -0.95,   1.00,   1.35,  -0.99,   0.00,
+        0.88,  -0.52,   0.00,  -1.19,   0.20,   0.20,   0.76,  -1.00,
+        0.00,   0.00,   0.76,   1.00,   0.00,   0.00,   0.76,   1.00,
+       -0.76,   1.00,   0.00,   0.00,   1.23,   0.76,   0.80,  -0.32,
+        0.40,  -0.72,   0.80,  -0.40,  -0.40,   0.00,   0.00,  -0.80,
+       -0.90,  -0.68,   0.90,  -0.16,  -0.20,  -0.16,  -0.20,   0.68,
+       -0.90,  -0.36,   0.50,  -0.56,  -0.80,   0.72,  -0.90,   0.44,
+       -0.60,  -0.48,  -0.70,  -0.16,   0.00,  -1.11,   0.32,   0.00,
+       -1.07,   0.60,  -0.80,  -0.28,  -0.40,  -0.64,   0.00,   0.91,
+        1.11,   0.64,  -0.90,   0.76,  -0.80,   0.00,   0.00,  -0.76,
+       -0.80,   1.03,   0.00,  -0.36,  -0.64,  -0.70,   0.36,  -0.40,
+
+   /* 3540-3667 */
+        1.07,   0.36,  -0.50,  -0.52,  -0.70,   0.60,   0.00,   0.88,
+        0.95,   0.00,   0.48,   0.16,  -0.20,   0.60,   0.80,   0.16,
+       -0.20,  -0.60,  -0.80,   0.00,  -1.00,   0.12,   0.20,   0.16,
+       -0.20,   0.68,   0.70,   0.59,  -0.80,  -0.99,  -0.56,  -0.60,
+        0.36,  -0.40,  -0.68,  -0.70,  -0.68,  -0.70,  -0.36,  -0.50,
+       -0.44,   0.60,   0.64,   0.70,  -0.12,   0.10,  -0.52,   0.60,
+        0.36,   0.40,   0.00,   0.00,   0.95,  -0.84,   0.00,   0.44,
+        0.56,   0.60,   0.32,  -0.30,   0.00,   0.00,   0.60,   0.70,
+        0.00,   0.00,   0.60,   0.70,  -0.12,  -0.20,   0.52,  -0.70,
+        0.00,   0.00,   0.56,   0.70,  -0.12,   0.10,  -0.52,  -0.70,
+        0.00,   0.00,   0.88,  -0.76,   0.00,  -0.44,   0.00,   0.00,
+       -0.52,  -0.70,   0.52,  -0.70,   0.36,  -0.40,  -0.44,  -0.50,
+        0.00,   0.00,   0.60,   0.60,   0.84,   0.00,   0.12,  -0.24,
+        0.00,   0.80,  -0.56,   0.60,  -0.32,  -0.30,   0.48,  -0.50,
+        0.28,  -0.30,  -0.48,  -0.50,   0.12,   0.20,   0.48,  -0.60,
+        0.48,   0.60,  -0.12,   0.20,   0.24,   0.00,   0.76,  -0.52,
+
+   /* 3668-3795 */
+       -0.60,  -0.52,   0.60,   0.48,  -0.50,  -0.24,  -0.30,   0.12,
+       -0.10,   0.48,   0.60,   0.52,  -0.20,   0.36,   0.40,  -0.44,
+        0.50,  -0.24,  -0.30,  -0.48,  -0.60,  -0.44,  -0.60,  -0.12,
+        0.10,   0.76,   0.76,   0.20,  -0.20,   0.48,   0.50,   0.40,
+       -0.50,  -0.24,  -0.30,   0.44,  -0.60,   0.44,  -0.60,   0.36,
+        0.00,  -0.64,   0.72,   0.00,  -0.12,   0.00,  -0.10,  -0.40,
+       -0.60,  -0.20,  -0.20,  -0.44,   0.50,  -0.44,   0.50,   0.20,
+        0.20,  -0.44,  -0.50,   0.20,  -0.20,  -0.20,   0.20,  -0.44,
+       -0.50,   0.64,   0.00,   0.32,  -0.36,   0.50,  -0.20,  -0.30,
+        0.12,  -0.10,   0.48,   0.50,  -0.12,   0.30,  -0.36,  -0.50,
+        0.00,   0.00,   0.48,   0.50,  -0.48,   0.50,   0.68,   0.00,
+       -0.12,   0.56,  -0.40,   0.44,  -0.50,  -0.12,  -0.10,   0.24,
+        0.30,  -0.40,   0.40,   0.64,   0.00,  -0.24,   0.64,   0.00,
+       -0.20,   0.00,   0.00,   0.44,  -0.50,   0.44,   0.50,  -0.12,
+        0.20,  -0.36,  -0.50,   0.12,   0.00,   0.64,  -0.40,   0.50,
+        0.00,   0.10,   0.00,   0.00,  -0.40,   0.50,   0.00,   0.00,
+
+   /* 3796-3923 */
+       -0.40,  -0.50,   0.56,   0.00,   0.28,   0.00,   0.10,   0.36,
+        0.50,   0.00,  -0.10,   0.36,  -0.50,   0.36,   0.50,   0.00,
+       -0.10,   0.24,  -0.20,  -0.36,  -0.40,   0.16,   0.20,   0.40,
+       -0.40,   0.00,   0.00,  -0.36,  -0.50,  -0.36,  -0.50,  -0.32,
+       -0.50,  -0.12,   0.10,   0.20,   0.20,  -0.36,   0.40,  -0.60,
+        0.60,   0.28,   0.00,   0.52,   0.12,  -0.10,   0.40,   0.40,
+        0.00,  -0.50,   0.20,  -0.20,  -0.32,   0.40,   0.16,   0.20,
+       -0.16,   0.20,   0.32,   0.40,   0.56,   0.00,  -0.12,   0.32,
+       -0.40,  -0.16,  -0.20,   0.00,   0.00,   0.40,   0.40,  -0.40,
+       -0.40,  -0.40,   0.40,  -0.36,   0.40,   0.12,   0.10,   0.00,
+        0.10,   0.36,   0.40,   0.00,  -0.10,   0.36,   0.40,  -0.36,
+        0.40,   0.00,   0.10,   0.32,   0.00,   0.44,   0.12,   0.20,
+        0.28,  -0.40,   0.00,   0.00,   0.36,   0.40,   0.32,  -0.40,
+       -0.16,   0.12,   0.10,   0.32,  -0.40,   0.20,   0.30,  -0.24,
+        0.30,   0.00,   0.10,   0.32,   0.40,   0.00,  -0.10,  -0.32,
+       -0.40,  -0.32,   0.40,   0.00,   0.10,  -0.52,  -0.52,   0.52,
+
+   /* 3924-4051 */
+        0.32,  -0.40,   0.00,   0.00,   0.32,   0.40,   0.32,  -0.40,
+        0.00,   0.00,  -0.32,  -0.40,  -0.32,   0.40,   0.32,   0.40,
+        0.00,   0.00,   0.32,   0.40,   0.00,   0.00,  -0.32,  -0.40,
+        0.00,   0.00,   0.32,   0.40,   0.16,   0.20,   0.32,  -0.30,
+       -0.16,   0.00,  -0.48,  -0.20,   0.20,  -0.28,  -0.30,   0.28,
+       -0.40,   0.00,   0.00,   0.28,  -0.40,   0.00,   0.00,   0.28,
+       -0.40,   0.00,   0.00,  -0.28,  -0.40,   0.28,   0.40,  -0.28,
+       -0.40,  -0.48,  -0.20,   0.20,   0.24,   0.30,   0.44,   0.00,
+        0.16,   0.24,   0.30,   0.16,  -0.20,   0.24,   0.30,  -0.12,
+        0.20,   0.20,   0.30,  -0.16,   0.20,   0.00,   0.00,   0.44,
+       -0.32,   0.30,   0.24,   0.00,  -0.36,   0.36,   0.00,   0.24,
+        0.12,  -0.20,   0.20,   0.30,  -0.12,   0.00,  -0.28,   0.30,
+       -0.24,   0.30,   0.12,   0.10,  -0.28,  -0.30,  -0.28,   0.30,
+        0.00,   0.00,  -0.28,  -0.30,   0.00,   0.00,  -0.28,  -0.30,
+        0.00,   0.00,   0.28,   0.30,   0.00,   0.00,  -0.28,  -0.30,
+       -0.28,   0.30,   0.00,   0.00,  -0.28,  -0.30,   0.00,   0.00,
+
+   /* 4052-4179 */
+        0.28,   0.30,   0.00,   0.00,  -0.28,   0.30,   0.28,  -0.30,
+       -0.28,   0.30,   0.40,   0.40,  -0.24,   0.30,   0.00,  -0.10,
+        0.16,   0.00,   0.36,  -0.20,   0.30,  -0.12,  -0.10,  -0.24,
+       -0.30,   0.00,   0.00,  -0.24,   0.30,  -0.24,   0.30,   0.00,
+        0.00,  -0.24,   0.30,  -0.24,   0.30,   0.24,  -0.30,   0.00,
+        0.00,   0.24,  -0.30,   0.00,   0.00,   0.24,   0.30,   0.24,
+       -0.30,   0.24,   0.30,  -0.24,   0.30,  -0.24,   0.30,  -0.20,
+        0.20,  -0.16,  -0.20,   0.00,   0.00,  -0.32,   0.20,   0.00,
+        0.10,   0.20,  -0.30,   0.20,  -0.20,   0.12,   0.20,  -0.16,
+        0.20,   0.16,   0.20,   0.20,   0.30,   0.20,   0.30,   0.00,
+        0.00,  -0.20,   0.30,   0.00,   0.00,   0.20,   0.30,  -0.20,
+       -0.30,  -0.20,  -0.30,   0.20,  -0.30,   0.00,   0.00,   0.20,
+        0.30,   0.00,   0.00,   0.20,   0.30,   0.00,   0.00,   0.20,
+        0.30,   0.00,   0.00,   0.20,   0.30,   0.00,   0.00,   0.20,
+       -0.30,   0.00,   0.00,  -0.20,  -0.30,   0.00,   0.00,  -0.20,
+        0.30,   0.00,   0.00,  -0.20,   0.30,   0.00,   0.00,   0.36,
+
+   /* 4180-4307 */
+        0.00,   0.00,   0.36,   0.12,   0.10,  -0.24,   0.20,   0.12,
+       -0.20,  -0.16,  -0.20,  -0.13,   0.10,   0.22,   0.21,   0.20,
+        0.00,  -0.28,   0.32,   0.00,  -0.12,  -0.20,  -0.20,   0.12,
+       -0.10,   0.12,   0.10,  -0.20,   0.20,   0.00,   0.00,  -0.32,
+        0.32,   0.00,   0.00,   0.32,   0.32,   0.00,   0.00,  -0.24,
+       -0.20,   0.24,   0.20,   0.20,   0.00,  -0.24,   0.00,   0.00,
+       -0.24,  -0.20,   0.00,   0.00,   0.24,   0.20,  -0.24,  -0.20,
+        0.00,   0.00,  -0.24,   0.20,   0.16,  -0.20,   0.12,   0.10,
+        0.20,   0.20,   0.00,  -0.10,  -0.12,   0.10,  -0.16,  -0.20,
+       -0.12,  -0.10,  -0.16,   0.20,   0.20,   0.20,   0.00,   0.00,
+       -0.20,   0.20,  -0.20,   0.20,  -0.20,   0.20,  -0.20,   0.20,
+        0.20,  -0.20,  -0.20,  -0.20,   0.00,   0.00,  -0.20,   0.20,
+        0.20,   0.00,  -0.20,   0.00,   0.00,  -0.20,   0.20,  -0.20,
+        0.20,  -0.20,  -0.20,  -0.20,  -0.20,   0.00,   0.00,   0.20,
+        0.20,   0.20,   0.20,   0.12,  -0.20,  -0.12,  -0.10,   0.28,
+       -0.28,   0.16,  -0.20,   0.00,  -0.10,   0.00,   0.10,  -0.16,
+
+   /* 4308-4435 */
+        0.20,   0.00,  -0.10,  -0.16,  -0.20,   0.00,  -0.10,   0.16,
+       -0.20,   0.16,  -0.20,   0.00,   0.00,   0.16,   0.20,  -0.16,
+        0.20,   0.00,   0.00,   0.16,   0.20,   0.16,  -0.20,   0.16,
+       -0.20,  -0.16,   0.20,   0.16,  -0.20,   0.00,   0.00,   0.16,
+        0.20,   0.00,   0.00,   0.16,   0.20,   0.00,   0.00,  -0.16,
+       -0.20,   0.16,  -0.20,  -0.16,  -0.20,   0.00,   0.00,  -0.16,
+       -0.20,   0.00,   0.00,  -0.16,   0.20,   0.00,   0.00,   0.16,
+       -0.20,   0.16,   0.20,   0.16,   0.20,   0.00,   0.00,  -0.16,
+       -0.20,   0.00,   0.00,  -0.16,  -0.20,   0.00,   0.00,   0.16,
+        0.20,   0.16,   0.20,   0.00,   0.00,   0.16,   0.20,   0.16,
+       -0.20,   0.16,   0.20,   0.00,   0.00,  -0.16,   0.20,   0.00,
+        0.10,   0.12,  -0.20,   0.12,  -0.20,   0.00,  -0.10,   0.00,
+       -0.10,   0.12,   0.20,   0.00,  -0.10,  -0.12,   0.20,  -0.15,
+        0.20,  -0.24,   0.24,   0.00,   0.00,   0.24,   0.24,   0.12,
+       -0.20,  -0.12,  -0.20,   0.00,   0.00,   0.12,   0.20,   0.12,
+       -0.20,   0.12,   0.20,   0.12,   0.20,   0.12,   0.20,   0.12,
+
+   /* 4436-4563 */
+       -0.20,  -0.12,   0.20,   0.00,   0.00,   0.12,   0.20,   0.12,
+        0.00,  -0.20,   0.00,   0.00,  -0.12,  -0.20,   0.12,  -0.20,
+        0.00,   0.00,   0.12,   0.20,  -0.12,   0.20,  -0.12,   0.20,
+        0.12,  -0.20,   0.00,   0.00,   0.12,   0.20,   0.20,   0.00,
+        0.12,   0.00,   0.00,  -0.12,   0.20,   0.00,   0.00,  -0.12,
+       -0.20,   0.00,   0.00,  -0.12,  -0.20,  -0.12,  -0.20,   0.00,
+        0.00,   0.12,  -0.20,   0.12,  -0.20,   0.12,   0.20,  -0.12,
+       -0.20,   0.00,   0.00,   0.12,  -0.20,   0.12,  -0.20,   0.12,
+        0.20,   0.12,   0.00,   0.20,  -0.12,  -0.20,   0.00,   0.00,
+        0.12,   0.20,  -0.16,   0.00,   0.16,  -0.20,   0.20,   0.00,
+        0.00,  -0.20,   0.00,   0.00,  -0.20,   0.20,   0.00,   0.00,
+        0.20,   0.20,  -0.20,   0.00,   0.00,  -0.20,   0.12,   0.00,
+       -0.16,   0.20,   0.00,   0.00,   0.20,   0.12,  -0.10,   0.00,
+        0.10,   0.16,  -0.16,  -0.16,  -0.16,  -0.16,  -0.16,   0.00,
+        0.00,  -0.16,   0.00,   0.00,  -0.16,  -0.16,  -0.16,   0.00,
+        0.00,  -0.16,   0.00,   0.00,   0.16,   0.00,   0.00,   0.16,
+
+   /* 4564-4691 */
+        0.00,   0.00,   0.16,   0.16,   0.00,   0.00,  -0.16,   0.00,
+        0.00,  -0.16,  -0.16,   0.00,   0.00,   0.16,   0.00,   0.00,
+       -0.16,  -0.16,   0.00,   0.00,  -0.16,  -0.16,   0.12,   0.10,
+        0.12,  -0.10,   0.12,   0.10,   0.00,   0.00,   0.12,   0.10,
+       -0.12,   0.10,   0.00,   0.00,   0.12,   0.10,   0.12,  -0.10,
+        0.00,   0.00,  -0.12,  -0.10,   0.00,   0.00,   0.12,   0.10,
+        0.12,   0.00,   0.00,   0.12,   0.00,   0.00,  -0.12,   0.00,
+        0.00,   0.12,   0.12,   0.12,   0.12,   0.12,   0.00,   0.00,
+        0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,   0.12,
+        0.00,   0.00,   0.12,  -0.12,  -0.12,   0.12,   0.12,  -0.12,
+       -0.12,   0.00,   0.00,   0.12,  -0.12,   0.12,   0.12,  -0.12,
+       -0.12,   0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
+        0.12,   0.00,   0.00,   0.12,   0.00,   0.00,   0.12,   0.00,
+        0.00,   0.12,  -0.12,   0.00,   0.00,  -0.12,   0.12,  -0.12,
+       -0.12,   0.12,   0.00,   0.00,   0.12,   0.12,   0.12,  -0.12,
+        0.00,   0.00,  -0.12,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
+
+   /* 4692-NA */
+       -0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,  -0.12,
+       -0.12,  -0.12,  -0.12,   0.12,   0.00,   0.00,   0.12,  -0.12,
+        0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,   0.12,  -0.12,
+       -0.12,  -0.12,  -0.12,   0.12,   0.12,  -0.12,  -0.12,   0.00,
+        0.00,  -0.12,   0.00,   0.00,  -0.12,   0.12,   0.00,   0.00,
+        0.12,   0.00,   0.00,  -0.12,  -0.12,   0.00,   0.00,  -0.12,
+       -0.12,   0.12,   0.00,   0.00,   0.12,   0.12,   0.00,   0.00,
+        0.12,   0.00,   0.00,   0.12,   0.12,   0.08,   0.00,   0.04
+   };
+
+/* Number of amplitude coefficients */
+   static const int NA = (int) (sizeof a / sizeof (double));
+
+/* Amplitude usage: X or Y, sin or cos, power of T. */
+   static const int jaxy[] = {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1};
+   static const int jasc[] = {0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0};
+   static const int japt[] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4};
+
+/* Miscellaneous */
+   double t, w, pt[MAXPT+1], fa[14], xypr[2], xypl[2], xyls[2], arg,
+          sc[2];
+   int jpt, i, j, jxy, ialast, ifreq, m, ia, jsc;
+
+/*--------------------------------------------------------------------*/
+
+/* Interval between fundamental date J2000.0 and given date (JC). */
+   t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
+
+/* Powers of T. */
+   w = 1.0;
+   for (jpt = 0; jpt <= MAXPT; jpt++) {
+      pt[jpt] = w;
+      w *= t;
+   }
+
+/* Initialize totals in X and Y:  polynomial, luni-solar, planetary. */
+   for (jxy = 0; jxy < 2; jxy++) {
+      xypr[jxy] = 0.0;
+      xyls[jxy] = 0.0;
+      xypl[jxy] = 0.0;
+   }
+
+/* --------------------------------- */
+/* Fundamental arguments (IERS 2003) */
+/* --------------------------------- */
+
+/* Mean anomaly of the Moon. */
+   fa[0] = eraFal03(t);
+
+/* Mean anomaly of the Sun. */
+   fa[1] = eraFalp03(t);
+
+/* Mean argument of the latitude of the Moon. */
+   fa[2] = eraFaf03(t);
+
+/* Mean elongation of the Moon from the Sun. */
+   fa[3] = eraFad03(t);
+
+/* Mean longitude of the ascending node of the Moon. */
+   fa[4] = eraFaom03(t);
+
+/* Planetary longitudes, Mercury through Neptune. */
+   fa[5] = eraFame03(t);
+   fa[6] = eraFave03(t);
+   fa[7] = eraFae03(t);
+   fa[8] = eraFama03(t);
+   fa[9] = eraFaju03(t);
+   fa[10] = eraFasa03(t);
+   fa[11] = eraFaur03(t);
+   fa[12] = eraFane03(t);
+
+/* General accumulated precession in longitude. */
+   fa[13] = eraFapa03(t);
+
+/* -------------------------------------- */
+/* Polynomial part of precession-nutation */
+/* -------------------------------------- */
+
+   for (jxy = 0; jxy < 2; jxy++) {
+      for (j = MAXPT; j >= 0; j--) {
+         xypr[jxy] += xyp[jxy][j] * pt[j];
+      }
+   }
+
+/* ---------------------------------- */
+/* Nutation periodic terms, planetary */
+/* ---------------------------------- */
+
+/* Work backwards through the coefficients per frequency list. */
+   ialast = NA;
+   for (ifreq = NFPL-1; ifreq >= 0; ifreq--) {
+
+   /* Obtain the argument functions. */
+      arg = 0.0;
+      for (i = 0; i < 14; i++) {
+         m = mfapl[ifreq][i];
+         if (m != 0) arg += (double)m * fa[i];
+      }
+      sc[0] = sin(arg);
+      sc[1] = cos(arg);
+
+   /* Work backwards through the amplitudes at this frequency. */
+      ia = nc[ifreq+NFLS];
+      for (i = ialast; i >= ia; i--) {
+
+      /* Coefficient number (0 = 1st). */
+         j = i-ia;
+
+      /* X or Y. */
+         jxy = jaxy[j];
+
+      /* Sin or cos. */
+         jsc = jasc[j];
+
+      /* Power of T. */
+         jpt = japt[j];
+
+      /* Accumulate the component. */
+         xypl[jxy] += a[i-1] * sc[jsc] * pt[jpt];
+      }
+      ialast = ia-1;
+   }
+
+/* ----------------------------------- */
+/* Nutation periodic terms, luni-solar */
+/* ----------------------------------- */
+
+/* Continue working backwards through the number of coefficients list. */
+   for (ifreq = NFLS-1; ifreq >= 0; ifreq--) {
+
+   /* Obtain the argument functions. */
+      arg = 0.0;
+      for (i = 0; i < 5; i++) {
+         m = mfals[ifreq][i];
+         if (m != 0) arg += (double)m * fa[i];
+      }
+      sc[0] = sin(arg);
+      sc[1] = cos(arg);
+
+   /* Work backwards through the amplitudes at this frequency. */
+      ia = nc[ifreq];
+      for (i = ialast; i >= ia; i--) {
+
+      /* Coefficient number (0 = 1st). */
+         j = i-ia;
+
+      /* X or Y. */
+         jxy = jaxy[j];
+
+      /* Sin or cos. */
+         jsc = jasc[j];
+
+      /* Power of T. */
+         jpt = japt[j];
+
+      /* Accumulate the component. */
+         xyls[jxy] += a[i-1] * sc[jsc] * pt[jpt];
+      }
+      ialast = ia-1;
+   }
+
+/* ------------------------------------ */
+/* Results:  CIP unit vector components */
+/* ------------------------------------ */
+
+   *x = ERFA_DAS2R * (xypr[0] + (xyls[0] + xypl[0]) / 1e6);
+   *y = ERFA_DAS2R * (xypr[1] + (xyls[1] + xypl[1]) / 1e6);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/xys00a.c b/cextern/erfa/xys00a.c
new file mode 100644
index 0000000..411627e
--- /dev/null
+++ b/cextern/erfa/xys00a.c
@@ -0,0 +1,142 @@
+#include "erfa.h"
+
+void eraXys00a(double date1, double date2,
+               double *x, double *y, double *s)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3];
+
+
+/* Form the bias-precession-nutation matrix, IAU 2000A. */
+   eraPnm00a(date1, date2, rbpn);
+
+/* Extract X,Y. */
+   eraBpn2xy(rbpn, x, y);
+
+/* Obtain s. */
+   *s = eraS00(date1, date2, *x, *y);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/xys00b.c b/cextern/erfa/xys00b.c
new file mode 100644
index 0000000..12bf0dc
--- /dev/null
+++ b/cextern/erfa/xys00b.c
@@ -0,0 +1,142 @@
+#include "erfa.h"
+
+void eraXys00b(double date1, double date2,
+               double *x, double *y, double *s)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3];
+
+
+/* Form the bias-precession-nutation matrix, IAU 2000A. */
+   eraPnm00b(date1, date2, rbpn);
+
+/* Extract X,Y. */
+   eraBpn2xy(rbpn, x, y);
+
+/* Obtain s. */
+   *s = eraS00(date1, date2, *x, *y);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/xys06a.c b/cextern/erfa/xys06a.c
new file mode 100644
index 0000000..8c3b3d8
--- /dev/null
+++ b/cextern/erfa/xys06a.c
@@ -0,0 +1,142 @@
+#include "erfa.h"
+
+void eraXys06a(double date1, double date2,
+               double *x, double *y, double *s)
+/*
+**  - - - - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   double rbpn[3][3];
+
+
+/* Form the bias-precession-nutation matrix, IAU 2006/2000A. */
+   eraPnm06a(date1, date2, rbpn);
+
+/* Extract X,Y. */
+   eraBpn2xy(rbpn, x, y);
+
+/* Obtain s. */
+   *s = eraS06(date1, date2, *x, *y);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/zp.c b/cextern/erfa/zp.c
new file mode 100644
index 0000000..37e8cc6
--- /dev/null
+++ b/cextern/erfa/zp.c
@@ -0,0 +1,86 @@
+#include "erfa.h"
+
+void eraZp(double p[3])
+/*
+**  - - - - - -
+**   e r a Z p
+**  - - - - - -
+**
+**  Zero a p-vector.
+**
+**  Returned:
+**     p        double[3]      p-vector
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   p[0] = 0.0;
+   p[1] = 0.0;
+   p[2] = 0.0;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/zpv.c b/cextern/erfa/zpv.c
new file mode 100644
index 0000000..2592f60
--- /dev/null
+++ b/cextern/erfa/zpv.c
@@ -0,0 +1,88 @@
+#include "erfa.h"
+
+void eraZpv(double pv[2][3])
+/*
+**  - - - - - - -
+**   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-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   eraZp(pv[0]);
+   eraZp(pv[1]);
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/erfa/zr.c b/cextern/erfa/zr.c
new file mode 100644
index 0000000..6fc8b24
--- /dev/null
+++ b/cextern/erfa/zr.c
@@ -0,0 +1,92 @@
+#include "erfa.h"
+
+void eraZr(double r[3][3])
+/*
+**  - - - - - -
+**   e r a Z r
+**  - - - - - -
+**
+**  Initialize an r-matrix to the null matrix.
+**
+**  Returned:
+**     r        double[3][3]    r-matrix
+**
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  Derived, with permission, from the SOFA library.  See notes at end of file.
+*/
+{
+   r[0][0] = 0.0;
+   r[0][1] = 0.0;
+   r[0][2] = 0.0;
+   r[1][0] = 0.0;
+   r[1][1] = 0.0;
+   r[1][2] = 0.0;
+   r[2][0] = 0.0;
+   r[2][1] = 0.0;
+   r[2][2] = 0.0;
+
+   return;
+
+}
+/*----------------------------------------------------------------------
+**  
+**  
+**  Copyright (C) 2013-2014, NumFOCUS Foundation.
+**  All rights reserved.
+**  
+**  This library is derived, with permission, from the International
+**  Astronomical Union's "Standards of Fundamental Astronomy" library,
+**  available from http://www.iausofa.org.
+**  
+**  The ERFA version is intended to retain identical functionality to
+**  the SOFA library, but made distinct through different function and
+**  file names, as set out in the SOFA license conditions.  The SOFA
+**  original has a role as a reference standard for the IAU and IERS,
+**  and consequently redistribution is permitted only in its unaltered
+**  state.  The ERFA version is not subject to this restriction and
+**  therefore can be included in distributions which do not support the
+**  concept of "read only" software.
+**  
+**  Although the intent is to replicate the SOFA API (other than
+**  replacement of prefix names) and results (with the exception of
+**  bugs;  any that are discovered will be fixed), SOFA is not
+**  responsible for any errors found in this version of the library.
+**  
+**  If you wish to acknowledge the SOFA heritage, please acknowledge
+**  that you are using a library derived from SOFA, rather than SOFA
+**  itself.
+**  
+**  
+**  TERMS AND CONDITIONS
+**  
+**  Redistribution and use in source and binary forms, with or without
+**  modification, are permitted provided that the following conditions
+**  are met:
+**  
+**  1 Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+**  
+**  2 Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in
+**    the documentation and/or other materials provided with the
+**    distribution.
+**  
+**  3 Neither the name of the Standards Of Fundamental Astronomy Board,
+**    the International Astronomical Union nor the names of its
+**    contributors may be used to endorse or promote products derived
+**    from this software without specific prior written permission.
+**  
+**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+**  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+**  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+**  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+**  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+**  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+**  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+**  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+**  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+**  POSSIBILITY OF SUCH DAMAGE.
+**  
+*/
diff --git a/cextern/wcslib/C/GNUmakefile b/cextern/wcslib/C/GNUmakefile
index 74d04ef..3a48f92 100644
--- a/cextern/wcslib/C/GNUmakefile
+++ b/cextern/wcslib/C/GNUmakefile
@@ -1,5 +1,5 @@
 #-----------------------------------------------------------------------------
-# GNU makefile for building WCSLIB 4.23 and its test suite.
+# GNU makefile for building WCSLIB 4.25 and its test suite.
 #
 # Summary of the main targets
 # ---------------------------
@@ -31,7 +31,7 @@
 #
 # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 # http://www.atnf.csiro.au/people/Mark.Calabretta
-# $Id: GNUmakefile,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+# $Id: GNUmakefile,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 #-----------------------------------------------------------------------------
 # Get configure settings.
 include ../makedefs
diff --git a/cextern/wcslib/C/cel.c b/cextern/wcslib/C/cel.c
index 86460d5..04749aa 100644
--- a/cextern/wcslib/C/cel.c
+++ b/cextern/wcslib/C/cel.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: cel.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: cel.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/cel.h b/cextern/wcslib/C/cel.h
index 054422a..e2bd3d5 100644
--- a/cextern/wcslib/C/cel.h
+++ b/cextern/wcslib/C/cel.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: cel.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: cel.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/fitshdr.h b/cextern/wcslib/C/fitshdr.h
index e1f8a05..00c7058 100644
--- a/cextern/wcslib/C/fitshdr.h
+++ b/cextern/wcslib/C/fitshdr.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: fitshdr.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: fitshdr.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * The Flexible Image Transport System (FITS), a data format widely used in
diff --git a/cextern/wcslib/C/fitshdr.l b/cextern/wcslib/C/fitshdr.l
index 1d7f46d..edec506 100644
--- a/cextern/wcslib/C/fitshdr.l
+++ b/cextern/wcslib/C/fitshdr.l
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: fitshdr.l,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: fitshdr.l,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * fitshdr.l is a Flex description file containing a lexical scanner
diff --git a/cextern/wcslib/C/flexed/fitshdr.c b/cextern/wcslib/C/flexed/fitshdr.c
index f4976c9..26f27c9 100644
--- a/cextern/wcslib/C/flexed/fitshdr.c
+++ b/cextern/wcslib/C/flexed/fitshdr.c
@@ -10083,7 +10083,7 @@ char *fitshdrtext;
 #line 1 "fitshdr.l"
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -10105,7 +10105,7 @@ char *fitshdrtext;
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: fitshdr.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: fitshdr.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * fitshdr.l is a Flex description file containing a lexical scanner
diff --git a/cextern/wcslib/C/flexed/wcsbth.c b/cextern/wcslib/C/flexed/wcsbth.c
index 24ab9b3..86eb75b 100644
--- a/cextern/wcslib/C/flexed/wcsbth.c
+++ b/cextern/wcslib/C/flexed/wcsbth.c
@@ -16669,7 +16669,7 @@ char *wcsbthtext;
 #line 1 "wcsbth.l"
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -16691,7 +16691,7 @@ char *wcsbthtext;
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsbth.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsbth.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsbth.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/C/flexed/wcspih.c b/cextern/wcslib/C/flexed/wcspih.c
index 994b4df..addb5f4 100644
--- a/cextern/wcslib/C/flexed/wcspih.c
+++ b/cextern/wcslib/C/flexed/wcspih.c
@@ -8153,7 +8153,7 @@ char *wcspihtext;
 #line 1 "wcspih.l"
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -8175,7 +8175,7 @@ char *wcspihtext;
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcspih.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcspih.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcspih.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/C/flexed/wcsulex.c b/cextern/wcslib/C/flexed/wcsulex.c
index 7b5d3b3..2210498 100644
--- a/cextern/wcslib/C/flexed/wcsulex.c
+++ b/cextern/wcslib/C/flexed/wcsulex.c
@@ -6860,7 +6860,7 @@ char *wcsulextext;
 #line 1 "wcsulex.l"
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -6882,7 +6882,7 @@ char *wcsulextext;
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsulex.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsulex.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsulex.l is a Flex description file containing the definition of a
diff --git a/cextern/wcslib/C/flexed/wcsutrn.c b/cextern/wcslib/C/flexed/wcsutrn.c
index 166c45a..578e2fc 100644
--- a/cextern/wcslib/C/flexed/wcsutrn.c
+++ b/cextern/wcslib/C/flexed/wcsutrn.c
@@ -3982,7 +3982,7 @@ char *wcsutrntext;
 #line 1 "wcsutrn.l"
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -4004,7 +4004,7 @@ char *wcsutrntext;
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsutrn.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsutrn.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsutrn.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/C/getwcstab.c b/cextern/wcslib/C/getwcstab.c
index fd152d5..d9a72ef 100644
--- a/cextern/wcslib/C/getwcstab.c
+++ b/cextern/wcslib/C/getwcstab.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: getwcstab.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: getwcstab.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <stdlib.h>
diff --git a/cextern/wcslib/C/getwcstab.h b/cextern/wcslib/C/getwcstab.h
index 175e014..130917d 100644
--- a/cextern/wcslib/C/getwcstab.h
+++ b/cextern/wcslib/C/getwcstab.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: getwcstab.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: getwcstab.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of the getwcstab routines
diff --git a/cextern/wcslib/C/lin.c b/cextern/wcslib/C/lin.c
index 513088c..09a85b4 100644
--- a/cextern/wcslib/C/lin.c
+++ b/cextern/wcslib/C/lin.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: lin.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: lin.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <stdio.h>
diff --git a/cextern/wcslib/C/lin.h b/cextern/wcslib/C/lin.h
index b278ea6..0eff754 100644
--- a/cextern/wcslib/C/lin.h
+++ b/cextern/wcslib/C/lin.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: lin.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: lin.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/log.c b/cextern/wcslib/C/log.c
index 29e5837..2428077 100644
--- a/cextern/wcslib/C/log.c
+++ b/cextern/wcslib/C/log.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: log.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: log.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/log.h b/cextern/wcslib/C/log.h
index d5545a9..0b05780 100644
--- a/cextern/wcslib/C/log.h
+++ b/cextern/wcslib/C/log.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: log.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: log.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement logarithmic coordinate systems as
+* WCSLIB 4.25 - C routines that implement logarithmic coordinate systems as
 * defined by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/prj.c b/cextern/wcslib/C/prj.c
index 796ece1..45d0250 100644
--- a/cextern/wcslib/C/prj.c
+++ b/cextern/wcslib/C/prj.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: prj.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: prj.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/prj.h b/cextern/wcslib/C/prj.h
index 06cc4e8..5b143f2 100644
--- a/cextern/wcslib/C/prj.h
+++ b/cextern/wcslib/C/prj.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: prj.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: prj.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spherical map projections
+* WCSLIB 4.25 - C routines that implement the spherical map projections
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/spc.c b/cextern/wcslib/C/spc.c
index 971be38..0226d9e 100644
--- a/cextern/wcslib/C/spc.c
+++ b/cextern/wcslib/C/spc.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spc.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spc.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/spc.h b/cextern/wcslib/C/spc.h
index f63e6c8..85f19ee 100644
--- a/cextern/wcslib/C/spc.h
+++ b/cextern/wcslib/C/spc.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spc.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spc.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spectral coordinate systems
+* WCSLIB 4.25 - C routines that implement the spectral coordinate systems
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/sph.c b/cextern/wcslib/C/sph.c
index e1e3683..4c839fd 100644
--- a/cextern/wcslib/C/sph.c
+++ b/cextern/wcslib/C/sph.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: sph.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: sph.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/sph.h b/cextern/wcslib/C/sph.h
index e032438..24c17e0 100644
--- a/cextern/wcslib/C/sph.h
+++ b/cextern/wcslib/C/sph.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: sph.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: sph.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spherical coordinate
+* WCSLIB 4.25 - C routines that implement the spherical coordinate
 * transformations used by the FITS World Coordinate System (WCS) standard.
 * Refer to
 *
diff --git a/cextern/wcslib/C/spx.c b/cextern/wcslib/C/spx.c
index 40ab56e..4b8561e 100644
--- a/cextern/wcslib/C/spx.c
+++ b/cextern/wcslib/C/spx.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spx.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spx.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/spx.h b/cextern/wcslib/C/spx.h
index 0d93978..27d7247 100644
--- a/cextern/wcslib/C/spx.h
+++ b/cextern/wcslib/C/spx.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: spx.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: spx.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the spectral coordinate systems
+* WCSLIB 4.25 - C routines that implement the spectral coordinate systems
 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/tab.c b/cextern/wcslib/C/tab.c
index 3bf16c4..cb33fac 100644
--- a/cextern/wcslib/C/tab.c
+++ b/cextern/wcslib/C/tab.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: tab.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: tab.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
@@ -412,6 +412,7 @@ int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst)
 /*--------------------------------------------------------------------------*/
 
 int tabcmp(int cmp,
+           double tol,
            const struct tabprm *tab1,
            const struct tabprm *tab2,
            int *equal)
@@ -434,20 +435,20 @@ int tabcmp(int cmp,
 
   if (!wcsutil_intEq(M, tab1->K, tab2->K) ||
       !wcsutil_intEq(M, tab1->map, tab2->map) ||
-      !wcsutil_Eq(M, tab1->crval, tab2->crval)) {
+      !wcsutil_Eq(M, tol, tab1->crval, tab2->crval)) {
     return 0;
   }
 
   N = M;
   for (m = 0; m < M; m++) {
-    if (!wcsutil_Eq(tab1->K[m], tab1->index[m], tab2->index[m])) {
+    if (!wcsutil_Eq(tab1->K[m], tol, tab1->index[m], tab2->index[m])) {
       return 0;
     }
 
     N *= tab1->K[m];
   }
 
-  if (!wcsutil_Eq(N, tab1->coord, tab2->coord)) {
+  if (!wcsutil_Eq(N, tol, tab1->coord, tab2->coord)) {
     return 0;
   }
 
diff --git a/cextern/wcslib/C/tab.h b/cextern/wcslib/C/tab.h
index f0531e2..1b55fcc 100644
--- a/cextern/wcslib/C/tab.h
+++ b/cextern/wcslib/C/tab.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: tab.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: tab.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement tabular coordinate systems as
+* WCSLIB 4.25 - C routines that implement tabular coordinate systems as
 * defined by the FITS World Coordinate System (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
@@ -193,6 +193,11 @@
 *                       indicating a strict comparison.  In the future, other
 *                       options may be added.
 *
+*   tol       double    Tolerance for comparison of floating-point values.
+*                       For example, for tol == 1e-6, all floating-point
+*                       values in the structs must be equal to the first 6
+*                       decimal places.  A value of 0 implies exact equality.
+*
 *   tab1      const struct tabprm*
 *                       The first tabprm struct to compare.
 *
@@ -576,8 +581,8 @@ int tabmem(struct tabprm *tab);
 
 int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst);
 
-int tabcmp(int cmp, const struct tabprm *tab1, const struct tabprm *tab2,
-           int *equal);
+int tabcmp(int cmp, double tol, const struct tabprm *tab1,
+           const struct tabprm *tab2, int *equal);
 
 int tabfree(struct tabprm *tab);
 
diff --git a/cextern/wcslib/C/tan.fits b/cextern/wcslib/C/tan.fits
new file mode 100644
index 0000000..3b3ba20
--- /dev/null
+++ b/cextern/wcslib/C/tan.fits
@@ -0,0 +1 @@
+SIMPLE  =                    T / conforms to FITS standard                      BITPIX  =                    8 / array data type                                NAXIS   =                    2                                                  NAXIS1  =                 4256                                                  NAXIS2  =                 2832                                                  CRPIX1  =                 2129 / X reference pixel                              CRPIX2  =    [...]
\ No newline at end of file
diff --git a/cextern/wcslib/C/tan.hdr b/cextern/wcslib/C/tan.hdr
new file mode 100644
index 0000000..93913b7
--- /dev/null
+++ b/cextern/wcslib/C/tan.hdr
@@ -0,0 +1,21 @@
+SIMPLE  =                    T / conforms to FITS standard
+BITPIX  =                    8 / array data type
+NAXIS   =                    2
+NAXIS1  =                 4256
+NAXIS2  =                 2832
+CRPIX1  =                 2129 / X reference pixel
+CRPIX2  =                 1417 / Y reference pixel
+CD1_1   =    -0.00912247310646 / Transformation matrix
+CD1_2   =    -0.00250608809647 / no comment
+CD2_1   =     0.00250608809647 / no comment
+CD2_2   =    -0.00912247310646 / no comment
+CTYPE1  = 'RA---TAN'           / TAN (gnomic) projection
+CTYPE2  = 'DEC--TAN'           / TAN (gnomic) projection
+CRVAL1  =        16.0531567459 / RA  of reference point
+CRVAL2  =        23.1148929108 / DEC of reference point
+CUNIT1  = 'deg     ' / X pixel scale units
+CUNIT2  = 'deg     ' / Y pixel scale units
+EQUINOX =               2000.0 / Equatorial coordinates definition (yr)
+LONPOLE =                180.0 / no comment
+LATPOLE =                  0.0 / no comment
+END
diff --git a/cextern/wcslib/C/wcs.c b/cextern/wcslib/C/wcs.c
index 574a9ad..e2cd2eb 100644
--- a/cextern/wcslib/C/wcs.c
+++ b/cextern/wcslib/C/wcs.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcs.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcs.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
@@ -982,6 +982,7 @@ cleanup:
 
 int wcscompare(
   int cmp,
+  double tol,
   const struct wcsprm *wcs1,
   const struct wcsprm *wcs2,
   int *equal)
@@ -1015,20 +1016,20 @@ int wcscompare(
       }
     }
   } else {
-    if (!wcsutil_Eq(naxis, wcs1->crpix, wcs2->crpix)) {
+    if (!wcsutil_Eq(naxis, tol, wcs1->crpix, wcs2->crpix)) {
       return 0;
     }
   }
 
-  if (!wcsutil_Eq(naxis2, wcs1->pc, wcs2->pc) ||
-      !wcsutil_Eq(naxis, wcs1->cdelt, wcs2->cdelt) ||
-      !wcsutil_Eq(naxis, wcs1->crval, wcs2->crval) ||
+  if (!wcsutil_Eq(naxis2, tol, wcs1->pc, wcs2->pc) ||
+      !wcsutil_Eq(naxis, tol, wcs1->cdelt, wcs2->cdelt) ||
+      !wcsutil_Eq(naxis, tol, wcs1->crval, wcs2->crval) ||
       !wcsutil_strEq(naxis, wcs1->cunit, wcs2->cunit) ||
       !wcsutil_strEq(naxis, wcs1->ctype, wcs2->ctype) ||
-      wcs1->lonpole != wcs2->lonpole ||
-      wcs1->latpole != wcs2->latpole ||
-      wcs1->restfrq != wcs2->restfrq ||
-      wcs1->restwav != wcs2->restwav ||
+      !wcsutil_Eq(1, tol, &wcs1->lonpole, &wcs2->lonpole) ||
+      !wcsutil_Eq(1, tol, &wcs1->latpole, &wcs2->latpole) ||
+      !wcsutil_Eq(1, tol, &wcs1->restfrq, &wcs2->restfrq) ||
+      !wcsutil_Eq(1, tol, &wcs1->restwav, &wcs2->restwav) ||
       wcs1->npv != wcs2->npv ||
       wcs1->nps != wcs2->nps) {
     return 0;
@@ -1039,7 +1040,7 @@ int wcscompare(
     for (j = 0; j < wcs2->npv; ++j) {
       if (wcs1->pv[i].i == wcs2->pv[j].i &&
           wcs1->pv[i].m == wcs2->pv[j].m) {
-        if (wcs1->pv[i].value != wcs2->pv[j].value) {
+        if (!wcsutil_Eq(1, tol, &wcs1->pv[i].value, &wcs2->pv[j].value)) {
           return 0;
         }
         break;
@@ -1069,8 +1070,8 @@ int wcscompare(
   }
 
   if (wcs1->flag != WCSSET || wcs2->flag != WCSSET) {
-    if (!wcsutil_Eq(naxis2, wcs1->cd, wcs2->cd) ||
-        !wcsutil_Eq(naxis, wcs1->crota, wcs2->crota) ||
+    if (!wcsutil_Eq(naxis2, tol, wcs1->cd, wcs2->cd) ||
+        !wcsutil_Eq(naxis, tol, wcs1->crota, wcs2->crota) ||
         wcs1->altlin != wcs2->altlin ||
         wcs1->velref != wcs2->velref) {
       return 0;
@@ -1082,21 +1083,21 @@ int wcscompare(
         wcs1->colnum != wcs2->colnum ||
         !wcsutil_intEq(naxis, wcs1->colax, wcs2->colax) ||
         !wcsutil_strEq(naxis, wcs1->cname, wcs2->cname) ||
-        !wcsutil_Eq(naxis, wcs1->crder, wcs2->crder) ||
-        !wcsutil_Eq(naxis, wcs1->csyer, wcs2->csyer) ||
+        !wcsutil_Eq(naxis, tol, wcs1->crder, wcs2->crder) ||
+        !wcsutil_Eq(naxis, tol, wcs1->csyer, wcs2->csyer) ||
         strncmp(wcs1->dateavg, wcs2->dateavg, 72) ||
         strncmp(wcs1->dateobs, wcs2->dateobs, 72) ||
-        wcs1->equinox != wcs2->equinox ||
-        wcs1->mjdavg != wcs2->mjdavg ||
-        wcs1->mjdobs != wcs2->mjdobs ||
-        !wcsutil_Eq(3, wcs1->obsgeo, wcs2->obsgeo) ||
+        !wcsutil_Eq(1, tol, &wcs1->equinox, &wcs2->equinox) ||
+        !wcsutil_Eq(1, tol, &wcs1->mjdavg, &wcs2->mjdavg) ||
+        !wcsutil_Eq(1, tol, &wcs1->mjdobs, &wcs2->mjdobs) ||
+        !wcsutil_Eq(3, tol, wcs1->obsgeo, wcs2->obsgeo) ||
         strncmp(wcs1->radesys, wcs2->radesys, 72) ||
         strncmp(wcs1->specsys, wcs2->specsys, 72) ||
         strncmp(wcs1->ssysobs, wcs2->ssysobs, 72) ||
-        wcs1->velosys != wcs2->velosys ||
-        wcs1->zsource != wcs2->zsource ||
+        !wcsutil_Eq(1, tol, &wcs1->velosys, &wcs2->velosys) ||
+        !wcsutil_Eq(1, tol, &wcs1->zsource, &wcs2->zsource) ||
         strncmp(wcs1->ssyssrc, wcs2->ssyssrc, 72) ||
-        wcs1->velangl != wcs2->velangl ||
+        !wcsutil_Eq(1, tol, &wcs1->velangl, &wcs2->velangl) ||
         strncmp(wcs1->wcsname, wcs2->wcsname, 72)) {
       return 0;
     }
@@ -1108,7 +1109,7 @@ int wcscompare(
   }
 
   for (i = 0; i < wcs1->ntab; ++i) {
-    if ((status = tabcmp(0, &wcs1->tab[i], &wcs2->tab[i], &tab_equal))) {
+    if ((status = tabcmp(0, tol, &wcs1->tab[i], &wcs2->tab[i], &tab_equal))) {
       return status;
     }
     if (!tab_equal) {
@@ -1873,6 +1874,40 @@ int wcsset(struct wcsprm *wcs)
   }
 
 
+  /* Set defaults for radesys and equinox for equatorial or ecliptic. */
+  if (strcmp(wcs->lngtyp, "RA")   == 0 ||
+      strcmp(wcs->lngtyp, "ELON") == 0 ||
+      strcmp(wcs->lngtyp, "HLON") == 0) {
+    if (wcs->radesys[0] == '\0') {
+      if (undefined(wcs->equinox)) {
+        strcpy(wcs->radesys, "ICRS");
+      } else if (wcs->equinox < 1984.0) {
+        strcpy(wcs->radesys, "FK4");
+      } else {
+        strcpy(wcs->radesys, "FK5");
+      }
+
+    } else if (strcmp(wcs->radesys, "ICRS")  == 0 ||
+               strcmp(wcs->radesys, "GAPPT") == 0) {
+      /* Equinox is not applicable for these coordinate systems. */
+      wcs->equinox = UNDEFINED;
+
+    } else if (undefined(wcs->equinox)) {
+      if (strcmp(wcs->radesys, "FK5") == 0) {
+        wcs->equinox = 2000.0;
+      } else if (strcmp(wcs->radesys, "FK4") == 0 ||
+                 strcmp(wcs->radesys, "FK4-NO-E") == 0) {
+        wcs->equinox = 1950.0;
+      }
+    }
+
+  } else {
+    /* No celestial axes, ensure that radesys and equinox are unset. */
+    memset(wcs->radesys, 0, 72);
+    wcs->equinox = UNDEFINED;
+  }
+
+
   /* Strip off trailing blanks and null-fill auxiliary string members. */
   wcsutil_null_fill(4, wcs->alt);
   wcsutil_null_fill(72, wcs->wcsname);
@@ -1985,15 +2020,21 @@ int wcs_types(struct wcsprm *wcs)
         strcmp(ctypei+1, "LON") == 0 ||
         strcmp(ctypei+2, "LN")  == 0) {
         /* Longitude axis. */
-        if (wcs->lng < 0) wcs->lng = i;
         wcs->types[i] += 2000;
+        if (wcs->lng < 0) {
+          wcs->lng = i;
+          strcpy(wcs->lngtyp, ctypei);
+        }
 
       } else if (strcmp(ctypei,   "DEC") == 0 ||
                  strcmp(ctypei+1, "LAT") == 0 ||
                  strcmp(ctypei+2, "LT")  == 0) {
         /* Latitude axis. */
-        if (wcs->lat < 0) wcs->lat = i;
         wcs->types[i] += 2001;
+        if (wcs->lat < 0) {
+          wcs->lat = i;
+          strcpy(wcs->lattyp, ctypei);
+        }
 
       } else if (strcmp(ctypei, "CUBEFACE") == 0) {
         /* CUBEFACE axis. */
diff --git a/cextern/wcslib/C/wcs.h b/cextern/wcslib/C/wcs.h
index 4dd84e2..14a17b6 100644
--- a/cextern/wcslib/C/wcs.h
+++ b/cextern/wcslib/C/wcs.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcs.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcs.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
@@ -334,6 +334,11 @@
 *                           of the same map projection but may not align on
 *                           the same grid map.  Overrides WCSCOMPARE_TILING.
 *
+*   tol       double    Tolerance for comparison of floating-point values.
+*                       For example, for tol == 1e-6, all floating-point
+*                       values in the structs must be equal to the first 6
+*                       decimal places.  A value of 0 implies exact equality.
+*
 *   wcs1      const struct wcsprm*
 *                       The first wcsprm struct to compare.
 *
@@ -1568,8 +1573,8 @@ int wcsini(int alloc, int naxis, struct wcsprm *wcs);
 int wcssub(int alloc, const struct wcsprm *wcssrc, int *nsub, int axes[],
            struct wcsprm *wcsdst);
 
-int wcscompare(int cmp, const struct wcsprm *wcs1, const struct wcsprm *wcs2,
-               int *equal);
+int wcscompare(int cmp, double tol, const struct wcsprm *wcs1,
+               const struct wcsprm *wcs2, int *equal);
 
 int wcsfree(struct wcsprm *wcs);
 
diff --git a/cextern/wcslib/C/wcsbth.l b/cextern/wcslib/C/wcsbth.l
index 66fb802..18aa637 100644
--- a/cextern/wcslib/C/wcsbth.l
+++ b/cextern/wcslib/C/wcsbth.l
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsbth.l,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsbth.l,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsbth.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/C/wcserr.c b/cextern/wcslib/C/wcserr.c
index 68a23f8..710aaf1 100644
--- a/cextern/wcslib/C/wcserr.c
+++ b/cextern/wcslib/C/wcserr.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -23,7 +23,7 @@
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   Module author: Michael Droettboom
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcserr.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcserr.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <stdarg.h>
diff --git a/cextern/wcslib/C/wcserr.h b/cextern/wcslib/C/wcserr.h
index 6421a35..7508809 100644
--- a/cextern/wcslib/C/wcserr.h
+++ b/cextern/wcslib/C/wcserr.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -23,7 +23,7 @@
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   Module author: Michael Droettboom
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcserr.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcserr.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of the wcserr routines
diff --git a/cextern/wcslib/C/wcsfix.c b/cextern/wcslib/C/wcsfix.c
index 10f6d7c..38ef296 100644
--- a/cextern/wcslib/C/wcsfix.c
+++ b/cextern/wcslib/C/wcsfix.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsfix.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsfix.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/wcsfix.h b/cextern/wcslib/C/wcsfix.h
index 8052710..2537f64 100644
--- a/cextern/wcslib/C/wcsfix.h
+++ b/cextern/wcslib/C/wcsfix.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsfix.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsfix.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/wcshdr.c b/cextern/wcslib/C/wcshdr.c
index 4b20549..f430612 100644
--- a/cextern/wcslib/C/wcshdr.c
+++ b/cextern/wcslib/C/wcshdr.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcshdr.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcshdr.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <ctype.h>
diff --git a/cextern/wcslib/C/wcshdr.h b/cextern/wcslib/C/wcshdr.h
index 1d1dfe0..c79da03 100644
--- a/cextern/wcslib/C/wcshdr.h
+++ b/cextern/wcslib/C/wcshdr.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcshdr.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcshdr.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/wcslib.h b/cextern/wcslib/C/wcslib.h
index e96fa14..b58bca6 100644
--- a/cextern/wcslib/C/wcslib.h
+++ b/cextern/wcslib/C/wcslib.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcslib.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcslib.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.
 *
 * Summary of wcslib.h
diff --git a/cextern/wcslib/C/wcsmath.h b/cextern/wcslib/C/wcsmath.h
index cc2758b..3dc321d 100644
--- a/cextern/wcslib/C/wcsmath.h
+++ b/cextern/wcslib/C/wcsmath.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsmath.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsmath.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of wcsmath.h
diff --git a/cextern/wcslib/C/wcspih.l b/cextern/wcslib/C/wcspih.l
index 88f3ebb..a6d4486 100644
--- a/cextern/wcslib/C/wcspih.l
+++ b/cextern/wcslib/C/wcspih.l
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcspih.l,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcspih.l,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcspih.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/C/wcsprintf.c b/cextern/wcslib/C/wcsprintf.c
index 8ae1a1d..e68e750 100644
--- a/cextern/wcslib/C/wcsprintf.c
+++ b/cextern/wcslib/C/wcsprintf.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsprintf.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsprintf.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <stdarg.h>
diff --git a/cextern/wcslib/C/wcsprintf.h b/cextern/wcslib/C/wcsprintf.h
index 10ecad1..6c94991 100644
--- a/cextern/wcslib/C/wcsprintf.h
+++ b/cextern/wcslib/C/wcsprintf.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsprintf.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsprintf.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.
 *
 * Summary of the wcsprintf routines
diff --git a/cextern/wcslib/C/wcstrig.c b/cextern/wcslib/C/wcstrig.c
index f60235a..f8a8b6c 100644
--- a/cextern/wcslib/C/wcstrig.c
+++ b/cextern/wcslib/C/wcstrig.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcstrig.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcstrig.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/wcstrig.h b/cextern/wcslib/C/wcstrig.h
index 8574cef..2298444 100644
--- a/cextern/wcslib/C/wcstrig.h
+++ b/cextern/wcslib/C/wcstrig.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcstrig.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcstrig.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of the wcstrig routines
diff --git a/cextern/wcslib/C/wcsulex.l b/cextern/wcslib/C/wcsulex.l
index b816b0c..588efdf 100644
--- a/cextern/wcslib/C/wcsulex.l
+++ b/cextern/wcslib/C/wcsulex.l
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsulex.l,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsulex.l,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsulex.l is a Flex description file containing the definition of a
diff --git a/cextern/wcslib/C/wcsunits.c b/cextern/wcslib/C/wcsunits.c
index c929347..375d1d9 100644
--- a/cextern/wcslib/C/wcsunits.c
+++ b/cextern/wcslib/C/wcsunits.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsunits.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsunits.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <math.h>
diff --git a/cextern/wcslib/C/wcsunits.h b/cextern/wcslib/C/wcsunits.h
index cb0f127..54f6bbb 100644
--- a/cextern/wcslib/C/wcsunits.h
+++ b/cextern/wcslib/C/wcsunits.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,10 +22,10 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsunits.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsunits.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
-* WCSLIB 4.23 - C routines that implement the FITS World Coordinate System
+* WCSLIB 4.25 - C routines that implement the FITS World Coordinate System
 * (WCS) standard.  Refer to
 *
 *   "Representations of world coordinates in FITS",
diff --git a/cextern/wcslib/C/wcsutil.c b/cextern/wcslib/C/wcsutil.c
index 859ae30..9b5c608 100644
--- a/cextern/wcslib/C/wcsutil.c
+++ b/cextern/wcslib/C/wcsutil.c
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,15 +22,17 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsutil.c,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsutil.c,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *===========================================================================*/
 
 #include <ctype.h>
 #include <locale.h>
+#include <math.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "wcsutil.h"
+#include "wcsmath.h"
 
 /*--------------------------------------------------------------------------*/
 
@@ -94,7 +96,7 @@ int wcsutil_allEq(int nvec, int nelem, const double *first)
 
 /*--------------------------------------------------------------------------*/
 
-int wcsutil_Eq(int nelem, const double *arr1, const double *arr2)
+int wcsutil_Eq(int nelem, double tol, const double *arr1, const double *arr2)
 
 {
   int i;
@@ -105,8 +107,21 @@ int wcsutil_Eq(int nelem, const double *arr1, const double *arr2)
   if (arr1 == 0x0 && arr2 == 0x0) return 1;
   if (arr1 == 0x0 || arr2 == 0x0) return 0;
 
-  for (i = 0; i < nelem; i++, arr1++, arr2++) {
-    if (*arr1 != *arr2) return 0;
+  if (tol == 0.0) {
+    /* Handled separately for speed of execution. */
+    for (i = 0; i < nelem; i++, arr1++, arr2++) {
+      if (*arr1 != *arr2) return 0;
+    }
+
+  } else {
+    for (i = 0; i < nelem; i++, arr1++, arr2++) {
+      /* Undefined values must match exactly. */
+      if (*arr1 == UNDEFINED && *arr2 != UNDEFINED) return 0;
+      if (*arr1 != UNDEFINED && *arr2 == UNDEFINED) return 0;
+
+      /* Otherwise, compare within the specified tolerance. */
+      if (fabs(*arr1 - *arr2) > 0.5*tol) return 0;
+    }
   }
 
   return 1;
diff --git a/cextern/wcslib/C/wcsutil.h b/cextern/wcslib/C/wcsutil.h
index 0098dcf..f273d27 100644
--- a/cextern/wcslib/C/wcsutil.h
+++ b/cextern/wcslib/C/wcsutil.h
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsutil.h,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsutil.h,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * Summary of the wcsutil routines
@@ -109,11 +109,16 @@
 * -----------------------------------------------------
 * INTERNAL USE ONLY.
 *
-* wcsutil_Eq() tests for equality of two arrays.
+* wcsutil_Eq() tests for equality of two double-precision arrays.
 *
 * Given:
 *   nelem     int       The number of elements in each array.
 *
+*   tol       double    Tolerance for comparison of the floating-point values.
+*                       For example, for tol == 1e-6, all floating-point
+*                       values in the arrays must be equal to the first 6
+*                       decimal places.  A value of 0 implies exact equality.
+*
 *   arr1      const double*
 *                       The first array.
 *
@@ -323,9 +328,10 @@ void wcsutil_blank_fill(int n, char c[]);
 void wcsutil_null_fill (int n, char c[]);
 
 int  wcsutil_allEq (int nvec, int nelem, const double *first);
-int  wcsutil_Eq(int nelem, const double *arr1, const double *arr2);
+int  wcsutil_Eq(int nelem, double tol, const double *arr1,
+                const double *arr2);
 int  wcsutil_intEq(int nelem, const int *arr1, const int *arr2);
-int wcsutil_strEq(int nelem, char (*arr1)[72], char (*arr2)[72]);
+int  wcsutil_strEq(int nelem, char (*arr1)[72], char (*arr2)[72]);
 void wcsutil_setAll(int nvec, int nelem, double *first);
 void wcsutil_setAli(int nvec, int nelem, int *first);
 void wcsutil_setBit(int nelem, const int *sel, int bits, int *array);
diff --git a/cextern/wcslib/C/wcsutrn.l b/cextern/wcslib/C/wcsutrn.l
index 56f2dd6..b159822 100644
--- a/cextern/wcslib/C/wcsutrn.l
+++ b/cextern/wcslib/C/wcsutrn.l
@@ -1,6 +1,6 @@
 /*============================================================================
 
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -22,7 +22,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: wcsutrn.l,v 4.23 2014/05/11 04:09:38 mcalabre Exp $
+  $Id: wcsutrn.l,v 4.25 2014/12/14 14:29:36 mcalabre Exp $
 *=============================================================================
 *
 * wcsutrn.l is a Flex description file containing the definition of a lexical
diff --git a/cextern/wcslib/CHANGES b/cextern/wcslib/CHANGES
index 8872716..cabda63 100644
--- a/cextern/wcslib/CHANGES
+++ b/cextern/wcslib/CHANGES
@@ -1,3 +1,32 @@
+WCSLIB version 4.25 (2014/12/15)
+----------------------------------
+
+* C library
+
+  - wcsset() now supplies default values for the auxiliary keywords
+    EQUINOXa and RADESYSa if not present in the FITS header.
+
+
+WCSLIB version 4.24 (2014/09/19)
+----------------------------------
+
+* C library
+
+  - Changed API to wcscompare() to allow a tolerance to be specified for
+    floating-point comparisons.  Contributed by Michael Droettboom.
+
+  - Documentation generation moved to doxygen 1.8.8 (was 1.8.4).
+
+* Fortran wrappers
+
+    Track the change to wcscompare().
+
+* User manual
+
+  - Added mention of WCSLIB in "homebrew-science" (MacOSX) in the
+    section on other packages.
+
+
 WCSLIB version 4.23 (2014/05/11)
 --------------------------------
 
@@ -2136,4 +2165,4 @@ WCSLIB version 1.0 (1995/01/31)
   Initial release.
 
 ------------------------------------------------------------------------
-$Id: CHANGES,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+$Id: CHANGES,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
diff --git a/cextern/wcslib/GNUmakefile b/cextern/wcslib/GNUmakefile
index e524125..0b91c07 100644
--- a/cextern/wcslib/GNUmakefile
+++ b/cextern/wcslib/GNUmakefile
@@ -1,5 +1,5 @@
 #-----------------------------------------------------------------------------
-# GNU makefile for building WCSLIB 4.23
+# GNU makefile for building WCSLIB 4.25
 #
 # Summary of the main targets
 # ---------------------------
@@ -32,7 +32,7 @@
 #
 # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 # http://www.atnf.csiro.au/people/Mark.Calabretta
-# $Id: GNUmakefile,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+# $Id: GNUmakefile,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 #-----------------------------------------------------------------------------
 # Get configure settings.
 include makedefs
diff --git a/cextern/wcslib/INSTALL b/cextern/wcslib/INSTALL
index aef8b68..1a7bd8b 100644
--- a/cextern/wcslib/INSTALL
+++ b/cextern/wcslib/INSTALL
@@ -1,5 +1,5 @@
 ------------------------------------------------------------------------------
-WCSLIB 4.23 and PGSBOX 4.23 INSTALLATION
+WCSLIB 4.25 and PGSBOX 4.25 INSTALLATION
 --------------------------------------
 
 WCSLIB requires an ANSI C compiler with standard ANSI C environment, that is,
@@ -10,8 +10,8 @@ Installation of WCSLIB is handled by GNU autoconf; GNU make (referred to here
 as 'gmake') must be used.  The WCSLIB distribution also includes PGSBOX (refer
 to the README file), to unpack it type
 
-  zcat wcslib-4.23.tar.gz | tar pvxf -
-  cd wcslib-4.23
+  zcat wcslib-4.25.tar.gz | tar pvxf -
+  cd wcslib-4.25
 
 then if you do not need to specify any configuration options, simply run
 
@@ -93,7 +93,7 @@ The INSTALL file provided with GNU autoconf 2.53 is appended without change.
 
 Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 http://www.atnf.csiro.au/people/Mark.Calabretta
-$Id: INSTALL,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+$Id: INSTALL,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 
 ==============================================================================
 
diff --git a/cextern/wcslib/README b/cextern/wcslib/README
index 789aa0f..3a7abd8 100644
--- a/cextern/wcslib/README
+++ b/cextern/wcslib/README
@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
-                         WCSLIB 4.23 and PGSBOX 4.23
+                         WCSLIB 4.25 and PGSBOX 4.25
 ------------------------------------------------------------------------------
-  WCSLIB 4.23 - an implementation of the FITS WCS standard.
+  WCSLIB 4.25 - an implementation of the FITS WCS standard.
   Copyright (C) 1995-2014, Mark Calabretta
 
   This file is part of WCSLIB.
@@ -23,7 +23,7 @@
 
   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
   http://www.atnf.csiro.au/people/Mark.Calabretta
-  $Id: README,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+  $Id: README,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 ------------------------------------------------------------------------------
 
 Please refer to
diff --git a/cextern/wcslib/THANKS b/cextern/wcslib/THANKS
index b8960b2..39279a1 100644
--- a/cextern/wcslib/THANKS
+++ b/cextern/wcslib/THANKS
@@ -83,4 +83,4 @@ Daren Scot Wilson (NRAO)
 Tony Wong (ATNF/CSIRO)
 
 
-$Id: THANKS,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+$Id: THANKS,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
diff --git a/cextern/wcslib/VALIDATION b/cextern/wcslib/VALIDATION
index 44440ef..43f40e7 100644
--- a/cextern/wcslib/VALIDATION
+++ b/cextern/wcslib/VALIDATION
@@ -313,4 +313,4 @@ WCSLIB version 4.4 (2009/08/06)
           2004/04/23
 
 ------------------------------------------------------------------------------
-$Id: VALIDATION,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+$Id: VALIDATION,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
diff --git a/cextern/wcslib/configure b/cextern/wcslib/configure
index ae450dc..729b285 100755
--- a/cextern/wcslib/configure
+++ b/cextern/wcslib/configure
@@ -1,63 +1,84 @@
 #! /bin/sh
-# From configure.ac Revision: 4.23 .
+# From configure.ac Revision: 4.25 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for WCSLIB 4.23.
+# Generated by GNU Autoconf 2.69 for WCSLIB 4.25.
 #
 # Report bugs to <mark at calabretta.id.au>.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
 esac
-
 fi
 
 
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
   else
-    PATH_SEPARATOR=:
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
   fi
-  rm -f conf$$.sh
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
 fi
 
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
 fi
 
 
@@ -66,20 +87,19 @@ fi
 # there to prevent editors from complaining about space-tab.
 # (If _AS_PATH_WALK were called with IFS unset, it would disable word
 # splitting by setting IFS to empty value.)
-as_nl='
-'
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
+as_myself=
+case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
 IFS=$as_save_IFS
 
      ;;
@@ -90,32 +110,316 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
 fi
 
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
 done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: mark at calabretta.id.au about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
   fi
-done
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
 
-# Required to use basename.
 if expr a : '\(a\)' >/dev/null 2>&1 &&
    test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
@@ -129,13 +433,17 @@ else
   as_basename=false
 fi
 
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
 
-# Name of the executable.
 as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
+$as_echo X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -150,434 +458,133 @@ echo X/"$0" |
 	  }
 	  s/.*/./; q'`
 
-# CDPATH.
-$as_unset CDPATH
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
 
-if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
-else
-  as_have_required=no
-fi
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
-  if test $as_have_required = yes && 	 (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
 }
 
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
 
-if as_func_ret_success; then
-  :
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
 else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
 fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
 
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
-  exitcode=1
-  echo positional parameters were not saved.
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
 fi
 
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
-else
-  as_candidate_shells=
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  case $as_dir in
-	 /*)
-	   for as_base in sh bash ksh sh5; do
-	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
-	   done;;
-       esac
-done
-IFS=$as_save_IFS
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
-      for as_shell in $as_candidate_shells $SHELL; do
-	 # Try only shells that exist, to save several forks.
-	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		{ ("$as_shell") 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
-esac
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
-fi
 
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
 
-:
-_ASEOF
-}; then
-  CONFIG_SHELL=$as_shell
-	       as_have_required=yes
-	       if { "$as_shell" 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
-esac
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
-fi
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
 
-
-:
-(as_func_return () {
-  (exit $1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
-  break
-fi
-
-fi
-
-      done
-
-      if test "x$CONFIG_SHELL" != x; then
-  for as_var in BASH_ENV ENV
-        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-        done
-        export CONFIG_SHELL
-        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
-    if test $as_have_required = no; then
-  echo This script requires a shell more modern than all the
-      echo shells that I found on your system.  Please install a
-      echo modern shell, or manually run the script under such a
-      echo shell if you do have one.
-      { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
-  echo No shell found that supports shell functions.
-  echo Please tell autoconf at gnu.org about your system,
-  echo including any error possibly output before this
-  echo message
-}
-
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-    as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
-else
-  as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-        test -d "$1/.";
-      else
-	case $1 in
-        -*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME='WCSLIB'
-PACKAGE_TARNAME='wcslib-4.23'
-PACKAGE_VERSION='4.23'
-PACKAGE_STRING='WCSLIB 4.23'
-PACKAGE_BUGREPORT='mark at calabretta.id.au'
+# Identity of this package.
+PACKAGE_NAME='WCSLIB'
+PACKAGE_TARNAME='wcslib-4.25'
+PACKAGE_VERSION='4.25'
+PACKAGE_STRING='WCSLIB 4.25'
+PACKAGE_BUGREPORT='mark at calabretta.id.au'
+PACKAGE_URL=''
 
 ac_unique_file="C/wcs.h"
 # Factoring default headers for most tests.
@@ -616,93 +623,111 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-LIBVER
-build
-build_cpu
-build_vendor
-build_os
-ARCH
-FLEX
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CPP
-GREP
-EGREP
-LIBOBJS
-F77
-FFLAGS
-ac_ct_F77
-FLIBS
-RANLIB
-SHRLIB
-SONAME
-SHRFLAGS
-SHRLD
-SHRSFX
-SHRLN
-LN_S
-INSTALL_PROGRAM
-INSTALL_SCRIPT
-INSTALL_DATA
-XMKMF
-CFITSIOINC
-CFITSIOLIB
-GETWCSTAB
-PGPLOTINC
-PGPLOTLIB
-SUBDIRS
-TSTDIRS
+ac_subst_vars='LTLIBOBJS
 INSTDIR
-LTLIBOBJS'
-ac_subst_files=''
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
+TSTDIRS
+SUBDIRS
+PGPLOTLIB
+PGPLOTINC
+GETWCSTAB
+CFITSIOLIB
+CFITSIOINC
+XMKMF
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LN_S
+SHRLN
+SHRSFX
+SHRLD
+SHRFLAGS
+SONAME
+SHRLIB
+RANLIB
+FLIBS
+host_os
+host_vendor
+host_cpu
+host
+ac_ct_F77
+FFLAGS
+F77
+LIBOBJS
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+FLEX
+ARCH
+build_os
+build_vendor
+build_cpu
+build
+LIBVER
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_fortran
+enable_largefile
+with_cfitsio
+with_cfitsiolib
+with_cfitsioinc
+with_pgplot
+with_pgplotlib
+with_pgplotinc
+with_x
+enable_utils
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
 LIBS
 CPPFLAGS
 CPP
@@ -714,6 +739,8 @@ XMKMF'
 # Initialize some variables set by options.
 ac_init_help=
 ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
 # The variables have the same names as the options, with
 # dashes changed to underlines.
 cache_file=/dev/null
@@ -769,8 +796,9 @@ do
   fi
 
   case $ac_option in
-  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)	ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -812,13 +840,20 @@ do
     datarootdir=$ac_optarg ;;
 
   -disable-* | --disable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
-    eval enable_$ac_feature=no ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
 
   -docdir | --docdir | --docdi | --doc | --do)
     ac_prev=docdir ;;
@@ -831,13 +866,20 @@ do
     dvidir=$ac_optarg ;;
 
   -enable-* | --enable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
-    eval enable_$ac_feature=\$ac_optarg ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -1028,22 +1070,36 @@ do
     ac_init_version=: ;;
 
   -with-* | --with-*)
-    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
-    eval with_$ac_package=\$ac_optarg ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
 
   -without-* | --without-*)
-    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
-    eval with_$ac_package=no ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -1063,26 +1119,26 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; }
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
     ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
-   { (exit 1); exit 1; }; }
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -1090,23 +1146,36 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  { echo "$as_me: error: missing argument to $ac_option" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
 fi
 
-# Be sure to have absolute directory names.
+# Check all directory arguments for consistency.
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
   case $ac_val in
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1120,8 +1189,6 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1136,23 +1203,21 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  { echo "$as_me: error: Working directory cannot be determined" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  { echo "$as_me: error: pwd does not report name of working directory" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
   # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$0" ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$0" : 'X\(//\)[^/]' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$0" |
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -1179,13 +1244,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
-   { (exit 1); exit 1; }; }
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
 	pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1211,7 +1274,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures WCSLIB 4.23 to adapt to many kinds of systems.
+\`configure' configures WCSLIB 4.25 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1225,7 +1288,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1233,9 +1296,9 @@ Configuration:
 
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
-			  [$ac_default_prefix]
+                          [$ac_default_prefix]
   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-			  [PREFIX]
+                          [PREFIX]
 
 By default, \`make install' will install all the files in
 \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
@@ -1245,25 +1308,25 @@ for instance \`--prefix=\$HOME'.
 For better control, use the options below.
 
 Fine tuning of the installation directories:
-  --bindir=DIR           user executables [EPREFIX/bin]
-  --sbindir=DIR          system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR       program executables [EPREFIX/libexec]
-  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
-  --libdir=DIR           object code libraries [EPREFIX/lib]
-  --includedir=DIR       C header files [PREFIX/include]
-  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR          info documentation [DATAROOTDIR/info]
-  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR           man documentation [DATAROOTDIR/man]
-  --docdir=DIR           documentation root [DATAROOTDIR/doc/wcslib-4.23]
-  --htmldir=DIR          html documentation [DOCDIR]
-  --dvidir=DIR           dvi documentation [DOCDIR]
-  --pdfdir=DIR           pdf documentation [DOCDIR]
-  --psdir=DIR            ps documentation [DOCDIR]
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/wcslib-4.25]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1274,16 +1337,18 @@ X features:
 
 System types:
   --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
 _ACEOF
 fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of WCSLIB 4.23:";;
+     short | recursive ) echo "Configuration of WCSLIB 4.25:";;
    esac
   cat <<\_ACEOF
 
 Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-fortran=ARG    Fortran compiler to use
@@ -1308,7 +1373,7 @@ Some influential environment variables:
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
   LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
   F77         Fortran 77 compiler command
@@ -1326,15 +1391,17 @@ fi
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" || continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
     ac_builddir=.
 
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1370,7 +1437,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
       echo &&
       $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi || ac_status=$?
     cd "$ac_pwd" || { ac_status=$?; break; }
   done
@@ -1379,3941 +1446,1606 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-WCSLIB configure 4.23
-generated by GNU Autoconf 2.61
+WCSLIB configure 4.25
+generated by GNU Autoconf 2.69
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
   exit
 fi
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
 
-It was created by WCSLIB $as_me 4.23, which was
-generated by GNU Autoconf 2.61.  Invocation command line was
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
 
-  $ $0 $@
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
 _ACEOF
-exec 5>>config.log
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
 {
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
 
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+} # ac_fn_c_check_type
 
-/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
-/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
-/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-_ASUNAME
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  echo "PATH: $as_dir"
-done
-IFS=$as_save_IFS
+} # ac_fn_c_try_run
 
-} >&5
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-cat >&5 <<_ACEOF
+} # ac_fn_c_check_header_compile
 
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in int$2_t 'int' 'long int' \
+	 'long long int' 'short int' 'signed char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	     enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
 
-## ----------- ##
-## Core tests. ##
-## ----------- ##
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	        enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+		 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
 
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
 
+else
+  case $ac_type in #(
+  int$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"; then :
 
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
-  for ac_arg
-  do
-    case $ac_arg in
-    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-    | -silent | --silent | --silen | --sile | --sil)
-      continue ;;
-    *\'*)
-      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    case $ac_pass in
-    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
-    2)
-      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
-      if test $ac_must_keep_next = true; then
-	ac_must_keep_next=false # Got value, back to normal.
-      else
-	case $ac_arg in
-	  *=* | --config-cache | -C | -disable-* | --disable-* \
-	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-	  | -with-* | --with-* | -without-* | --without-* | --x)
-	    case "$ac_configure_args0 " in
-	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-	    esac
-	    ;;
-	  -* ) ac_must_keep_next=true ;;
-	esac
-      fi
-      ac_configure_args="$ac_configure_args '$ac_arg'"
-      ;;
-    esac
-  done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
-  {
-    echo
-
-    cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
-    echo
-    # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
-  (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      sed -n \
-	"s/'\''/'\''\\\\'\'''\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
-    *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-)
-    echo
-
-    cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
-    echo
-    for ac_var in $ac_subst_vars
-    do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      echo "$ac_var='\''$ac_val'\''"
-    done | sort
-    echo
-
-    if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
-      echo
-      for ac_var in $ac_subst_files
-      do
-	eval ac_val=\$$ac_var
-	case $ac_val in
-	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-	esac
-	echo "$ac_var='\''$ac_val'\''"
-      done | sort
-      echo
-    fi
-
-    if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
-      echo
-      cat confdefs.h
-      echo
-    fi
-    test "$ac_signal" != 0 &&
-      echo "$as_me: caught signal $ac_signal"
-    echo "$as_me: exit $exit_status"
-  } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
-    exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
-  set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
-  set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
-  set x "$ac_default_prefix/share/config.site" \
-	"$ac_default_prefix/etc/config.site"
-fi
-shift
-for ac_site_file
-do
-  if test -r "$ac_site_file"; then
-    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
-    sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
-  fi
-done
-
-if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
-    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
-    case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
-    esac
-  fi
-else
-  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
-  >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
-echo "$as_me:   former value:  $ac_old_val" >&2;}
-	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
-echo "$as_me:   current value: $ac_new_val" >&2;}
-	ac_cache_corrupted=:
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define WCSLIB_VERSION $PACKAGE_VERSION
-_ACEOF
-
-
-# Library version number, same as package version.
-LIBVER="$PACKAGE_VERSION"
-
-
-
-ac_aux_dir=
-for ac_dir in config "$srcdir"/config; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config \"$srcdir\"/config" >&5
-echo "$as_me: error: cannot find install-sh or install.sh in config \"$srcdir\"/config" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
-
-
-
-# Get the system type.
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
-echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
-   { (exit 1); exit 1; }; }
-
-{ echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
-if test "${ac_cv_build+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
-   { (exit 1); exit 1; }; }
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
-echo "$as_me: error: invalid value of canonical build" >&2;}
-   { (exit 1); exit 1; }; };;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-ARCH="${build_cpu}-$build_os"
-
-
-
-# Look for Flex.
-# Extract the first word of "flex", so it can be a program name with args.
-set dummy flex; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_FLEX+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$FLEX"; then
-  ac_cv_prog_FLEX="$FLEX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_FLEX="flex"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-FLEX=$ac_cv_prog_FLEX
-if test -n "$FLEX"; then
-  { echo "$as_me:$LINENO: result: $FLEX" >&5
-echo "${ECHO_T}$FLEX" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-if test "x$FLEX" = xflex ; then
-  # Version 2.5.9 or later is required.
-  V=`flex --version | awk '{print $NF}'`
-  W=`echo $V | awk -F. '{if ((($1*100 + $2)*100 + $3) < 20509) print "no"}'`
-  if test "x$W" != x ; then
-    { echo "$as_me:$LINENO: Flex version $V is too old, ignored." >&5
-echo "$as_me: Flex version $V is too old, ignored." >&6;}
-    FLEX=
-  else
-    { echo "$as_me:$LINENO: Using Flex version $V." >&5
-echo "$as_me: Using Flex version $V." >&6;}
-  fi
-fi
-
-if test "x$FLEX" = x ; then
-  { echo "$as_me:$LINENO: WARNING: Flex version 2.5.9 or later does not appear to be
-           available, will use pre-generated sources." >&5
-echo "$as_me: WARNING: Flex version 2.5.9 or later does not appear to be
-           available, will use pre-generated sources." >&2;}
-fi
-
-
-# Look for an ANSI C compiler.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort.  b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions.  Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
-	;;
-    [ab].out )
-	# We found the default executable, but exeext='' is most
-	# certainly right.
-	break;;
-    *.* )
-        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-	then :; else
-	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	fi
-	# We set ac_cv_exeext here because the later test for it is not
-	# safe: cross compilers may not add the suffix if given an `-o'
-	# argument, so we may need to know it at that point already.
-	# Even if this section looks crufty: it has the advantage of
-	# actually working.
-	break;;
-    * )
-	break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
-  ac_file=''
-fi
-
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-if test -z "$ac_file"; then
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_c89=$ac_arg
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
-else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_c89=$ac_arg
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-   case $ac_cv_prog_cc_stdc in
-  no) ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;;
-  *) { echo "$as_me:$LINENO: checking for $CC option to accept ISO C99" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C99... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c99+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_c99=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <stdio.h>
-
-// Check varargs macros.  These examples are taken from C99 6.10.3.5.
-#define debug(...) fprintf (stderr, __VA_ARGS__)
-#define showlist(...) puts (#__VA_ARGS__)
-#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
-static void
-test_varargs_macros (void)
-{
-  int x = 1234;
-  int y = 5678;
-  debug ("Flag");
-  debug ("X = %d\n", x);
-  showlist (The first, second, and third items.);
-  report (x>y, "x is %d but y is %d", x, y);
-}
-
-// Check long long types.
-#define BIG64 18446744073709551615ull
-#define BIG32 4294967295ul
-#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
-#if !BIG_OK
-  your preprocessor is broken;
-#endif
-#if BIG_OK
-#else
-  your preprocessor is broken;
-#endif
-static long long int bignum = -9223372036854775807LL;
-static unsigned long long int ubignum = BIG64;
-
-struct incomplete_array
-{
-  int datasize;
-  double data[];
-};
-
-struct named_init {
-  int number;
-  const wchar_t *name;
-  double average;
-};
-
-typedef const char *ccp;
-
-static inline int
-test_restrict (ccp restrict text)
-{
-  // See if C++-style comments work.
-  // Iterate through items via the restricted pointer.
-  // Also check for declarations in for loops.
-  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
-    continue;
-  return 0;
-}
-
-// Check varargs and va_copy.
-static void
-test_varargs (const char *format, ...)
-{
-  va_list args;
-  va_start (args, format);
-  va_list args_copy;
-  va_copy (args_copy, args);
-
-  const char *str;
-  int number;
-  float fnumber;
-
-  while (*format)
-    {
-      switch (*format++)
-	{
-	case 's': // string
-	  str = va_arg (args_copy, const char *);
-	  break;
-	case 'd': // int
-	  number = va_arg (args_copy, int);
-	  break;
-	case 'f': // float
-	  fnumber = va_arg (args_copy, double);
-	  break;
-	default:
-	  break;
-	}
-    }
-  va_end (args_copy);
-  va_end (args);
-}
-
-int
-main ()
-{
-
-  // Check bool.
-  _Bool success = false;
-
-  // Check restrict.
-  if (test_restrict ("String literal") == 0)
-    success = true;
-  char *restrict newvar = "Another string";
-
-  // Check varargs.
-  test_varargs ("s, d' f .", "string", 65, 34.234);
-  test_varargs_macros ();
-
-  // Check flexible array members.
-  struct incomplete_array *ia =
-    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
-  ia->datasize = 10;
-  for (int i = 0; i < ia->datasize; ++i)
-    ia->data[i] = i * 1.234;
-
-  // Check named initializers.
-  struct named_init ni = {
-    .number = 34,
-    .name = L"Test wide string",
-    .average = 543.34343,
-  };
-
-  ni.number = 58;
-
-  int dynamic_array[ni.number];
-  dynamic_array[ni.number - 1] = 543;
-
-  // work around unused variable warnings
-  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
-	  || dynamic_array[ni.number - 1] != 543);
-
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -std=gnu99 -c99 -qlanglvl=extc99
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_c99=$ac_arg
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+  break
 fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c99" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
+     done
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c99" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c99"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c99" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c99" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c99" != xno; then
-  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
-else
-  { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+} # ac_fn_c_find_intX_t
 
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
 {
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_prog_cc_c89=$ac_arg
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then
-  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
-else
-  ac_cv_prog_cc_stdc=no
-fi
-
-
-fi
-
- ;;
-esac
-  { echo "$as_me:$LINENO: checking for $CC option to accept ISO Standard C" >&5
-echo $ECHO_N "checking for $CC option to accept ISO Standard C... $ECHO_C" >&6; }
-  if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-
-  case $ac_cv_prog_cc_stdc in
-  no) { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  '') { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  *) { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6; } ;;
-esac
-
-
-
-{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
-echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
-if test "${ac_cv_c_const+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-
+$ac_includes_default
 int
 main ()
 {
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
-  /* Ultrix mips cc rejects this.  */
-  typedef int charset[2];
-  const charset cs;
-  /* SunOS 4.1.1 cc rejects this.  */
-  char const *const *pcpcc;
-  char **ppc;
-  /* NEC SVR4.0.2 mips cc rejects this.  */
-  struct point {int x, y;};
-  static struct point const zero = {0,0};
-  /* AIX XL C 1.02.0.0 rejects this.
-     It does not let you subtract one const X* pointer from another in
-     an arm of an if-expression whose if-part is not a constant
-     expression */
-  const char *g = "string";
-  pcpcc = &g + (g ? g-g : 0);
-  /* HPUX 7.0 cc rejects these. */
-  ++pcpcc;
-  ppc = (char**) pcpcc;
-  pcpcc = (char const *const *) ppc;
-  { /* SCO 3.2v4 cc rejects this.  */
-    char *t;
-    char const *s = 0 ? (char *) 0 : (char const *) 0;
-
-    *t++ = 0;
-    if (s) return 0;
-  }
-  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
-    int x[] = {25, 17};
-    const int *foo = &x[0];
-    ++foo;
-  }
-  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
-    typedef const int *iptr;
-    iptr p = 0;
-    ++p;
-  }
-  { /* AIX XL C 1.02.0.0 rejects this saying
-       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; };
-    struct s *b; b->j = 5;
-  }
-  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
-    const int foo = 10;
-    if (!foo) return 0;
-  }
-  return !cs[0] && !zero.x;
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_c_const=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_c_const=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
-echo "${ECHO_T}$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define const
-_ACEOF
-
-fi
-
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in grep ggrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-    # Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_GREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];
 
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  case $ac_type in #(
+  uint$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"; then :
 
 else
-  ac_cv_path_GREP=$GREP
+  break
 fi
-
-
+     done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
+} # ac_fn_c_find_uintX_t
 
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
 else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
 else
-  ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in egrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-    # Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_EGREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
+  ac_header_compiler=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
 
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
 fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
 
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------ ##
+## Report this to mark at calabretta.id.au ##
+## ------------------------------------ ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_cv_path_EGREP=$EGREP
+  eval "$3=\$ac_header_compiler"
 fi
-
-
-   fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
+} # ac_fn_c_check_header_mongrel
 
-int
-main ()
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
 {
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_header_stdc=yes
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
 else
-  echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_cv_header_stdc=no
+	ac_retval=1
 fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <string.h>
+} # ac_fn_c_try_link
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_cv_header_stdc=no
-fi
-rm -f -r conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f -r conftest*
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
 
-fi
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#ifdef __STDC__
+# include <limits.h>
 #else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
 #endif
 
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
 int
 main ()
 {
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
+return $2 ();
+  ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
+  eval "$3=no"
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
+} # ac_fn_c_check_func
 
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
 
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
 fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
 
-#include <$ac_header>
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  eval "$as_ac_Header=yes"
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	eval "$as_ac_Header=no"
+  ac_lo= ac_hi=
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
 fi
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 done
-
-
-{ echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_size_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-typedef size_t ac__type_new_;
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_f77_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_f77_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_type_size_t=yes
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
 else
-  echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_cv_type_size_t=no
+	ac_retval=1
 fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6; }
-if test $ac_cv_type_size_t = yes; then
-  :
-else
+} # ac_fn_f77_try_compile
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by WCSLIB $as_me 4.25, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
 
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
 _ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
 
-fi
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
 
-if test "x$ac_cv_prog_cc_stdc" = xno -o \
-        "x$ac_cv_c_const"      = xno -o \
-        "x$ac_cv_type_size_t"  = xno; then
-  { { echo "$as_me:$LINENO: error:
-    -------------------------------------------------------
-    An ANSI standard C library is required to build WCSLIB.
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
 
-    ERROR: WCSLIB configuration failure.
-    -------------------------------------------------------" >&5
-echo "$as_me: error:
-    -------------------------------------------------------
-    An ANSI standard C library is required to build WCSLIB.
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
 
-    ERROR: WCSLIB configuration failure.
-    -------------------------------------------------------" >&2;}
-   { (exit 1); exit 1; }; }
-fi
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
 
-# Check for data types (suggested by autoscan - off_t is only required by
-# fitshdr).
-{ echo "$as_me:$LINENO: checking for off_t" >&5
-echo $ECHO_N "checking for off_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_off_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-typedef off_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_type_off_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_cv_type_off_t=no
-fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
-echo "${ECHO_T}$ac_cv_type_off_t" >&6; }
-if test $ac_cv_type_off_t = yes; then
-  :
-else
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
 
 cat >>confdefs.h <<_ACEOF
-#define off_t long int
+#define PACKAGE_NAME "$PACKAGE_NAME"
 _ACEOF
 
-fi
-
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
 
-  { echo "$as_me:$LINENO: checking for int8_t" >&5
-echo $ECHO_N "checking for int8_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_int8_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_c_int8_t=no
-     for ac_type in 'int8_t' 'int' 'long int' \
-	 'long long int' 'short int' 'signed char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 1))];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 1)
-	         < ($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 2))];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	case $ac_type in
-  int8_t) ac_cv_c_int8_t=yes ;;
-  *) ac_cv_c_int8_t=$ac_type ;;
-esac
 
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
 fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_int8_t" != no && break
-     done
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_int8_t" >&5
-echo "${ECHO_T}$ac_cv_c_int8_t" >&6; }
-  case $ac_cv_c_int8_t in #(
-  no|yes) ;; #(
-  *)
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
 
 cat >>confdefs.h <<_ACEOF
-#define int8_t $ac_cv_c_int8_t
+#define WCSLIB_VERSION $PACKAGE_VERSION
 _ACEOF
-;;
-  esac
 
 
-  { echo "$as_me:$LINENO: checking for int16_t" >&5
-echo $ECHO_N "checking for int16_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_int16_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_c_int16_t=no
-     for ac_type in 'int16_t' 'int' 'long int' \
-	 'long long int' 'short int' 'signed char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 1))];
-test_array [0] = 0
+# Library version number, same as package version.
+LIBVER="$PACKAGE_VERSION"
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 1)
-	         < ($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 2))];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
+
+ac_aux_dir=
+for ac_dir in config "$srcdir"/config; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+# Get the system type.
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
 
-	case $ac_type in
-  int16_t) ac_cv_c_int16_t=yes ;;
-  *) ac_cv_c_int16_t=$ac_type ;;
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
 esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+ARCH="${build_cpu}-$build_os"
+
+
+
+# Look for Flex.
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_FLEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$FLEX"; then
+  ac_cv_prog_FLEX="$FLEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_FLEX="flex"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+FLEX=$ac_cv_prog_FLEX
+if test -n "$FLEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5
+$as_echo "$FLEX" >&6; }
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
 
+if test "x$FLEX" = xflex ; then
+  # Version 2.5.9 or later is required.
+  V=`flex --version | awk '{print $2}'`
+  W=`echo $V | awk -F. '{if ((($1*100 + $2)*100 + $3) < 20509) print "no"}'`
+  if test "x$W" != x ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Flex version $V is too old, ignored." >&5
+$as_echo "$as_me: Flex version $V is too old, ignored." >&6;}
+    FLEX=
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Using Flex version $V." >&5
+$as_echo "$as_me: Using Flex version $V." >&6;}
+  fi
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_int16_t" != no && break
-     done
+if test "x$FLEX" = x ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Flex version 2.5.9 or later does not appear to be
+           available, will use pre-generated sources." >&5
+$as_echo "$as_me: WARNING: Flex version 2.5.9 or later does not appear to be
+           available, will use pre-generated sources." >&2;}
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_int16_t" >&5
-echo "${ECHO_T}$ac_cv_c_int16_t" >&6; }
-  case $ac_cv_c_int16_t in #(
-  no|yes) ;; #(
-  *)
 
-cat >>confdefs.h <<_ACEOF
-#define int16_t $ac_cv_c_int16_t
-_ACEOF
-;;
-  esac
 
+# Look for an ANSI C compiler.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-  { echo "$as_me:$LINENO: checking for int32_t" >&5
-echo $ECHO_N "checking for int32_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_int32_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  ac_cv_c_int32_t=no
-     for ac_type in 'int32_t' 'int' 'long int' \
-	 'long long int' 'short int' 'signed char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 1))];
-test_array [0] = 0
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 1)
-	         < ($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 2))];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	case $ac_type in
-  int32_t) ac_cv_c_int32_t=yes ;;
-  *) ac_cv_c_int32_t=$ac_type ;;
-esac
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
 fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  CC="$ac_cv_prog_CC"
+fi
 
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_int32_t" != no && break
-     done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_int32_t" >&5
-echo "${ECHO_T}$ac_cv_c_int32_t" >&6; }
-  case $ac_cv_c_int32_t in #(
-  no|yes) ;; #(
-  *)
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-cat >>confdefs.h <<_ACEOF
-#define int32_t $ac_cv_c_int32_t
-_ACEOF
-;;
-  esac
 
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-  { echo "$as_me:$LINENO: checking for uint8_t" >&5
-echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_uint8_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  ac_cv_c_uint8_t=no
-     for ac_type in 'uint8_t' 'unsigned int' 'unsigned long int' \
-	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) -1 >> (8 - 1) == 1)];
-test_array [0] = 0
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  case $ac_type in
-  uint8_t) ac_cv_c_uint8_t=yes ;;
-  *) ac_cv_c_uint8_t=$ac_type ;;
-esac
 
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
 
+    test -n "$CC" && break
+  done
 fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_uint8_t" != no && break
-     done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_uint8_t" >&5
-echo "${ECHO_T}$ac_cv_c_uint8_t" >&6; }
-  case $ac_cv_c_uint8_t in #(
-  no|yes) ;; #(
-  *)
-
-cat >>confdefs.h <<\_ACEOF
-#define _UINT8_T 1
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint8_t $ac_cv_c_uint8_t
-_ACEOF
-;;
-  esac
-
-
-  { echo "$as_me:$LINENO: checking for uint16_t" >&5
-echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_uint16_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
 else
-  ac_cv_c_uint16_t=no
-     for ac_type in 'uint16_t' 'unsigned int' 'unsigned long int' \
-	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) -1 >> (16 - 1) == 1)];
-test_array [0] = 0
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  case $ac_type in
-  uint16_t) ac_cv_c_uint16_t=yes ;;
-  *) ac_cv_c_uint16_t=$ac_type ;;
-esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
+  test -n "$ac_ct_CC" && break
+done
 
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_uint16_t" != no && break
-     done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_uint16_t" >&5
-echo "${ECHO_T}$ac_cv_c_uint16_t" >&6; }
-  case $ac_cv_c_uint16_t in #(
-  no|yes) ;; #(
-  *)
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint16_t $ac_cv_c_uint16_t
-_ACEOF
-;;
-  esac
 
 
-  { echo "$as_me:$LINENO: checking for uint32_t" >&5
-echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; }
-if test "${ac_cv_c_uint32_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_c_uint32_t=no
-     for ac_type in 'uint32_t' 'unsigned int' 'unsigned long int' \
-	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) -1 >> (32 - 1) == 1)];
-test_array [0] = 0
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  case $ac_type in
-  uint32_t) ac_cv_c_uint32_t=yes ;;
-  *) ac_cv_c_uint32_t=$ac_type ;;
-esac
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       test "$ac_cv_c_uint32_t" != no && break
-     done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_uint32_t" >&5
-echo "${ECHO_T}$ac_cv_c_uint32_t" >&6; }
-  case $ac_cv_c_uint32_t in #(
-  no|yes) ;; #(
-  *)
-
-cat >>confdefs.h <<\_ACEOF
-#define _UINT32_T 1
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint32_t $ac_cv_c_uint32_t
-_ACEOF
-;;
-  esac
-
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
 
-# Check for ANSI C headers.
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
 
 int
 main ()
@@ -5323,3000 +3055,2556 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_header_stdc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_header_stdc=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <string.h>
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
 else
-  ac_cv_header_stdc=no
-fi
-rm -f -r conftest*
-
+  ac_file=''
 fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
 else
-  ac_cv_header_stdc=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 fi
-rm -f -r conftest*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
 
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+#include <stdio.h>
 int
 main ()
 {
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
   (eval "$ac_try") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
 
-
-
-
-
-
-
-
-
-
-
-for ac_header in ctype.h errno.h limits.h locale.h math.h setjmp.h stdarg.h \
-                  stdio.h stdlib.h string.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
   ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
 else
-  echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_header_compiler=no
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
 
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
+  ;
+  return 0;
+}
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
-  ac_header_preproc=no
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
+int
+main ()
+{
 
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    ( cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to mark at calabretta.id.au ##
-## ------------------------------------ ##
-_ASBOX
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
-done
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
-if test "x$ac_cv_header_stdc" = xno; then
-  { { echo "$as_me:$LINENO: error:
-    -------------------------------------------------------------------
-    An ANSI standard C library is required to build WCSLIB.  One of the
-    ANSI C header files it requires is missing or unusable.
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
 
-    ERROR: WCSLIB configuration failure.
-    -------------------------------------------------------------------" >&5
-echo "$as_me: error:
-    -------------------------------------------------------------------
-    An ANSI standard C library is required to build WCSLIB.  One of the
-    ANSI C header files it requires is missing or unusable.
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
 
-    ERROR: WCSLIB configuration failure.
-    -------------------------------------------------------------------" >&2;}
-   { (exit 1); exit 1; }; }
 fi
 
-# Checks for ANSI C library functions (suggested by autoscan - fseeko and
-# stat are only required by fitshdr).
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-{ echo "$as_me:$LINENO: checking for floor in -lm" >&5
-echo $ECHO_N "checking for floor in -lm... $ECHO_C" >&6; }
-if test "${ac_cv_lib_m_floor+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
 #endif
-char floor ();
-int
-main ()
-{
-return floor ();
-  ;
-  return 0;
-}
+		     Syntax error
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_m_floor=yes
+if ac_fn_c_try_cpp "$LINENO"; then :
+
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-	ac_cv_lib_m_floor=no
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
 fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_floor" >&5
-echo "${ECHO_T}$ac_cv_lib_m_floor" >&6; }
-if test $ac_cv_lib_m_floor = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBM 1
-_ACEOF
 
-  LIBS="-lm $LIBS"
+    done
+    ac_cv_prog_CPP=$CPP
 
 fi
-
-{ echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
-echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_source+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  CPP=$ac_cv_prog_CPP
 else
-  while :; do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
-  ;
-  return 0;
-}
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_sys_largefile_source=no; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+if ac_fn_c_try_cpp "$LINENO"; then :
 
+else
+  # Broken: fails on valid input.
+continue
 fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#define _LARGEFILE_SOURCE 1
-#include <stdio.h>
-int
-main ()
-{
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
-  ;
-  return 0;
-}
+#include <ac_nonexistent.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_sys_largefile_source=1; break
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+  # Passes both tests.
+ac_preproc_ok=:
+break
 fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-  ac_cv_sys_largefile_source=unknown
-  break
 done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6; }
-case $ac_cv_sys_largefile_source in #(
-  no | unknown) ;;
-  *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
-_ACEOF
-;;
-esac
-rm -f -r conftest*
-
-# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
-# in glibc 2.1.3, but that breaks too many other things.
-# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
-if test $ac_cv_sys_largefile_source != unknown; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FSEEKO 1
-_ACEOF
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
 
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-for ac_header in stdlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-	ac_header_compiler=no
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-  ac_header_preproc=no
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    ( cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to mark at calabretta.id.au ##
-## ------------------------------------ ##
-_ASBOX
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
 esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    CC=$ac_ct_CC
+  fi
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
+  CC="$ac_cv_prog_CC"
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
 fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-done
 
-{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5
-echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; }
-if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_malloc_0_nonnull=no
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#if defined STDC_HEADERS || defined HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-char *malloc ();
-#endif
-
-int
-main ()
-{
-return ! malloc (0);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_malloc_0_nonnull=yes
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-( exit $ac_status )
-ac_cv_func_malloc_0_nonnull=no
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5
-echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; }
-if test $ac_cv_func_malloc_0_nonnull = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MALLOC 1
-_ACEOF
-
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_MALLOC 0
-_ACEOF
-
-   case " $LIBOBJS " in
-  *" malloc.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
- ;;
-esac
-
-
-cat >>confdefs.h <<\_ACEOF
-#define malloc rpl_malloc
-_ACEOF
-
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
-
-
-for ac_header in stdlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-	ac_header_compiler=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
 fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    ( cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to mark at calabretta.id.au ##
-## ------------------------------------ ##
-_ASBOX
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
+    test -n "$CC" && break
+  done
 fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5
-echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6; }
-if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_realloc_0_nonnull=no
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#if defined STDC_HEADERS || defined HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-char *realloc ();
-#endif
-
-int
-main ()
-{
-return ! realloc (0, 0);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_realloc_0_nonnull=yes
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-( exit $ac_status )
-ac_cv_func_realloc_0_nonnull=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5
-echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6; }
-if test $ac_cv_func_realloc_0_nonnull = yes; then
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_REALLOC 1
-_ACEOF
 
-else
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_REALLOC 0
-_ACEOF
+  test -n "$ac_ct_CC" && break
+done
 
-   case " $LIBOBJS " in
-  *" realloc.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS realloc.$ac_objext"
- ;;
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
 esac
-
-
-cat >>confdefs.h <<\_ACEOF
-#define realloc rpl_realloc
-_ACEOF
+    CC=$ac_ct_CC
+  fi
+fi
 
 fi
 
 
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
-{ echo "$as_me:$LINENO: checking for function prototypes" >&5
-echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6; }
-if test "$ac_cv_prog_cc_c89" != no; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
 
-cat >>confdefs.h <<\_ACEOF
-#define PROTOTYPES 1
-_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
 
-cat >>confdefs.h <<\_ACEOF
-#define __PROTOTYPES 1
+  ;
+  return 0;
+}
 _ACEOF
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  ac_compiler_gnu=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
-{ echo "$as_me:$LINENO: checking whether setvbuf arguments are reversed" >&5
-echo $ECHO_N "checking whether setvbuf arguments are reversed... $ECHO_C" >&6; }
-if test "${ac_cv_func_setvbuf_reversed+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
 else
-  ac_cv_func_setvbuf_reversed=no
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
-#	  ifdef PROTOTYPES
-	   int (setvbuf) (FILE *, int, char *, size_t);
-#	  endif
+
 int
 main ()
 {
-char buf; return setvbuf (stdout, _IOLBF, &buf, 1);
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
-#	     ifdef PROTOTYPES
-	      int (setvbuf) (FILE *, int, char *, size_t);
-#	     endif
+
 int
 main ()
 {
-char buf; return setvbuf (stdout, &buf, _IOLBF, 1);
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  # It compiles and links either way, so it must not be declared
-	 # with a prototype and most likely this is a K&R C compiler.
-	 # Try running it.
-	 if test "$cross_compiling" = yes; then
-  : # Assume setvbuf is not reversed when cross-compiling.
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
+
 int
 main ()
 {
-/* This call has the arguments reversed.
-		   A reversed system may check and see that the address of buf
-		   is not _IOLBF, _IONBF, or _IOFBF, and return nonzero.  */
-		char buf;
-		if (setvbuf (stdout, _IOLBF, &buf, 1) != 0)
-		  return 1;
-		putchar ('\r');
-		return 0; /* Non-reversed systems SEGV here.  */
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_setvbuf_reversed=yes
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-
-
-	ac_cv_func_setvbuf_reversed=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_setvbuf_reversed" >&5
-echo "${ECHO_T}$ac_cv_func_setvbuf_reversed" >&6; }
-if test $ac_cv_func_setvbuf_reversed = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
-cat >>confdefs.h <<\_ACEOF
-#define SETVBUF_REVERSED 1
-_ACEOF
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
-fi
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
 
-{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5
-echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; }
-if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  rm -f conftest.sym conftest.file
-echo >conftest.file
-if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_lstat_dereferences_slashed_symlink=no
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
 int
 main ()
 {
-struct stat sbuf;
-     /* Linux will dereference the symlink and fail.
-	That is better in the sense that it means we will not
-	have to compile and use the lstat wrapper.  */
-     return lstat ("conftest.sym/", &sbuf) == 0;
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_lstat_dereferences_slashed_symlink=yes
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 
-( exit $ac_status )
-ac_cv_func_lstat_dereferences_slashed_symlink=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
 fi
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+   case $ac_cv_prog_cc_stdc in #(
+  no) :
+    ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
+  *) :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # If the `ln -s' command failed, then we probably don't even
-  # have an lstat function.
-  ac_cv_func_lstat_dereferences_slashed_symlink=no
-fi
-rm -f conftest.sym conftest.file
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
-echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
 
-test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
 
-cat >>confdefs.h <<_ACEOF
-#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
-_ACEOF
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+  your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
 
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
 
-if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
-  case " $LIBOBJS " in
-  *" lstat.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS lstat.$ac_objext"
- ;;
-esac
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
 
-fi
+typedef const char *ccp;
 
-{ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5
-echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6; }
-if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_stat_empty_string_bug=yes
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
+static inline int
+test_restrict (ccp restrict text)
 {
-struct stat sbuf;
-  return stat ("", &sbuf) == 0;
-  ;
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+    continue;
   return 0;
 }
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_stat_empty_string_bug=no
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-ac_cv_func_stat_empty_string_bug=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
 
+  const char *str;
+  int number;
+  float fnumber;
 
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5
-echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6; }
-if test $ac_cv_func_stat_empty_string_bug = yes; then
-  case " $LIBOBJS " in
-  *" stat.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS stat.$ac_objext"
- ;;
-esac
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case 's': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case 'd': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case 'f': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+}
 
+int
+main ()
+{
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STAT_EMPTY_STRING_BUG 1
-_ACEOF
+  // Check bool.
+  _Bool success = false;
 
-fi
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
 
+  // Check varargs.
+  test_varargs ("s, d' f .", "string", 65, 34.234);
+  test_varargs_macros ();
 
-for ac_func in vprintf
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
 
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+  ni.number = 58;
 
-#undef $ac_func
+  int dynamic_array[ni.number];
+  dynamic_array[ni.number - 1] = 543;
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
+  // work around unused variable warnings
+  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+	  || dynamic_array[ni.number - 1] != 543);
 
-int
-main ()
-{
-return $ac_func ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	eval "$as_ac_var=no"
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c99=$ac_arg
 fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-{ echo "$as_me:$LINENO: checking for _doprnt" >&5
-echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; }
-if test "${ac_cv_func__doprnt+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c99"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define _doprnt innocuous__doprnt
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char _doprnt (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
-#undef _doprnt
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char _doprnt ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub__doprnt || defined __stub____doprnt
-choke me
-#endif
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
 
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
 int
 main ()
 {
-return _doprnt ();
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_func__doprnt=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_func__doprnt=no
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
 fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
-echo "${ECHO_T}$ac_cv_func__doprnt" >&6; }
-if test $ac_cv_func__doprnt = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_DOPRNT 1
-_ACEOF
-
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+else
+  ac_cv_prog_cc_stdc=no
 fi
 
 fi
-done
-
-
-
-
-
-
+ ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
+$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
+  if ${ac_cv_prog_cc_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
 
+  case $ac_cv_prog_cc_stdc in #(
+  no) :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;; #(
+  '') :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;; #(
+  *) :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
+$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
+esac
 
 
-for ac_func in floor memset pow setlocale sqrt strchr strstr
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+int
+main ()
+{
 
-#undef $ac_func
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
 #endif
 
-int
-main ()
-{
-return $ac_func ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_path_GREP=$GREP
+fi
 
-	eval "$as_ac_var=no"
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
 
+   fi
 fi
-done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
 
 
-# System libraries that may be required by WCSLIB itself.
-# SunOS, extra maths functions.
-{ echo "$as_me:$LINENO: checking for cosd in -lsunmath" >&5
-echo $ECHO_N "checking for cosd in -lsunmath... $ECHO_C" >&6; }
-if test "${ac_cv_lib_sunmath_cosd+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsunmath  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char cosd ();
 int
 main ()
 {
-return cosd ();
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_sunmath_cosd=yes
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_sunmath_cosd=no
+  ac_cv_header_stdc=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_sunmath_cosd" >&5
-echo "${ECHO_T}$ac_cv_lib_sunmath_cosd" >&6; }
-if test $ac_cv_lib_sunmath_cosd = yes; then
-  LIBS="-lsunmath $LIBS"
+rm -f conftest*
+
 fi
 
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
 
-# See if we can find sincos().
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
 
-for ac_func in sincos
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
 
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
+fi
 
-#ifdef __STDC__
-# include <limits.h>
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
 #else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
 #endif
 
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
 int
 main ()
 {
-return $ac_func ();
-  ;
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+if ac_fn_c_try_run "$LINENO"; then :
+
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
 
-	eval "$as_ac_var=no"
 fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
+
 done
 
 
-# Check the size and availability of integer data types.
-{ echo "$as_me:$LINENO: checking for int" >&5
-echo $ECHO_N "checking for int... $ECHO_C" >&6; }
-if test "${ac_cv_type_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-typedef int ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_type_int=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_cv_type_int=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test "x$ac_cv_prog_cc_stdc" = xno -o \
+        "x$ac_cv_c_const"      = xno -o \
+        "x$ac_cv_type_size_t"  = xno; then
+  as_fn_error 1 "
+    -------------------------------------------------------
+    An ANSI standard C library is required to build WCSLIB.
+
+    ERROR: WCSLIB configuration failure.
+    -------------------------------------------------------" "$LINENO" 5
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
-echo "${ECHO_T}$ac_cv_type_int" >&6; }
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ echo "$as_me:$LINENO: checking size of int" >&5
-echo $ECHO_N "checking size of int... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check for data types (suggested by autoscan - off_t is only required by
+# fitshdr).
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
+if test "x$ac_cv_type_off_t" = xyes; then :
+
 else
-  if test "$cross_compiling" = yes; then
-  # Depending upon the size, compute the lo and hi bounds.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
+fi
+
+ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int8_t $ac_cv_c_int8_t
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+
+ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int16_t $ac_cv_c_int16_t
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
+;;
+esac
 
-  ;
-  return 0;
-}
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_lo=`expr $ac_mid + 1`
-			if test $ac_lo -le $ac_mid; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid + 1`
-fi
+ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT8_T 1" >>confdefs.h
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+cat >>confdefs.h <<_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
-test_array [0] = 0
+;;
+  esac
 
-  ;
-  return 0;
-}
+ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+  no|yes) ;; #(
+  *)
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+;;
+  esac
+
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+;;
+  esac
+
+
+# Check for ANSI C headers.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
-test_array [0] = 0
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=$ac_mid; break
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_hi=`expr '(' $ac_mid ')' - 1`
-			if test $ac_mid -le $ac_hi; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid`
+  ac_cv_header_stdc=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_lo= ac_hi=
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
 fi
+rm -f conftest*
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
+#include <stdlib.h>
 
-  ;
-  return 0;
-}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
 
-	ac_lo=`expr '(' $ac_mid ')' + 1`
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in
-?*) ac_cv_sizeof_int=$ac_lo;;
-'') if test "$ac_cv_type_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-   else
-     ac_cv_sizeof_int=0
-   fi ;;
-esac
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef int ac__type_sizeof_;
-static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
-static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
-#include <stdio.h>
+#include <ctype.h>
 #include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
 int
 main ()
 {
-
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (((long int) (sizeof (ac__type_sizeof_))) < 0)
-    {
-      long int i = longval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%ld\n", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%lu\n", i);
-    }
-  return ferror (f) || fclose (f) != 0;
-
-  ;
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sizeof_int=`cat conftest.val`
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_run "$LINENO"; then :
 
-( exit $ac_status )
-if test "$ac_cv_type_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-   else
-     ac_cv_sizeof_int=0
-   fi
+else
+  ac_cv_header_stdc=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f conftest.val
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_int" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
 
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
+fi
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
+for ac_header in ctype.h errno.h limits.h locale.h math.h setjmp.h stdarg.h \
+                  stdio.h stdlib.h string.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
+fi
 
-{ echo "$as_me:$LINENO: checking for long int" >&5
-echo $ECHO_N "checking for long int... $ECHO_C" >&6; }
-if test "${ac_cv_type_long_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-typedef long int ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_type_long_int=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+done
 
-	ac_cv_type_long_int=no
-fi
+if test "x$ac_cv_header_stdc" = xno; then
+  as_fn_error 1 "
+    -------------------------------------------------------------------
+    An ANSI standard C library is required to build WCSLIB.  One of the
+    ANSI C header files it requires is missing or unusable.
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ERROR: WCSLIB configuration failure.
+    -------------------------------------------------------------------" "$LINENO" 5
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_long_int" >&5
-echo "${ECHO_T}$ac_cv_type_long_int" >&6; }
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ echo "$as_me:$LINENO: checking size of long int" >&5
-echo $ECHO_N "checking size of long int... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_long_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Checks for ANSI C library functions (suggested by autoscan - fseeko and
+# stat are only required by fitshdr).
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
+$as_echo_n "checking for floor in -lm... " >&6; }
+if ${ac_cv_lib_m_floor+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  if test "$cross_compiling" = yes; then
-  # Depending upon the size, compute the lo and hi bounds.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floor ();
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
+return floor ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid; break
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_floor=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_lo=`expr $ac_mid + 1`
-			if test $ac_lo -le $ac_mid; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid + 1`
+  ac_cv_lib_m_floor=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
+$as_echo "$ac_cv_lib_m_floor" >&6; }
+if test "x$ac_cv_lib_m_floor" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=-1 ac_mid=-1
+  LIBS="-lm $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
   while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
-test_array [0] = 0
-
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=$ac_mid; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_hi=`expr '(' $ac_mid ')' - 1`
-			if test $ac_mid -le $ac_hi; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid`
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_lo= ac_hi=
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_sys_largefile_source=no; break
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_sys_largefile_source=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  ac_cv_sys_largefile_source=unknown
+  break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+rm -rf conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
+
+fi
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
 
-	ac_lo=`expr '(' $ac_mid ')' + 1`
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 done
-case $ac_lo in
-?*) ac_cv_sizeof_long_int=$ac_lo;;
-'') if test "$ac_cv_type_long_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-   else
-     ac_cv_sizeof_long_int=0
-   fi ;;
-esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef long int ac__type_sizeof_;
-static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
-static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
-#include <stdio.h>
-#include <stdlib.h>
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
 int
 main ()
 {
-
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (((long int) (sizeof (ac__type_sizeof_))) < 0)
-    {
-      long int i = longval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%ld\n", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%lu\n", i);
-    }
-  return ferror (f) || fclose (f) != 0;
-
+return ! malloc (0);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sizeof_long_int=`cat conftest.val`
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-if test "$ac_cv_type_long_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-   else
-     ac_cv_sizeof_long_int=0
-   fi
+  ac_cv_func_malloc_0_nonnull=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f conftest.val
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
 
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
 
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG_INT $ac_cv_sizeof_long_int
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
 _ACEOF
 
+fi
+
+done
 
-{ echo "$as_me:$LINENO: checking for long long int" >&5
-echo $ECHO_N "checking for long long int... $ECHO_C" >&6; }
-if test "${ac_cv_type_long_long_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5
+$as_echo_n "checking for GNU libc compatible realloc... " >&6; }
+if ${ac_cv_func_realloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_realloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-typedef long long int ac__type_new_;
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *realloc ();
+#endif
+
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+return ! realloc (0, 0);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_type_long_long_int=yes
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_realloc_0_nonnull=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_type_long_long_int=no
+  ac_cv_func_realloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_long_long_int" >&5
-echo "${ECHO_T}$ac_cv_type_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_realloc_0_nonnull" >&6; }
+if test $ac_cv_func_realloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_REALLOC 1" >>confdefs.h
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ echo "$as_me:$LINENO: checking size of long long int" >&5
-echo $ECHO_N "checking size of long long int... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_long_long_int+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$cross_compiling" = yes; then
-  # Depending upon the size, compute the lo and hi bounds.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef long long int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
-test_array [0] = 0
+  $as_echo "#define HAVE_REALLOC 0" >>confdefs.h
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+   case " $LIBOBJS " in
+  *" realloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS realloc.$ac_objext"
+ ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+
+
+$as_echo "#define realloc rpl_realloc" >>confdefs.h
+
+fi
+
+
+if ${ac_cv_func_setvbuf_reversed+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_func_setvbuf_reversed=no
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
+$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
+if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f conftest.sym conftest.file
+echo >conftest.file
+if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
-   typedef long long int ac__type_sizeof_;
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
+struct stat sbuf;
+     /* Linux will dereference the symlink and fail, as required by POSIX.
+	That is better in the sense that it means we will not
+	have to compile and use the lstat wrapper.  */
+     return lstat ("conftest.sym/", &sbuf) == 0;
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid; break
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_lstat_dereferences_slashed_symlink=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+  # If the `ln -s' command failed, then we probably don't even
+  # have an lstat function.
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+fi
+rm -f conftest.sym conftest.file
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
+$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
+
+test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+
+cat >>confdefs.h <<_ACEOF
+#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+_ACEOF
+
+
+if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then
+  case " $LIBOBJS " in
+  *" lstat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS lstat.$ac_objext"
+ ;;
+esac
 
-	ac_lo=`expr $ac_mid + 1`
-			if test $ac_lo -le $ac_mid; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid + 1`
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5
+$as_echo_n "checking whether stat accepts an empty string... " >&6; }
+if ${ac_cv_func_stat_empty_string_bug+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_stat_empty_string_bug=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
-   typedef long long int ac__type_sizeof_;
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
-test_array [0] = 0
-
+struct stat sbuf;
+  return stat ("", &sbuf) == 0;
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_stat_empty_string_bug=no
+else
+  ac_cv_func_stat_empty_string_bug=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5
+$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; }
+if test $ac_cv_func_stat_empty_string_bug = yes; then
+  case " $LIBOBJS " in
+  *" stat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS stat.$ac_objext"
+ ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef long long int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
-test_array [0] = 0
 
-  ;
-  return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STAT_EMPTY_STRING_BUG 1
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_lo=$ac_mid; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_hi=`expr '(' $ac_mid ')' - 1`
-			if test $ac_mid -le $ac_hi; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			ac_mid=`expr 2 '*' $ac_mid`
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+for ac_func in vprintf
+do :
+  ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
 
-	ac_lo= ac_hi=
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+done
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+
+for ac_func in floor memset pow setlocale sqrt strchr strstr
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+
+fi
+done
+
+
+# System libraries that may be required by WCSLIB itself.
+# SunOS, extra maths functions.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cosd in -lsunmath" >&5
+$as_echo_n "checking for cosd in -lsunmath... " >&6; }
+if ${ac_cv_lib_sunmath_cosd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsunmath  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-   typedef long long int ac__type_sizeof_;
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cosd ();
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
+return cosd ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_hi=$ac_mid
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sunmath_cosd=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_lo=`expr '(' $ac_mid ')' + 1`
+  ac_cv_lib_sunmath_cosd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_cosd" >&5
+$as_echo "$ac_cv_lib_sunmath_cosd" >&6; }
+if test "x$ac_cv_lib_sunmath_cosd" = xyes; then :
+  LIBS="-lsunmath $LIBS"
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# See if we can find sincos().
+for ac_func in sincos
+do :
+  ac_fn_c_check_func "$LINENO" "sincos" "ac_cv_func_sincos"
+if test "x$ac_cv_func_sincos" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SINCOS 1
+_ACEOF
+
+fi
 done
-case $ac_lo in
-?*) ac_cv_sizeof_long_long_int=$ac_lo;;
-'') if test "$ac_cv_type_long_long_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-   else
-     ac_cv_sizeof_long_long_int=0
-   fi ;;
-esac
+
+
+# Check the size and availability of integer data types.
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+  if test "$ac_cv_type_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-   typedef long long int ac__type_sizeof_;
-static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
-static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
 
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (((long int) (sizeof (ac__type_sizeof_))) < 0)
-    {
-      long int i = longval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%ld\n", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ((long int) (sizeof (ac__type_sizeof_))))
-	return 1;
-      fprintf (f, "%lu\n", i);
-    }
-  return ferror (f) || fclose (f) != 0;
 
-  ;
-  return 0;
-}
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5
+$as_echo_n "checking size of long int... " >&6; }
+if ${ac_cv_sizeof_long_int+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long int)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5
+$as_echo "$ac_cv_sizeof_long_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_INT $ac_cv_sizeof_long_int
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sizeof_long_long_int=`cat conftest.val`
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5
+$as_echo_n "checking size of long long int... " >&6; }
+if ${ac_cv_sizeof_long_long_int+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int"        "$ac_includes_default"; then :
 
-( exit $ac_status )
-if test "$ac_cv_type_long_long_int" = yes; then
-     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long int)
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
+else
+  if test "$ac_cv_type_long_long_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long int)
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_long_long_int=0
    fi
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f conftest.val
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5
+$as_echo "$ac_cv_sizeof_long_long_int" >&6; }
 
 
 
@@ -8334,42 +5622,30 @@ _ACEOF
 #   gcc x86_64:   32     64       64          64
 if test "x$ac_cv_sizeof_long_long_int" = x8; then
 
-cat >>confdefs.h <<\_ACEOF
-#define WCSLIB_INT64 long long int
-_ACEOF
+$as_echo "#define WCSLIB_INT64 long long int" >>confdefs.h
 
 elif test "x$ac_cv_sizeof_long_int" = x8; then
 
-cat >>confdefs.h <<\_ACEOF
-#define WCSLIB_INT64 long int
-_ACEOF
+$as_echo "#define WCSLIB_INT64 long int" >>confdefs.h
 
 elif test "x$ac_cv_sizeof_int" = x8; then
 
-cat >>confdefs.h <<\_ACEOF
-#define WCSLIB_INT64 int
-_ACEOF
+$as_echo "#define WCSLIB_INT64 int" >>confdefs.h
 
 fi
 
 # Does printf() have the z modifier for size_t type?  Important for 64-bit.
-{ echo "$as_me:$LINENO: checking for printf z format modifier for size_t type" >&5
-echo $ECHO_N "checking for printf z format modifier for size_t type... $ECHO_C" >&6; }
-if test "$cross_compiling" = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf z format modifier for size_t type" >&5
+$as_echo_n "checking for printf z format modifier for size_t type... " >&6; }
+if test "$cross_compiling" = yes; then :
 
-cat >>confdefs.h <<\_ACEOF
-#define MODZ ""
-_ACEOF
+$as_echo "#define MODZ \"\"" >>confdefs.h
 
-    { echo "$as_me:$LINENO: result: assumed not" >&5
-echo "${ECHO_T}assumed not" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: assumed not" >&5
+$as_echo "assumed not" >&6; }
 
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
@@ -8384,53 +5660,25 @@ char buf[64];
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
 
-cat >>confdefs.h <<\_ACEOF
-#define MODZ "z"
-_ACEOF
+$as_echo "#define MODZ \"z\"" >>confdefs.h
 
-    { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
 
-cat >>confdefs.h <<\_ACEOF
-#define MODZ ""
-_ACEOF
+$as_echo "#define MODZ \"\"" >>confdefs.h
 
-    { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
 
 
-
 # Starting values, may be augmented later.
 SUBDIRS="C"
 TSTDIRS="C"
@@ -8446,12 +5694,12 @@ INSTDIR="C"
 #   configure --enable-fortran=no
 #   F77=no configure            ...bash
 # Check whether --enable-fortran was given.
-if test "${enable_fortran+set}" = set; then
+if test "${enable_fortran+set}" = set; then :
   enableval=$enable_fortran;
 fi
 
 # Check whether --enable-fortran was given.
-if test "${enable_fortran+set}" = set; then
+if test "${enable_fortran+set}" = set; then :
   enableval=$enable_fortran;
 fi
 
@@ -8462,8 +5710,8 @@ fi
 if test "x$F77" = xno ; then
   F77=
 
-  { echo "$as_me:$LINENO: WARNING: Compilation of Fortran wrappers and PGSBOX disabled" >&5
-echo "$as_me: WARNING: Compilation of Fortran wrappers and PGSBOX disabled" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compilation of Fortran wrappers and PGSBOX disabled" >&5
+$as_echo "$as_me: WARNING: Compilation of Fortran wrappers and PGSBOX disabled" >&2;}
 
 else
   if test "x$F77" = x ; then
@@ -8478,10 +5726,10 @@ if test -n "$ac_tool_prefix"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_F77+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_F77+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$F77"; then
   ac_cv_prog_F77="$F77" # Let the user override the test.
@@ -8491,25 +5739,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 F77=$ac_cv_prog_F77
 if test -n "$F77"; then
-  { echo "$as_me:$LINENO: result: $F77" >&5
-echo "${ECHO_T}$F77" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -8523,10 +5771,10 @@ if test -z "$F77"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_F77+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_F77"; then
   ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
@@ -8536,25 +5784,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_F77="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_F77=$ac_cv_prog_ac_ct_F77
 if test -n "$ac_ct_F77"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
-echo "${ECHO_T}$ac_ct_F77" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -8566,12 +5814,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     F77=$ac_ct_F77
@@ -8580,50 +5824,41 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
 rm -f a.out
 
 # If we don't use `.F' as extension, the preprocessor is not run on the
 # input file.  (Note that this only needs to work for GNU compilers.)
 ac_save_ext=$ac_ext
 ac_ext=F
-{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; }
-if test "${ac_cv_f77_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if ${ac_cv_f77_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  cat > conftest.$ac_ext <<_ACEOF
       program main
 #ifndef __GNUC__
        choke me
@@ -8631,82 +5866,42 @@ else
 
       end
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_f77_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_f77_try_compile "$LINENO"; then :
   ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_compiler_gnu=no
+else
+  ac_compiler_gnu=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_f77_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
 ac_ext=$ac_save_ext
 ac_test_FFLAGS=${FFLAGS+set}
 ac_save_FFLAGS=$FFLAGS
 FFLAGS=
-{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
-echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_f77_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if ${ac_cv_prog_f77_g+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   FFLAGS=-g
-cat >conftest.$ac_ext <<_ACEOF
+cat > conftest.$ac_ext <<_ACEOF
       program main
 
       end
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_f77_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_f77_try_compile "$LINENO"; then :
   ac_cv_prog_f77_g=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_prog_f77_g=no
+  ac_cv_prog_f77_g=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
-echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
 if test "$ac_test_FFLAGS" = set; then
   FFLAGS=$ac_save_FFLAGS
 elif test $ac_cv_prog_f77_g = yes; then
@@ -8723,7 +5918,11 @@ else
   fi
 fi
 
-G77=`test $ac_compiler_gnu = yes && echo yes`
+if test $ac_compiler_gnu = yes; then
+  G77=yes
+else
+  G77=
+fi
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8733,20 +5932,18 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
   fi
 
   if test "x$F77" = x; then
-    { echo "$as_me:$LINENO: WARNING:
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
       ------------------------------------------------------------------
       Fortran compiler not found, will skip Fortran wrappers and PGSBOX.
       ------------------------------------------------------------------" >&5
-echo "$as_me: WARNING:
+$as_echo "$as_me: WARNING:
       ------------------------------------------------------------------
       Fortran compiler not found, will skip Fortran wrappers and PGSBOX.
       ------------------------------------------------------------------" >&2;}
 
     # Best guess at Fortran name mangling for use if a compiler does ever
     # become available.
-    cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) name ## _
-_ACEOF
+    $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h
 
 
   else
@@ -8757,8 +5954,8 @@ _ACEOF
       fi
     fi
 
-    { echo "$as_me:$LINENO: checking whether $F77 accepts -I" >&5
-echo $ECHO_N "checking whether $F77 accepts -I... $ECHO_C" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -I" >&5
+$as_echo_n "checking whether $F77 accepts -I... " >&6; }
     ac_ext=f
 ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -8767,38 +5964,18 @@ ac_compiler_gnu=$ac_cv_f77_compiler_gnu
     FFLAGS_save=$FFLAGS
     FFLAGS=-I.
 
-cat >conftest.$ac_ext <<_ACEOF
+cat > conftest.$ac_ext <<_ACEOF
       program main
 
       end
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_f77_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  FFLAGS="$FFLAGS_save -I."; { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+if ac_fn_f77_try_compile "$LINENO"; then :
+  FFLAGS="$FFLAGS_save -I."; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	FFLAGS="$FFLAGS_save"; { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  FFLAGS="$FFLAGS_save"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8810,41 +5987,58 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
     # Libraries required by the Fortran compiler itself (sets FLIBS).
     # Required by utilities and test programs written in C that link to
     # Fortran object modules such as pgsbox.
-    ac_ext=f
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+ac_ext=f
 ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to get verbose linking output from $F77" >&5
-echo $ECHO_N "checking how to get verbose linking output from $F77... $ECHO_C" >&6; }
-if test "${ac_cv_prog_f77_v+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $F77" >&5
+$as_echo_n "checking how to get verbose linking output from $F77... " >&6; }
+if ${ac_cv_prog_f77_v+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  cat > conftest.$ac_ext <<_ACEOF
       program main
 
       end
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_f77_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_f77_try_compile "$LINENO"; then :
   ac_cv_prog_f77_v=
 # Try some options frequently used verbose output
 for ac_verb in -v -verbose --verbose -V -\#\#\#; do
-  cat >conftest.$ac_ext <<_ACEOF
+  cat > conftest.$ac_ext <<_ACEOF
       program main
 
       end
@@ -8858,27 +6052,38 @@ ac_save_FFLAGS=$FFLAGS
 FFLAGS="$FFLAGS $ac_verb"
 eval "set x $ac_link"
 shift
-echo "$as_me:$LINENO: $*" >&5
-ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'`
-echo "$ac_f77_v_output" >&5
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+  sed '/^Driving:/d; /^Configured with:/d;
+      '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_f77_v_output" >&5
 FFLAGS=$ac_save_FFLAGS
 
-rm -f -r conftest*
+rm -rf conftest*
 
 # On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
 # /foo, /bar, and /baz are search directories for the Fortran linker.
 # Here, we change these into -L/foo -L/bar -L/baz (and put it first):
 ac_f77_v_output="`echo $ac_f77_v_output |
 	grep 'LPATH is:' |
-	sed 's,.*LPATH is\(: *[^ ]*\).*,\1,;s,: */, -L/,g'` $ac_f77_v_output"
+	sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
 
 # FIXME: we keep getting bitten by quoted arguments; a more general fix
 #        that detects unbalanced quotes in FLIBS should be implemented
 #        and (ugh) tested at some point.
 case $ac_f77_v_output in
-  # If we are using xlf then replace all the commas with spaces.
+  # With xlf replace commas with spaces,
+  # and remove "-link" and closing parenthesis.
   *xlfentry*)
-    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` ;;
+    ac_f77_v_output=`echo $ac_f77_v_output |
+      sed '
+        s/,/ /g
+        s/ -link / /g
+        s/) *$//
+      '
+    ` ;;
 
   # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
   # $LIBS confuse us, and the libraries appear later in the output anyway).
@@ -8890,9 +6095,19 @@ case $ac_f77_v_output in
   # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
   *-cmdline\ * | *-ignore\ * | *-def\ *)
     ac_f77_v_output=`echo $ac_f77_v_output | sed "\
-        s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
-        s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
-        s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+	s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
+	s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
+	s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+
+  # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+  *fort77*f2c*gcc*)
+    ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n '
+        /:[	 ]\+Running[	 ]\{1,\}"gcc"/{
+          /"-c"/d
+          /[.]c"*/d
+          s/^.*"gcc"/"gcc"/
+          s/"//gp
+        }'` ;;
 
   # If we are using Cray Fortran then delete quotes.
   *cft90*)
@@ -8903,39 +6118,35 @@ esac
   # look for -l* and *.a constructs in the output
   for ac_arg in $ac_f77_v_output; do
      case $ac_arg in
-        [\\/]*.a | ?:[\\/]*.a | -[lLRu]*)
-          ac_cv_prog_f77_v=$ac_verb
-          break 2 ;;
+	[\\/]*.a | ?:[\\/]*.a | -[lLRu]*)
+	  ac_cv_prog_f77_v=$ac_verb
+	  break 2 ;;
      esac
   done
 done
 if test -z "$ac_cv_prog_f77_v"; then
-   { echo "$as_me:$LINENO: WARNING: cannot determine how to obtain linking information from $F77" >&5
-echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;}
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $F77" >&5
+$as_echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;}
 fi
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	{ echo "$as_me:$LINENO: WARNING: compilation failed" >&5
-echo "$as_me: WARNING: compilation failed" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5
+$as_echo "$as_me: WARNING: compilation failed" >&2;}
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_v" >&5
-echo "${ECHO_T}$ac_cv_prog_f77_v" >&6; }
-{ echo "$as_me:$LINENO: checking for Fortran 77 libraries of $F77" >&5
-echo $ECHO_N "checking for Fortran 77 libraries of $F77... $ECHO_C" >&6; }
-if test "${ac_cv_f77_libs+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_v" >&5
+$as_echo "$ac_cv_prog_f77_v" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 libraries of $F77" >&5
+$as_echo_n "checking for Fortran 77 libraries of $F77... " >&6; }
+if ${ac_cv_f77_libs+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test "x$FLIBS" != "x"; then
   ac_cv_f77_libs="$FLIBS" # Let the user override the test.
 else
 
-cat >conftest.$ac_ext <<_ACEOF
+cat > conftest.$ac_ext <<_ACEOF
       program main
 
       end
@@ -8949,27 +6160,38 @@ ac_save_FFLAGS=$FFLAGS
 FFLAGS="$FFLAGS $ac_cv_prog_f77_v"
 eval "set x $ac_link"
 shift
-echo "$as_me:$LINENO: $*" >&5
-ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'`
-echo "$ac_f77_v_output" >&5
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+  sed '/^Driving:/d; /^Configured with:/d;
+      '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_f77_v_output" >&5
 FFLAGS=$ac_save_FFLAGS
 
-rm -f -r conftest*
+rm -rf conftest*
 
 # On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
 # /foo, /bar, and /baz are search directories for the Fortran linker.
 # Here, we change these into -L/foo -L/bar -L/baz (and put it first):
 ac_f77_v_output="`echo $ac_f77_v_output |
 	grep 'LPATH is:' |
-	sed 's,.*LPATH is\(: *[^ ]*\).*,\1,;s,: */, -L/,g'` $ac_f77_v_output"
+	sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
 
 # FIXME: we keep getting bitten by quoted arguments; a more general fix
 #        that detects unbalanced quotes in FLIBS should be implemented
 #        and (ugh) tested at some point.
 case $ac_f77_v_output in
-  # If we are using xlf then replace all the commas with spaces.
+  # With xlf replace commas with spaces,
+  # and remove "-link" and closing parenthesis.
   *xlfentry*)
-    ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` ;;
+    ac_f77_v_output=`echo $ac_f77_v_output |
+      sed '
+        s/,/ /g
+        s/ -link / /g
+        s/) *$//
+      '
+    ` ;;
 
   # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
   # $LIBS confuse us, and the libraries appear later in the output anyway).
@@ -8981,9 +6203,19 @@ case $ac_f77_v_output in
   # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
   *-cmdline\ * | *-ignore\ * | *-def\ *)
     ac_f77_v_output=`echo $ac_f77_v_output | sed "\
-        s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
-        s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
-        s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+	s/-cmdline  *'[^']*'/ /g; s/-cmdline  *\"[^\"]*\"/ /g
+	s/-ignore  *'[^']*'/ /g; s/-ignore  *\"[^\"]*\"/ /g
+	s/-def  *'[^']*'/ /g; s/-def  *\"[^\"]*\"/ /g"` ;;
+
+  # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+  *fort77*f2c*gcc*)
+    ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n '
+        /:[	 ]\+Running[	 ]\{1,\}"gcc"/{
+          /"-c"/d
+          /[.]c"*/d
+          s/^.*"gcc"/"gcc"/
+          s/"//gp
+        }'` ;;
 
   # If we are using Cray Fortran then delete quotes.
   *cft90*)
@@ -9002,8 +6234,8 @@ while test $# != 1; do
   shift
   ac_arg=$1
   case $ac_arg in
-        [\\/]*.a | ?:[\\/]*.a)
-            ac_exists=false
+	[\\/]*.a | ?:[\\/]*.a)
+	    ac_exists=false
   for ac_i in $ac_cv_f77_libs; do
     if test x"$ac_arg" = x"$ac_i"; then
       ac_exists=true
@@ -9011,15 +6243,14 @@ while test $# != 1; do
     fi
   done
 
-  if test x"$ac_exists" = xtrue; then
-  :
+  if test x"$ac_exists" = xtrue; then :
+
 else
   ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
 fi
-
-          ;;
-        -bI:*)
-            ac_exists=false
+	  ;;
+	-bI:*)
+	    ac_exists=false
   for ac_i in $ac_cv_f77_libs; do
     if test x"$ac_arg" = x"$ac_i"; then
       ac_exists=true
@@ -9027,8 +6258,8 @@ fi
     fi
   done
 
-  if test x"$ac_exists" = xtrue; then
-  :
+  if test x"$ac_exists" = xtrue; then :
+
 else
   if test "$ac_compiler_gnu" = yes; then
   for ac_link_opt in $ac_arg; do
@@ -9038,18 +6269,22 @@ else
   ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
 fi
 fi
-
-          ;;
-          # Ignore these flags.
-        -lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*)
-          ;;
-        -lkernel32)
-          test x"$CYGWIN" != xyes && ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
-          ;;
-        -[LRuYz])
-          # These flags, when seen by themselves, take an argument.
-          # We remove the space between option and argument and re-iterate
-          # unless we find an empty arg or a new option (starting with -)
+	  ;;
+	  # Ignore these flags.
+	-lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \
+	  |-LANG:=* | -LIST:* | -LNO:* | -link)
+	  ;;
+	-lkernel32)
+	  case $host_os in
+	  *cygwin*) ;;
+	  *) ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+	    ;;
+	  esac
+	  ;;
+	-[LRuYz])
+	  # These flags, when seen by themselves, take an argument.
+	  # We remove the space between option and argument and re-iterate
+	  # unless we find an empty arg or a new option (starting with -)
 	  case $2 in
 	     "" | -*);;
 	     *)
@@ -9058,10 +6293,10 @@ fi
 		set X $ac_arg "$@"
 		;;
 	  esac
-          ;;
-        -YP,*)
-          for ac_j in `echo $ac_arg | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do
-              ac_exists=false
+	  ;;
+	-YP,*)
+	  for ac_j in `$as_echo "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do
+	      ac_exists=false
   for ac_i in $ac_cv_f77_libs; do
     if test x"$ac_j" = x"$ac_i"; then
       ac_exists=true
@@ -9069,17 +6304,16 @@ fi
     fi
   done
 
-  if test x"$ac_exists" = xtrue; then
-  :
+  if test x"$ac_exists" = xtrue; then :
+
 else
   ac_arg="$ac_arg $ac_j"
-                               ac_cv_f77_libs="$ac_cv_f77_libs $ac_j"
+			       ac_cv_f77_libs="$ac_cv_f77_libs $ac_j"
 fi
-
-          done
-          ;;
-        -[lLR]*)
-            ac_exists=false
+	  done
+	  ;;
+	-[lLR]*)
+	    ac_exists=false
   for ac_i in $ac_cv_f77_libs; do
     if test x"$ac_arg" = x"$ac_i"; then
       ac_exists=true
@@ -9087,17 +6321,16 @@ fi
     fi
   done
 
-  if test x"$ac_exists" = xtrue; then
-  :
+  if test x"$ac_exists" = xtrue; then :
+
 else
   ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
 fi
-
-          ;;
+	  ;;
 	-zallextract*| -zdefaultextract)
 	  ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
 	  ;;
-          # Ignore everything else.
+	  # Ignore everything else.
   esac
 done
 # restore positional arguments
@@ -9108,10 +6341,10 @@ set X $ac_save_positional; shift
 # must begin with a "/").
 case `(uname -sr) 2>/dev/null` in
    "SunOS 5"*)
-      ac_ld_run_path=`echo $ac_f77_v_output |
-                        sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'`
+      ac_ld_run_path=`$as_echo "$ac_f77_v_output" |
+			sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'`
       test "x$ac_ld_run_path" != x &&
-        if test "$ac_compiler_gnu" = yes; then
+	if test "$ac_compiler_gnu" = yes; then
   for ac_link_opt in $ac_ld_run_path; do
     ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt"
   done
@@ -9123,8 +6356,8 @@ esac
 fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x"
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_libs" >&5
-echo "${ECHO_T}$ac_cv_f77_libs" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_libs" >&5
+$as_echo "$ac_cv_f77_libs" >&6; }
 FLIBS="$ac_cv_f77_libs"
 
 
@@ -9141,10 +6374,10 @@ ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
 
-{ echo "$as_me:$LINENO: checking for dummy main to link with Fortran 77 libraries" >&5
-echo $ECHO_N "checking for dummy main to link with Fortran 77 libraries... $ECHO_C" >&6; }
-if test "${ac_cv_f77_dummy_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dummy main to link with Fortran 77 libraries" >&5
+$as_echo_n "checking for dummy main to link with Fortran 77 libraries... " >&6; }
+if ${ac_cv_f77_dummy_main+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_f77_dm_save_LIBS=$LIBS
  LIBS="$LIBS $FLIBS"
@@ -9156,11 +6389,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
  # First, try linking without a dummy main:
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 #ifdef F77_DUMMY_MAIN
@@ -9179,42 +6408,17 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_fortran_dummy_main=none
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_fortran_dummy_main=unknown
+  ac_cv_fortran_dummy_main=unknown
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 
  if test $ac_cv_fortran_dummy_main = unknown; then
    for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do
-     cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define $ac_fortran_dm_var $ac_func
 #ifdef F77_DUMMY_MAIN
@@ -9233,34 +6437,11 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_fortran_dummy_main=$ac_func; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
    done
  fi
  ac_ext=f
@@ -9268,14 +6449,14 @@ ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
  ac_cv_f77_dummy_main=$ac_cv_fortran_dummy_main
- rm -f -r conftest*
+ rm -rf conftest*
  LIBS=$ac_f77_dm_save_LIBS
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_dummy_main" >&5
-echo "${ECHO_T}$ac_cv_f77_dummy_main" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_dummy_main" >&5
+$as_echo "$ac_cv_f77_dummy_main" >&6; }
 F77_DUMMY_MAIN=$ac_cv_f77_dummy_main
-if test "$F77_DUMMY_MAIN" != unknown; then
+if test "$F77_DUMMY_MAIN" != unknown; then :
   if test $F77_DUMMY_MAIN != none; then
 
 cat >>confdefs.h <<_ACEOF
@@ -9284,21 +6465,17 @@ _ACEOF
 
   if test "x$ac_cv_fc_dummy_main" = "x$ac_cv_f77_dummy_main"; then
 
-cat >>confdefs.h <<\_ACEOF
-#define FC_DUMMY_MAIN_EQ_F77 1
-_ACEOF
+$as_echo "#define FC_DUMMY_MAIN_EQ_F77 1" >>confdefs.h
 
   fi
 fi
 else
-  { { echo "$as_me:$LINENO: error: linking to Fortran libraries from C fails
-See \`config.log' for more details." >&5
-echo "$as_me: error: linking to Fortran libraries from C fails
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "linking to Fortran libraries from C fails
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -9309,12 +6486,12 @@ ac_ext=f
 ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-{ echo "$as_me:$LINENO: checking for Fortran 77 name-mangling scheme" >&5
-echo $ECHO_N "checking for Fortran 77 name-mangling scheme... $ECHO_C" >&6; }
-if test "${ac_cv_f77_mangling+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 name-mangling scheme" >&5
+$as_echo_n "checking for Fortran 77 name-mangling scheme... " >&6; }
+if ${ac_cv_f77_mangling+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  cat > conftest.$ac_ext <<_ACEOF
       subroutine foobar()
       return
       end
@@ -9322,23 +6499,7 @@ else
       return
       end
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_f77_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_f77_try_compile "$LINENO"; then :
   mv conftest.$ac_objext cfortran_test.$ac_objext
 
   ac_save_LIBS=$LIBS
@@ -9353,11 +6514,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
   for ac_foobar in foobar FOOBAR; do
     for ac_underscore in "" "_"; do
       ac_func="$ac_foobar$ac_underscore"
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -9383,34 +6540,11 @@ return $ac_func ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_success=yes; break 2
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
     done
   done
   ac_ext=f
@@ -9438,11 +6572,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
      ac_success_extra=no
      for ac_extra in "" "_"; do
 	ac_func="$ac_foo_bar$ac_underscore$ac_extra"
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -9468,34 +6598,11 @@ return $ac_func ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_success_extra=yes; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
      done
      ac_ext=f
 ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
@@ -9504,16 +6611,16 @@ ac_compiler_gnu=$ac_cv_f77_compiler_gnu
 
      if test "$ac_success_extra" = "yes"; then
 	ac_cv_f77_mangling="$ac_case case"
-        if test -z "$ac_underscore"; then
-           ac_cv_f77_mangling="$ac_cv_f77_mangling, no underscore"
+	if test -z "$ac_underscore"; then
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, no underscore"
 	else
-           ac_cv_f77_mangling="$ac_cv_f77_mangling, underscore"
-        fi
-        if test -z "$ac_extra"; then
-           ac_cv_f77_mangling="$ac_cv_f77_mangling, no extra underscore"
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, underscore"
+	fi
+	if test -z "$ac_extra"; then
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, no extra underscore"
 	else
-           ac_cv_f77_mangling="$ac_cv_f77_mangling, extra underscore"
-        fi
+	   ac_cv_f77_mangling="$ac_cv_f77_mangling, extra underscore"
+	fi
       else
 	ac_cv_f77_mangling="unknown"
       fi
@@ -9522,23 +6629,19 @@ ac_compiler_gnu=$ac_cv_f77_compiler_gnu
   fi
 
   LIBS=$ac_save_LIBS
-  rm -f -r cfortran_test* conftest*
+  rm -rf conftest*
+  rm -f cfortran_test*
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	{ { echo "$as_me:$LINENO: error: cannot compile a simple Fortran program
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compile a simple Fortran program
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compile a simple Fortran program
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_mangling" >&5
-echo "${ECHO_T}$ac_cv_f77_mangling" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_mangling" >&5
+$as_echo "$ac_cv_f77_mangling" >&6; }
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -9550,85 +6653,51 @@ ac_ext=f
 ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-
-
 case $ac_cv_f77_mangling in
   "lower case, no underscore, no extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) name
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) name
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) name" >>confdefs.h
  ;;
   "lower case, no underscore, extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) name
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) name ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h
  ;;
   "lower case, underscore, no extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) name ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) name ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h
  ;;
   "lower case, underscore, extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) name ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) name ## __
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) name ## __" >>confdefs.h
  ;;
   "upper case, no underscore, no extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) NAME
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) NAME
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME" >>confdefs.h
  ;;
   "upper case, no underscore, extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) NAME
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) NAME ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h
  ;;
   "upper case, underscore, no extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) NAME ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) NAME ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h
  ;;
   "upper case, underscore, extra underscore")
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC(name,NAME) NAME ## _
-_ACEOF
+	  $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h
 
-          cat >>confdefs.h <<\_ACEOF
-#define F77_FUNC_(name,NAME) NAME ## __
-_ACEOF
+	  $as_echo "#define F77_FUNC_(name,NAME) NAME ## __" >>confdefs.h
  ;;
   *)
-          { echo "$as_me:$LINENO: WARNING: unknown Fortran name-mangling scheme" >&5
-echo "$as_me: WARNING: unknown Fortran name-mangling scheme" >&2;}
-          ;;
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown Fortran name-mangling scheme" >&5
+$as_echo "$as_me: WARNING: unknown Fortran name-mangling scheme" >&2;}
+	  ;;
 esac
 
 ac_ext=c
@@ -9648,19 +6717,15 @@ fi
 # System-dependent system libraries (for building the sharable library).
 #-----------------------------------------------------------------------
 # Darwin (contains stubs for long double).
-as_ac_Lib=`echo "ac_cv_lib_SystemStubs_printf\$LDBLStub" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for printf\$LDBLStub in -lSystemStubs" >&5
-echo $ECHO_N "checking for printf\$LDBLStub in -lSystemStubs... $ECHO_C" >&6; }
-if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+as_ac_Lib=`$as_echo "ac_cv_lib_SystemStubs_printf\\$LDBLStub" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf\$LDBLStub in -lSystemStubs" >&5
+$as_echo_n "checking for printf\$LDBLStub in -lSystemStubs... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lSystemStubs  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -9686,40 +6751,19 @@ return printf\$LDBLStub ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   eval "$as_ac_Lib=yes"
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	eval "$as_ac_Lib=no"
+  eval "$as_ac_Lib=no"
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-ac_res=`eval echo '${'$as_ac_Lib'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Lib'}'` = yes; then
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
   LIBS="$LIBS -lSystemStubs"
 fi
 
@@ -9731,10 +6775,10 @@ fi
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
@@ -9744,25 +6788,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 RANLIB=$ac_cv_prog_RANLIB
 if test -n "$RANLIB"; then
-  { echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -9771,10 +6815,10 @@ if test -z "$ac_cv_prog_RANLIB"; then
   ac_ct_RANLIB=$RANLIB
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_RANLIB"; then
   ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
@@ -9784,25 +6828,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
 if test -n "$ac_ct_RANLIB"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
   if test "x$ac_ct_RANLIB" = x; then
@@ -9810,12 +6854,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     RANLIB=$ac_ct_RANLIB
@@ -9874,15 +6914,15 @@ fi
 
 
 # Installation utilities.
-{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
 LN_S=$as_ln_s
 if test "$LN_S" = "ln -s"; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
 fi
 
 # Find a good install program.  We prefer a C program (faster),
@@ -9898,22 +6938,23 @@ fi
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
-{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in
-  ./ | .// | /cC/* | \
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
-  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
   /usr/ucb/* ) ;;
   *)
     # OSF1 and SCO ODT 3.0 have their own names for install.
@@ -9921,7 +6962,7 @@ case $as_dir/ in
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -9931,17 +6972,29 @@ case $as_dir/ in
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
-	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-	    break 3
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
 	  fi
 	fi
       done
     done
     ;;
 esac
-done
+
+  done
 IFS=$as_save_IFS
 
+rm -rf conftest.one conftest.two conftest.dir
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
@@ -9954,8 +7007,8 @@ fi
     INSTALL=$ac_install_sh
   fi
 fi
-{ echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -9966,157 +7019,24 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
-{ echo "$as_me:$LINENO: End of primary configuration.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: End of primary configuration.
 " >&5
-echo "$as_me: End of primary configuration.
+$as_echo "$as_me: End of primary configuration.
 " >&6;}
 
 
 # The following are required to build utilities and test programs.
 # ----------------------------------------------------------------
-{ echo "$as_me:$LINENO: Looking for libraries etc. for utilities and test suite..." >&5
-echo "$as_me: Looking for libraries etc. for utilities and test suite..." >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Looking for libraries etc. for utilities and test suite..." >&5
+$as_echo "$as_me: Looking for libraries etc. for utilities and test suite..." >&6;}
 
 # Check for other quasi-standard header files.
-
 for ac_header in unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    ( cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to mark at calabretta.id.au ##
-## ------------------------------------ ##
-_ASBOX
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_UNISTD_H 1
 _ACEOF
 
 fi
@@ -10125,19 +7045,16 @@ done
 
 
 # Large file support.
-{ echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
-echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_source+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   while :; do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 #ifdef F77_DUMMY_MAIN
 
 #  ifdef __cplusplus
@@ -10149,47 +7066,22 @@ cat >>conftest.$ac_ext <<_ACEOF
 int
 main ()
 {
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_sys_largefile_source=no; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define _LARGEFILE_SOURCE 1
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 #ifdef F77_DUMMY_MAIN
 
 #  ifdef __cplusplus
@@ -10201,45 +7093,23 @@ cat >>conftest.$ac_ext <<_ACEOF
 int
 main ()
 {
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_sys_largefile_source=1; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
   ac_cv_sys_largefile_source=unknown
   break
 done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
 case $ac_cv_sys_largefile_source in #(
   no | unknown) ;;
   *)
@@ -10248,30 +7118,28 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 ;;
 esac
-rm -f -r conftest*
+rm -rf conftest*
 
 # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
 # in glibc 2.1.3, but that breaks too many other things.
 # If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
 if test $ac_cv_sys_largefile_source != unknown; then
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FSEEKO 1
-_ACEOF
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
 
 fi
 
 # Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then
+if test "${enable_largefile+set}" = set; then :
   enableval=$enable_largefile;
 fi
 
 if test "$enable_largefile" != no; then
 
-  { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_cv_sys_largefile_CC=no
      if test "$GCC" != yes; then
@@ -10279,11 +7147,7 @@ else
        while :; do
 	 # IRIX 6.2 and later do not support large files by default,
 	 # so use the C compiler's -n32 option if that helps.
-	 cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
  /* Check that off_t can represent 2**63 - 1 correctly.
@@ -10310,58 +7174,14 @@ main ()
   return 0;
 }
 _ACEOF
-	 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+	 if ac_fn_c_try_compile "$LINENO"; then :
   break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext
 	 CC="$CC -n32"
-	 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+	 if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_sys_largefile_CC=' -n32'; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext
 	 break
        done
@@ -10369,23 +7189,19 @@ rm -f core conftest.err conftest.$ac_objext
        rm -f conftest.$ac_ext
     fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
   if test "$ac_cv_sys_largefile_CC" != no; then
     CC=$CC$ac_cv_sys_largefile_CC
   fi
 
-  { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   while :; do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
  /* Check that off_t can represent 2**63 - 1 correctly.
@@ -10412,37 +7228,11 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_sys_file_offset_bits=no; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define _FILE_OFFSET_BITS 64
 #include <sys/types.h>
@@ -10470,38 +7260,16 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_sys_file_offset_bits=64; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   ac_cv_sys_file_offset_bits=unknown
   break
 done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
-echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
 case $ac_cv_sys_file_offset_bits in #(
   no | unknown) ;;
   *)
@@ -10510,19 +7278,15 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 ;;
 esac
-rm -f -r conftest*
+rm -rf conftest*
   if test $ac_cv_sys_file_offset_bits = unknown; then
-    { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
-echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_large_files+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   while :; do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
  /* Check that off_t can represent 2**63 - 1 correctly.
@@ -10549,37 +7313,11 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_sys_large_files=no; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define _LARGE_FILES 1
 #include <sys/types.h>
@@ -10607,38 +7345,16 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_sys_large_files=1; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   ac_cv_sys_large_files=unknown
   break
 done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
-echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
 case $ac_cv_sys_large_files in #(
   no | unknown) ;;
   *)
@@ -10647,8 +7363,10 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 ;;
 esac
-rm -f -r conftest*
+rm -rf conftest*
   fi
+
+
 fi
 
 
@@ -10658,17 +7376,17 @@ LIBDIRS=
 
 
 # Check whether --with-cfitsio was given.
-if test "${with_cfitsio+set}" = set; then
+if test "${with_cfitsio+set}" = set; then :
   withval=$with_cfitsio;
 fi
 
 if test "x$with_cfitsio" = xno ; then
-  { echo "$as_me:$LINENO: WARNING: CFITSIO disabled" >&5
-echo "$as_me: WARNING: CFITSIO disabled" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CFITSIO disabled" >&5
+$as_echo "$as_me: WARNING: CFITSIO disabled" >&2;}
 else
 
 # Check whether --with-cfitsiolib was given.
-if test "${with_cfitsiolib+set}" = set; then
+if test "${with_cfitsiolib+set}" = set; then :
   withval=$with_cfitsiolib;
 fi
 
@@ -10678,7 +7396,7 @@ fi
 
 
 # Check whether --with-cfitsioinc was given.
-if test "${with_cfitsioinc+set}" = set; then
+if test "${with_cfitsioinc+set}" = set; then :
   withval=$with_cfitsioinc;
 fi
 
@@ -10697,17 +7415,17 @@ fi
 
 
 # Check whether --with-pgplot was given.
-if test "${with_pgplot+set}" = set; then
+if test "${with_pgplot+set}" = set; then :
   withval=$with_pgplot;
 fi
 
 if test "x$with_pgplot" = xno ; then
-  { echo "$as_me:$LINENO: WARNING: PGPLOT disabled" >&5
-echo "$as_me: WARNING: PGPLOT disabled" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PGPLOT disabled" >&5
+$as_echo "$as_me: WARNING: PGPLOT disabled" >&2;}
 else
 
 # Check whether --with-pgplotlib was given.
-if test "${with_pgplotlib+set}" = set; then
+if test "${with_pgplotlib+set}" = set; then :
   withval=$with_pgplotlib;
 fi
 
@@ -10717,7 +7435,7 @@ fi
 
 
 # Check whether --with-pgplotinc was given.
-if test "${with_pgplotinc+set}" = set; then
+if test "${with_pgplotinc+set}" = set; then :
   withval=$with_pgplotinc;
 fi
 
@@ -10745,26 +7463,24 @@ if test "x$with_cfitsio" != xno -o \
            /sw/lib"
 
   for LIBDIR in $LIBDIRS ; do
-    as_ac_File=`echo "ac_cv_file_$LIBDIR" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $LIBDIR" >&5
-echo $ECHO_N "checking for $LIBDIR... $ECHO_C" >&6; }
-if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    as_ac_File=`$as_echo "ac_cv_file_$LIBDIR" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LIBDIR" >&5
+$as_echo_n "checking for $LIBDIR... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "$LIBDIR"; then
   eval "$as_ac_File=yes"
 else
   eval "$as_ac_File=no"
 fi
 fi
-ac_res=`eval echo '${'$as_ac_File'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_File'}'` = yes; then
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
   LDFLAGS="$LDFLAGS -L$LIBDIR"
 else
   continue
@@ -10785,66 +7501,58 @@ fi
   if test "x$with_cfitsio" != xno ; then
     # Search for CFITSIO.
     for INCDIR in $CFITSIO_INCDIRS $INCDIRS ; do
-      as_ac_File=`echo "ac_cv_file_$INCDIR/cfitsio/fitsio.h" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $INCDIR/cfitsio/fitsio.h" >&5
-echo $ECHO_N "checking for $INCDIR/cfitsio/fitsio.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      as_ac_File=`$as_echo "ac_cv_file_$INCDIR/cfitsio/fitsio.h" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/cfitsio/fitsio.h" >&5
+$as_echo_n "checking for $INCDIR/cfitsio/fitsio.h... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "$INCDIR/cfitsio/fitsio.h"; then
   eval "$as_ac_File=yes"
 else
   eval "$as_ac_File=no"
 fi
 fi
-ac_res=`eval echo '${'$as_ac_File'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_File'}'` = yes; then
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
   CFITSIOINC="-I$INCDIR/cfitsio"; break
 fi
 
-      as_ac_File=`echo "ac_cv_file_$INCDIR/fitsio.h" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $INCDIR/fitsio.h" >&5
-echo $ECHO_N "checking for $INCDIR/fitsio.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      as_ac_File=`$as_echo "ac_cv_file_$INCDIR/fitsio.h" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/fitsio.h" >&5
+$as_echo_n "checking for $INCDIR/fitsio.h... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "$INCDIR/fitsio.h"; then
   eval "$as_ac_File=yes"
 else
   eval "$as_ac_File=no"
 fi
 fi
-ac_res=`eval echo '${'$as_ac_File'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_File'}'` = yes; then
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
   CFITSIOINC="-I$INCDIR"; break
 fi
 
     done
 
-    { echo "$as_me:$LINENO: checking for recv in -lsocket" >&5
-echo $ECHO_N "checking for recv in -lsocket... $ECHO_C" >&6; }
-if test "${ac_cv_lib_socket_recv+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recv in -lsocket" >&5
+$as_echo_n "checking for recv in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_recv+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsocket $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -10870,54 +7578,29 @@ return recv ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_socket_recv=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_socket_recv=no
+  ac_cv_lib_socket_recv=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_recv" >&5
-echo "${ECHO_T}$ac_cv_lib_socket_recv" >&6; }
-if test $ac_cv_lib_socket_recv = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_recv" >&5
+$as_echo "$ac_cv_lib_socket_recv" >&6; }
+if test "x$ac_cv_lib_socket_recv" = xyes; then :
   CFITSIOLIB="-lsocket"
 fi
 
-    { echo "$as_me:$LINENO: checking for ffopen in -lcfitsio" >&5
-echo $ECHO_N "checking for ffopen in -lcfitsio... $ECHO_C" >&6; }
-if test "${ac_cv_lib_cfitsio_ffopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffopen in -lcfitsio" >&5
+$as_echo_n "checking for ffopen in -lcfitsio... " >&6; }
+if ${ac_cv_lib_cfitsio_ffopen+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lcfitsio $CFITSIOLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -10943,68 +7626,41 @@ return ffopen ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_cfitsio_ffopen=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_cfitsio_ffopen=no
+  ac_cv_lib_cfitsio_ffopen=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_cfitsio_ffopen" >&5
-echo "${ECHO_T}$ac_cv_lib_cfitsio_ffopen" >&6; }
-if test $ac_cv_lib_cfitsio_ffopen = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cfitsio_ffopen" >&5
+$as_echo "$ac_cv_lib_cfitsio_ffopen" >&6; }
+if test "x$ac_cv_lib_cfitsio_ffopen" = xyes; then :
   CFITSIOLIB="-lcfitsio $CFITSIOLIB"
 fi
 
 
     if test "x$CFITSIOINC" = x -o "x$CFITSIOLIB" = x; then
-      { echo "$as_me:$LINENO: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&5
-echo "$as_me: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&5
+$as_echo "$as_me: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&2;}
     else
-      { echo "$as_me:$LINENO: CFITSIO appears to be available." >&5
-echo "$as_me: CFITSIO appears to be available." >&6;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: CFITSIO appears to be available." >&5
+$as_echo "$as_me: CFITSIO appears to be available." >&6;}
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CFITSIO 1
-_ACEOF
+$as_echo "#define HAVE_CFITSIO 1" >>confdefs.h
 
 
       # Check for fits_read_wcstab, present in CFITSIO 3.004beta and later.
-      { echo "$as_me:$LINENO: checking for fits_read_wcstab in -lcfitsio" >&5
-echo $ECHO_N "checking for fits_read_wcstab in -lcfitsio... $ECHO_C" >&6; }
-if test "${ac_cv_lib_cfitsio_fits_read_wcstab+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fits_read_wcstab in -lcfitsio" >&5
+$as_echo_n "checking for fits_read_wcstab in -lcfitsio... " >&6; }
+if ${ac_cv_lib_cfitsio_fits_read_wcstab+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lcfitsio $CFITSIOLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11030,48 +7686,27 @@ return fits_read_wcstab ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_cfitsio_fits_read_wcstab=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_cfitsio_fits_read_wcstab=no
+  ac_cv_lib_cfitsio_fits_read_wcstab=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_cfitsio_fits_read_wcstab" >&5
-echo "${ECHO_T}$ac_cv_lib_cfitsio_fits_read_wcstab" >&6; }
-if test $ac_cv_lib_cfitsio_fits_read_wcstab = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cfitsio_fits_read_wcstab" >&5
+$as_echo "$ac_cv_lib_cfitsio_fits_read_wcstab" >&6; }
+if test "x$ac_cv_lib_cfitsio_fits_read_wcstab" = xyes; then :
   GETWCSTAB=
 else
   GETWCSTAB=getwcstab.o
 fi
 
       if test "x$GETWCSTAB" != x ; then
-        { echo "$as_me:$LINENO: WARNING: fits_read_wcstab not found in CFITSIO, will use
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fits_read_wcstab not found in CFITSIO, will use
                         getwcstab.c to compile test programs." >&5
-echo "$as_me: WARNING: fits_read_wcstab not found in CFITSIO, will use
+$as_echo "$as_me: WARNING: fits_read_wcstab not found in CFITSIO, will use
                         getwcstab.c to compile test programs." >&2;}
       fi
     fi
@@ -11081,49 +7716,45 @@ echo "$as_me: WARNING: fits_read_wcstab not found in CFITSIO, will use
   if test "x$F77" != x -a "x$with_pgplot" != xno ; then
     # Search for PGPLOT.
     for INCDIR in $PGPLOT_INCDIRS $INCDIRS ; do
-      as_ac_File=`echo "ac_cv_file_$INCDIR/pgplot/cpgplot.h" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $INCDIR/pgplot/cpgplot.h" >&5
-echo $ECHO_N "checking for $INCDIR/pgplot/cpgplot.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      as_ac_File=`$as_echo "ac_cv_file_$INCDIR/pgplot/cpgplot.h" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/pgplot/cpgplot.h" >&5
+$as_echo_n "checking for $INCDIR/pgplot/cpgplot.h... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "$INCDIR/pgplot/cpgplot.h"; then
   eval "$as_ac_File=yes"
 else
   eval "$as_ac_File=no"
 fi
 fi
-ac_res=`eval echo '${'$as_ac_File'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_File'}'` = yes; then
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
   PGPLOTINC="-I$INCDIR/pgplot"; break
 fi
 
-      as_ac_File=`echo "ac_cv_file_$INCDIR/cpgplot.h" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $INCDIR/cpgplot.h" >&5
-echo $ECHO_N "checking for $INCDIR/cpgplot.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      as_ac_File=`$as_echo "ac_cv_file_$INCDIR/cpgplot.h" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/cpgplot.h" >&5
+$as_echo_n "checking for $INCDIR/cpgplot.h... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "$INCDIR/cpgplot.h"; then
   eval "$as_ac_File=yes"
 else
   eval "$as_ac_File=no"
 fi
 fi
-ac_res=`eval echo '${'$as_ac_File'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_File'}'` = yes; then
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
   PGPLOTINC="-I$INCDIR"; break
 fi
 
@@ -11134,18 +7765,14 @@ fi
 
     # PGPLOT compiled by the SUN Fortran compiler but linked with something
     # else.
-    { echo "$as_me:$LINENO: checking for iand_ in -lM77" >&5
-echo $ECHO_N "checking for iand_ in -lM77... $ECHO_C" >&6; }
-if test "${ac_cv_lib_M77_iand_+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iand_ in -lM77" >&5
+$as_echo_n "checking for iand_ in -lM77... " >&6; }
+if ${ac_cv_lib_M77_iand_+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lM77 $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11171,54 +7798,29 @@ return iand_ ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_M77_iand_=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_M77_iand_=no
+  ac_cv_lib_M77_iand_=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_M77_iand_" >&5
-echo "${ECHO_T}$ac_cv_lib_M77_iand_" >&6; }
-if test $ac_cv_lib_M77_iand_ = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_M77_iand_" >&5
+$as_echo "$ac_cv_lib_M77_iand_" >&6; }
+if test "x$ac_cv_lib_M77_iand_" = xyes; then :
   PGPLOTLIB="-lM77 $PGPLOTLIB"
 fi
 
-    { echo "$as_me:$LINENO: checking for f77_init in -lF77" >&5
-echo $ECHO_N "checking for f77_init in -lF77... $ECHO_C" >&6; }
-if test "${ac_cv_lib_F77_f77_init+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for f77_init in -lF77" >&5
+$as_echo_n "checking for f77_init in -lF77... " >&6; }
+if ${ac_cv_lib_F77_f77_init+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lF77 $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11244,57 +7846,32 @@ return f77_init ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_F77_f77_init=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_F77_f77_init=no
+  ac_cv_lib_F77_f77_init=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_F77_f77_init" >&5
-echo "${ECHO_T}$ac_cv_lib_F77_f77_init" >&6; }
-if test $ac_cv_lib_F77_f77_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_F77_f77_init" >&5
+$as_echo "$ac_cv_lib_F77_f77_init" >&6; }
+if test "x$ac_cv_lib_F77_f77_init" = xyes; then :
   PGPLOTLIB="-lF77 $PGPLOTLIB"
 fi
 
 
     if test "x$F77" != xg77; then
       # For PGPLOT compiled with g77 but linked with something else.
-      { echo "$as_me:$LINENO: checking for main in -lfrtbegin" >&5
-echo $ECHO_N "checking for main in -lfrtbegin... $ECHO_C" >&6; }
-if test "${ac_cv_lib_frtbegin_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lfrtbegin" >&5
+$as_echo_n "checking for main in -lfrtbegin... " >&6; }
+if ${ac_cv_lib_frtbegin_main+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lfrtbegin $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 
@@ -11314,54 +7891,29 @@ return main ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_frtbegin_main=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_frtbegin_main=no
+  ac_cv_lib_frtbegin_main=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_frtbegin_main" >&5
-echo "${ECHO_T}$ac_cv_lib_frtbegin_main" >&6; }
-if test $ac_cv_lib_frtbegin_main = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_frtbegin_main" >&5
+$as_echo "$ac_cv_lib_frtbegin_main" >&6; }
+if test "x$ac_cv_lib_frtbegin_main" = xyes; then :
   PGPLOTLIB="-lfrtbegin $PGPLOTLIB"
 fi
 
-      { echo "$as_me:$LINENO: checking for gerror_ in -lg2c" >&5
-echo $ECHO_N "checking for gerror_ in -lg2c... $ECHO_C" >&6; }
-if test "${ac_cv_lib_g2c_gerror_+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gerror_ in -lg2c" >&5
+$as_echo_n "checking for gerror_ in -lg2c... " >&6; }
+if ${ac_cv_lib_g2c_gerror_+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lg2c $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11387,39 +7939,18 @@ return gerror_ ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_g2c_gerror_=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_g2c_gerror_=no
+  ac_cv_lib_g2c_gerror_=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_g2c_gerror_" >&5
-echo "${ECHO_T}$ac_cv_lib_g2c_gerror_" >&6; }
-if test $ac_cv_lib_g2c_gerror_ = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_g2c_gerror_" >&5
+$as_echo "$ac_cv_lib_g2c_gerror_" >&6; }
+if test "x$ac_cv_lib_g2c_gerror_" = xyes; then :
   PGPLOTLIB="-lg2c $PGPLOTLIB"
 fi
 
@@ -11431,18 +7962,14 @@ fi
       # to add -lgfortran to the link list without also adding -lgfortranbegin.
       # Doing so stops gfortran from adding -lgfortranbegin which is needed to
       # resolve "main".
-      { echo "$as_me:$LINENO: checking for _gfortran_abort in -lgfortran" >&5
-echo $ECHO_N "checking for _gfortran_abort in -lgfortran... $ECHO_C" >&6; }
-if test "${ac_cv_lib_gfortran__gfortran_abort+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _gfortran_abort in -lgfortran" >&5
+$as_echo_n "checking for _gfortran_abort in -lgfortran... " >&6; }
+if ${ac_cv_lib_gfortran__gfortran_abort+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lgfortran $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11468,51 +7995,30 @@ return _gfortran_abort ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_gfortran__gfortran_abort=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_gfortran__gfortran_abort=no
+  ac_cv_lib_gfortran__gfortran_abort=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_gfortran__gfortran_abort" >&5
-echo "${ECHO_T}$ac_cv_lib_gfortran__gfortran_abort" >&6; }
-if test $ac_cv_lib_gfortran__gfortran_abort = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gfortran__gfortran_abort" >&5
+$as_echo "$ac_cv_lib_gfortran__gfortran_abort" >&6; }
+if test "x$ac_cv_lib_gfortran__gfortran_abort" = xyes; then :
   PGPLOTLIB="-lgfortran $PGPLOTLIB"
 fi
 
     fi
 
     # Search for X11 includes and libraries.
-    { echo "$as_me:$LINENO: checking for X" >&5
-echo $ECHO_N "checking for X... $ECHO_C" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
+$as_echo_n "checking for X... " >&6; }
 
 
 # Check whether --with-x was given.
-if test "${with_x+set}" = set; then
+if test "${with_x+set}" = set; then :
   withval=$with_x;
 fi
 
@@ -11522,11 +8028,9 @@ if test "x$with_x" = xno; then
   have_x=disabled
 else
   case $x_includes,$x_libraries in #(
-    *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5
-echo "$as_me: error: Cannot use X directory names containing '" >&2;}
-   { (exit 1); exit 1; }; };; #(
-    *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+    *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   # One or both of the vars are not set, and there is no cached value.
 ac_x_includes=no ac_x_libraries=no
@@ -11542,7 +8046,7 @@ libdir:
 	@echo libdir='${LIBDIR}'
 _ACEOF
   if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
-    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
     for ac_var in incroot usrlibdir libdir; do
       eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
     done
@@ -11561,7 +8065,7 @@ _ACEOF
 	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
     esac
     case $ac_im_usrlibdir in
-	/usr/lib | /lib) ;;
+	/usr/lib | /usr/lib64 | /lib | /lib64) ;;
 	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
     esac
   fi
@@ -11573,21 +8077,25 @@ fi
 # Check X11 before X11Rn because it is often a symlink to the current release.
 ac_x_header_dirs='
 /usr/X11/include
+/usr/X11R7/include
 /usr/X11R6/include
 /usr/X11R5/include
 /usr/X11R4/include
 
 /usr/include/X11
+/usr/include/X11R7
 /usr/include/X11R6
 /usr/include/X11R5
 /usr/include/X11R4
 
 /usr/local/X11/include
+/usr/local/X11R7/include
 /usr/local/X11R6/include
 /usr/local/X11R5/include
 /usr/local/X11R4/include
 
 /usr/local/include/X11
+/usr/local/include/X11R7
 /usr/local/include/X11R6
 /usr/local/include/X11R5
 /usr/local/include/X11R4
@@ -11609,36 +8117,14 @@ ac_x_header_dirs='
 if test "$ac_x_includes" = no; then
   # Guess where to find include files, by looking for Xlib.h.
   # First, try using that file with no special directory specified.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <X11/Xlib.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
+if ac_fn_c_try_cpp "$LINENO"; then :
   # We can compile using X headers with no special include directory.
 ac_x_includes=
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
   for ac_dir in $ac_x_header_dirs; do
   if test -r "$ac_dir/X11/Xlib.h"; then
     ac_x_includes=$ac_dir
@@ -11646,8 +8132,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
   fi
 done
 fi
-
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 fi # $ac_x_includes = no
 
 if test "$ac_x_libraries" = no; then
@@ -11656,11 +8141,7 @@ if test "$ac_x_libraries" = no; then
   # Don't add to $LIBS permanently.
   ac_save_LIBS=$LIBS
   LIBS="-lX11 $LIBS"
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <X11/Xlib.h>
 #ifdef F77_DUMMY_MAIN
@@ -11679,33 +8160,13 @@ XrmInitialize ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   LIBS=$ac_save_LIBS
 # We can link X programs with no special library path.
 ac_x_libraries=
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	LIBS=$ac_save_LIBS
-for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+  LIBS=$ac_save_LIBS
+for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
 do
   # Don't even attempt the hair of trying to link an X program!
   for ac_extension in a so sl dylib la dll; do
@@ -11716,9 +8177,8 @@ do
   done
 done
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 fi # $ac_x_libraries = no
 
 case $ac_x_includes,$ac_x_libraries in #(
@@ -11739,8 +8199,8 @@ fi
 fi # $with_x != no
 
 if test "$have_x" != yes; then
-  { echo "$as_me:$LINENO: result: $have_x" >&5
-echo "${ECHO_T}$have_x" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
+$as_echo "$have_x" >&6; }
   no_x=yes
 else
   # If each of the values was on the command line, it overrides each guess.
@@ -11750,8 +8210,8 @@ else
   ac_cv_have_x="have_x=yes\
 	ac_x_includes='$x_includes'\
 	ac_x_libraries='$x_libraries'"
-  { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
-echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
+$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
 fi
 
     if test "x$no_x" = x; then
@@ -11764,18 +8224,14 @@ fi
 
     # It is possible that other libraries may be required depending on what
     # graphics drivers were installed with PGPLOT.
-    { echo "$as_me:$LINENO: checking for deflate in -lz" >&5
-echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_deflate+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5
+$as_echo_n "checking for deflate in -lz... " >&6; }
+if ${ac_cv_lib_z_deflate+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lz $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11801,54 +8257,29 @@ return deflate ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_z_deflate=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_z_deflate=no
+  ac_cv_lib_z_deflate=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5
-echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6; }
-if test $ac_cv_lib_z_deflate = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5
+$as_echo "$ac_cv_lib_z_deflate" >&6; }
+if test "x$ac_cv_lib_z_deflate" = xyes; then :
   PGPLOTLIB="-lz $PGPLOTLIB"
 fi
 
-    { echo "$as_me:$LINENO: checking for png_error in -lpng" >&5
-echo $ECHO_N "checking for png_error in -lpng... $ECHO_C" >&6; }
-if test "${ac_cv_lib_png_png_error+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_error in -lpng" >&5
+$as_echo_n "checking for png_error in -lpng... " >&6; }
+if ${ac_cv_lib_png_png_error+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lpng $PGPLOTLIB $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11874,54 +8305,29 @@ return png_error ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_png_png_error=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_png_png_error=no
+  ac_cv_lib_png_png_error=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_error" >&5
-echo "${ECHO_T}$ac_cv_lib_png_png_error" >&6; }
-if test $ac_cv_lib_png_png_error = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_error" >&5
+$as_echo "$ac_cv_lib_png_png_error" >&6; }
+if test "x$ac_cv_lib_png_png_error" = xyes; then :
   PGPLOTLIB="-lpng $PGPLOTLIB"
 fi
 
-    { echo "$as_me:$LINENO: checking for pgbeg_ in -lpgplot" >&5
-echo $ECHO_N "checking for pgbeg_ in -lpgplot... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pgplot_pgbeg_+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pgbeg_ in -lpgplot" >&5
+$as_echo_n "checking for pgbeg_ in -lpgplot... " >&6; }
+if ${ac_cv_lib_pgplot_pgbeg_+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lpgplot $PGPLOTLIB $FLIBS $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -11947,54 +8353,29 @@ return pgbeg_ ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_pgplot_pgbeg_=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_pgplot_pgbeg_=no
+  ac_cv_lib_pgplot_pgbeg_=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pgplot_pgbeg_" >&5
-echo "${ECHO_T}$ac_cv_lib_pgplot_pgbeg_" >&6; }
-if test $ac_cv_lib_pgplot_pgbeg_ = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pgplot_pgbeg_" >&5
+$as_echo "$ac_cv_lib_pgplot_pgbeg_" >&6; }
+if test "x$ac_cv_lib_pgplot_pgbeg_" = xyes; then :
   PGPLOTLIB="-lpgplot $PGPLOTLIB"
 fi
 
-    { echo "$as_me:$LINENO: checking for cpgbeg in -lcpgplot" >&5
-echo $ECHO_N "checking for cpgbeg in -lcpgplot... $ECHO_C" >&6; }
-if test "${ac_cv_lib_cpgplot_cpgbeg+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpgbeg in -lcpgplot" >&5
+$as_echo_n "checking for cpgbeg in -lcpgplot... " >&6; }
+if ${ac_cv_lib_cpgplot_cpgbeg+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lcpgplot $PGPLOTLIB $FLIBS $LIBS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -12020,39 +8401,18 @@ return cpgbeg ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_cpgplot_cpgbeg=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_cpgplot_cpgbeg=no
+  ac_cv_lib_cpgplot_cpgbeg=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_cpgplot_cpgbeg" >&5
-echo "${ECHO_T}$ac_cv_lib_cpgplot_cpgbeg" >&6; }
-if test $ac_cv_lib_cpgplot_cpgbeg = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cpgplot_cpgbeg" >&5
+$as_echo "$ac_cv_lib_cpgplot_cpgbeg" >&6; }
+if test "x$ac_cv_lib_cpgplot_cpgbeg" = xyes; then :
   PGPLOTLIB="-lcpgplot $PGPLOTLIB"
 else
   PGPLOTLIB=
@@ -12067,11 +8427,11 @@ fi
 
     # Also need the PGPLOT library to build pgtest and cpgtest.
     if test "x$PGPLOTLIB" = x; then
-      { echo "$as_me:$LINENO: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&5
-echo "$as_me: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&5
+$as_echo "$as_me: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&2;}
     else
-      { echo "$as_me:$LINENO: PGPLOT appears to be available." >&5
-echo "$as_me: PGPLOT appears to be available." >&6;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: PGPLOT appears to be available." >&5
+$as_echo "$as_me: PGPLOT appears to be available." >&6;}
 
       TSTDIRS="$TSTDIRS pgsbox"
     fi
@@ -12084,7 +8444,7 @@ fi
 #   configure --disable-utils
 #   configure --enable-utils=no
 # Check whether --enable-utils was given.
-if test "${enable_utils+set}" = set; then
+if test "${enable_utils+set}" = set; then :
   enableval=$enable_utils;
 fi
 
@@ -12092,8 +8452,8 @@ if test "x$enable_utils" != xno ; then
   SUBDIRS="$SUBDIRS utils"
   INSTDIR="$INSTDIR utils"
 else
-  { echo "$as_me:$LINENO: WARNING: Compilation of WCS utilities disabled" >&5
-echo "$as_me: WARNING: Compilation of WCS utilities disabled" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compilation of WCS utilities disabled" >&5
+$as_echo "$as_me: WARNING: Compilation of WCS utilities disabled" >&2;}
 fi
 
 
@@ -12108,15 +8468,15 @@ fi
 
 
 
-{ echo "$as_me:$LINENO: End of auxiliary configuration.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: End of auxiliary configuration.
 " >&5
-echo "$as_me: End of auxiliary configuration.
+$as_echo "$as_me: End of auxiliary configuration.
 " >&6;}
 
 
 # Do it.
-{ echo "$as_me:$LINENO: Configuring files..." >&5
-echo "$as_me: Configuring files..." >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring files..." >&5
+$as_echo "$as_me: Configuring files..." >&6;}
 ac_config_files="$ac_config_files makedefs wcslib.pc"
 
 ac_config_headers="$ac_config_headers wcsconfig.h wcsconfig_f77.h wcsconfig_tests.h wcsconfig_utils.h"
@@ -12148,12 +8508,13 @@ _ACEOF
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
       esac ;;
     esac
   done
@@ -12161,8 +8522,8 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
   (set) 2>&1 |
     case $as_nl`(ac_space=' '; set) 2>&1` in #(
     *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes (double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
       sed -n \
 	"s/'/'\\\\''/g;
 	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
@@ -12184,13 +8545,24 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
-      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
   else
-    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -12203,14 +8575,15 @@ DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
-  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -12218,12 +8591,14 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
 # Generated by $as_me.
 # Run this file to recreate the current configuration.
@@ -12233,59 +8608,79 @@ cat >$CONFIG_STATUS <<_ACEOF
 debug=false
 ac_cs_recheck=false
 ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
 esac
-
 fi
 
 
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
   else
-    PATH_SEPARATOR=:
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
   fi
-  rm -f conf$$.sh
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
 fi
 
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
 fi
 
 
@@ -12294,20 +8689,19 @@ fi
 # there to prevent editors from complaining about space-tab.
 # (If _AS_PATH_WALK were called with IFS unset, it would disable word
 # splitting by setting IFS to empty value.)
-as_nl='
-'
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
+as_myself=
+case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
 IFS=$as_save_IFS
 
      ;;
@@ -12318,32 +8712,111 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
 fi
 
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
 done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-done
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
 
-# Required to use basename.
 if expr a : '\(a\)' >/dev/null 2>&1 &&
    test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
@@ -12357,13 +8830,17 @@ else
   as_basename=false
 fi
 
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
 
-# Name of the executable.
 as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
+$as_echo X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -12378,131 +8855,118 @@ echo X/"$0" |
 	  }
 	  s/.*/./; q'`
 
-# CDPATH.
-$as_unset CDPATH
-
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
 ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
+case `echo -n x` in #(((((
 -n*)
-  case `echo 'x\c'` in
+  case `echo 'xy\c'` in
   *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
   esac;;
 *)
   ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
 else
   rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-    as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
-else
-  as_ln_s='cp -p'
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
 
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
 if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
   test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-        test -d "$1/.";
-      else
-	case $1 in
-        -*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -12512,13 +8976,19 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
 exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 
-# Save the log message, to keep $[0] and so on meaningful, and to
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by WCSLIB $as_me 4.23, which was
-generated by GNU Autoconf 2.61.  Invocation command line was
+This file was extended by WCSLIB $as_me 4.25, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -12531,29 +9001,41 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q`
 
 _ACEOF
 
-cat >>$CONFIG_STATUS <<_ACEOF
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 # Files that config.status was made for.
 config_files="$ac_config_files"
 config_headers="$ac_config_headers"
 
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
 
-Usage: $0 [OPTIONS] [FILE]...
+Usage: $0 [OPTION]... [TAG]...
 
   -h, --help       print this help, then exit
   -V, --version    print version number and configuration settings, then exit
-  -q, --quiet      do not print progress messages
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
-  --file=FILE[:TEMPLATE]
-		   instantiate the configuration file FILE
-  --header=FILE[:TEMPLATE]
-		   instantiate the configuration header FILE
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
 
 Configuration files:
 $config_files
@@ -12561,36 +9043,42 @@ $config_files
 Configuration headers:
 $config_headers
 
-Report bugs to <bug-autoconf at gnu.org>."
+Report bugs to <mark at calabretta.id.au>."
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-WCSLIB config.status 4.23
-configured by $0, generated by GNU Autoconf 2.61,
-  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+WCSLIB config.status 4.25
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2006 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
 ac_pwd='$ac_pwd'
 srcdir='$srcdir'
 INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value.  By we need to know if files were specified by the user.
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
 ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -12603,34 +9091,41 @@ do
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    echo "$ac_cs_version"; exit ;;
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
-    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
   --header | --heade | --head | --hea )
     $ac_shift
-    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
   --he | --h)
     # Conflict between --help and --header
-    { echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; };;
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
   --help | --hel | -h )
-    echo "$ac_cs_usage"; exit ;;
+    $as_echo "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; } ;;
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
 
-  *) ac_config_targets="$ac_config_targets $1"
+  *) as_fn_append ac_config_targets " $1"
      ac_need_defaults=false ;;
 
   esac
@@ -12645,30 +9140,32 @@ if $ac_cs_silent; then
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  CONFIG_SHELL=$SHELL
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
-  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  exec "\$@"
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 exec 5>>config.log
 {
   echo
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  echo "$ac_log"
+  $as_echo "$ac_log"
 } >&5
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 
 # Handling of arguments.
 for ac_config_target in $ac_config_targets
@@ -12681,9 +9178,7 @@ do
     "wcsconfig_tests.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig_tests.h" ;;
     "wcsconfig_utils.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig_utils.h" ;;
 
-  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
-   { (exit 1); exit 1; }; };;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -12705,191 +9200,302 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
-  trap '{ (exit 1); exit 1; }' 1 2 13 15
+  trap 'as_fn_exit 1' 1 2 13 15
 }
 # Create a (secure) tmp directory for tmp files.
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} ||
-{
-   echo "$me: cannot create a temporary directory in ." >&2
-   { (exit 1); exit 1; }
-}
-
-#
-# Set up the sed scripts for CONFIG_FILES section.
-#
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
 if test -n "$CONFIG_FILES"; then
 
-_ACEOF
 
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
 
 
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
-  cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-LIBVER!$LIBVER$ac_delim
-build!$build$ac_delim
-build_cpu!$build_cpu$ac_delim
-build_vendor!$build_vendor$ac_delim
-build_os!$build_os$ac_delim
-ARCH!$ARCH$ac_delim
-FLEX!$FLEX$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-F77!$F77$ac_delim
-FFLAGS!$FFLAGS$ac_delim
-ac_ct_F77!$ac_ct_F77$ac_delim
-FLIBS!$FLIBS$ac_delim
-RANLIB!$RANLIB$ac_delim
-SHRLIB!$SHRLIB$ac_delim
-SONAME!$SONAME$ac_delim
-SHRFLAGS!$SHRFLAGS$ac_delim
-SHRLD!$SHRLD$ac_delim
-SHRSFX!$SHRSFX$ac_delim
-SHRLN!$SHRLN$ac_delim
-LN_S!$LN_S$ac_delim
-INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
-INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
-INSTALL_DATA!$INSTALL_DATA$ac_delim
-XMKMF!$XMKMF$ac_delim
-CFITSIOINC!$CFITSIOINC$ac_delim
-CFITSIOLIB!$CFITSIOLIB$ac_delim
-GETWCSTAB!$GETWCSTAB$ac_delim
-PGPLOTINC!$PGPLOTINC$ac_delim
-PGPLOTLIB!$PGPLOTLIB$ac_delim
-SUBDIRS!$SUBDIRS$ac_delim
-TSTDIRS!$TSTDIRS$ac_delim
-INSTDIR!$INSTDIR$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 80; then
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
 done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
 
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
-  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
-  ac_eof=`expr $ac_eof + 1`
-fi
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
 
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACAWK
 _ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[	 ]*\):*/\1/
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[	 ]*$//
 }'
 fi
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 fi # test -n "$CONFIG_FILES"
 
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
 
-for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    "
+shift
+for ac_tag
 do
   case $ac_tag in
   :[FHLC]) ac_mode=$ac_tag; continue;;
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
-   { (exit 1); exit 1; }; };;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -12908,7 +9514,7 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;}
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
 	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
 	 # because $ac_f cannot contain `:'.
@@ -12917,26 +9523,34 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;}
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
-   { (exit 1); exit 1; }; };;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      ac_file_inputs="$ac_file_inputs $ac_f"
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
     done
 
     # Let's still pretend it is `configure' which instantiates (i.e., don't
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
-    configure_input="Generated from "`IFS=:
-	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
     fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin";;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -12946,42 +9560,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$ac_file" : 'X\(//\)[^/]' \| \
 	 X"$ac_file" : 'X\(//\)$' \| \
 	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  { as_dir="$ac_dir"
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$as_dir" |
+$as_echo X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -12999,20 +9578,15 @@ echo X"$as_dir" |
 	    q
 	  }
 	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
-   { (exit 1); exit 1; }; }; }
+  as_dir="$ac_dir"; as_fn_mkdir_p
   ac_builddir=.
 
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -13052,12 +9626,12 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
   esac
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # If the template does not know about datarootdir, expand it.
 # FIXME: This hack should be removed a few years after 2.60.
 ac_datarootdir_hack=; ac_datarootdir_seen=
-
-case `sed -n '/datarootdir/ {
+ac_sed_dataroot='
+/datarootdir/ {
   p
   q
 }
@@ -13065,36 +9639,37 @@ case `sed -n '/datarootdir/ {
 /@docdir@/p
 /@infodir@/p
 /@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
   s&@datadir@&$datadir&g
   s&@docdir@&$docdir&g
   s&@infodir@&$infodir&g
   s&@localedir@&$localedir&g
   s&@mandir@&$mandir&g
-    s&\\\${datarootdir}&$datarootdir&g' ;;
+  s&\\\${datarootdir}&$datarootdir&g' ;;
 esac
 _ACEOF
 
 # Neutralize VPATH when `$srcdir' = `.'.
 # Shell code in configure.ac might set extrasub.
 # FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF
-  sed "$ac_vpsub
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
 $extrasub
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
+s|@configure_input@|$ac_sed_conf_input|;t t
 s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
 s&@srcdir@&$ac_srcdir&;t t
 s&@abs_srcdir@&$ac_abs_srcdir&;t t
 s&@top_srcdir@&$ac_top_srcdir&;t t
@@ -13104,119 +9679,49 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
-  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
-
-  rm -f "$tmp/stdin"
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out"; rm -f "$tmp/out";;
-  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
-  esac
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
   :H)
   #
   # CONFIG_HEADER
   #
-_ACEOF
-
-# Transform confdefs.h into a sed script `conftest.defines', that
-# substitutes the proper values into config.h.in to produce config.h.
-rm -f conftest.defines conftest.tail
-# First, append a space to every undef/define line, to ease matching.
-echo 's/$/ /' >conftest.defines
-# Then, protect against being on the right side of a sed subst, or in
-# an unquoted here document, in config.status.  If some macros were
-# called several times there might be several #defines for the same
-# symbol, which is useless.  But do not sort them, since the last
-# AC_DEFINE must be honored.
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
-# NAME is the cpp macro being defined, VALUE is the value it is being given.
-# PARAMS is the parameter list in the macro definition--in most cases, it's
-# just an empty string.
-ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
-ac_dB='\\)[	 (].*,\\1define\\2'
-ac_dC=' '
-ac_dD=' ,'
-
-uniq confdefs.h |
-  sed -n '
-	t rset
-	:rset
-	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
-	t ok
-	d
-	:ok
-	s/[\\&,]/\\&/g
-	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
-	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
-  ' >>conftest.defines
-
-# Remove the space that was appended to ease matching.
-# Then replace #undef with comments.  This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-# (The regexp can be short, since the line contains either #define or #undef.)
-echo 's/ $//
-s,^[	 #]*u.*,/* & */,' >>conftest.defines
-
-# Break up conftest.defines:
-ac_max_sed_lines=50
-
-# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
-# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
-# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
-# et cetera.
-ac_in='$ac_file_inputs'
-ac_out='"$tmp/out1"'
-ac_nxt='"$tmp/out2"'
-
-while :
-do
-  # Write a here document:
-    cat >>$CONFIG_STATUS <<_ACEOF
-    # First, check the format of the line:
-    cat >"\$tmp/defines.sed" <<\\CEOF
-/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
-/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
-b
-:def
-_ACEOF
-  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
-  echo 'CEOF
-    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
-  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
-  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
-  grep . conftest.tail >/dev/null || break
-  rm -f conftest.defines
-  mv conftest.tail conftest.defines
-done
-rm -f conftest.defines conftest.tail
-
-echo "ac_result=$ac_in" >>$CONFIG_STATUS
-cat >>$CONFIG_STATUS <<\_ACEOF
   if test x"$ac_file" != x-; then
-    echo "/* $configure_input  */" >"$tmp/config.h"
-    cat "$ac_result" >>"$tmp/config.h"
-    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
-      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
-echo "$as_me: $ac_file is unchanged" >&6;}
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
     else
-      rm -f $ac_file
-      mv "$tmp/config.h" $ac_file
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    echo "/* $configure_input  */"
-    cat "$ac_result"
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
   fi
-  rm -f "$tmp/out12"
  ;;
 
 
@@ -13225,11 +9730,13 @@ echo "$as_me: $ac_file is unchanged" >&6;}
 done # for ac_tag
 
 
-{ (exit 0); exit 0; }
+as_fn_exit 0
 _ACEOF
-chmod +x $CONFIG_STATUS
 ac_clean_files=$ac_clean_files_save
 
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
 
 # configure is writing to config.log, and then calls config.status.
 # config.status does its own redirection, appending to config.log.
@@ -13249,6 +9756,10 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || { (exit 1); exit 1; }
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
diff --git a/cextern/wcslib/configure.ac b/cextern/wcslib/configure.ac
index 1c1f1a8..876f411 100644
--- a/cextern/wcslib/configure.ac
+++ b/cextern/wcslib/configure.ac
@@ -1,19 +1,14 @@
 #-----------------------------------------------------------------------------
 # Process this file with autoconf-2.53 or later to produce a configure script.
 #-----------------------------------------------------------------------------
-# N.B. it is necessary to run autoconf on a Mac in order for configure to
-# locate the X11 dylibs for PGPLOT.  Use autoconf-2.61 in MacOSX 10.6.2 or
-# later to avoid spurious messages about deleting conftest.dSYM when
-# configuring in MacOSX 10.6.
-#
 # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 # http://www.atnf.csiro.au/people/Mark.Calabretta
-# $Id: configure.ac,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+# $Id: configure.ac,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 #-----------------------------------------------------------------------------
 
-AC_INIT([WCSLIB], [4.23], [mark at calabretta.id.au], [wcslib-4.23])
+AC_INIT([WCSLIB], [4.25], [mark at calabretta.id.au], [wcslib-4.25])
 AC_PREREQ([2.53])
-AC_REVISION([$Revision: 4.23 $])
+AC_REVISION([$Revision: 4.25 $])
 AC_SUBST([PACKAGE_VERSION])
 AC_DEFINE_UNQUOTED([WCSLIB_VERSION], [$PACKAGE_VERSION], [Define wcslib version])
 
@@ -34,7 +29,7 @@ AC_SUBST([ARCH])
 AC_CHECK_PROG([FLEX], [flex], [flex], [], [], [])
 if test "x$FLEX" = xflex ; then
   # Version 2.5.9 or later is required.
-  V=`flex --version | awk '{print $NF}'`
+  V=`flex --version | awk '{print $2}'`
   W=`echo $V | awk -F. '{if ((($1*100 + $2)*100 + $3) < 20509) print "no"}'`
   if test "x$W" != x ; then
     AC_MSG_NOTICE([Flex version $V is too old, ignored.])
diff --git a/cextern/wcslib/flavours b/cextern/wcslib/flavours
index 98bfaa7..b9d887e 100644
--- a/cextern/wcslib/flavours
+++ b/cextern/wcslib/flavours
@@ -12,7 +12,7 @@
 #
 # Reminder: add '-d' to FLFLAGS for debugging.
 #
-# $Id: flavours,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+# $Id: flavours,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 #-----------------------------------------------------------------------------
 
 # The list of FLAVOURs can be set on the command line.
diff --git a/cextern/wcslib/makedefs.in b/cextern/wcslib/makedefs.in
index 855f9f3..66b9a10 100644
--- a/cextern/wcslib/makedefs.in
+++ b/cextern/wcslib/makedefs.in
@@ -1,5 +1,5 @@
 #-----------------------------------------------------------------------------
-# GNU makefile definitions for building WCSLIB 4.23
+# GNU makefile definitions for building WCSLIB 4.25
 #
 # makedefs is generated from makedefs.in by configure.  It contains variable
 # definitions and some general-purpose rules for building WCSLIB.
@@ -39,11 +39,11 @@
 #      compiled separately without this option.
 #
 #      The shared library will be installed with version number, e.g. as
-#      libwcs.so.4.23 or libwcs.4.23.dylib with or without the symlink
+#      libwcs.so.4.25 or libwcs.4.25.dylib with or without the symlink
 #      required to make it visible to the linker (controlled by the SHRLN
 #      variable).  On Macs it is deliberately not created because its very
 #      existence precludes static linking with the cctools linker.  You can
-#      still link dynamically by using -lwcs.4.23.
+#      still link dynamically by using -lwcs.4.25.
 #
 #   4) PGPLOT is Tim Pearson's Fortran graphics library with separate C
 #      interface available from astro.caltech.edu.  It is only required by
@@ -74,7 +74,7 @@
 #
 # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 # http://www.atnf.csiro.au/people/Mark.Calabretta
-# $Id: makedefs.in,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+# $Id: makedefs.in,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 #-----------------------------------------------------------------------------
 # Version.
   LIBVER    := @LIBVER@
diff --git a/cextern/wcslib/wcsconfig.h.in b/cextern/wcslib/wcsconfig.h.in
index 1d609a1..20ca0f0 100644
--- a/cextern/wcslib/wcsconfig.h.in
+++ b/cextern/wcslib/wcsconfig.h.in
@@ -1,11 +1,11 @@
 /*============================================================================
 *
 * wcsconfig.h is generated from wcsconfig.h.in by 'configure'.  It contains
-* C preprocessor macro definitions for compiling WCSLIB 4.23
+* C preprocessor macro definitions for compiling WCSLIB 4.25
 *
 * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 * http://www.atnf.csiro.au/people/Mark.Calabretta
-* $Id: wcsconfig.h.in,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+* $Id: wcsconfig.h.in,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 *===========================================================================*/
 
 /* WCSLIB library version number. */
diff --git a/cextern/wcslib/wcsconfig_f77.h.in b/cextern/wcslib/wcsconfig_f77.h.in
index 5c9fe53..a091368 100644
--- a/cextern/wcslib/wcsconfig_f77.h.in
+++ b/cextern/wcslib/wcsconfig_f77.h.in
@@ -1,12 +1,12 @@
 /*============================================================================
 *
 * wcsconfig_f77.h is generated from wcsconfig_f77.h.in by 'configure'.  It
-* contains C preprocessor definitions for building the WCSLIB 4.23 Fortran
+* contains C preprocessor definitions for building the WCSLIB 4.25 Fortran
 * wrappers.
 *
 * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 * http://www.atnf.csiro.au/people/Mark.Calabretta
-* $Id: wcsconfig_f77.h.in,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+* $Id: wcsconfig_f77.h.in,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 *===========================================================================*/
 
 /* Integer array type large enough to hold an address.  Set here to int[2] for
diff --git a/cextern/wcslib/wcsconfig_tests.h.in b/cextern/wcslib/wcsconfig_tests.h.in
index 0a153a8..83b0fd3 100644
--- a/cextern/wcslib/wcsconfig_tests.h.in
+++ b/cextern/wcslib/wcsconfig_tests.h.in
@@ -1,12 +1,12 @@
 /*============================================================================
 *
 * wcsconfig_test.h is generated from wcsconfig_test.h.in by 'configure'.  It
-* contains C preprocessor definitions for compiling the WCSLIB 4.23 test/demo
+* contains C preprocessor definitions for compiling the WCSLIB 4.25 test/demo
 * programs.
 *
 * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 * http://www.atnf.csiro.au/people/Mark.Calabretta
-* $Id: wcsconfig_tests.h.in,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+* $Id: wcsconfig_tests.h.in,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 *===========================================================================*/
 
 #include <wcsconfig.h>
diff --git a/cextern/wcslib/wcsconfig_utils.h.in b/cextern/wcslib/wcsconfig_utils.h.in
index 3f6ba37..0bd6117 100644
--- a/cextern/wcslib/wcsconfig_utils.h.in
+++ b/cextern/wcslib/wcsconfig_utils.h.in
@@ -1,12 +1,12 @@
 /*============================================================================
 *
 * wcsconfig_utils.h is generated from wcsconfig_utils.h.in by 'configure'.
-* It contains C preprocessor macro definitions for compiling the WCSLIB 4.23
+* It contains C preprocessor macro definitions for compiling the WCSLIB 4.25
 * utilities.
 *
 * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
 * http://www.atnf.csiro.au/people/Mark.Calabretta
-* $Id: wcsconfig_utils.h.in,v 4.23 2014/05/11 04:09:39 mcalabre Exp $
+* $Id: wcsconfig_utils.h.in,v 4.25 2014/12/14 14:29:38 mcalabre Exp $
 *===========================================================================*/
 
 #include <wcsconfig.h>
diff --git a/docs/analytic_functions/index.rst b/docs/analytic_functions/index.rst
new file mode 100644
index 0000000..706af5f
--- /dev/null
+++ b/docs/analytic_functions/index.rst
@@ -0,0 +1,119 @@
+.. doctest-skip-all
+
+.. _astropy_analytic_functions:
+
+***************************************************
+Analytic Functions (``astropy.analytic_functions``)
+***************************************************
+
+Introduction
+============
+
+The ``astropy.analytic_functions`` subpackage provides analytic functions that
+are commonly used in astronomy. These already understand
+`~astropy.units.Quantity`, i.e., they can handle units of input and output
+parameters.
+
+In future versions of ``astropy``, many of these might be accessible as
+`~astropy.modeling.core.Model`.
+
+
+Getting Started
+===============
+
+>>> from astropy import units as u
+>>> from astropy.analytic_functions import blackbody_lambda, blackbody_nu
+
+Calculate blackbody flux for 10000 K at 6000 Angstrom:
+
+>>> blackbody_lambda(6000 * u.AA, 10000 * u.K)
+<Quantity 15315791.836941158 erg / (Angstrom cm2 s sr)>
+>>> blackbody_nu(6000 * u.AA, 10000 * u.K)
+<Quantity 0.00018391673686797075 erg / (cm2 Hz s sr)
+
+
+Using ``astropy.analytic_functions``
+====================================
+
+.. _blackbody-planck-law:
+
+Blackbody Radiation
+-------------------
+
+Blackbody flux is calculated with Planck law
+(:ref:`Rybicki & Lightman 1979 <ref-rybicki1979>`):
+
+.. math::
+
+    B_{\lambda}(T) = \frac{2 h c^{2} / \lambda^{5}}{exp(h c / \lambda k T) - 1}
+
+    B_{\nu}(T) = \frac{2 h \nu^{3} / c^{2}}{exp(h \nu / k T) - 1}
+
+where the unit of :math:`B_{\lambda}(T)` is
+:math:`erg \; s^{-1} cm^{-2} \AA^{-1} sr^{-1}`, and :math:`B_{\nu}(T)` is
+:math:`erg \; s^{-1} cm^{-2} Hz^{-1} sr^{-1}`.
+:func:`~astropy.analytic_functions.blackbody.blackbody_lambda` and
+:func:`~astropy.analytic_functions.blackbody.blackbody_nu` calculate the
+blackbody flux for :math:`B_{\lambda}(T)` and :math:`B_{\nu}(T)`, respectively.
+
+.. _blackbody-examples:
+
+Examples
+^^^^^^^^
+
+>>> import numpy as np
+>>> from astropy import units as u
+>>> from astropy.analytic_functions import blackbody_lambda, blackbody_nu
+
+Calculate blackbody flux for 5000 K at 100 and 10000 Angstrom while suppressing
+any Numpy warnings:
+
+>>> wavelengths = [100, 10000] * u.AA
+>>> temperature = 5000 * u.K
+>>> with np.errstate(all='ignore'):
+...     flux_lam = blackbody_lambda(wavelengths, temperature)
+...     flux_nu = blackbody_nu(wavelengths, temperature)
+>>> flux_lam
+Quantity [1.27452545e-108, 7.10190526e+005] erg / (Angstrom cm2 s sr)>
+>>> flux_nu
+<Quantity [4.25135927e-123, 2.36894060e-005] erg / (cm2 Hz s sr)>
+
+Plot a blackbody spectrum for 5000 K:
+
+.. plot::
+
+    import matplotlib.pyplot as plt
+    import numpy as np
+    from astropy import constants as const
+    from astropy import units as u
+    from astropy.analytic_functions import blackbody_lambda
+
+    temperature = 5000 * u.K
+    wavemax = (const.b_wien / temperature).to(u.AA)  # Wien's displacement law
+    waveset = np.logspace(
+        0, np.log10(wavemax.value + 10 * wavemax.value), num=1000) * u.AA
+    with np.errstate(all='ignore'):
+        flux = blackbody_lambda(waveset, temperature)
+
+    fig, ax = plt.subplots(figsize=(8,5))
+    ax.plot(waveset.value, flux.value)
+    ax.axvline(wavemax.value, ls='--')
+    ax.get_yaxis().get_major_formatter().set_powerlimits((0, 1))
+    ax.set_xlabel(r'$\lambda$ ({0})'.format(waveset.unit))
+    ax.set_ylabel(r'$B_{\lambda}(T)$')
+    ax.set_title('Blackbody, T = {0}'.format(temperature))
+
+
+See Also
+========
+
+.. _ref-rybicki1979:
+
+Rybicki, G. B., & Lightman, A. P. 1979, Radiative Processes in Astrophysics (New York, NY: Wiley)
+
+
+Reference/API
+=============
+
+.. automodapi:: astropy.analytic_functions.blackbody
+   :no-inheritance-diagram:
diff --git a/docs/coordinates/frames.rst b/docs/coordinates/frames.rst
index 170ddce..3e9c909 100644
--- a/docs/coordinates/frames.rst
+++ b/docs/coordinates/frames.rst
@@ -28,11 +28,11 @@ is first created::
 
     >>> from astropy.coordinates import ICRS, FK5
     >>> FK5(equinox='J1975')
-    <FK5 Frame: equinox=J1975.000>
+    <FK5 Frame (equinox=J1975.000)>
     >>> ICRS()  # has no attributes
     <ICRS Frame>
     >>> FK5()  # uses default equinox
-    <FK5 Frame: equinox=J2000.000>
+    <FK5 Frame (equinox=J2000.000)>
 
 The specific names of attributes available for a particular frame (and
 their default values)  are available as the class method
@@ -72,7 +72,7 @@ equatorial systems)::
     >>> ICRS(ra=1.1*u.deg, dec=2.2*u.deg)
     <ICRS Coordinate: ra=1.1 deg, dec=2.2 deg>
     >>> FK5(ra=1.1*u.deg, dec=2.2*u.deg, equinox='J1975')
-    <FK5 Coordinate: equinox=J1975.000, ra=1.1 deg, dec=2.2 deg>
+    <FK5 Coordinate (equinox=J1975.000): ra=1.1 deg, dec=2.2 deg>
 
 These same attributes can be used to access the data in the frames, as
 |Angle| objects (or |Angle| subclasses)::
@@ -136,7 +136,7 @@ any  frame attributes required::
     >>> from astropy.coordinates import SphericalRepresentation
     >>> rep = SphericalRepresentation(lon=1.1*u.deg, lat=2.2*u.deg, distance=3.3*u.kpc)
     >>> FK5(rep, equinox='J1975')
-    <FK5 Coordinate: equinox=J1975.000, ra=1.1 deg, dec=2.2 deg, distance=3.3 kpc>
+    <FK5 Coordinate (equinox=J1975.000): ra=1.1 deg, dec=2.2 deg, distance=3.3 kpc>
 
 A final way is to create a frame object from an already existing frame
 (either one with or without data), using the ``realize_frame`` method. This
@@ -144,10 +144,10 @@ will yield a frame with the same attributes, but new data::
 
     >>> f1 = FK5(equinox='J1975')
     >>> f1
-    <FK5 Frame: equinox=J1975.000>
+    <FK5 Frame (equinox=J1975.000)>
     >>> rep = SphericalRepresentation(lon=1.1*u.deg, lat=2.2*u.deg, distance=3.3*u.kpc)
     >>> f1.realize_frame(rep)
-    <FK5 Coordinate: equinox=J1975.000, ra=1.1 deg, dec=2.2 deg, distance=3.3 kpc>
+    <FK5 Coordinate (equinox=J1975.000): ra=1.1 deg, dec=2.2 deg, distance=3.3 kpc>
 
 You can check if a frame object has data using the ``has_data`` attribute, and
 if it is preset, it can be accessed from the ``data`` attribute::
@@ -194,9 +194,9 @@ data)::
 
     >>> cooi = ICRS(1.5*u.deg, 2.5*u.deg)
     >>> cooi.transform_to(FK5)  # doctest: +FLOAT_CMP
-    <FK5 Coordinate: equinox=J2000.000, ra=1.50000660527 deg, dec=2.50000238221 deg>
+    <FK5 Coordinate (equinox=J2000.000): ra=1.50000660527 deg, dec=2.50000238221 deg>
     >>> cooi.transform_to(FK5(equinox='J1975'))  # doctest: +FLOAT_CMP
-    <FK5 Coordinate: equinox=J1975.000, ra=1.17960348105 deg, dec=2.36085320826 deg>
+    <FK5 Coordinate (equinox=J1975.000): ra=1.17960348105 deg, dec=2.36085320826 deg>
 
 The :ref:`astropy-coordinates-api` includes a list of all of the frames built
 into `astropy.coordinates`, as well as the defined transformations between
@@ -247,7 +247,7 @@ the way you want.  As an example::
 
   >>> c = MyFrame(R=10*u.deg, D=20*u.deg)
   >>> c  # doctest: +FLOAT_CMP
-  <MyFrame Coordinate: location=None, equinox=B1950.000, obstime=B1950.000, R=0.174532925199 rad, D=0.349065850399 rad>
+  <MyFrame Coordinate (location=None, equinox=B1950.000, obstime=B1950.000): R=0.174532925199 rad, D=0.349065850399 rad>
   >>> c.equinox
   <Time object: scale='utc' format='byear_str' value=B1950.000>
 
diff --git a/docs/coordinates/galactocentric.rst b/docs/coordinates/galactocentric.rst
new file mode 100644
index 0000000..b19c123
--- /dev/null
+++ b/docs/coordinates/galactocentric.rst
@@ -0,0 +1,115 @@
+.. _coordinates-galactocentric:
+
+==========================================
+Transforming to Galactocentric coordinates
+==========================================
+
+This document describes the mathematics behind the transformation from
+:class:`~astropy.coordinates.ICRS` to `~astropy.coordinates.Galactocentric`
+coordinates. For examples of how to use this transformation in code, see
+the *Examples* section of the
+`~astropy.coordinates.Galactocentric` class documentation.
+
+We assume that we start with a 3D position in the ICRS reference frame:
+a Right Ascension, Declination, and heliocentric distance,
+:math:`(\alpha, \delta, d)`. We can trivially convert this to a
+Cartesian position using the standard transformation from Cartesian to
+spherical coordinates:
+
+.. math::
+
+   \begin{aligned}
+       x_{\rm icrs} &= d\cos{\alpha}\cos{\delta}\\
+       y_{\rm icrs} &= d\sin{\alpha}\cos{\delta}\\
+       z_{\rm icrs} &= d\sin{\delta}\\
+       \boldsymbol{r}_{\rm icrs} &= \begin{pmatrix}
+         x_{\rm icrs}\\
+         y_{\rm icrs}\\
+         z_{\rm icrs}
+       \end{pmatrix}\end{aligned}
+
+The first transformations will rotate the :math:`x_{\rm icrs}` axis so
+that the new :math:`x'` axis points towards the Galactic Center (GC),
+specified by the ICRS position
+:math:`(\alpha_{\rm GC}, \delta_{\rm GC})`:
+
+.. math::
+
+   \begin{aligned}
+       \boldsymbol{R}_1 &= \begin{bmatrix}
+         \cos\delta_{\rm GC}& 0 & -\sin\delta_{\rm GC}\\
+         0 & 1 & 0 \\
+         \sin\delta_{\rm GC}& 0 & \cos\delta_{\rm GC}\end{bmatrix}\\
+       \boldsymbol{R}_2 &=
+       \begin{bmatrix}
+         \cos\alpha_{\rm GC}& \sin\alpha_{\rm GC}& 0\\
+         -\sin\alpha_{\rm GC}& \cos\alpha_{\rm GC}& 0\\
+         0 & 0 & 1
+       \end{bmatrix}.\end{aligned}
+
+The transformation thus far has aligned the :math:`x'` axis with the
+vector pointing from the Sun to the GC, but the :math:`y'` and
+:math:`z'` axes point in an arbitrary direction. We adopt the
+orientation of the Galactic plane as the normal to the north pole of
+Galactic coordinates defined by the IAU
+(`Blaauw et. al. 1960 <http://adsabs.harvard.edu/abs/1960MNRAS.121..164B>`_).
+This extra “roll” angle, :math:`\eta`, was measured by transforming a grid
+of points along :math:`l=0` to this interim frame and minimizing the square
+of their :math:`y'` positions. We find:
+
+.. math::
+
+   \begin{aligned}
+       \eta &= 148.5986320^\circ\\
+       \boldsymbol{R}_3 &=
+       \begin{bmatrix}
+         1 & 0 & 0\\
+         0 & \cos\eta & \sin\eta\\
+         0 & -\sin\eta & \cos\eta
+       \end{bmatrix}\end{aligned}
+
+The full rotation matrix thus far is:
+
+.. math::
+
+   \begin{gathered}
+       \boldsymbol{R} = \boldsymbol{R}_3 \boldsymbol{R}_1 \boldsymbol{R}_2 = \\
+       \begin{bmatrix}
+         \cos\alpha_{\rm GC}\cos\delta_{\rm GC}& \cos\delta_{\rm GC}\sin\alpha_{\rm GC}& -\sin\delta_{\rm GC}\\
+         \cos\alpha_{\rm GC}\sin\delta_{\rm GC}\sin\eta - \sin\alpha_{\rm GC}\cos\eta & \sin\alpha_{\rm GC}\sin\delta_{\rm GC}\sin\eta + \cos\alpha_{\rm GC}\cos\eta & \cos\delta_{\rm GC}\sin\eta\\
+         \cos\alpha_{\rm GC}\sin\delta_{\rm GC}\cos\eta + \sin\alpha_{\rm GC}\sin\eta & \sin\alpha_{\rm GC}\sin\delta_{\rm GC}\cos\eta - \cos\alpha_{\rm GC}\sin\eta & \cos\delta_{\rm GC}\cos\eta
+       \end{bmatrix}\end{gathered}
+
+With the rotated position vector
+:math:`\boldsymbol{R}\boldsymbol{r}_{\rm icrs}`, we can now subtract the
+distance to the GC, :math:`d_{\rm GC}`, which is purely along the
+:math:`x'` axis:
+
+.. math::
+
+   \begin{aligned}
+       \boldsymbol{r}' &= \boldsymbol{R}\boldsymbol{r}_{\rm icrs} - d_{\rm GC}\hat{\boldsymbol{x}}_{\rm GC}.\end{aligned}
+
+where :math:`\hat{\boldsymbol{x}}_{\rm GC} = (1,0,0)^{\mathsf{T}}`.
+
+The final transformation is to account for the height of the Sun above
+the Galactic midplane by rotating about the final :math:`y''` axis by
+the angle :math:`\theta= \sin^{-1}(z_\odot / d_{\rm GC})`:
+
+.. math::
+
+   \begin{aligned}
+       \boldsymbol{H} &=
+       \begin{bmatrix}
+         \cos\theta & 0 & \sin\theta\\
+         0 & 1 & 0\\
+         -\sin\theta & 0 & \cos\theta
+       \end{bmatrix}\end{aligned}
+
+where :math:`z_\odot` is the measured height of the Sun above the
+midplane.
+
+The full transformation is then:
+
+.. math:: \boldsymbol{r}_{\rm GC} = \boldsymbol{H} \left( \boldsymbol{R}\boldsymbol{r}_{\rm icrs} - d_{\rm GC}\hat{\boldsymbol{x}}_{\rm GC}\right).
+
diff --git a/docs/coordinates/index.rst b/docs/coordinates/index.rst
index 8f4bc72..d1dbc26 100644
--- a/docs/coordinates/index.rst
+++ b/docs/coordinates/index.rst
@@ -32,12 +32,14 @@ equivalent::
     >>> from astropy import units as u
     >>> from astropy.coordinates import SkyCoord
 
-    >>> c = SkyCoord(ra=10.5*u.degree, dec=41.2*u.degree, frame='icrs')
-    >>> c = SkyCoord(10.5, 41.2, 'icrs', unit='deg')
-    >>> c = SkyCoord('00h42m00s', '+41d12m00s', 'icrs')
-    >>> c = SkyCoord('00 42 00 +41 12 00', 'icrs', unit=(u.hourangle, u.deg))
+    >>> c = SkyCoord(ra=10.625*u.degree, dec=41.2*u.degree, frame='icrs')
+    >>> c = SkyCoord(10.625, 41.2, frame='icrs', unit='deg')
+    >>> c = SkyCoord('00h42m30s', '+41d12m00s', frame='icrs')
+    >>> c = SkyCoord('00h42.5m', '+41d12m', frame='icrs')
+    >>> c = SkyCoord('00 42 30 +41 12 00', frame='icrs', unit=(u.hourangle, u.deg))
+    >>> c = SkyCoord('00:42.5 +41:12', frame='icrs', unit=(u.hourangle, u.deg))
     >>> c
-    <SkyCoord (ICRS): ra=10.5 deg, dec=41.2 deg>
+    <SkyCoord (ICRS): ra=10.625 deg, dec=41.2 deg>
 
 The examples above illustrate a few simple rules to follow when creating a coordinate
 object:
@@ -103,18 +105,26 @@ are defined in::
 
 Once you've defined the frame of your coordinates, you can transform from that
 frame to another frame.  You can do this a few different ways: if you just want
-the default version of that frame, you can use attribute-style access.  For
-more control, you can use the `~astropy.coordinates.SkyCoord.transform_to` method,
-which accepts a frame name, frame class, or frame instance::
+the default version of that frame, you can use attribute-style access::
 
     >>> from astropy.coordinates import FK5
     >>> c_icrs.galactic  # doctest: +FLOAT_CMP
     <SkyCoord (Galactic): l=121.174241811 deg, b=-21.5728855724 deg>
+
+For more control, you can use the `~astropy.coordinates.SkyCoord.transform_to`
+method, which accepts a frame name, frame class, or frame instance::
+
     >>> c_fk5 = c_icrs.transform_to('fk5')  # c_icrs.fk5 does the same thing
     >>> c_fk5  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2000.000, ra=10.6845915393 deg, dec=41.2691714591 deg>
+    <SkyCoord (FK5: equinox=J2000.000): ra=10.6845915393 deg, dec=41.2691714591 deg>
     >>> c_fk5.transform_to(FK5(equinox='J1975'))  # precess to a different equinox  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J1975.000, ra=10.3420913461 deg, dec=41.1323211229 deg>
+    <SkyCoord (FK5: equinox=J1975.000): ra=10.3420913461 deg, dec=41.1323211229 deg>
+
+This form of `~astropy.coordinates.SkyCoord.transform_to` also makes it
+straightforward to convert from celestial coordinates to
+`~astropy.coordinates.AltAz` coordinates, allowing the use of |skycoord|
+as a tool for planning observations.  For a more complete example of
+this, see :doc:`observing-example`.
 
 |skycoord| and all other `~astropy.coordinates` objects also support
 array coordinates.  These work the same as single-value coordinates, but
@@ -260,12 +270,14 @@ listed below.
    angles
    skycoord
    transforming
+   observing-example
    formatting
    matchsep
    representations
    frames
    sgr-example
    definitions
+   galactocentric
 
 
 In addition, another resource for the capabilities of this package is the
@@ -330,19 +342,24 @@ custom coordinates is available at :ref:`astropy-coordinates-overview`,
 and :ref:`astropy-coordinates-create-repr`.
 
 
+.. _astropy-coordinates-seealso:
+
 See Also
 ========
 
 Some references particularly useful in understanding subtleties of the
 coordinate systems implemented here include:
 
+* `USNO Circular 179 <http://aa.usno.navy.mil/publications/docs/Circular_179.php>`_
+    A useful guide to the IAU 2000/2003 work surrounding ICRS/IERS/CIRS and
+    related problems in precision coordinate system work.
 * `Standards Of Fundamental Astronomy <http://www.iausofa.org/>`_
     The definitive implementation of IAU-defined algorithms.  The "SOFA Tools
     for Earth Attitude" document is particularly valuable for understanding
     the latest IAU standards in detail.
-* `USNO Circular 179 <http://aa.usno.navy.mil/publications/docs/Circular_179.php>`_
-    A useful guide to the IAU 2000/2003 work surrounding ICRS/IERS/CIRS and
-    related problems in precision coordinate system work.
+* `IERS Conventions (2010) <http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html>`_
+    An exhaustive reference covering the ITRS, the IAU2000 celestial coordinates
+    framework, and other related details of modern coordinate conventions.
 * Meeus, J. "Astronomical Algorithms"
     A valuable text describing details of a wide range of coordinate-related
     problems and concepts.
diff --git a/docs/coordinates/matchsep.rst b/docs/coordinates/matchsep.rst
index da7f3af..bd4551c 100644
--- a/docs/coordinates/matchsep.rst
+++ b/docs/coordinates/matchsep.rst
@@ -110,3 +110,18 @@ will work on either |skycoord| objects *or* the lower-level frame classes::
     >>> idx, d2d, d3d = match_coordinates_sky(c, catalog)  # doctest: +SKIP
     >>> idx, d2d, d3d = match_coordinates_sky(c.frame, catalog.frame)  # doctest: +SKIP
 
+Closely-related functionality can be used to search for *all* coordinates within
+a certain distance (either 3D distance or on-sky) of another set of coordinates.
+The ``search_around_*`` methods (and functions) provide this functionality,
+with an interface very similar to ``match_coordinates_*``::
+
+   >>> idxc, idxcatalog, d2d, d3d = catalog.search_around_sky(c, 1*u.deg)  # doctest: +SKIP
+   >>> np.all(d2d < 1*u.deg)  # doctest: +SKIP
+   True
+   >>> idxc, idxcatalog, d2d, d3d = catalog.search_around_3d(c, 1*u.kpc)  # doctest: +SKIP
+   >>> np.all(d2d < 1*u.kpc)  # doctest: +SKIP
+   True
+
+The key difference for these methods is that there can be multiple (or no)
+matches in ``catalog`` around any locations in ``c``.  Hence, indecies into both
+``c`` and ``catalog`` are returned instead of just indecies into ``catalog``.
diff --git a/docs/coordinates/observing-example.rst b/docs/coordinates/observing-example.rst
new file mode 100644
index 0000000..08d8a53
--- /dev/null
+++ b/docs/coordinates/observing-example.rst
@@ -0,0 +1,135 @@
+.. _observing-example:
+
+Example: Observation Planning
+-----------------------------
+
+This example outlines a common use case for coordinate transformations:
+observability curves to assist planning or executing an observing run.
+This serves to demonstrate typical usage of `~astropy.coordinates.SkyCoord`
+and the transformation framework.
+
+Let's suppose you are planning to visit picturesque Bear Mountain State
+Park in New York, USA.  You're bringing your telescope with you (of course),
+and someone told you M33 is a great target to observe there.  You happen to
+know you're free at 11:00 pm local time, and you want to know if it will be
+up. Astropy can answer that:
+
+>>> import numpy as np
+>>> from astropy import units as u
+>>> from astropy.time import Time
+>>> from astropy.coordinates import SkyCoord, EarthLocation, AltAz
+>>> m33 = SkyCoord.from_name('M33')  # doctest: +REMOTE_DATA
+>>> bear_mountain = EarthLocation(lat=41.3*u.deg, lon=-74*u.deg, height=390*u.m)
+>>> utcoffset = -4*u.hour  # Eastern Daylight Time
+>>> time = Time('2012-7-12 23:00:00') - utcoffset
+>>> m33altaz = m33.transform_to(AltAz(obstime=time,location=bear_mountain))  # doctest: +REMOTE_DATA
+>>> "M33's Altitude = {0.alt:.2}".format(m33altaz)  # doctest: +FLOAT_CMP +REMOTE_DATA
+"M33's Altitude = 0.13 deg"
+
+Oops, it's only just rising, so the trees and mountains will be in the way.
+You'd better make a plot to see what the night is going to look like.
+
+    >>> midnight = Time('2012-7-13 00:00:00') - utcoffset
+    >>> delta_midnight = np.linspace(-2, 7, 100)*u.hour
+    >>> m33altazs = m33.transform_to(AltAz(obstime=midnight+delta_midnight, location=bear_mountain))  # doctest: +REMOTE_DATA
+
+.. doctest-requires:: matplotlib
+
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot(delta_midnight, m33altazs.secz)  # doctest: +REMOTE_DATA +SKIP
+    >>> plt.xlim(-2, 7)  # doctest: +SKIP
+    >>> plt.ylim(1, 4)  # doctest: +SKIP
+    >>> plt.xlabel('Hours from EDT Midnight')  # doctest: +SKIP
+    >>> plt.ylabel('Airmass [Sec(z)]')  # doctest: +SKIP
+
+
+.. plot::
+
+    import numpy as np
+    import matplotlib.pyplot as plt
+    from astropy import units as u
+    from astropy.time import Time
+    from astropy.coordinates import SkyCoord, EarthLocation, AltAz
+
+    #supress the warning about vector transforms so as not to clutter the doc build log
+    import warnings
+    warnings.filterwarnings('ignore',module='astropy.coordinates.baseframe')
+
+    m33 = SkyCoord.from_name('M33')
+    bear_mountain = EarthLocation(lat=41.3*u.deg, lon=-74*u.deg, height=390*u.m)
+    utcoffset = -4*u.hour  # Eastern Daylight Time
+    midnight = Time('2012-7-13 00:00:00') - utcoffset
+    delta_midnight = np.linspace(-2, 7, 100)*u.hour
+    m33altazs = m33.transform_to(AltAz(obstime=midnight+delta_midnight, location=bear_mountain))
+
+    plt.plot(delta_midnight, m33altazs.secz)
+    plt.xlim(-2, 7)
+    plt.ylim(1, 4)
+    plt.xlabel('Hours from EDT Midnight')
+    plt.ylabel('Airmass [Sec(z)]')
+
+
+
+Hmm, looks like you may need to stay up pretty late.  But maybe you're an
+early-riser?  But then you need to know when the sun is rising, and
+when it will be twilight::
+
+    >>> from astropy.coordinates import get_sun
+    >>> delta_midnight = np.linspace(-12, 12, 1000)*u.hour
+    >>> times = midnight + delta_midnight
+    >>> altazframe = AltAz(obstime=times, location=bear_mountain)
+    >>> sunaltazs = get_sun(times).transform_to(altazframe)
+    >>> m33altazs = m33.transform_to(altazframe)  # doctest: +REMOTE_DATA
+
+.. doctest-requires:: matplotlib
+
+    >>> plt.plot(delta_midnight, sunaltazs.alt, color='y', label='Sun')  # doctest: +SKIP
+    >>> plt.scatter(delta_midnight, m33altazs.alt, c=m33altazs.az, label='M33', lw=0, s=8)  # doctest: +REMOTE_DATA +SKIP
+    >>> plt.fill_between(delta_midnight, 0, 90, sunaltazs.alt < -0*u.deg, color='0.5', zorder=0)  # doctest: +SKIP
+    >>> plt.fill_between(delta_midnight, 0, 90, sunaltazs.alt < -18*u.deg, color='k', zorder=0)  # doctest: +SKIP
+    >>> plt.colorbar().set_label('Azimuth [deg]')  # doctest: +SKIP
+    >>> plt.legend(loc='upper left')
+    >>> plt.xlim(-12, 12)  # doctest: +SKIP
+    >>> plt.xticks(np.arange(13)*2 -12)  # doctest: +SKIP
+    >>> plt.ylim(0, 90)  # doctest: +SKIP
+    >>> plt.xlabel('Hours from EDT Midnight')  # doctest: +SKIP
+    >>> plt.ylabel('Altitude [deg]')  # doctest: +SKIP
+
+
+.. plot::
+
+    import numpy as np
+    import matplotlib.pyplot as plt
+    from astropy import units as u
+    from astropy.time import Time
+    from astropy.coordinates import SkyCoord, EarthLocation, AltAz, get_sun
+
+    #supress the warning about vector transforms so as not to clutter the doc build log
+    import warnings
+    warnings.filterwarnings('ignore',module='astropy.coordinates.baseframe')
+
+    m33 = SkyCoord.from_name('M33')
+    bear_mountain = EarthLocation(lat=41.3*u.deg, lon=-74*u.deg, height=390*u.m)
+    utcoffset = -4*u.hour  # Eastern Daylight Time
+    midnight = Time('2012-7-13 00:00:00') - utcoffset
+
+    delta_midnight = np.linspace(-12, 12, 1000)*u.hour
+    times = midnight + delta_midnight
+    altazframe = AltAz(obstime=times, location=bear_mountain)
+    sunaltazs = get_sun(times).transform_to(altazframe)
+    m33altazs = m33.transform_to(altazframe)
+
+    plt.plot(delta_midnight, sunaltazs.alt, color='y', label='Sun')
+    plt.scatter(delta_midnight, m33altazs.alt, c=m33altazs.az, label='M33', lw=0, s=8)
+    plt.fill_between(delta_midnight, 0, 90, sunaltazs.alt < -0*u.deg, color='0.5', zorder=0)
+    plt.fill_between(delta_midnight, 0, 90, sunaltazs.alt < -18*u.deg, color='k', zorder=0)
+    plt.colorbar().set_label('Azimuth [deg]')
+    plt.legend(loc='upper left')
+    plt.xlim(-12, 12)
+    plt.xticks(np.arange(13)*2 -12)
+    plt.ylim(0, 90)
+    plt.xlabel('Hours from EDT Midnight')
+    plt.ylabel('Altitude [deg]')
+
+Now you're fully-equipped with the tools you need to plan your next
+observing run... Or have have a proper vacation.  You decide!
diff --git a/docs/coordinates/skycoord.rst b/docs/coordinates/skycoord.rst
index cae82bc..4413567 100644
--- a/docs/coordinates/skycoord.rst
+++ b/docs/coordinates/skycoord.rst
@@ -70,10 +70,10 @@ The coordinate values and frame specification can now be provided using
 positional and keyword arguments.  First we show positional arguments for
 RA and Dec::
 
-  >>> SkyCoord(10, 20, unit="deg")  # Defaults to ICRS
+  >>> SkyCoord(10, 20, unit='deg')  # Defaults to ICRS
   <SkyCoord (ICRS): ra=10.0 deg, dec=20.0 deg>
 
-  >>> SkyCoord([1, 2, 3], [-30, 45, 8], "icrs", unit="deg")
+  >>> SkyCoord([1, 2, 3], [-30, 45, 8], frame='icrs', unit='deg')
   <SkyCoord (ICRS): (ra, dec) in deg
       [(1.0, -30.0), (2.0, 45.0), (3.0, 8.0)]>
 
@@ -84,16 +84,33 @@ explicitly specify the frame when it is known to be ICRS, however, as
 anyone reading the code will be better able to understand the intent.
 
 String inputs in common formats are acceptable, and the frame can be supplied
-as either a class type like `~astropy.coordinates.FK4` or the lower-case
-version of the name as a string, e.g. ``"fk4"``::
+as either a class type like `~astropy.coordinates.FK4`, an instance of a
+frame class, a `~astropy.coordinates.SkyCoord` instance (from which the frame
+will be extracted), or the lower-case version of a frame name as a string,
+e.g. ``"fk4"``::
 
   >>> coords = ["1:12:43.2 +1:12:43", "1 12 43.2 +1 12 43"]
-  >>> sc = SkyCoord(coords, FK4, unit=(u.hourangle, u.deg), obstime="J1992.21")
-  >>> sc = SkyCoord(coords, 'fk4', unit='hourangle,deg', obstime="J1992.21")
+  >>> sc = SkyCoord(coords, frame=FK4, unit=(u.hourangle, u.deg), obstime="J1992.21")
+  >>> sc = SkyCoord(coords, frame=FK4(obstime="J1992.21"), unit=(u.hourangle, u.deg))
+  >>> sc = SkyCoord(coords, frame='fk4', unit='hourangle,deg', obstime="J1992.21")
 
-  >>> sc = SkyCoord("1h12m43.2s", "+1d12m43s", Galactic)  # Units from strings
-  >>> sc = SkyCoord("1h12m43.2s +1d12m43s", Galactic)  # Units from string
-  >>> sc = SkyCoord("galactic", l="1h12m43.2s", b="+1d12m43s")
+  >>> sc = SkyCoord("1h12m43.2s", "+1d12m43s", frame=Galactic)  # Units from strings
+  >>> sc = SkyCoord("1h12m43.2s +1d12m43s", frame=Galactic)  # Units from string
+  >>> sc = SkyCoord(l="1h12m43.2s", b="+1d12m43s", frame='galactic')
+  >>> sc = SkyCoord("1h12.72m +1d12.71m", frame='galactic')
+
+Note that frame instances with data and `~astropy.coordinates.SkyCoord` instances
+can only be passed as frames using the ``frame=`` keyword argument and not as
+positional arguments.
+
+For representations that have ``ra`` and ``dec`` attributes one can supply a coordinate
+string in a number of other common formats.  Examples include::
+
+  >>> sc = SkyCoord("15h17+89d15")
+  >>> sc = SkyCoord("275d11m15.6954s+17d59m59.876s")
+  >>> sc = SkyCoord("8 00 -5 00.6", unit=(u.hour, u.deg))
+  >>> sc = SkyCoord("J080000.00-050036.00", unit=(u.hour, u.deg))
+  >>> sc = SkyCoord("J1874221.31+122328.03", unit=u.deg)
 
 Astropy `~astropy.units.Quantity`-type objects are acceptable and encouraged
 as a form of input::
@@ -101,7 +118,7 @@ as a form of input::
   >>> ra = Longitude([1, 2, 3], unit=u.deg)  # Could also use Angle
   >>> dec = np.array([4.5, 5.2, 6.3]) * u.deg  # Astropy Quantity
   >>> sc = SkyCoord(ra, dec, frame='icrs')
-  >>> sc = SkyCoord(ICRS, ra=ra, dec=dec, obstime='2001-01-02T12:34:56')
+  >>> sc = SkyCoord(ra=ra, dec=dec, frame=ICRS, obstime='2001-01-02T12:34:56')
 
 Finally it is possible to initialize from a low-level coordinate frame object.
 
@@ -193,12 +210,13 @@ represented in the standard spherical coordinates:
 
 **FRAME**
 
-This can be a `~astropy.coordinates.BaseCoordinateFrame` frame
-class or the corresponding string alias.  The frame classes that are built in
-to astropy are `~astropy.coordinates.ICRS`, `~astropy.coordinates.FK5`,
-`~astropy.coordinates.FK4`, `~astropy.coordinates.FK4NoETerms`,
-`~astropy.coordinates.Galactic`, and `~astropy.coordinates.AltAz`.
-The string aliases are simply lower-case versions of the class name.
+This can be a `~astropy.coordinates.BaseCoordinateFrame` frame class, an
+instance of such a class, or the corresponding string alias. The frame
+classes that are built in to astropy are `~astropy.coordinates.ICRS`,
+`~astropy.coordinates.FK5`, `~astropy.coordinates.FK4`,
+`~astropy.coordinates.FK4NoETerms`, `~astropy.coordinates.Galactic`, and
+`~astropy.coordinates.AltAz`. The string aliases are simply lower-case
+versions of the class name.
 
 If the frame is not supplied then you will see a special ``ICRS``
 identifier.  This indicates that the frame is unspecified and operations
@@ -255,11 +273,11 @@ looping over a list of individual |SkyCoord| objects::
   >>> ra = np.random.uniform(0, 360, size=1000) * u.deg
   >>> dec = np.random.uniform(-90, 90, size=1000) * u.deg
 
-  >>> sc_list = [SkyCoord(r, d, 'icrs') for r, d in zip(ra, dec)]
+  >>> sc_list = [SkyCoord(r, d, frame='icrs') for r, d in zip(ra, dec)]
   >>> timeit sc_gal_list = [c.galactic for c in sc_list]  # doctest: +SKIP
   1 loops, best of 3: 7.66 s per loop
 
-  >>> sc = SkyCoord(ra, dec, 'icrs')
+  >>> sc = SkyCoord(ra, dec, frame='icrs')
   >>> timeit sc_gal = sc.galactic  # doctest: +SKIP
   100 loops, best of 3: 8.92 ms per loop
 
@@ -291,7 +309,7 @@ within IPython you can type an object name, the period, and then the <TAB> key
 to see what's available.  This can often be faster than reading the
 documentation::
 
-  >>> sc = SkyCoord(1, 2, 'icrs', unit='deg', obstime='2013-01-02 14:25:36')
+  >>> sc = SkyCoord(1, 2, frame='icrs', unit='deg', obstime='2013-01-02 14:25:36')
   >>> sc.<TAB>  # doctest: +SKIP
   sc.cartesian                           sc.match_to_catalog_3d
   sc.data                                sc.match_to_catalog_sky
@@ -363,7 +381,7 @@ the coordinate keyword arguments that |SkyCoord| will accept.
 Another important attribute is ``frame_attr_names``, which defines the
 additional attributes that are required to fully define the frame::
 
-  >>> sc_fk4 = SkyCoord(1, 2, 'fk4', unit='deg')
+  >>> sc_fk4 = SkyCoord(1, 2, frame='fk4', unit='deg')
   >>> sc_fk4.get_frame_attr_names()  # doctest: +SKIP
   {u'equinox': <Time object: scale='tai' format='byear_str' value=B1950.000>,
    u'obstime': None}
@@ -429,22 +447,22 @@ previously).  For more control, you can use the
 name, frame class, frame instance, or |SkyCoord|::
 
   >>> from astropy.coordinates import FK5
-  >>> sc = SkyCoord(1, 2, 'icrs', unit='deg')
+  >>> sc = SkyCoord(1, 2, frame='icrs', unit='deg')
   >>> sc.galactic  # doctest: +FLOAT_CMP
   <SkyCoord (Galactic): l=99.6378552814 deg, b=-58.7096929334 deg>
 
   >>> sc.transform_to('fk5')  # Same as sc.fk5 and sc.transform_to(FK5)  # doctest: +FLOAT_CMP
-  <SkyCoord (FK5): equinox=J2000.000, ra=1.00000655566 deg, dec=2.00000243092 deg>
+  <SkyCoord (FK5: equinox=J2000.000): ra=1.00000655566 deg, dec=2.00000243092 deg>
 
   >>> sc.transform_to(FK5(equinox='J1975'))  # Transform to FK5 with a different equinox  # doctest: +FLOAT_CMP
-  <SkyCoord (FK5): equinox=J1975.000, ra=0.679672818323 deg, dec=1.86083014099 deg>
+  <SkyCoord (FK5: equinox=J1975.000): ra=0.679672818323 deg, dec=1.86083014099 deg>
 
 Transforming to a |SkyCoord| instance is an easy way of ensuring that two
 coordinates are in the exact same reference frame::
 
-  >>> sc2 = SkyCoord(3, 4, 'fk4', unit='deg', obstime='J1978.123', equinox='B1960.0')
+  >>> sc2 = SkyCoord(3, 4, frame='fk4', unit='deg', obstime='J1978.123', equinox='B1960.0')
   >>> sc.transform_to(sc2)
-  <SkyCoord (FK4): equinox=B1960.000, obstime=J1978.123, ra=0.48726331438 deg, dec=1.77731617297 deg>
+  <SkyCoord (FK4: equinox=B1960.000, obstime=J1978.123): ra=0.48726331438 deg, dec=1.77731617297 deg>
 
 .. _astropy-skycoord-representations:
 
@@ -668,27 +686,23 @@ state of the |SkyCoord| object, you should instead use the
 Example 1: Plotting random data in Aitoff projection
 ====================================================
 
-This is an example how to make a plot in the Aitoff projection using data 
+This is an example how to make a plot in the Aitoff projection using data
 in a |SkyCoord| object. Here a randomly generated data set will be used.
 
-First we need to import the required packages. We use 
+First we need to import the required packages. We use
 `matplotlib <http://www.matplotlib.org/>`_ here for
-plotting and `numpy <http://www.numpy.org/>`_  to get the value of pi and to 
+plotting and `numpy <http://www.numpy.org/>`_  to get the value of pi and to
 generate our random data.
 
-.. doctest-requires:: matplotlib
-
     >>> from astropy import units as u
     >>> from astropy.coordinates import SkyCoord
-    >>> import matplotlib.pyplot as plt
     >>> import numpy as np
 
 We now generate random data for visualisation. For RA this is done in the range
 of 0 and 360 degrees (``ra_random``), for DEC between -90 and +90 degrees
-(``dec_random``). Finally, we multiply these values by degrees to get an 
+(``dec_random``). Finally, we multiply these values by degrees to get an
 `~astropy.units.Quantity` with units of degrees.
 
-.. doctest-requires:: matplotlib
 
     >>> ra_random = np.random.rand(100)*360.0 * u.degree
     >>> dec_random = (np.random.rand(100)*180.0-90.0) * u.degree
@@ -696,46 +710,45 @@ of 0 and 360 degrees (``ra_random``), for DEC between -90 and +90 degrees
 As next step, those coordinates are transformed into an astropy.coordinates
 |SkyCoord| object.
 
-.. doctest-requires:: matplotlib
 
     >>> c = SkyCoord(ra=ra_random, dec=dec_random, frame='icrs')
 
 Because matplotlib needs the coordinates in radians and between :math:`-\pi`
-and :math:`\pi`, not 0 and :math:`2\pi`, we have to convert them. 
+and :math:`\pi`, not 0 and :math:`2\pi`, we have to convert them.
 For this purpose the `astropy.coordinates.Angle` object provides a special method,
 which we use here to wrap at 180:
 
-.. doctest-requires:: matplotlib
 
     >>> ra_rad = c.ra.wrap_at(180 * u.deg).radian
     >>> dec_rad = c.dec.radian
 
 As last step we set up the plotting environment with matplotlib using the
 Aitoff projection with a specific title, a grid, filled circles as markers with
-a markersize of 2 and an alpha value of 0.3. We use a figure with an x-y ratio 
-that is well suited for such a projection and we move the title upwards from 
+a markersize of 2 and an alpha value of 0.3. We use a figure with an x-y ratio
+that is well suited for such a projection and we move the title upwards from
 its usual position to avoid overlap with the axis labels.
 
-.. doctest-requires:: matplotlib
+.. doctest-skip::
 
+    >>> import matplotlib.pyplot as plt
     >>> plt.figure(figsize=(8,4.2))
     >>> plt.subplot(111, projection="aitoff")
     >>> plt.title("Aitoff projection of our random data")
     >>> plt.grid(True)
     >>> plt.plot(ra_rad, dec_rad, 'o', markersize=2, alpha=0.3)
-    >>> plt.subplots_adjust(top=0.95,bottom=0.0) 
+    >>> plt.subplots_adjust(top=0.95,bottom=0.0)
     >>> plt.show()
 
 
 .. plot::
 
-    # This is an example how to make a plot in the Aitoff projection using data 
+    # This is an example how to make a plot in the Aitoff projection using data
     # in a SkyCoord object. Here a randomly generated data set will be used. The
     # final script can be found below.
 
-    # First we need to import the required packages. We use 
+    # First we need to import the required packages. We use
     # `matplotlib <http://www.matplotlib.org/>`_ here for
-    # plotting and `numpy <http://www.numpy.org/>`_  to get the value of pi and to 
+    # plotting and `numpy <http://www.numpy.org/>`_  to get the value of pi and to
     # generate our random data.
     from astropy import units as u
     from astropy.coordinates import SkyCoord
@@ -744,7 +757,7 @@ its usual position to avoid overlap with the axis labels.
 
     # We now generate random data for visualisation. For RA this is done in the range
     # of 0 and 360 degrees (``ra_random``), for DEC between -90 and +90 degrees
-    # (``dec_random``). Finally, we multiply these values by degrees to get an 
+    # (``dec_random``). Finally, we multiply these values by degrees to get an
     # `~astropy.units.Quantity` with units of degrees.
     ra_random = np.random.rand(100)*360.0 * u.degree
     dec_random = (np.random.rand(100)*180.0-90.0) * u.degree
@@ -754,7 +767,7 @@ its usual position to avoid overlap with the axis labels.
     c = SkyCoord(ra=ra_random, dec=dec_random, frame='icrs')
 
     # Because matplotlib needs the coordinates in radians and between :math:`-\pi`
-    # and :math:`\pi`, not 0 and :math:`2\pi`, we have to convert them. 
+    # and :math:`\pi`, not 0 and :math:`2\pi`, we have to convert them.
     # For this purpose the `astropy.coordinates.Angle` object provides a special method,
     # which we use here to wrap at 180:
     ra_rad = c.ra.wrap_at(180 * u.deg).radian
@@ -768,7 +781,7 @@ its usual position to avoid overlap with the axis labels.
     plt.title("Aitoff projection of our random data", y=1.08)
     plt.grid(True)
     plt.plot(ra_rad, dec_rad, 'o', markersize=2, alpha=0.3)
-    plt.subplots_adjust(top=0.95,bottom=0.0) 
+    plt.subplots_adjust(top=0.95,bottom=0.0)
     plt.show()
 
 
@@ -776,26 +789,21 @@ its usual position to avoid overlap with the axis labels.
 Example 2: Plotting star positions in bulge and disk
 ====================================================
 
-This is more realitic example how to make a plot in the Aitoff projection
+This is more realistic example how to make a plot in the Aitoff projection
 using data in a |SkyCoord| object.
-Here a randomly generated data set (multivariante
+Here a randomly generated data set (multivariate
 normal distribution) for both stars in the bulge and in the disk of a galaxy
-will be used. Both types will be plotted with different number counts. 
+will be used. Both types will be plotted with different number counts.
 
 As in the last example, we first import the required packages.
 
-.. doctest-requires:: matplotlib
-
     >>> from astropy import units as u
     >>> from astropy.coordinates import SkyCoord
-    >>> import matplotlib.pyplot as plt
     >>> import numpy as np
 
 We now generate random data for visualisation using
 `numpy.random.multivariate_normal`.
 
-.. doctest-requires:: matplotlib
-
     >>> disk = np.random.multivariate_normal(mean=[0,0,0], cov=np.diag([1,1,0.5]), size=5000)
     >>> bulge = np.random.multivariate_normal(mean=[0,0,0], cov=np.diag([1,1,1]), size=500)
     >>> galaxy = np.concatenate([disk, bulge])
@@ -803,37 +811,34 @@ We now generate random data for visualisation using
 As next step, those coordinates are transformed into an astropy.coordinates
 |SkyCoord| object.
 
-.. doctest-requires:: matplotlib
-
     >>> c_gal = SkyCoord(galaxy, representation='cartesian', frame='galactic')
     >>> c_gal_icrs = c_gal.icrs
 
-Again, as in the last example, we need to convert the coordinates in radians 
+Again, as in the last example, we need to convert the coordinates in radians
 and make sure they are between :math:`-\pi` and :math:`\pi`:
 
-.. doctest-requires:: matplotlib
-
     >>> ra_rad = c_gal_icrs.ra.wrap_at(180 * u.deg).radian
     >>> dec_rad = c_gal_icrs.dec.radian
 
 We use the same plotting setup as in the last example:
 
-.. doctest-requires:: matplotlib
+.. doctest-skip::
 
+    >>> import matplotlib.pyplot as plt
     >>> plt.figure(figsize=(8,4.2))
     >>> plt.subplot(111, projection="aitoff")
     >>> plt.title("Aitoff projection of our random data")
     >>> plt.grid(True)
     >>> plt.plot(ra_rad, dec_rad, 'o', markersize=2, alpha=0.3)
-    >>> plt.subplots_adjust(top=0.95,bottom=0.0) 
+    >>> plt.subplots_adjust(top=0.95,bottom=0.0)
     >>> plt.show()
 
 
 .. plot::
 
-    # This is more realitic example how to make a plot in the Aitoff projection
+    # This is more realistic example how to make a plot in the Aitoff projection
     # using data in a SkyCoord object.
-    # Here a randomly generated data set (multivariante normal distribution) 
+    # Here a randomly generated data set (multivariate normal distribution)
     # for both stars in the bulge and in the disk of a galaxy
     # will be used. Both types will be plotted with different number counts. The
     # final script can be found below.
@@ -844,7 +849,7 @@ We use the same plotting setup as in the last example:
     import matplotlib.pyplot as plt
     import numpy as np
 
-    # We now generate random data for visualisation with 
+    # We now generate random data for visualisation with
     # np.random.multivariate_normal.
     disk = np.random.multivariate_normal(mean=[0,0,0], cov=np.diag([1,1,0.5]), size=5000)
     bulge = np.random.multivariate_normal(mean=[0,0,0], cov=np.diag([1,1,1]), size=500)
@@ -855,7 +860,7 @@ We use the same plotting setup as in the last example:
     c_gal = SkyCoord(galaxy, representation='cartesian', frame='galactic')
     c_gal_icrs = c_gal.icrs
 
-    # Again, as in the last example, we need to convert the coordinates in radians 
+    # Again, as in the last example, we need to convert the coordinates in radians
     # and make sure they are between :math:`-\pi` and :math:`\pi`:
     ra_rad = c_gal_icrs.ra.wrap_at(180 * u.deg).radian
     dec_rad = c_gal_icrs.dec.radian
@@ -866,7 +871,7 @@ We use the same plotting setup as in the last example:
     plt.title("Aitoff projection of our random data", y=1.08)
     plt.grid(True)
     plt.plot(ra_rad, dec_rad, 'o', markersize=2, alpha=0.3)
-    plt.subplots_adjust(top=0.95,bottom=0.0) 
+    plt.subplots_adjust(top=0.95,bottom=0.0)
     plt.show()
 
 
diff --git a/docs/coordinates/transforming.rst b/docs/coordinates/transforming.rst
index 98191f0..e0eb87a 100644
--- a/docs/coordinates/transforming.rst
+++ b/docs/coordinates/transforming.rst
@@ -6,20 +6,24 @@ Transforming Between Systems
 ----------------------------
 
 `astropy.coordinates` supports a rich system for transforming
-coordinates from one system to another.  While common astronomy frames
+coordinates from one frame to another.  While common astronomy frames
 are  built into Astropy, the transformation infrastructure is dynamic.
 This means it allows users to define new coordinate frames and their
 transformations.  The topic of writing your own coordinate frame or
 transforms is detailed in :ref:`astropy-coordinates-design`, and this
 section is focused on how to *use* transformations.
 
+The full list of built-in coordinate frames, the included transformations,
+and the frame names are shown as a (clickable) graph in the `~astropy.coordinates` API
+documentation.
+
 The simplest method of transformation is shown below::
 
     >>> import astropy.units as u
     >>> from astropy.coordinates import SkyCoord
     >>> gc = SkyCoord(l=0*u.degree, b=45*u.degree, frame='galactic')
     >>> gc.fk5  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2000.000, ra=229.272514629 deg, dec=-1.12844288043 deg>
+    <SkyCoord (FK5: equinox=J2000.000): ra=229.272514629 deg, dec=-1.12844288043 deg>
 
 While this appears to be simple attribute-style access, it is actually
 syntactic sugar for the more general
@@ -28,11 +32,11 @@ accept either a frame name, class or instance::
 
     >>> from astropy.coordinates import FK5
     >>> gc.transform_to('fk5')  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2000.000, ra=229.272514629 deg, dec=-1.12844288043 deg>
+    <SkyCoord (FK5: equinox=J2000.000): ra=229.272514629 deg, dec=-1.12844288043 deg>
     >>> gc.transform_to(FK5)  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2000.000, ra=229.272514629 deg, dec=-1.12844288043 deg>
+    <SkyCoord (FK5: equinox=J2000.000): ra=229.272514629 deg, dec=-1.12844288043 deg>
     >>> gc.transform_to(FK5(equinox='J1980.0'))  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J1980.000, ra=229.014693505 deg, dec=-1.05560349378 deg>
+    <SkyCoord (FK5: equinox=J1980.000): ra=229.014693505 deg, dec=-1.05560349378 deg>
 
 As a convenience it is also possible to use a |SkyCoord| object as the frame in
 :meth:`~astropy.coordinates.SkyCoord.transform_to`.  This allows easily putting one
@@ -40,39 +44,25 @@ coordinate object into the frame of another::
 
     >>> sc = SkyCoord(ra=1.0, dec=2.0, unit='deg', frame=FK5, equinox='J1980.0')
     >>> gc.transform_to(sc)  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J1980.000, ra=229.014693505 deg, dec=-1.05560349378 deg>
-
-The table below summarizes the built-in coordinate frames.  For details of
-these frames and the transformations between them see the `astropy.coordinates`
-API documentation and the `~astropy.coordinates.BaseCoordinateFrame` class
-which forms the basis for all `astropy.coordinates` coordinate frames.
-
-================================== ================
- Frame class                        Frame name
-================================== ================
-`~astropy.coordinates.ICRS`         ``icrs``
-`~astropy.coordinates.FK5`          ``fk5``
-`~astropy.coordinates.FK4`          ``fk4``
-`~astropy.coordinates.FK4NoETerms`  ``fk4noeterms``
-`~astropy.coordinates.Galactic`     ``galactic``
-================================== ================
+    <SkyCoord (FK5: equinox=J1980.000): ra=229.014693505 deg, dec=-1.05560349378 deg>
+
 
 Additionally, some coordinate frames (including `~astropy.coordinates.FK5`,
 `~astropy.coordinates.FK4`, and `~astropy.coordinates.FK4NoETerms`) support
 "self transformations", meaning the *type* of frame doesn't change, but the
 frame attributes do.  Any example is precessing a coordinate from one equinox
-to another in an equatorial system. This is done by passing ``transform_to`` a
+to another in an equatorial frame. This is done by passing ``transform_to`` a
 frame class with the relevant attributes, as shown below. Note that these
-systems use a default equinox if you don't specify one::
+frames use a default equinox if you don't specify one::
 
     >>> fk5c = FK5('02h31m49.09s', '+89d15m50.8s')
     >>> fk5c.equinox
     <Time object: scale='utc' format='jyear_str' value=J2000.000>
     >>> fk5c  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2000.000, ra=37.9545416667 deg, dec=89.2641111111 deg>
+    <SkyCoord (FK5: equinox=J2000.000): ra=37.9545416667 deg, dec=89.2641111111 deg>
     >>> fk5_2005 = FK5(equinox='J2005')  # String initializes an astropy.time.Time object
     >>> fk5c.transform_to(fk5_2005)  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=J2005.000, ra=39.3931763878 deg, dec=89.2858442155 deg>
+    <SkyCoord (FK5: equinox=J2005.000): ra=39.3931763878 deg, dec=89.2858442155 deg>
 
 You can also specify the equinox when you create a coordinate using an
 `~astropy.time.Time` object::
@@ -82,7 +72,7 @@ You can also specify the equinox when you create a coordinate using an
     ...            equinox=Time('J1970', scale='utc'))
     >>> fk5_2000 = FK5(equinox=Time(2000, format='jyear', scale='utc'))
     >>> fk5c.transform_to(fk5_2000)  # doctest: +FLOAT_CMP
-    <SkyCoord (FK5): equinox=2000.0, ra=48.0231710002 deg, dec=89.386724854 deg>
+    <SkyCoord (FK5: equinox=2000.0): ra=48.0231710002 deg, dec=89.386724854 deg>
 
 The same lower-level frame classes also have a
 :meth:`~astropy.coordinates.BaseCoordinateFrame.transform_to` method
diff --git a/docs/cosmology/index.rst b/docs/cosmology/index.rst
index 66bb0ec..defed7c 100644
--- a/docs/cosmology/index.rst
+++ b/docs/cosmology/index.rst
@@ -57,7 +57,7 @@ classes::
   >>> cosmo = FlatLambdaCDM(H0=70, Om0=0.3)
   >>> cosmo
   FlatLambdaCDM(H0=70 km / (Mpc s), Om0=0.3, Tcmb0=2.725 K,
-                Neff=3.04, m_nu=[ 0.  0.  0.] eV)
+                Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=None)
 
 The cosmology subpackage makes use of `~astropy.units`, so in many
 cases returns values with units attached.  Consult the documentation
@@ -88,7 +88,7 @@ arguments giving the Hubble parameter and omega matter (both at z=0)::
   >>> cosmo = FlatLambdaCDM(H0=70, Om0=0.3)
   >>> cosmo
   FlatLambdaCDM(H0=70 km / (Mpc s), Om0=0.3, Tcmb0=2.725 K,
-                Neff=3.04, m_nu=[ 0.  0.  0.] eV)
+                Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=None)
 
 This can also be done more explicitly using units, which is recommended::
 
@@ -149,6 +149,31 @@ flat Universe because photons and neutrinos are included. Also note
 that they are unitless and so are not `~astropy.units.Quantity`
 objects.
 
+It is possible to specify the baryonic matter density at redshift zero
+at class instantiation by passing the keyword argument ``Ob0``::
+
+  >>> from astropy.cosmology import FlatLambdaCDM
+  >>> cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05)
+  >>> cosmo
+  FlatLambdaCDM(H0=70 km / (Mpc s), Om0=0.3, Tcmb0=2.725 K,
+                Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=0.05)
+
+In this case the dark matter only density at redshift zero is
+available as class attribute ``Odm0`` and the redshift evolution of
+dark and baryonic matter densities can be computed using the methods
+``Odm`` and ``Ob``, respectively. If ``Ob0`` is not specified at class
+instantiation it defaults to ``None`` and any method relying on it
+being specified will raise a ``ValueError``:
+
+  >>> from astropy.cosmology import FlatLambdaCDM
+  >>> cosmo = FlatLambdaCDM(H0=70, Om0=0.3)
+  >>> cosmo.Odm(1)
+  Traceback (most recent call last):
+      cosmo.Odm(1)
+    File "astropy/cosmology/core.py", line 539, in Odm
+      raise ValueError("Baryonic density not set for this cosmology, "
+  ValueError: Baryonic density not set for this cosmology, unclear meaning of dark matter density
+
 Cosmological instances have an optional ``name`` attribute which can be
 used to describe the cosmology::
 
@@ -156,7 +181,7 @@ used to describe the cosmology::
   >>> cosmo = FlatwCDM(name='SNLS3+WMAP7', H0=71.58, Om0=0.262, w0=-1.016)
   >>> cosmo
   FlatwCDM(name="SNLS3+WMAP7", H0=71.6 km / (Mpc s), Om0=0.262,
-           w0=-1.02, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV)
+           w0=-1.02, Tcmb0=2.725 K, Neff=3.04, m_nu=[ 0.  0.  0.] eV, Ob0=None)
 
 This is also an example with a different model for dark energy, a flat
 Universe with a constant dark energy equation of state, but not
@@ -166,7 +191,20 @@ model`_.
 
 A important point is that the cosmological parameters of each
 instance are immutable -- that is, if you want to change, say,
-``Om``, you need to make a new instance of the class.
+``Om``, you need to make a new instance of the class.  To make
+this more convenient, a ``clone`` operation is provided, which
+allows you to make a copy with specified values changed.
+Note that you can't change the type of cosmology with this operation
+(e.g., flat to non-flat). For example:
+
+  >>> from astropy.cosmology import WMAP9
+  >>> newcosmo = WMAP9.clone(name='WMAP9 modified', Om0=0.3141)
+  >>> WMAP9.H0, newcosmo.H0  # some values unchanged
+  (<Quantity 69.3... km / (Mpc s)>, <Quantity 69.3... km / (Mpc s)>)
+  >>> WMAP9.Om0, newcosmo.Om0  # some changed
+  (0.286..., 0.314...)
+  >>> WMAP9.Ode0, newcosmo.Ode0  # Indirectly changed since this is flat
+  (0.713..., 0.685...)
 
 
 Finding the Redshift at a Given Value of a Cosmological Quantity
@@ -245,7 +283,9 @@ redshift by `~astropy.cosmology.wpwaCDM`: :math:`w(z) = w_{p} + w_{a}
 
 Users can specify their own equation of state by sub-classing
 `~astropy.cosmology.FLRW`.  See the provided subclasses for
-examples.
+examples. It is recommended, but not required, that all arguments to the
+constructor of a new subclass be available as properties, since the
+``clone`` method assumes this is the case.
 
 Photons and Neutrinos
 ---------------------
diff --git a/docs/credits.rst b/docs/credits.rst
index eb99557..79fd3a7 100644
--- a/docs/credits.rst
+++ b/docs/credits.rst
@@ -28,6 +28,7 @@ Core Package Contributors
 * Gustavo Bragança
 * Erik M. Bray
 * Eli Bressert
+* Mihai Cara
 * Mabry Cervin
 * Pritish Chakraborty
 * Alex Conley
diff --git a/docs/development/affiliated-packages.rst b/docs/development/affiliated-packages.rst
index fa50f70..4075fe2 100644
--- a/docs/development/affiliated-packages.rst
+++ b/docs/development/affiliated-packages.rst
@@ -5,22 +5,226 @@ How to create and maintain an Astropy affiliated package
 If you run into any problems, don't hesitate to ask for help on the
 astropy-dev mailing list!
 
+The `package-template`_ repository provides a template for packages that are
+affiliated with the `Astropy`_ project. This package design mirrors the
+layout of the main `Astropy`_ repository, as well as reusing much of the
+helper code used to organize `Astropy`_. The instructions below describe how
+to take this template and adjust it for your particular affiliated package,
+as well as how to update your package to the latest version of the package
+template.
+
+There are two main ways you can use this template layout to create a new
+package:
+
+#. simply copy over the files you need manually
+
+#. start from a fork of the package-template repository
+
+There are advantages and disadvantages to both methods. In the first case your
+repository history will be clean and you will only include the files you really
+need. However, when updating you will need to make sure you update all the
+files manually. In the second case, the history of your package will be
+cluttered with all the commits from the `package-template`_ repository, but if
+done properly this can be easier to update in future since it simply involves
+pulling from the latest version of the `package-template`_ repository and then
+merging in the changes (and resolving conflicts).
+
+.. note:: The instructions below assume you are using git for version control,
+          as is used by the Astropy repository. If this is not the case,
+          hopefully it will be clear from context what to do with your
+          particular VCS.
+
+Everywhere below that the text ``<packagename>`` is shown, replace it with the
+name of your particular package. In fact, you can do this automatically by
+entering your package name in the box below:
+
+.. raw:: html
+
+    <form id="myform">
+      Package name: <input type="text" name="packagename">
+      <button>Update package name</button>
+    </form>
+    <br>
+
+Managing the template files manually
+====================================
+
 Starting a new package
-======================
+----------------------
+
+#. Clone the `package-template`_ package so that we can have access to the
+   files, but do not go inside it - instead, create another empty repository
+   into which we will copy the required files::
+
+    git clone http://github.com/astropy/package-template.git template
+    mkdir <packagename>
+    cd <packagename>
+    git init
+
+#. The `package-template`_ infrastructure relies on the `astropy-helpers`_
+   package, and we recommend adding this as a sub-module so as to easily be
+   able to bundle it in releases of affiliated packages::
+
+    git submodule add http://github.com/astropy/astropy-helpers.git astropy_helpers
+
+#. Copy over the following files from the package template (these define the
+   bare minimum of what is needed) and add them to the repository::
+
+    # .gitignore specifies which types of files to ignore in the repository
+    cp ../template/.gitignore .
+
+    # MANIFEST.in specifies which files to include in a tar file release
+    cp ../template/MANIFEST.in .
+
+    # ah_bootstrap.py is used by setup.py to use the astropy-helpers
+    cp ../template/ah_bootstrap.py .
+
+    # ez_setup.py is used by setup.py to be able to get setuptools on-the-fly
+    cp ../template/ez_setup.py .
+
+    # setup.cfg contains details about your package - edit it after copying!
+    # Note: it is important that the package_name variable matches the name you
+    #       are using for your package.
+    cp ../template/setup.cfg .
+
+    # edit the VERSION variable, the rest can be kept as-is
+    cp ../template/setup.py .
+
+   .. important:: Before proceeding, make sure you have edited ``setup.cfg`` and
+                 ``setup.py`` as indicated above!
+
+   Once you have edited ``setup.cfg`` and ``setup.py``, you can commit the
+   changes::
+
+    git add .gitignore MANIFEST.in ah_bootstrap.py ez_setup.py setup.cfg setup.py
+
+#. Next, you can create a directory for your package's source code, which will
+   usually also be called the same name as your package. In this directory
+   you can copy over the following files::
+
+    mkdir <packagename>
+
+    cp ../template/packagename/__init__.py <packagename>/
+    cp ../template/packagename/_astropy_init.py <packagename>/
+
+    # edit <packagename>/__init__.py to change the docstring and change the
+    # example import ``from example_mod import *`` to whatever is needed for
+    # your package. If you don't want to try out any specific code yet, just
+    # replace the import by ``pass``.
+
+   The main purpose of the ``_astropy_init.py`` file is to set up the
+   ``test()`` command at the root of your package so that you can do
+   ``<packagename>.test()``. This file is imported into ``__init__``.
+
+   .. important:: Before proceeding, make sure you have edited ``__init__.py`` as
+                  indicated above!
+
+   Once you have made the above changes, you can commit the files::
+
+    git add <packagename>/__init__.py
+    git add <packagename>/_astropy_init.py
+
+#. In order to benefit from the pytest plugins in Astropy, you should also
+   copy over the ``conftest.py`` file to your repository::
+
+    cp ../template/packagename/conftest.py <packagename>/
+
+    git add <packagename>/conftest.py
 
-The `package-template <https://github.com/astropy/package-template>`_
-repository provides a template for packages that are affiliated with the
-`Astropy`_ project. This package design mirrors the layout of the main
-`Astropy`_ repository, as well as reusing much of the helper code used to
-organize `Astropy`_.  The instructions below describe how to take this
-template and adjust it for your particular affiliated package.
+   You can also uncomment the line ``enable_deprecations_as_exceptions()`` if
+   you want deprecation warnings to make tests fail.
 
-Everywhere below that the text ``yourpkg`` is shown, replace it with the name
-of your particular package.
+#. If you are interested in accurate coverage test results, copy over the
+   ``coveragerc`` and the ``setup_package.py`` files to your repository (the
+   latter ensures that ``coveragerc`` gets installed with the package::
 
-**Note**: The instructions below assume you are using git for version control,
-as is used by the Astropy repository. If this is not the case, hopefully it
-will be clear from context what to do with your particular VCS.
+    mkdir <packagename>/tests/
+    cp ../template/packagename/tests/__init__.py <packagename>/tests
+    cp ../template/packagename/tests/setup_package.py <packagename>/tests
+    cp ../template/packagename/tests/coveragerc <packagename>/tests
+
+    git add <packagename>/tests/__init__.py
+    git add <packagename>/tests/setup_package.py
+    git add <packagename>/tests/coveragerc
+
+   to your repository. When you run tests with with ``--coverage`` option this
+   file will be used to exclude certain files that should not typically be
+   included. Note that you don't need to change the ``{packagename}`` string in
+   ``coveragerc`` - this gets changed automatically using the package name
+   defined in ``setup.cfg``.
+
+   .. note:: the ``python setup.py`` commands will not work until you
+             have made your first commit, as shown in the last step of these
+             instructions.
+
+#. To set up the infrastructure to build the documentation, copy over the
+   following files into a new directory called ``docs``::
+
+    mkdir docs
+    cp ../template/docs/Makefile docs/
+    cp ../template/docs/conf.py docs/
+    cp ../template/docs/make.bat docs/
+    touch docs/index.rst  # creates empty page
+    git add docs/Makefile docs/conf.py docs/make.bat docs/index.rst
+
+   you can later start adding content to ``index.rst`` and other documentation
+   files.
+
+#. Finally, if you plan on using Travis for continuous integration, copy over
+   the ``.travis.yml`` file and edit it::
+
+    cp ../template/.travis.yml .
+    # edit .travis.yml
+    git add .travis.yml
+
+   .. important:: Before proceeding, make sure you have edited ``.travis.yml`` as
+                  indicated above!
+
+#. Now you are ready to make your first commit::
+
+    git commit -m "Initial layout for package"
+
+#. You can test that your package works correctly by doing e.g.::
+
+    python setup.py build
+    python setup.py test --coverage
+    python setup.py build_sphinx
+
+   If you have any issues that you cannot fix, feel free to ask us on the
+   `astropy-dev mailing list`_!
+
+Updating to the latest template files
+-------------------------------------
+
+From time to time we will make changes to the package-template to fix bugs or
+add functionality. Updating to the latest version is simple - simply check
+the `TEMPLATE_CHANGES.md`_ file, which provides a changelog of the package
+template. You can also re-copy over all the files listed in the above section
+and see if any of the changes should be committed (some of the changes will
+be reverting some of your edits, so do not include those!). Remember to
+update the astropy-helpers sub-module to the latest stable version, and
+update the corresponding ``ah_bootstrap.py`` file, for example::
+
+    cd astropy_helpers
+    git fetch origin
+    git checkout v0.4.3
+    cd ..
+    cp astropy_helpers/ah_bootstrap.py .
+    git add astropy_helpers ah_bootstrap.py
+    git commit -m "Updated astropy-helpers to v0.4.3"
+
+You can find out what the latest version of astropy-helpers is by checking the
+`astropy-helpers <https://pypi.python.org/pypi/astropy-helpers/>`__ entry on
+PyPI.
+
+Managing the template files via git
+===================================
+
+Starting a new package
+----------------------
+
+Before reading this we recommend reading over the `Managing the template
+files manually`_ section since this explains what many of the files do.
 
 #. Make sure `Astropy`_ is installed, as the template depends in part on
    Astropy to do its setup.
@@ -29,10 +233,10 @@ will be clear from context what to do with your particular VCS.
    if not, you will need to obtain a copy of the package template.  Assuming
    you have `git`_ installed, just do::
 
-      git clone git://github.com/astropy/package-template.git yourpkg
+      git clone git://github.com/astropy/package-template.git <packagename>
 
   This will download the latest version of the template from `github`_ and
-  place it in a directory named ``yourpkg``.
+  place it in a directory named ``<packagename>``.
 
 #. Go into the directory you just created, and open the ``setup.cfg``
    file with your favorite text editor.  Edit the settings in the
@@ -51,7 +255,7 @@ will be clear from context what to do with your particular VCS.
       or just delete it.
    5. Exit out of your text editor
 
-#. Update the main package docstring in ``packagename/__init__.py``.
+#. Update the main package docstring in ``<packagename>/__init__.py``.
 
 #. Decide what license you want to use to release your source code. If
    you don't care and/or are fine with the Astropy license, just edit
@@ -60,13 +264,13 @@ will be clear from context what to do with your particular VCS.
    sure to replace that file with whatever license you prefer, and
    update the ``license`` variable in ``setup.cfg`` to reflect your
    choice of license. You also may need to update the comment at the
-   top of ``packagename/__init__.py`` to reflect your choice of
+   top of ``<packagename>/__init__.py`` to reflect your choice of
    license.
 
-#. Take a moment to look over the ``packagename/example_mod.py``,
-   ``packagename/tests/test_example.py``, ``scripts/script_example``,
-   and ``packagename/example_c.pyx`` files, as well as the
-   ``packagename/example_subpkg`` directory. These are examples of a
+#. Take a moment to look over the ``<packagename>/example_mod.py``,
+   ``<packagename>/tests/test_example.py``, ``scripts/script_example``,
+   and ``<packagename>/example_c.pyx`` files, as well as the
+   ``<packagename>/example_subpkg`` directory. These are examples of a
    pure-python module, a test script, an example command-line script, a
    `Cython`_ module, and a sub-package, respectively. (`Cython`_ is a
    way to compile python-like code to C to make it run faster - see the
@@ -75,9 +279,9 @@ will be clear from context what to do with your particular VCS.
    you'll want to delete them (and later replace with your own)::
 
       git rm scripts/script_example
-      git rm packagename/example_c.pyx
-      git rm packagename/tests/test_example.py
-      git rm -r packagename/example_subpkg
+      git rm <packagename>/example_c.pyx
+      git rm <packagename>/tests/test_example.py
+      git rm -r <packagename>/example_subpkg
       git commit -m "removed examples from package template"
 
 #. Optional: If you're hosting your source code on github, you can
@@ -90,25 +294,25 @@ will be clear from context what to do with your particular VCS.
    To tell your DVCS about this move, you should use it, and not ``mv``
    directly, to make the move.  For example, with git::
 
-    git mv packagename yourpkg
+    git mv packagename <packagename>
 
 #. Update the names of the documentation files to match your package's name.
    First open ``docs/index.rst`` in a text editor and change the text
-   ``"packagename/index.rst"`` to e.g., ``"yourpkg/index.rst"``.  Then do::
+   ``"packagename/index.rst"`` to e.g., ``"<packagename>/index.rst"``.  Then do::
 
       git add docs/index.rst
-      git mv docs/packagename docs/yourpkg
+      git mv docs/packagename docs/<packagename>
 
 #. Edit this file (``README.rst``) and delete all of this content, and replace it
    with a short description of your affiliated package.
 
-#.  Open ``docs/yourpkg/index.rst`` and you can start writing the documentation
+#.  Open ``docs/<packagename>/index.rst`` and you can start writing the documentation
     for your package, but at least replace ``packagename`` in ``automodapi::``
     with your package name.
 
 #. Now tell git to remember the changes you just made::
 
-      git commit -a -m "Adjusted for new project yourpkg"
+      git commit -a -m "Adjusted for new project <packagename>"
 
 #. (This step assumes your affiliated package is hosted as part of the astropy
    organization on Github.  If it's instead hosted somewhere else, just adjust
@@ -117,7 +321,7 @@ will be clear from context what to do with your particular VCS.
    to the repository of *your* project, rather than the package template::
 
       git remote rename origin template
-      git remote add upstream git at github.com:astropy/yourpkg.git
+      git remote add upstream git at github.com:astropy/<packagename>.git
 
    Now that it is pointing to the correct master, you should push everything up
    to your project and make sure that your local master is tied to your project
@@ -130,10 +334,10 @@ will be clear from context what to do with your particular VCS.
 
 #. (optional) If you are adopting the standard workflow used by `Astropy`_ with
    github, you will also want to set up a fork of the repo on your own account,
-   by going to the Github page https://github.com/astropy/yourpkg and clicking
+   by going to the Github page https://github.com/astropy/<packagename> and clicking
    the "fork" button on the upper right.  Then run the following commands::
 
-      git remote add origin git at github.com:yourgithubusername/yourpkg.git
+      git remote add origin git at github.com:yourgithubusername/<packagename>.git
       git branch master --set-upstream origin/master
 
    Now you can push, pull, and branch whatever you want in your local fork
@@ -209,6 +413,11 @@ will be clear from context what to do with your particular VCS.
 
 #. Good luck with your code and your science!
 
+Updating to the latest template files
+-------------------------------------
+
+.. TODO
+
 Releasing an affiliated package
 ===============================
 
@@ -217,20 +426,20 @@ instructions, we assume that the changelog file is named ``CHANGES.rst``, like
 for the astropy core package. If instead you use Markdown, then you should
 replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
 
-1. Make sure that Travis and any other continuous integration is passing.
+#. Make sure that Travis and any other continuous integration is passing.
 
-2. Update the ``CHANGES.rst`` file to make sure that all the changes are listed,
+#. Update the ``CHANGES.rst`` file to make sure that all the changes are listed,
    and update the release date, which should currently be set to
    ``unreleased``, to the current date in ``yyyy-mm-dd`` format.
 
-3. Update the version number in ``setup.py`` to the version you're about to
+#. Update the version number in ``setup.py`` to the version you're about to
    release, without the ``.dev`` suffix (e.g. ``v0.1``).
 
-4. Run ``git clean -fxd`` to remove any untracked files (WARNING: this will
+#. Run ``git clean -fxd`` to remove any untracked files (WARNING: this will
    permanently remove any files that have not been previously committed, so
    make sure that you don't need to keep any of these files).
 
-5. Run::
+#. Run::
 
         python setup.py sdist --format=gztar
 
@@ -243,11 +452,11 @@ replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
    You may need to add the ``--remote-data`` flag or any other flags that you
    normally add when fully testing your affiliated package.
 
-6. Go back to the root of the directory and remove the generated files with::
+#. Go back to the root of the directory and remove the generated files with::
 
         git clean -fxd
 
-7. Add the changes to ``CHANGES.rst`` and ``setup.py``::
+#. Add the changes to ``CHANGES.rst`` and ``setup.py``::
 
         git add CHANGES.rst setup.py
 
@@ -255,20 +464,20 @@ replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
 
         git commit -m "Preparing release <version>"
 
-8. Tag commit with ``v<version>``, optionally signing with the ``-s`` option::
+#. Tag commit with ``v<version>``, optionally signing with the ``-s`` option::
 
         git tag v<version>
 
-9. Change ``VERSION`` in ``setup.py`` to next version number, but with a
+#. Change ``VERSION`` in ``setup.py`` to next version number, but with a
    ``.dev`` suffix at the end (e.g. ``v0.2.dev``). Add a new section to
    ``CHANGES.rst`` for next version, with a single entry ``No changes yet``, e.g.::
-   
+
        0.2 (unreleased)
        ----------------
-   
+
        - No changes yet
 
-10. Add the changes to ``CHANGES.rst`` and ``setup.py``::
+#. Add the changes to ``CHANGES.rst`` and ``setup.py``::
 
         git add CHANGES.rst setup.py
 
@@ -276,8 +485,8 @@ replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
 
         git commit -m "Back to development: <next_version>"
 
-11. Check out the release commit with ``git checkout v<version>``. Run ``git
-    clean -fxd`` to remove any non-committed files, then either release with::
+#. Check out the release commit with ``git checkout v<version>``. Run
+   ``git clean -fxd`` to remove any non-committed files, then either release with::
 
         python setup.py register sdist --format=gztar upload
 
@@ -286,7 +495,7 @@ replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
     instructions. Either way, check that the entry on PyPI is correct, and that
     the tarfile is present.
 
-12. Go back to the master branch and push your changes to github::
+#. Go back to the master branch and push your changes to github::
 
         git checkout master
         git push --tags origin master
@@ -303,3 +512,24 @@ replace ``CHANGES.rst`` by ``CHANGES.md`` in the instructions.
 .. _git: http://git-scm.com/
 .. _github: http://github.com
 .. _Cython: http://cython.org/
+.. _package-template: https://github.com/astropy/package-template
+.. _astropy-helpers: https://github.com/astropy/astropy-helpers
+.. _TEMPLATE_CHANGES.md: https://github.com/astropy/package-template/blob/master/TEMPLATE_CHANGES.md
+
+.. raw:: html
+
+    <script>
+
+    function get_url_vars() {
+        var vars = {};
+        var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
+            vars[key] = value;
+        });
+        return vars;
+    }
+
+    packagename = get_url_vars()["packagename"]
+    if(packagename) {
+      document.body.innerHTML = document.body.innerHTML.replace(/<packagename>/g, packagename);
+    }
+    </script>
diff --git a/docs/development/building.rst b/docs/development/building.rst
index 67b5d32..992cf52 100644
--- a/docs/development/building.rst
+++ b/docs/development/building.rst
@@ -105,9 +105,9 @@ process:
 * ``requires_2to3``
     This function declares whether the package requires processing
     through the `2to3`_ tool to run on Python 3.  If not included, it
-    defaults to `True`.  The use of `2to3`_ is being phased out in
-    astropy, in favor of using `six`_ instead.  See :ref:`dev-portable`
-    for more information.
+    defaults to `True`.  The use of `2to3`_ is phased out in astropy
+    and is retained for use in affliate packages which have not switched
+    to using `six`_ instead.  See :ref:`dev-portable` for more information.
 
 The ``astropy_helpers.setup_helpers`` modules includes an
 ``update_package_files`` function which automatically searches the given source
diff --git a/docs/development/ccython.rst b/docs/development/ccython.rst
index 8aca98c..76ec71f 100644
--- a/docs/development/ccython.rst
+++ b/docs/development/ccython.rst
@@ -50,13 +50,12 @@ Preventing importing at build time
 ----------------------------------
 
 In rare cases, some packages may need to be imported at build time.
-Unfortunately, anything that requires a C or Cython extension or
-processing through 2to3 will fail to import until the build phase has
-completed.  In those cases, the ``_ASTROPY_SETUP_`` variable can be used
-to determine if the package is being imported as part of the build and
-choose to not import problematic modules.  ``_ASTROPY_SETUP_`` is
-inserted into the builtins, and is `True` when inside of astropy's
-``setup.py`` script, and `False` otherwise.
+Unfortunately, anything that requires a C or Cython extension will fail to
+import until the build phase has completed. In this cases, the
+``_ASTROPY_SETUP_`` variable can be used to determine if the package is being
+imported as part of the build and choose to not import problematic modules.
+``_ASTROPY_SETUP_`` is inserted into the builtins, and is `True` when inside
+of astropy's ``setup.py`` script, and `False` otherwise.
 
 For example, suppose there is a subpackage ``foo`` that needs to
 import a module called ``version.py`` at build time in order to set
diff --git a/docs/development/codeguide.rst b/docs/development/codeguide.rst
index 4e438a2..566d245 100644
--- a/docs/development/codeguide.rst
+++ b/docs/development/codeguide.rst
@@ -15,10 +15,10 @@ both for the core package and for affiliated packages.
 Interface and Dependencies
 --------------------------
 
-* All code must be compatible with Python 2.6, 2.7, as well as 3.1 and
+* All code must be compatible with Python 2.6, 2.7, as well as 3.3 and
   later.  The use of `six`_ for writing code that is portable between Python
-  2.x and 3.x is encouraged going forward.  However, much of our legacy code
-  still uses `2to3`_ to process Python 2.x files to be compatible with
+  2.x and 3.x is encouraged going forward.  However, much of our affiliate code
+  may still use `2to3`_ to process Python 2.x files to be compatible with
   Python 3.x.
 
 .. _six: http://pythonhosted.org/six/
@@ -165,6 +165,11 @@ Coding Style/Conventions
   <http://www.python.org/dev/peps/pep-0008/>`_. In particular, this includes
   using only 4 spaces for indentation, and never tabs.
 
+* *Follow the existing coding style* within a subpackage and avoid making
+  changes that are purely stylistic.  In particular, there is variation in the
+  maximum line length for different subpackages (typically either 80 or 100
+  characters).  Please try to maintain the style when adding or modifying code.
+
 * One exception is to be made from the PEP8 style: new style relative imports
   of the form ``from . import modname`` are allowed and required for Astropy,
   as opposed to absolute (as PEP8 suggests) or the simpler ``import modname``
@@ -355,10 +360,10 @@ Writing portable code for Python 2 and 3
 ----------------------------------------
 
 As of astropy 0.3, the `six`_ library is included to allow supporting Python
-2 and 3 from a single code base.  The use of the `2to3`_ tool is being
+2 and 3 from a single code base.  The use of the `2to3`_ tool has been
 phased out in favor of using ``six``.
 
-To start using ``six`` instead of ``2to3`` in a package, you first
+To start using ``six`` instead of ``2to3`` in an affiliate package, you first
 need to put the following in the package's ``setup_package.py`` file::
 
     def requires_2to3():
@@ -520,6 +525,15 @@ of that and still support Python 2::
     >>> '\\u'
     '\\u'
 
+Compatibility between versions of Numpy
+---------------------------------------
+
+In general, code should aim to be compatible with the lowest supported version
+of NumPy_.  Sometimes, however, it is inefficient to code repeatedly around
+bugs in earlier versions. For those cases, code can be added to
+`astropy.utils.compat.numpy`; see the corresponding :ref:`instructions
+<numpy-compatibility>` for details.
+
 Requirements Specific to Affiliated Packages
 --------------------------------------------
 
diff --git a/docs/development/docrules.rst b/docs/development/docrules.rst
index f843bd0..0a29ff4 100644
--- a/docs/development/docrules.rst
+++ b/docs/development/docrules.rst
@@ -193,7 +193,7 @@ The sections of the docstring are:
    When two or more input parameters have exactly the same type, shape and
    description, they can be combined::
 
-     x1, x2 : array_like
+     x1, x2 : array-like
          Input arrays, description of `x1`, `x2`.
 
 5. **Returns**
@@ -508,10 +508,10 @@ Other points to keep in mind
   that are not answered in this document, refer to
   `<http://docs-old.scipy.org/numpy/Questions+Answers/>`_.
 
-* ``array_like`` : For functions that take arguments which can have not only
+* ``array-like`` : For functions that take arguments which can have not only
   a type ``ndarray``, but also types that can be converted to an ndarray
   (i.e. scalar types, sequence types), those arguments can be documented
-  with type ``array_like``.
+  with type ``array-like``.
 
 Common reST concepts
 --------------------
diff --git a/docs/development/releasing.rst b/docs/development/releasing.rst
index 84cd874..2ba58cd 100644
--- a/docs/development/releasing.rst
+++ b/docs/development/releasing.rst
@@ -69,7 +69,13 @@ procedure is that ensures a consistent release process each time.
     ensure that the latest version is installed in the virtualenv (if you're
     running a csh variant make sure to run ``rehash`` afterwards too)::
 
-        $ pip install zest.releaser --upgrade --force
+        $ pip install zest.releaser==3.49 --upgrade --force
+        
+    .. note::
+    
+        zest.releaser > 3.49 has a still open issue that prevents our release
+        code from correctly updating the ``VERSION`` variable in our ``setup.py``;
+        see `zestsoftware/zest.releaser#62 <https://github.com/zestsoftware/zest.releaser/pull/62>`_.
 
  9. Ensure that all changes to the code have been committed, then start the
     release by running::
diff --git a/docs/development/scripts.rst b/docs/development/scripts.rst
index 88301ee..79f0c71 100644
--- a/docs/development/scripts.rst
+++ b/docs/development/scripts.rst
@@ -5,40 +5,27 @@ Writing Command-Line Scripts
 Command-line scripts in Astropy should follow a consistent scheme to promote
 readability and compatibility.
 
-The actual script should be in the ``/scripts`` directory of the Astropy
-source distribution, and should do nothing aside from importing a ``main``
-function from astropy and execute it.  This is partly necessary because the
-"2to3" utility that converts python 2.x code to 3.x does not convert scripts.
-These scripts should be executable, include ``#!/usr/bin/env python`` at the
-top, and should *not* end in ``.py``.
-
-The ``main`` functions these scripts call should accept an optional single
-argument that holds the ``sys.argv`` list, except for the script name
-(e.g., ``argv[1:]``). This function can live in its own module, or be part of a
-larger module that implements a class or function for astropy library use. The
-``main`` function should do very little actual work - it should only parse the
-arguments and pass those arguments on to some library function so that the
-library function can be used programmatically when needed.
+Setuptools' `"entry points"`_ are used to automatically generate wrappers with
+the correct extension. The scripts can live in their own module, or be part of
+a larger module that implements a class or function for astropy library use.
+They should have a ``main`` function to parse the arguments and pass those
+arguments on to some library function so that the library function can be used
+programmatically when needed. The ``main`` function should accept an optional
+single argument that holds the ``sys.argv`` list, except for the script name
+(e.g., ``argv[1:]``). It must then be added to the list of entry points in the
+``setup.py`` file (see the example below).
+
 Command-line options can be parsed however desired, but the :mod:`argparse`
 module is recommended when possible, due to its simpler and more flexible
-interface relative to the older :mod:`optparse`. :mod:`argparse` is only
-available in python >=2.7 and >=3.2, however, so it should be imported as
-``from astropy.util.compat import argparse`` .
+interface relative to the older :mod:`optparse`.  :mod:`argparse` is only
+available in python >=2.7 and >=3.2, however, so it should be imported as ``from
+astropy.util.compat import argparse`` .
 
+.. _"entry points": https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation
 
 Example
 -------
 
-Contents of ``/scripts/cmdlinescript`` ::
-
-    #!/usr/bin/env python
-    # -*- coding: utf-8 -*-
-    """An astropy command-line script"""
-
-    import astropy.somepackage.somemod
-
-    astropy.somepackage.somemod.main()
-
 Contents of ``/astropy/somepackage/somemod.py`` ::
 
     def do_something(args, option=False):
@@ -61,3 +48,9 @@ Contents of ``/astropy/somepackage/somemod.py`` ::
 
         do_something(res.stuff,res.op)
 
+Then add the script to the ``setup.py`` ::
+
+    entry_points['console_scripts'] = [
+        'somescript = astropy.somepackage.somemod:main',
+        ...
+    ]
diff --git a/docs/development/testguide.rst b/docs/development/testguide.rst
index aeff16d..9a7a1be 100644
--- a/docs/development/testguide.rst
+++ b/docs/development/testguide.rst
@@ -73,9 +73,6 @@ within those files.
     To test any compiled C/Cython extensions, you must run ``python setup.py
     develop`` prior to running the py.test command-line script.  Otherwise,
     any tests that make use of these extensions will not succeed.
-    Similarly, in python 3, these tests will not run correctly in the source
-    code, because they need the `2to3
-    <https://docs.python.org/2/library/2to3.html>`_ tool to be run on them.
 
 You may specify a specific test file or directory at the command line::
 
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index c0e9d8d..f2b147c 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -83,6 +83,9 @@ to open a Python interpreter. These utilities include:
 
 - :ref:`fitsdiff`: compares two FITS files and reports the differences.
 
+- :ref:`fits2bitmap`: converts FITS images to bitmaps, including scaling and
+  stretching.
+
 - :ref:`samp_hub <vo-samp-example_hub>`: starts a :ref:`SAMP <vo-samp>` hub.
 
 - ``volint``: checks a :ref:`VOTable <astropy-io-votable>`
diff --git a/docs/index.rst b/docs/index.rst
index b779f6e..13e63c5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -33,7 +33,7 @@ User Documentation
 
 .. only:: html
 
-    :doc:`whatsnew/0.4`
+    :doc:`whatsnew/1.0`
     -------------------
 
 .. only:: latex
@@ -41,7 +41,7 @@ User Documentation
     .. toctree::
        :maxdepth: 1
 
-       whatsnew/0.4
+       whatsnew/1.0
 
 **Astropy at a glance**
 
@@ -65,6 +65,7 @@ User Documentation
    coordinates/index
    wcs/index
    modeling/index
+   analytic_functions/index
 
 **Connecting up: Files and I/O**
 
@@ -83,6 +84,7 @@ User Documentation
    :maxdepth: 1
 
    convolution/index
+   visualization/index
    cosmology/index
    stats/index
    vo/index
diff --git a/docs/install.rst b/docs/install.rst
index bf5cd71..50c3a7d 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -7,7 +7,9 @@ Requirements
 
 Astropy has the following strict requirements:
 
-- `Python <http://www.python.org/>`_ 2.6 (>=2.6.5), 2.7, 3.1, 3.2, 3.3, or 3.4
+- `Python <http://www.python.org/>`_ 2.6 (>=2.6.5), 2.7, 3.3, or 3.4
+
+  - Prior to Astropy v1.0 Python 3.1 and 3.2 are also supported.
 
 - `Numpy`_ |minimum_numpy_version| or later
 
@@ -19,6 +21,9 @@ Astropy also depends on other packages for optional features:
 - `BeautifulSoup <http://www.crummy.com/software/BeautifulSoup/>`_: To read
   :class:`~astropy.table.table.Table` objects from HTML files
 
+- `PyYAML <http:://pyyaml.org>`_: To read/write
+  :class:`~astropy.table.Table` objects from/to the Enhanced CSV ASCII table format.
+
 - `scipy`_: To power a variety of features (currently
   mainly cosmology-related functionality)
 
@@ -97,7 +102,7 @@ run::
 Binary installers
 -----------------
 
-Binary installers are available on Windows for Python 2.6, 2.7, 3.1, and 3.2
+Binary installers are available on Windows for Python 2.6, 2.7, and >= 3.3
 at `PyPI <https://pypi.python.org/pypi/astropy>`_.
 
 .. _testing_installed_astropy:
@@ -145,7 +150,8 @@ The `instructions for building Numpy from source
 <http://docs.scipy.org/doc/numpy/user/install.html>`_ are also a good
 resource for setting up your environment to build Python packages.
 
-You will also need `Cython <http://cython.org/>`_ (v0.15 or later) installed
+You will also need `Cython <http://cython.org/>`_ (v0.15 or later) and
+`jinja2 <http://jinja.pocoo.org/docs/dev/>`_ installed
 to build from source, unless you are installing a numbered release. (The
 releases packages have the necessary C files packaged with them, and hence do
 not require Cython.)
diff --git a/docs/io/ascii/fast_ascii_io.rst b/docs/io/ascii/fast_ascii_io.rst
new file mode 100644
index 0000000..d68c7ae
--- /dev/null
+++ b/docs/io/ascii/fast_ascii_io.rst
@@ -0,0 +1,173 @@
+.. include:: references.txt
+
+.. _fast_ascii_io:
+
+Fast ASCII I/O
+--------------
+
+While :mod:`astropy.io.ascii` was designed with flexibility and extensibility
+in mind, there is also a less flexible but significantly faster Cython/C engine for
+reading and writing ASCII files. By default, |read| and |write| will attempt to
+use this engine when dealing with compatible formats. The following formats
+are currently compatible with the fast engine:
+
+ * ``basic``
+ * ``commented_header``
+ * ``csv``
+ * ``no_header``
+ * ``rdb``
+ * ``tab``
+
+The fast engine can also be enabled through the format parameter by prefixing
+a compatible format with "fast" and then an underscore. In this case, |read|
+will not fall back on an ordinary reader if fast reading fails.
+For example::
+
+   >>> from astropy.table import Table
+   >>> t = ascii.read('file.csv', format='fast_csv')  # doctest: +SKIP
+   >>> t.write('output.csv', format='ascii.fast_csv')  # doctest: +SKIP
+
+To disable the fast engine, specify ``fast_reader=False`` or
+``fast_writer=False``. For example::
+
+   >>> t = ascii.read('file.csv', format='csv', fast_reader=False) # doctest: +SKIP
+   >>> t.write('file.csv', format='csv', fast_writer=False) # doctest: +SKIP
+
+.. Note:: Guessing and Fast reading
+
+   By default |read| will try to guess the format of in the input data by successively
+   trying different formats until one succeeds ([reference the guessing section]).
+   For the default ``'ascii'`` format this means that a number of pure Python readers
+   with no fast implementation will be tried before getting to the fast readers.
+
+   **For optimum performance**, turn off guessing entirely (``guess=False``) or
+   narrow down the format options as much as possible by specifying the format
+   (e.g. ``format='csv'``) and/or other options such as the delimiter.
+
+Reading
+^^^^^^^
+Since the fast engine is not part of the ordinary :mod:`astropy.io.ascii`
+infrastructure, fast readers raise an error when passed certain
+parameters which are not implemented in the fast reader
+infrastructure. In this case |read| will fall back on the ordinary reader.
+These parameters are:
+
+ * Negative ``header_start`` (except for commented-header format)
+ * Negative ``data_start``
+ * ``data_start=None``
+ * ``comment`` string not of length 1
+ * ``delimiter`` string not of length 1
+ * ``quotechar`` string not of length 1
+ * ``converters``
+ * ``Outputter``
+ * ``Inputter``
+ * ``data_Splitter``
+ * ``header_Splitter``
+
+Parallel and fast conversion options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In addition to ``True`` and ``False``, the parameter ``fast_reader`` can also
+be a dict specifying one or both of two additional parameters, ``parallel`` and
+``use_fast_converter``. For example::
+
+   >>> ascii.read('data.txt', format='basic', fast_reader={'parallel': True, 'use_fast_converter': True}) # doctest: +SKIP
+
+These options allow for even faster table reading when enabled, but both are
+disabled by default because they come with some caveats.
+
+The ``parallel`` parameter can be used to enable multiprocessing via
+the ``multiprocessing`` module, and can either be set to a number (the number
+of processes to use) or ``True``, in which case the number of processes will be
+``multiprocessing.cpu_count()``.   Note that this can cause issues within the
+IPython Notebook and so enabling multiprocessing in this context is discouraged.
+
+Setting ``use_fast_converter`` to be ``True`` enables a faster but
+slightly imprecise conversion method for floating-point values, as described below.
+
+Writing
+^^^^^^^
+The fast engine supports the same functionality as the ordinary writing engine
+and is generally about 2 to 4 times faster than the ordinary engine. An IPython
+notebook testing the relative performance of the fast writer against the
+ordinary writing system and the data analysis library `Pandas
+<http://pandas.pydata.org/>`__ is available `here <http://nbviewer.ipython.org/github/astropy/astropy-notebooks/blob/master/io/ascii/ascii_write_bench.ipynb>`__.
+The speed advantage of the faster engine is greatest for integer data and least
+for floating-point data; the fast engine is around 3.6 times faster for a
+sample file including a mixture of floating-point, integer, and text data.
+Also note that stripping string values slows down the writing process, so
+specifying ``strip_whitespace=False`` can improve performance.
+
+Fast converter
+^^^^^^^^^^^^^^
+Input floating-point values should ideally be converted to the
+nearest possible floating-point approximation; that is, the conversion
+should be correct within half of the distance between the two closest
+representable values, or 0.5 `ULP
+<http://en.wikipedia.org/wiki/Unit_in_the_last_place>`__. The ordinary readers,
+as well as the default fast reader, are guaranteed to convert floating-point
+values within 0.5 ULP, but there is also a faster and less accurate
+conversion method accessible via ``use_fast_converter``. If the input
+data has less than about 15 significant figures, or if accuracy is relatively
+unimportant, this converter might be the best option in
+performance-critical scenarios.
+
+`Here
+<http://nbviewer.ipython.org/github/astropy/astropy-notebooks/blob/master/io/ascii/conversion_profile.ipynb>`__
+is an IPython notebook analyzing the error of the fast converter, both in
+decimal values and in ULP. For values with a reasonably small number of
+significant figures, the fast converter is guaranteed to produce an optimal
+conversion (within 0.5 ULP). Once the number of significant figures exceeds
+the precision of 64-bit floating-point values, the fast converter is no
+longer guaranteed to be within 0.5 ULP, but about 60% of values end up
+within 0.5 ULP and about 90% within 1.0 ULP. Another notebook analyzing
+the fast converter's behavior with extreme values (such as subnormals
+and values out of the range of floats) is available `here
+<http://nbviewer.ipython.org/github/astropy/astropy-notebooks/blob/master/io/ascii/test_converter.ipynb>`__.
+
+Speed gains
+^^^^^^^^^^^
+The fast ASCII engine was designed based on the general parsing strategy
+used in the `Pandas <http://pandas.pydata.org/>`__ data analysis library, so
+its performance is generally comparable (although slightly slower by
+default) to the Pandas ``read_csv`` method.
+`Here
+<http://nbviewer.ipython.org/github/astropy/astropy-notebooks/blob/master/io/ascii/ascii_read_bench.ipynb>`__
+is an IPython notebook comparing the performance of the ordinary
+:mod:`astropy.io.ascii` reader, the fast reader, the fast reader with the
+fast converter enabled, numpy's ``genfromtxt``, and Pandas' ``read_csv``
+for different kinds of table data in a basic space-delimited file.
+
+In summary, ``genfromtxt`` and the ordinary :mod:`astropy.io.ascii` reader
+are very similar in terms of speed, while ``read_csv`` is slightly faster
+than the fast engine for integer and floating-point data; for pure
+floating-point data, enabling the fast converter yields a speedup of about
+50%. Also note that Pandas uses the exact same method as the fast
+converter in AstroPy when converting floating-point data.
+
+The difference in performance between the fast engine and Pandas for
+text data depends on the extent to which data values are repeated, as
+Pandas is almost twice as fast as the fast engine when every value is
+identical and the reverse is true when values are randomized. This is
+because the fast engine uses fixed-size numpy string arrays for
+text data, while Pandas uses variable-size object arrays and uses an
+underlying set to avoid copying repeated values.
+
+Overall, the fast engine tends to be around 4 or 5 times faster than
+the ordinary ASCII engine. If the input data is very large (generally
+about 100,000 rows or greater), and particularly if the data doesn't
+contain primarily integer data or repeated string values, specifying
+``parallel`` as ``True`` can yield further performance gains. Although
+IPython doesn't work well with ``multiprocessing``, there is a
+`script <https://github.com/amras1/ascii-profiling/blob/master/parallel.py>`__
+available for testing the performance of the fast engine in parallel,
+and a sample result may be viewed `here
+<http://amras1.github.io/ascii-profiling/>`__. This profile uses the
+fast converter for both the serial and parallel AstroPy
+readers.
+
+Another point worth noting is that the fast engine uses memory mapping
+if a filename is supplied as input. If you want to avoid this for whatever
+reason, supply an open file object instead. However, this will generally
+be less efficient from both a time and a memory perspective, as the entire
+file input will have to be read at once.
+
diff --git a/docs/io/ascii/fixed_width_gallery.rst b/docs/io/ascii/fixed_width_gallery.rst
index 879ee3f..9031d8c 100644
--- a/docs/io/ascii/fixed_width_gallery.rst
+++ b/docs/io/ascii/fixed_width_gallery.rst
@@ -43,9 +43,12 @@ FixedWidth
   ... |  2.4   |'s worlds|
   ... """
   >>> ascii.read(table, format='fixed_width')
-  <Table rows=2 names=('Col1','Col2')>
-  array([(1.2, '"hello"'), (2..., "'s worlds")],
-        dtype=[('Col1', '<f8'), ('Col2', 'S9')])
+  <Table masked=False length=2>
+    Col1     Col2
+  float64  string72
+  ------- ---------
+      1.2   "hello"
+      2.4 's worlds
 
 **Typical fixed format table with col names provided**
 ::
@@ -56,10 +59,13 @@ FixedWidth
   ... |  1.2   | "hello" |
   ... |  2.4   |'s worlds|
   ... """
-  >>> ascii.read(table, format='fixed_width', names=('name1', 'name2'))
-  <Table rows=2 names=('name1','name2')>
-  array([(1.2, '"hello"'), (2..., "'s worlds")],
-        dtype=[('name1', '<f8'), ('name2', 'S9')])
+  >>> ascii.read(table, format='fixed_width', names=['name1', 'name2'])
+  <Table masked=False length=2>
+   name1    name2
+  float64  string72
+  ------- ---------
+      1.2   "hello"
+      2.4 's worlds
 
 **Weird input table with data values chopped by col extent**
 ::
@@ -70,9 +76,12 @@ FixedWidth
   ...   2.4   sdf's worlds
   ... """
   >>> ascii.read(table, format='fixed_width')
-  <Table rows=2 names=('Col1','Col2')>
-  array([(1.2, '"hel'), (2..., "df's wo")],
-        dtype=[('Col1', '<f8'), ('Col2', 'S7')])
+  <Table masked=False length=2>
+    Col1    Col2
+  float64 string56
+  ------- --------
+      1.2     "hel
+      2.4  df's wo
 
 **Table with double delimiters**
 ::
@@ -84,11 +93,13 @@ FixedWidth
   ... |   Bob  | 555-4527 | 192.168.1.9X|
   ... """
   >>> ascii.read(table, format='fixed_width')
-  <Table rows=3 names=('Name','Phone','TCP')>
-  array([('John', '555-1234', '192.168.1.10'),
-         ('Mary', '555-2134', '192.168.1.12'),
-         ('Bob', '555-4527', '192.168.1.9')],
-        dtype=[('Name', 'S4'), ('Phone', 'S8'), ('TCP', 'S12')])
+  <Table masked=False length=3>
+    Name    Phone       TCP
+  string32 string64   string96
+  -------- -------- ------------
+      John 555-1234 192.168.1.10
+      Mary 555-2134 192.168.1.12
+       Bob 555-4527  192.168.1.9
 
 **Table with space delimiter**
 ::
@@ -100,11 +111,13 @@ FixedWidth
   ...   Bob  555-4527     192.168.1.9
   ... """
   >>> ascii.read(table, format='fixed_width', delimiter=' ')
-  <Table rows=3 names=('Name','--Phone-','----TCP-----')>
-  array([('John', '555-1234', '192.168.1.10'),
-         ('Mary', '555-2134', '192.168.1.12'),
-         ('Bob', '555-4527', '192.168.1.9')],
-        dtype=[('Name', 'S4'), ('--Phone-', 'S8'), ('----TCP-----', 'S12')])
+  <Table masked=False length=3>
+    Name   --Phone- ----TCP-----
+  string32 string64   string96
+  -------- -------- ------------
+      John 555-1234 192.168.1.10
+      Mary 555-2134 192.168.1.12
+       Bob 555-4527  192.168.1.9
 
 **Table with no header row and auto-column naming.**
 
@@ -118,11 +131,13 @@ Use header_start and data_start keywords to indicate no header line.
   ... """
   >>> ascii.read(table, format='fixed_width',
   ...            header_start=None, data_start=0)
-  <Table rows=3 names=('col1','col2','col3')>
-  array([('John', '555-1234', '192.168.1.10'),
-         ('Mary', '555-2134', '192.168.1.12'),
-         ('Bob', '555-4527', '192.168.1.9')],
-        dtype=[('col1', 'S4'), ('col2', 'S8'), ('col3', 'S12')])
+  <Table masked=False length=3>
+    col1     col2       col3
+  string32 string64   string96
+  -------- -------- ------------
+      John 555-1234 192.168.1.10
+      Mary 555-2134 192.168.1.12
+       Bob 555-4527  192.168.1.9
 
 **Table with no header row and with col names provided.**
 
@@ -136,11 +151,13 @@ keywords to indicate no header line.
   >>> ascii.read(table, format='fixed_width',
   ...                 header_start=None, data_start=0,
   ...                 names=('Name', 'Phone', 'TCP'))
-  <Table rows=3 names=('Name','Phone','TCP')>
-  array([('John', '555-1234', '192.168.1.10'),
-         ('Mary', '555-2134', '192.168.1.12'),
-         ('Bob', '555-4527', '192.168.1.9')],
-        dtype=[('Name', 'S4'), ('Phone', 'S8'), ('TCP', 'S12')])
+  <Table masked=False length=3>
+    Name    Phone       TCP
+  string32 string64   string96
+  -------- -------- ------------
+      John 555-1234 192.168.1.10
+      Mary 555-2134 192.168.1.12
+       Bob 555-4527  192.168.1.9
 
 
 FixedWidthNoHeader
@@ -156,11 +173,13 @@ convenience class.**
   ... |   Bob  | 555-4527 | 192.168.1.9|
   ... """
   >>> ascii.read(table, format='fixed_width_no_header')
-  <Table rows=3 names=('col1','col2','col3')>
-  array([('John', '555-1234', '192.168.1.10'),
-         ('Mary', '555-2134', '192.168.1.12'),
-         ('Bob', '555-4527', '192.168.1.9')],
-        dtype=[('col1', 'S4'), ('col2', 'S8'), ('col3', 'S12')])
+  <Table masked=False length=3>
+    col1     col2       col3
+  string32 string64   string96
+  -------- -------- ------------
+      John 555-1234 192.168.1.10
+      Mary 555-2134 192.168.1.12
+       Bob 555-4527  192.168.1.9
 
 **Table with no delimiter with column start and end values specified.**
 
@@ -181,11 +200,13 @@ will select the first 6 characters.
   ...                 col_starts=(0, 9, 18),
   ...                 col_ends=(5, 17, 28),
   ...                 )
-  <Table rows=3 names=('Name','Phone','TCP')>
-  array([('John', '555- 1234', '192.168.1.'),
-         ('Mary', '555- 2134', '192.168.1.'),
-         ('Bob', '555- 4527', '192.168.1')],
-        dtype=[('Name', 'S4'), ('Phone', 'S9'), ('TCP', 'S10')])
+  <Table masked=False length=3>
+    Name     Phone      TCP
+  string32  string72  string80
+  -------- --------- ----------
+      John 555- 1234 192.168.1.
+      Mary 555- 2134 192.168.1.
+       Bob 555- 4527  192.168.1
 
 FixedWidthTwoLine
 """""""""""""""""
@@ -200,9 +221,12 @@ FixedWidthTwoLine
   ...   2.4   's worlds
   ... """
   >>> ascii.read(table, format='fixed_width_two_line')
-  <Table rows=2 names=('Col1','Col2')>
-  array([(1.2, '"hello"'), (2..., "'s worlds")],
-        dtype=[('Col1', '<f8'), ('Col2', 'S9')])
+  <Table masked=False length=2>
+    Col1     Col2
+  float64  string72
+  ------- ---------
+      1.2   "hello"
+      2.4 's worlds
 
 **Restructured text table**
 ::
@@ -217,9 +241,12 @@ FixedWidthTwoLine
   ... """
   >>> ascii.read(table, format='fixed_width_two_line',
   ...                 header_start=1, position_line=2, data_end=-1)
-  <Table rows=2 names=('Col1','Col2')>
-  array([(1.2, '"hello"'), (2..., "'s worlds")],
-        dtype=[('Col1', '<f8'), ('Col2', 'S9')])
+  <Table masked=False length=2>
+    Col1     Col2
+  float64  string72
+  ------- ---------
+      1.2   "hello"
+      2.4 's worlds
 
 **Text table designed for humans and test having position line before the header line.**
 ::
@@ -234,9 +261,12 @@ FixedWidthTwoLine
   ... """
   >>> ascii.read(table, format='fixed_width_two_line', delimiter='+',
   ...                 header_start=1, position_line=0, data_start=3, data_end=-1)
-  <Table rows=2 names=('Col1','Col2')>
-  array([(1.2, '"hello"'), (2..., "'s worlds")],
-        dtype=[('Col1', '<f8'), ('Col2', 'S9')])
+  <Table masked=False length=2>
+    Col1     Col2
+  float64  string72
+  ------- ---------
+      1.2   "hello"
+      2.4 's worlds
 
 Writing
 ^^^^^^^
diff --git a/docs/io/ascii/index.rst b/docs/io/ascii/index.rst
index d68533c..ebaf284 100644
--- a/docs/io/ascii/index.rst
+++ b/docs/io/ascii/index.rst
@@ -10,7 +10,9 @@ Introduction
 ============
 
 `astropy.io.ascii` provides methods for reading and writing a wide range of ASCII data table
-formats via built-in :ref:`extension_reader_classes`.  The emphasis is on flexibility and ease of use.
+formats via built-in :ref:`extension_reader_classes`.  The emphasis is on flexibility and ease of use,
+although readers can optionally use a less flexible C/Cython engine for reading and writing for
+improved performance.
 
 The following shows a few of the ASCII formats that are available, while the section on
 `Supported formats`_ contains the full list.
@@ -18,6 +20,7 @@ The following shows a few of the ASCII formats that are available, while the sec
 * :class:`~astropy.io.ascii.Basic`: basic table with customizable delimiters and header configurations
 * :class:`~astropy.io.ascii.Cds`: `CDS format table <http://vizier.u-strasbg.fr/doc/catstd.htx>`_ (also Vizier and ApJ machine readable tables)
 * :class:`~astropy.io.ascii.Daophot`: table from the IRAF DAOphot package
+* :class:`~astropy.io.ascii.Ecsv`: `Enhanced CSV format <https://github.com/astropy/astropy-APEs/blob/master/APE6.rst>`_
 * :class:`~astropy.io.ascii.FixedWidth`: table with fixed-width columns (see also :ref:`fixed_width_gallery`)
 * :class:`~astropy.io.ascii.Ipac`: `IPAC format table <http://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html>`_
 * :class:`~astropy.io.ascii.HTML`: HTML format table contained in a <table> tag
@@ -82,6 +85,15 @@ of the values in the `supported formats`_.  For example::
 
    >>> data = ascii.read(lines, format='fixed_width_two_line', delimiter='&')
 
+For simpler formats such as CSV, |read| will automatically try reading with the
+Cython/C parsing engine, which is significantly faster than the ordinary Python
+implementation (described in :ref:`fast_ascii_io`). If the fast engine fails,
+|read| will fall back on the Python reader by default. The argument
+``fast_reader`` can be specified to control this behavior. For example, to
+disable the fast engine::
+
+   >>> data = ascii.read(lines, format='csv', fast_reader=False)
+
 Writing Tables
 --------------
 
@@ -90,7 +102,7 @@ table.  For example the following writes a table as a simple space-delimited
 file::
 
   >>> import numpy as np
-  >>> from astropy.table import Table
+  >>> from astropy.table import Table, Column
   >>> x = np.array([1, 2, 3])
   >>> y = x ** 2
   >>> data = Table([x, y], names=['x', 'y'])
@@ -103,7 +115,7 @@ The ``values.dat`` file will then contain::
   2 4
   3 9
 
-All of the input Reader formats supported by `astropy.io.ascii` for reading are
+Most of the input Reader formats supported by `astropy.io.ascii` for reading are
 also supported for writing.  This provides a great deal of flexibility in the
 format for writing.  The example below writes the data as a LaTeX table, using
 the option to send the output to ``sys.stdout`` instead of a file::
@@ -119,6 +131,41 @@ the option to send the output to ``sys.stdout`` instead of a file::
   \end{tabular}
   \end{table}
 
+There is also a faster Cython engine for writing simple formats,
+which is enabled by default for these formats (see :ref:`fast_ascii_io`).
+To disable this engine, use the parameter ``fast_writer``::
+
+   >>> ascii.write(data, 'values.csv', format='csv', fast_writer=False)  # doctest: +SKIP
+
+Finally, one can write data in the `ECSV table format
+<https://github.com/astropy/astropy-APEs/blob/master/APE6.rst>`_ which allows
+preserving table meta-data such as column data types and units.  In this way a
+data table can be stored and read back as ASCII with no loss of information.
+
+  >>> t = Table()
+  >>> t['x'] = Column([1.0, 2.0], unit='m', dtype='float32')
+  >>> t['y'] = Column([False, True], dtype='bool')
+
+  >>> from astropy.extern.six.moves import StringIO
+  >>> fh = StringIO()
+  >>> t.write(fh, format='ascii.ecsv')  # doctest: +SKIP
+  >>> table_string = fh.getvalue()      # doctest: +SKIP
+  >>> print(table_string)               # doctest: +SKIP
+  # %ECSV 1.0
+  # ---
+  # columns:
+  # - {name: x, unit: m, type: float32}
+  # - {name: y, type: bool}
+  x y
+  1.0 False
+  2.0 True
+
+  >>> Table.read(table_string, format='ascii')  # doctest: +SKIP
+  <Table rows=2 names=('x','y') units=('m',None)>
+  array([(1.0, False), (2.0, True)],
+        dtype=[('x', '<f4'), ('y', '?')])
+
+
 .. _supported_formats:
 
 Supported formats
@@ -126,28 +173,30 @@ Supported formats
 
 A full list of the supported ``format`` values and corresponding format types for ASCII
 tables is given below.  The ``Write`` column indicates which formats support write
-functionality.
-
-========================= ===== ============================================================================================
-           Format         Write                                          Description
-========================= ===== ============================================================================================
-``aastex``                  Yes :class:`~astropy.io.ascii.AASTex`: AASTeX deluxetable used for AAS journals
-``basic``                   Yes :class:`~astropy.io.ascii.Basic`: Basic table with custom delimiters
-``cds``                         :class:`~astropy.io.ascii.Cds`: CDS format table
-``commented_header``        Yes :class:`~astropy.io.ascii.CommentedHeader`: Column names in a commented line
-``csv``                     Yes :class:`~astropy.io.ascii.Csv`: Basic table with comma-separated values
-``daophot``                     :class:`~astropy.io.ascii.Daophot`: IRAF DAOphot format table
-``fixed_width``             Yes :class:`~astropy.io.ascii.FixedWidth`: Fixed width
-``fixed_width_no_header``   Yes :class:`~astropy.io.ascii.FixedWidthNoHeader`: Fixed width with no header
-``fixed_width_two_line``    Yes :class:`~astropy.io.ascii.FixedWidthTwoLine`: Fixed width with second header line
-``html``                    Yes :class:`~astropy.io.ascii.HTML`: HTML format table
-``ipac``                    Yes :class:`~astropy.io.ascii.Ipac`: IPAC format table
-``latex``                   Yes :class:`~astropy.io.ascii.Latex`: LaTeX table
-``no_header``               Yes :class:`~astropy.io.ascii.NoHeader`: Basic table with no headers
-``rdb``                     Yes :class:`~astropy.io.ascii.Rdb`: Tab-separated with a type definition header line
-``sextractor``                  :class:`~astropy.io.ascii.SExtractor`: SExtractor format table
-``tab``                     Yes :class:`~astropy.io.ascii.Tab`: Basic table with tab-separated values
-========================= ===== ============================================================================================
+functionality, and the ``Fast`` column indicates which formats are compatible with
+the fast Cython/C engine for reading and writing.
+
+========================= ===== ==== ============================================================================================
+           Format         Write Fast                                          Description
+========================= ===== ==== ============================================================================================
+``aastex``                  Yes      :class:`~astropy.io.ascii.AASTex`: AASTeX deluxetable used for AAS journals
+``basic``                   Yes  Yes :class:`~astropy.io.ascii.Basic`: Basic table with custom delimiters
+``cds``                              :class:`~astropy.io.ascii.Cds`: CDS format table
+``commented_header``        Yes  Yes :class:`~astropy.io.ascii.CommentedHeader`: Column names in a commented line
+``csv``                     Yes  Yes :class:`~astropy.io.ascii.Csv`: Basic table with comma-separated values
+``daophot``                          :class:`~astropy.io.ascii.Daophot`: IRAF DAOphot format table
+``ecsv``                    Yes      :class:`~astropy.io.ascii.Ecsv`: Enhanced CSV format
+``fixed_width``             Yes      :class:`~astropy.io.ascii.FixedWidth`: Fixed width
+``fixed_width_no_header``   Yes      :class:`~astropy.io.ascii.FixedWidthNoHeader`: Fixed width with no header
+``fixed_width_two_line``    Yes      :class:`~astropy.io.ascii.FixedWidthTwoLine`: Fixed width with second header line
+``html``                    Yes      :class:`~astropy.io.ascii.HTML`: HTML format table
+``ipac``                    Yes      :class:`~astropy.io.ascii.Ipac`: IPAC format table
+``latex``                   Yes      :class:`~astropy.io.ascii.Latex`: LaTeX table
+``no_header``               Yes  Yes :class:`~astropy.io.ascii.NoHeader`: Basic table with no headers
+``rdb``                     Yes  Yes :class:`~astropy.io.ascii.Rdb`: Tab-separated with a type definition header line
+``sextractor``                       :class:`~astropy.io.ascii.SExtractor`: SExtractor format table
+``tab``                     Yes  Yes :class:`~astropy.io.ascii.Tab`: Basic table with tab-separated values
+========================= ===== ==== ============================================================================================
 
 
 Using `astropy.io.ascii`
@@ -179,6 +228,14 @@ Fixed-width Gallery
 
    fixed_width_gallery
 
+Fast ASCII Engine
+-----------------
+
+.. toctree::
+   :maxdepth: 2
+
+   fast_ascii_io
+
 Base class elements
 -------------------
 
diff --git a/docs/io/ascii/read.rst b/docs/io/ascii/read.rst
index 0f4c6ef..f9e8c3d 100644
--- a/docs/io/ascii/read.rst
+++ b/docs/io/ascii/read.rst
@@ -126,6 +126,10 @@ Parameters for ``read()``
 
 **header_Splitter**: Splitter class to split header columns
 
+**fast_reader**: whether to use the C engine, can also be a dict with options
+  which default to False
+  (see :ref:`fast_ascii_io`)
+
 **Reader** : Reader class (*deprecated* in favor of ``format``)
   This specifies the top-level format of the ASCII table, for example
   if it is a basic character delimited table, fixed format table, or
@@ -256,16 +260,21 @@ look like a number.
 The order of guessing is shown by this Python code, where ``Reader`` is the
 class which actually implements reading the different file formats::
 
-  for Reader in (Rdb, Tab, Cds, Daophot, SExtractor, Ipac, Latex, AASTex, HTML):
+  for Reader in (Ecsv, FixedWidthTwoLine, FastBasic, Basic,
+                 Rdb, FastTab, Tab, Cds, Daophot, SExtractor,
+                 Ipac, Latex, AASTex, HTML):
       read(Reader=Reader)
-  for Reader in (CommentedHeader, Basic, NoHeader):
+
+  for Reader in (CommentedHeader, FastBasic, Basic, FastNoHeader, NoHeader):
       for delimiter in ("|", ",", " ", "\\s"):
           for quotechar in ('"', "'"):
               read(Reader=Reader, delimiter=delimiter, quotechar=quotechar)
 
 Note that the :class:`~astropy.io.ascii.FixedWidth` derived-readers are not included
 in the default guess sequence (this causes problems), so to read such tables
-one must explicitly specify the format with the ``format`` keyword.
+one must explicitly specify the format with the ``format`` keyword. Also notice
+that formats compatible with the fast reading engine attempt to use the fast
+engine before the ordinary reading engine.
 
 If none of the guesses succeed in reading the table (subject to the column
 requirements) a final try is made using just the user-supplied parameters but
@@ -289,6 +298,36 @@ Guessing can be disabled in two ways::
   astropy.io.ascii.set_guess(False)                 # set default to False globally
   data = astropy.io.ascii.read(table)               # guessing disabled
 
+Comments and metadata
+^^^^^^^^^^^^^^^^^^^^^
+
+Any comment lines detected during reading are inserted into the output table
+via the ``comments`` key in the table's ``.meta`` dictionary. For example::
+
+ >>> table='''# TELESCOPE = 30 inch
+ ...          # TARGET = PV Ceph
+ ...          # BAND = V
+ ...          MJD mag
+ ...          55555 12.3
+ ...          55556 12.4'''
+ >>> dat = ascii.read(table)
+ >>> print(dat.meta['comments'])
+ ['TELESCOPE = 30 inch', 'TARGET = PV Ceph', 'BAND = V']
+
+While :mod:`astropy.io.ascii` will not do any post-processing on comment lines,
+custom post-processing can be accomplished by re-reading with the metadata line
+comments. Here is one example, where comments are of the form "# KEY = VALUE"::
+
+ >>> header = ascii.read(dat.meta['comments'], delimiter='=',
+ ...                     format='no_header', names=['key', 'val'])
+ >>> print(header)
+    key      val
+ --------- -------
+ TELESCOPE 30 inch
+    TARGET PV Ceph
+      BAND       V
+
+
 Converters
 ^^^^^^^^^^
 
@@ -327,8 +366,91 @@ functionality to handle special cases.  To go beyond these simple examples the
 best reference is to read the code for the existing
 :ref:`extension_reader_classes`.
 
+**Define custom readers by class inheritance**
+
+The most useful way to define a new reader class is by inheritance.
+This is the way all the build-in readers are defined, so there are plenty
+of examples in the code.
+
+In most cases, you will define one class to handle the header,
+one class that handles the data and a reader class that ties it all together.
+Here is a simple example from the code that defines a reader that is just like
+the basic reader, but header and data start in different lines of the file::
+
+  # Note: NoHeader is already included in astropy.io.ascii for convenience.
+  class NoHeaderHeader(BasicHeader):
+      '''Reader for table header without a header
+
+      Set the start of header line number to `None`, which tells the basic
+      reader there is no header line.
+      '''
+      start_line = None
+
+  class NoHeaderData(BasicData):
+      '''Reader for table data without a header
+
+      Data starts at first uncommented line since there is no header line.
+      '''
+      start_line = 0
+
+  class NoHeader(Basic):
+      """Read a table with no header line.  Columns are autonamed using
+      header.auto_format which defaults to "col%d".  Otherwise this reader
+      the same as the :class:`Basic` class from which it is derived.  Example::
+
+        # Table data
+        1 2 "hello there"
+        3 4 world
+      """
+      _format_name = 'no_header'
+      _description = 'Basic table with no headers'
+      header_class = NoHeaderHeader
+      data_class = NoHeaderData
+
+In a slightly more involved case, the implementation can also override some of
+the methods in the base class::
+
+  # Note: CommentedHeader is already included in astropy.io.ascii for convenience.
+  class CommentedHeaderHeader(BasicHeader):
+      """Header class for which the column definition line starts with the
+      comment character.  See the :class:`CommentedHeader` class  for an example.
+      """
+      def process_lines(self, lines):
+          """Return only lines that start with the comment regexp.  For these
+          lines strip out the matching characters."""
+          re_comment = re.compile(self.comment)
+          for line in lines:
+              match = re_comment.match(line)
+              if match:
+                  yield line[match.end():]
+
+      def write(self, lines):
+          lines.append(self.write_comment + self.splitter.join(self.colnames))
+
+
+  class CommentedHeader(Basic):
+      """Read a file where the column names are given in a line that begins with
+      the header comment character. ``header_start`` can be used to specify the
+      line index of column names, and it can be a negative index (for example -1
+      for the last commented line).  The default delimiter is the <space>
+      character.::
+
+        # col1 col2 col3
+        # Comment line
+        1 2 3
+        4 5 6
+      """
+      _format_name = 'commented_header'
+      _description = 'Column names in a commented line'
+
+      header_class = CommentedHeaderHeader
+      data_class = NoHeaderData
+
+
 **Define a custom reader functionally**
-::
+Instead of defining a new class, it is also possible to obtain an instance
+of a reader and then to modify the properties of this one reader instance
+in a function::
 
    def read_rdb_table(table):
        reader = astropy.io.ascii.Basic()
@@ -340,34 +462,6 @@ best reference is to read the code for the existing
 
        return reader.read(table)
 
-**Define custom readers by class inheritance**
-::
-
-   # Note: Tab, Csv, and Rdb are included in astropy.io.ascii for convenience.
-   class Tab(astropy.io.ascii.Basic):
-       def __init__(self):
-           astropy.io.ascii.Basic.__init__(self)
-           self.header.splitter.delimiter = '\t'
-           self.data.splitter.delimiter = '\t'
-           # Don't strip line whitespace since that includes tabs
-           self.header.splitter.process_line = None
-           self.data.splitter.process_line = None
-           # Don't strip data value spaces since that is significant in TSV tables
-           self.data.splitter.process_val = None
-           self.data.splitter.skipinitialspace = False
-
-   class Rdb(astropy.io.ascii.Tab):
-       def __init__(self):
-           astropy.io.ascii.Tab.__init__(self)
-           self.data.start_line = 2
-
-    class Csv(astropy.io.ascii.Basic):
-        def __init(self):
-            astropy.io.ascii.Basic.__init__(self)
-            self.data.splitter.delimiter = ','
-            self.header.splitter.delimiter = ','
-            self.header.start_line = 0
-            self.data.start_line = 1
 
 **Create a custom splitter.process_val function**
 ::
diff --git a/docs/io/ascii/toc.txt b/docs/io/ascii/toc.txt
index 02df2d5..779c0a5 100644
--- a/docs/io/ascii/toc.txt
+++ b/docs/io/ascii/toc.txt
@@ -5,4 +5,5 @@
    write
    base_classes
    fixed_width_gallery
+   fast_ascii_io
    ascii_api
diff --git a/docs/io/ascii/write.rst b/docs/io/ascii/write.rst
index c3d9437..93f90d4 100644
--- a/docs/io/ascii/write.rst
+++ b/docs/io/ascii/write.rst
@@ -41,6 +41,12 @@ file::
   \end{tabular}
   \end{table}
 
+There is also a faster Cython engine for writing simple formats,
+which is enabled by default for these formats (see :ref:`fast_ascii_io`).
+To disable this engine, use the parameter ``fast_writer``::
+
+   >>> ascii.write(data, 'values.csv', format='csv', fast_writer=False)  # doctest: +SKIP
+
 Input data format
 ^^^^^^^^^^^^^^^^^
 
@@ -170,11 +176,14 @@ details.
   A one-character string used to separate fields which typically defaults to the space character.
   Other common values might be "," or "|" or "\\t".
 
-**comment** : string defining a comment line in table
-  For the :class:`~astropy.io.ascii.Basic` Writer this defaults to "#".
-  Which and how comments are written depends on the format chosen (e.g.
-  :class:`~astropy.io.ascii.CommentedHeader` puts the comment symbol in the line
-  with the column names).
+**comment** : string defining start of a comment line in output table
+  For the :class:`~astropy.io.ascii.Basic` Writer this defaults to "# ".
+  Which and how comments are written depends on the format chosen.
+  The comments are defined as a list of strings in the input table
+  ``meta['comments']`` element. Comments in the metadata of the given
+  |Table| will normally be written before the header, although
+  :class:`~astropy.io.ascii.CommentedHeader` writes table comments after the
+  commented header. To disable writing comments, set ``comment=False``.
 
 **formats**: dict of data type converters
   For each key (column name) use the given value to convert the column data to a string.
@@ -255,6 +264,11 @@ details.
 **fill_exclude_names**: list of column names, which are not affected by ``fill_values``.
   If not supplied, then ``fill_values`` can affect all columns.
 
+**fast_writer**: whether to use the fast Cython writer
+  If this parameter is ``None`` (which it is by default), |write| will attempt
+  to use the faster writer (described in :ref:`fast_ascii_io`) if possible.
+  Specifying ``fast_writer=False`` disables this behavior.
+
 **Writer** : Writer class (*deprecated* in favor of ``format``)
   This specifies the top-level format of the ASCII table to be written, for
   example if it is a basic character delimited table, fixed format table, or a
diff --git a/docs/io/fits/index.rst b/docs/io/fits/index.rst
index 8a85455..a0e7b23 100644
--- a/docs/io/fits/index.rst
+++ b/docs/io/fits/index.rst
@@ -94,7 +94,7 @@ because by that point you're likely to run out of physical memory anyways), but
 	that were built with the assumption that the .data attribute has all the data in-memory.
 	
 	In order to force the mmap to close either wait for the containing ``HDUList`` object to go 
-	out of scope, or manually call del ``hdul[0].data`` (this works so long as there are no other
+	out of scope, or manually call ``del hdul[0].data`` (this works so long as there are no other
 	references held to the data array).
 
 Working with FITS Headers
@@ -352,7 +352,7 @@ attribute::
     >>> cols = hdulist[1].columns
 
 This attribute is a :class:`ColDefs` (column definitions) object. If we use the
-:meth:`ColDefs.info` method::
+:meth:`ColDefs.info` method from the interactive prompt::
 
     >>> cols.info()
      name:
@@ -375,7 +375,12 @@ This attribute is a :class:`ColDefs` (column definitions) object. If we use the
           ['', '', '', '']
 
 it will show the attributes of all columns in the table, such as their names,
-formats, bscales, bzeros, etc.  We can also get these properties individually;
+formats, bscales, bzeros, etc. A similar output that will display the column
+names and their formats can be printed from within a script with::
+
+    print hdulist[1].columns
+
+We can also get these properties individually;
 e.g.
 
 ::
diff --git a/docs/io/unified.rst b/docs/io/unified.rst
index d7d40b2..bdff519 100644
--- a/docs/io/unified.rst
+++ b/docs/io/unified.rst
@@ -70,6 +70,7 @@ The full list of built-in readers and writers is shown in the table below:
                   ascii.cds  Yes    No            No
      ascii.commented_header  Yes   Yes            No
               ascii.daophot  Yes    No            No
+              ascii.ecsv     Yes   Yes            No
           ascii.fixed_width  Yes   Yes            No
 ascii.fixed_width_no_header  Yes   Yes            No
  ascii.fixed_width_two_line  Yes   Yes            No
diff --git a/docs/known_issues.rst b/docs/known_issues.rst
index 70c9f3a..f470165 100644
--- a/docs/known_issues.rst
+++ b/docs/known_issues.rst
@@ -265,15 +265,3 @@ One workaround is to install the ``bsddb3`` module.
 .. [#] Continuum `says
        <https://groups.google.com/a/continuum.io/forum/#!topic/anaconda/mCQL6fVx55A>`_
        this will be fixed in their next Python build.
-
-
-Very long integers in ASCII tables silently converted to float for Numpy 1.5
-----------------------------------------------------------------------------
-
-For Numpy 1.5, when reading an ASCII table that has integers which are too
-large to fit into the native C long int type for the machine, then the
-values get converted to float type with no warning.  This is due to the
-behavior of `numpy.array` and cannot easily be worked around.  We recommend
-that users upgrade to a newer version of Numpy.  For Numpy >= 1.6 a warning
-is printed and the values are treated as strings to preserve all information.
-
diff --git a/docs/modeling/compound-models.rst b/docs/modeling/compound-models.rst
new file mode 100644
index 0000000..f2a5da4
--- /dev/null
+++ b/docs/modeling/compound-models.rst
@@ -0,0 +1,862 @@
+.. _compound-models:
+
+Compound Models
+===============
+
+.. versionadded:: 1.0
+
+As noted in the :ref:`introduction to the modeling package
+<compound-models-intro>`, it is now possible to create new models just by
+combining existing models using the arithmetic operators ``+``, ``-``, ``*``,
+``/``, and ``**``, as well as by model composition using ``|`` and
+concatenation (explained below) with ``&``.
+
+
+Some terminology
+----------------
+
+In discussing the compound model feature, it is useful to be clear about a
+few terms where there have been points of confusion:
+
+- The term "model" can refer either to a model *class* or a model *instance*.
+
+  - All models in `astropy.modeling`, whether it represents some
+    `function <astropy.modeling.functional_models>`, a
+    `rotation <astropy.modeling.rotations>`, etc. is represented in the
+    abstract by a model *class*--specifically a subclass of
+    `~astropy.modeling.Model`--that encapsulates the routine for evaluating the
+    model, a list of its required parameters, and other metadata about the
+    model.
+
+  - Per typical object-oriented parlance, a model *instance* is the object
+    created when when calling a model class with some arguments--in most cases
+    values for the model's parameters.
+
+  A model class, by itself, cannot be used to perform any computation because
+  most models, at least, have one or more parameters that must be specified
+  before the model can be evaluated on some input data. However, we can still
+  get some information about a model class from its representation.  For
+  example::
+
+      >>> from astropy.modeling.models import Gaussian1D
+      >>> Gaussian1D
+      <class 'astropy.modeling.functional_models.Gaussian1D'>
+      Name: Gaussian1D
+      Inputs: ('x',)
+      Outputs: ('y',)
+      Fittable parameters: ('amplitude', 'mean', 'stddev')
+
+  We can then create a model *instance* by passing in values for the three
+  parameters::
+
+      >>> my_gaussian = Gaussian1D(amplitude=1.0, mean=0, stddev=0.2)
+      >>> my_gaussian  # doctest: +FLOAT_CMP
+      <Gaussian1D(amplitude=1.0, mean=0.0, stddev=0.2)>
+
+  We now have an *instance* of `~astropy.modeling.functional_models.Gaussian1D`
+  with all its parameters (and in principle other details like fit constraints)
+  filled in so that we can perform calculations with it as though it were a
+  function::
+
+      >>> my_gaussian(0.2)  # doctest: +FLOAT_CMP
+      0.6065306597126334
+
+  In many cases this document just refers to "models", where the class/instance
+  distinction is either irrelevant or clear from context.  But a distinction
+  will be made where necessary.
+
+- A *compound model* can be created by combining two or more existing models--
+  be they model *instances* or *classes*, and can be models that come with
+  Astropy, :doc:`user defined models <new>`, or other compound models--using
+  Python expressions consisting of one or more of the supported binary
+  operators.
+
+- In some places the term *composite model* is used interchangeably with
+  *compound model*.  This can be seen in the cases of the now deprecated
+  `~astropy.modeling.SerialCompositeModel` and
+  `~astropy.modeling.SummedCompositeModel`.  However, this document uses the
+  term *composite model* to refer *only* to the case of a compound model
+  created from the functional composition of two or more models using the pipe
+  operator ``|`` as explained below.  This distinction is used consistently
+  within this document, but it may be helpful to understand the distinction.
+
+
+Creating compound models
+------------------------
+
+As discussed in the :ref:`introduction to compound models
+<compound-models-intro>`, the only way, currently, to create compound models is
+to combine existing single models and/or compound models using expressions in
+Python with the binary operators ``+``, ``-``, ``*``, ``/``, ``**``, ``|``,
+and ``&``, each of which are discussed in the following sections.  The operands
+used in these expressions may be model *classes*, or model *instances*.  In
+other words, any object for which either ``isinstance(obj, Model)`` or
+``issubclass(obj, Model)`` is `True`.
+
+
+.. _compound-model-classes:
+
+Compound model classes
+^^^^^^^^^^^^^^^^^^^^^^
+
+We start by demonstrating how new compound model *classes* can be created
+by combining other classes.  This is more advanced usage, but it's useful to
+understand that this is what's going on under the hood in the more basic usage
+of :ref:`compound model instances <compound-model-instances>`.
+
+When all models involved in the expression are classes, the result of the
+expression is, itself, a class (remember, classes in Python are themselves also
+objects just like strings and integers or model instances)::
+
+    >>> TwoGaussians = Gaussian1D + Gaussian1D
+    >>> from astropy.modeling import Model
+    >>> isinstance(TwoGaussians, Model)
+    False
+    >>> issubclass(TwoGaussians, Model)
+    True
+
+When we inspect the variable ``TwoGaussians`` by printing its representation at
+the command prompt we can get some more information about it::
+
+    >>> TwoGaussians
+    <class '__main__.CompoundModel...'>
+    Name: CompoundModel...
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude_0', 'mean_0', 'stddev_0', 'amplitude_1', 'mean_1', 'stddev_1')
+    Expression: [0] + [1]
+    Components:
+        [0]: <class 'astropy.modeling.functional_models.Gaussian1D'>
+        Name: Gaussian1D
+        Inputs: ('x',)
+        Outputs: ('y',)
+        Fittable parameters: ('amplitude', 'mean', 'stddev')
+    <BLANKLINE>
+        [1]: <class 'astropy.modeling.functional_models.Gaussian1D'>
+        Name: Gaussian1D
+        Inputs: ('x',)
+        Outputs: ('y',)
+        Fittable parameters: ('amplitude', 'mean', 'stddev')
+
+There are a number of things to point out here:  This model class has six
+fittable parameters.  How parameters are handled is discussed further in the
+section on :ref:`compound-model-parameters`.  We also see that there is a
+listing of the *expression* that was used to create this compound model, which
+in this case is summarized as ``[0] + [1]``.  The ``[0]`` and ``[1]`` refer to
+the first and second components of the model listed next (in this case both
+components are the `~astropy.modeling.functional_models.Gaussian1D` class).
+
+Each component of a compound model is a single, non-compound model.  This is
+the case even when performing an existing compound model in a new expression.
+The existing compound model is not treated as a single model--instead the
+expression represented by that compound model is extended.  An expression
+involving two or more compound models results in a new expression that is the
+concatenation of all involved models' expressions::
+
+    >>> FourGaussians = TwoGaussians + TwoGaussians
+    >>> FourGaussians
+    <class '__main__.CompoundModel...'>
+    Name: CompoundModel...
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude_0', 'mean_0', 'stddev_0', ..., 'amplitude_3', 'mean_3', 'stddev_3')
+    Expression: [0] + [1] + [2] + [3]
+    Components:
+        [0]: <class 'astropy.modeling.functional_models.Gaussian1D'>
+        Name: Gaussian1D
+        Inputs: ('x',)
+        Outputs: ('y',)
+        Fittable parameters: ('amplitude', 'mean', 'stddev')
+        ...
+        [3]: <class 'astropy.modeling.functional_models.Gaussian1D'>
+        Name: Gaussian1D
+        Inputs: ('x',)
+        Outputs: ('y',)
+        Fittable parameters: ('amplitude', 'mean', 'stddev')
+
+In a future version it may be possible to "freeze" a compound model, so that
+from the user's perspective it is treated as a single model.  However, as this
+is the default behavior it is good to be aware of.
+
+
+Model names
+^^^^^^^^^^^
+
+In the last two examples another notable feature of the generated compound
+model classes is that the class name, as displayed when printing the class at
+the command prompt, is not "TwoGaussians", "FourGaussians", etc.  Instead it is
+a generated name consisting of "CompoundModel" followed by an essentially
+arbitrary integer that is chosen simply so that every compound model has a
+unique default name.  This is a limitation at present, due to the limitation
+that it is not generally possible in Python when an object is created by an
+expression for it to "know" the name of the variable it will be assigned to, if
+any.  It may be possible in the future to work around this in limited cases,
+but for now there are a couple workarounds for creating compound model classes
+with friendlier names.  The first is to use the
+`Model.rename <astropy.modeling.Model.rename>` class method on the result of
+the model expression::
+
+    >>> TwoGaussians = (Gaussian1D + Gaussian1D).rename('TwoGaussians')
+    >>> TwoGaussians
+    <class '__main__.TwoGaussians'>
+    Name: TwoGaussians (CompoundModel...)
+    ...
+
+This actually takes the generated compound model and creates a light subclass
+of it with the desired name.  This does not impose any additional overhead.  An
+alternative syntax, which is equivalent to what
+`~astropy.modeling.Model.rename` is doing, is to directly use the model
+expression as the base class of a new class::
+
+    >>> class TwoGaussians(Gaussian1D + Gaussian1D):
+    ...     """A superposition of two Gaussians."""
+    ...
+    >>> TwoGaussians
+    <class '__main__.TwoGaussians'>
+    Name: TwoGaussians (CompoundModel...)
+    ...
+
+Because the result of the expression ``Gaussian1D + Gaussian1D`` *is* a class,
+it can be used directly in the standard class declaration syntax
+``class ClassName(Base):`` as the base.  This syntax also has the advantage of
+allowing a docstring to be assigned to the new class.  In future versions it
+may be possible to customize other aspects of compound model classes in this
+way.  Single model classes can also be given custom names by using
+`~astropy.modeling.Model.rename`, and model instances can be given names as
+well.  This can be used to good effect, for example as shown in the section on
+:ref:`compound-model-indexing`.
+
+
+.. _compound-model-instances:
+
+Compound models with model instances
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+So far we have seen how to create compound model *classes* from expressions
+involving other model classes.  This is the most "generic" way to create new
+models from existing models.  However, many may find it more useful most of the
+time, especially when providing an initial guess to a fitter, to create a new
+model from a combination of model *instances* with already defined parameter
+values.  This can also be done and works mostly the same way::
+
+    >>> both_gaussians = Gaussian1D(1, 0, 0.2) + Gaussian1D(2.5, 0.5, 0.1)
+    >>> both_gaussians  # doctest: +FLOAT_CMP
+    <CompoundModel...(amplitude_0=1.0, mean_0=0.0, stddev_0=0.2, amplitude_1=2.5, mean_1=0.5, stddev_1=0.1)>
+
+Unlike when a model was created from model classes, this expression does not
+directly return a new class; instead it creates a model instance that is ready
+to be used for evaluation::
+
+    >>> both_gaussians(0.2)  # doctest: +FLOAT_CMP
+    0.6343031510582392
+
+This was found to be much more convenient and natural, in this case, than
+returning a class.  It is worth understanding that the way this works under the
+hood is to create the compound class, and then immediately instantiate it with
+the already known parameter values.  We can see this by checking the type of
+``both_gaussians``::
+
+    >>> type(both_gaussians)  # doctest: +FLOAT_CMP
+    <class '__main__.CompoundModel...'>
+    Name: CompoundModel...
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude_0', 'mean_0', 'stddev_0', 'amplitude_1', 'mean_1', 'stddev_1')
+    Expression: [0] + [1]
+    Components:
+        [0]: <Gaussian1D(amplitude=1.0, mean=0.0, stddev=0.2)>
+    <BLANKLINE>
+        [1]: <Gaussian1D(amplitude=2.5, mean=0.5, stddev=0.1)>
+
+It is also possible, and sometimes useful, to make a compound model from a
+combination of classes *and* instances in the same expression::
+
+    >>> from astropy.modeling.models import Linear1D, Sine1D
+    >>> MyModel = Linear1D + Sine1D(amplitude=1, frequency=1)
+    >>> MyModel
+    <class '__main__.CompoundModel...'>
+    Name: CompoundModel...
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('slope_0', 'intercept_0', 'amplitude_1', 'frequency_1')
+    Expression: [0] + [1]
+    Components:
+        [0]: <class 'astropy.modeling.functional_models.Linear1D'>
+        Name: Linear1D
+        Inputs: ('x',)
+        Outputs: ('y',)
+        Fittable parameters: ('slope', 'intercept')
+    <BLANKLINE>
+        [1]: <Sine1D(amplitude=1.0, frequency=1.0)>
+
+In this case the result is always a class.  However (and this is not
+immediately obvious by the representation) the difference is that the
+``amplitude`` and ``frequency`` parameters for the
+`~astropy.modeling.functional_models.Sine1D` part of the model are
+"baked into" the class as default values for those parameters.  So it is
+possible to instantiate one of these models by specifying just the ``slope``
+and ``intercept`` parameters for the
+`~astropy.modeling.functional_models.Linear1D` part of the model::
+
+    >>> my_model = MyModel(1, 0)
+    >>> my_model(0.25)  # doctest +FLOAT_CMP
+    1.25
+
+This does not prevent the other parameters from being overridden, however::
+
+    >>> my_model = MyModel(slope_0=1, intercept_0=0, frequency_1=2)
+    >>> my_model(0.125)  # doctest +FLOAT_CMP
+    1.125
+
+In fact, this is currently the only way to use a `polynomial
+<astropy.modeling.polynomial>` model in a compound model, because the design of
+the polynomial models is currently such that they must be instantiated in order
+to specify their polynomial degree.  Because the polynomials are already
+designed so that their coefficients all default to zero, this "limitation"
+should not have any practical drawbacks.
+
+.. note::
+
+    There is currently a caveat in the example of combining model classes and
+    instances, which is that the parameter values of model *instances* are only
+    treated as defaults if the expression is written in such a way that all
+    model instances are to the right of all model classes.  This limitation
+    will be lifted in a later version--in particular, Python 3 offers a lot
+    more flexibility with respect to how function arguments are handled.
+
+
+Operators
+---------
+
+Arithmetic operators
+^^^^^^^^^^^^^^^^^^^^
+
+Compound models can be created from expressions that include any number of the
+arithmetic operators ``+``, ``-``, ``*``, ``/``, and ``**`` which have the same
+meanings as they do for other numeric objects in Python.
+
+.. note::
+
+    In the case of division ``/`` always means floating point division--integer
+    division and the ``//`` operator are not supported for models).
+
+As demonstrated in previous examples, for models that have a single output
+the result of evaluating a model like ``A + B`` is to evaluate ``A`` and
+``B`` separately on the given input, and then return the sum of the outputs of
+``A`` and ``B``.  This requires that ``A`` and ``B`` take the same number of
+inputs and both have a single output.
+
+It is also possible to use arithmetic operators between models with multiple
+outputs.  Again, the number of inputs must be the same between the models, as
+must be the number of outputs.  In this case the operator is applied to the
+operators element-wise, similarly to how arithmetic operators work on two Numpy
+arrays.
+
+
+.. _compound-model-composition:
+
+Model composition
+^^^^^^^^^^^^^^^^^
+
+The sixth binary operator that can be used to create compound models is the
+composition operator, also known as the "pipe" operator ``|`` (not to be
+confused with the boolean "or" operator that this implements for Python numeric
+objects).  A model created with the composition operator like ``M = F | G``,
+when evaluated, is equivalent to evaluating :math:`g \circ f = g(f(x))`.
+
+.. note::
+
+    The fact that the ``|`` operator has the opposite sense as the functional
+    composition operator :math:`\circ` is sometimes a point of confusion.
+    This is in part because there is no operator symbol supported in Python
+    that corresponds well to this.  The ``|`` operator should instead be read
+    like the `pipe operator
+    <http://en.wikipedia.org/wiki/Pipeline_%28Unix%29>`_ of UNIX shell syntax:
+    It chains together models by piping the output of the left-hand operand to
+    the input of the right-hand operand, forming a "pipeline" of models, or
+    transformations.
+
+This has different requirements on the inputs/outputs of its operands than do
+the arithmetic operators.  For composition all that is required is that the
+left-hand model has the same number of outputs as the right-hand model has
+inputs.
+
+For simple functional models this is exactly the same as functional
+composition, except for the aforementioned caveat about ordering.  For
+example:
+
+.. plot::
+    :include-source:
+
+    import numpy as np
+    from astropy.modeling.models import Redshift, Gaussian1D
+
+    class RedshiftedGaussian(Redshift | Gaussian1D(1, 0.75, 0.1)):
+        """Evaluates a Gaussian with optional redshift applied to the input."""
+
+    x = np.linspace(0, 1.2, 100)
+    g0 = RedshiftedGaussian(z_0=0)
+
+    plt.figure(figsize=(8, 3))
+    plt.plot(x, g0(x), 'g--', lw=2, label='$z=0$')
+
+    for z in (0.2, 0.4, 0.6):
+        g = RedshiftedGaussian(z_0=z)
+        plt.plot(x, g(x), color=plt.cm.OrRd(z), lw=2,
+                 label='$z={0}$'.format(z))
+
+    plt.xlabel('Energy')
+    plt.ylabel('Flux')
+    plt.legend()
+
+When working with models with multiple inputs and outputs the same idea
+applies.  If each input is thought of as a coordinate axis, then this defines a
+pipeline of transformations for the coordinates on each axis (though it does
+not necessarily guarantee that these transformations are separable).  For
+example:
+
+.. plot::
+    :include-source:
+
+    import numpy as np
+    from astropy.modeling.models import Rotation2D, Gaussian2D
+
+    class RotatedGaussian(Rotation2D | Gaussian2D(1, 0, 0, 0.1, 0.3)):
+        """A Gaussian2D composed with a coordinate rotation."""
+
+    x, y = np.mgrid[-1:1:0.01, -1:1:0.01]
+
+    plt.figure(figsize=(8, 2.5))
+
+    for idx, theta in enumerate((0, 45, 90)):
+        g = RotatedGaussian(theta)
+        plt.subplot(1, 3, idx + 1)
+        plt.imshow(g(x, y))
+        plt.xticks([])
+        plt.yticks([])
+        plt.title('Rotated $ {0}^\circ $'.format(theta))
+
+.. note::
+
+    The above example is a bit contrived in that
+    `~astropy.modeling.functional_models.Gaussian2D` already supports an
+    optional rotation parameter.  However, this demonstrates how coordinate
+    rotation could be added to arbitrary models.
+
+Normally it is not possible to compose, say, a model with two outputs and a
+function of only one input::
+
+    >>> from astropy.modeling.models import Rotation2D
+    >>> Rotation2D | Gaussian1D
+    Traceback (most recent call last):
+    ...
+    ModelDefinitionError: Unsupported operands for |: Rotation2D (n_inputs=2, n_outputs=2) and Gaussian1D (n_inputs=1, n_outputs=1); n_outputs for the left-hand model must match n_inputs for the right-hand model.
+
+However, as we will see in the next section,
+:ref:`compound-model-concatenation`, provides a means of creating models
+that apply transformations to only some of the outputs from a model,
+especially when used in concert with :ref:`mappings <compound-model-mappings>`.
+
+
+.. _compound-model-concatenation:
+
+Model concatenation
+^^^^^^^^^^^^^^^^^^^
+
+The concatenation operator ``&``, sometimes also referred to as a "join",
+combines two models into a single, fully separable transformation.  That is, it
+makes a new model that takes the inputs to the left-hand model, concatenated
+with the inputs to the right-hand model, and returns a tuple consisting of the
+two models' outputs concatenated together, without mixing in any way.  In other
+words, it simply evaluates the two models in parallel--it can be thought of as
+something like a tuple of models.  For example, given two coordinate axes, we
+can scale each coordinate by a different factor by concatenating two
+`~astropy.modeling.functional_models.Scale` models::
+
+    >>> from astropy.modeling.models import Scale
+    >>> separate_scales = Scale(factor=1.2) & Scale(factor=3.4)
+    >>> separate_scales(1, 2)  # doctest: +FLOAT_CMP
+    (1.2, 6.8)
+
+We can also combine concatenation with composition to build chains of
+transformations that use both "1D" and "2D" models on two (or more) coordinate
+axes::
+
+    >>> scale_and_rotate = ((Scale(factor=1.2) & Scale(factor=3.4)) |
+    ...                     Rotation2D(90))
+    >>> scale_and_rotate.n_inputs
+    2
+    >>> scale_and_rotate.n_outputs
+    2
+    >>> scale_and_rotate(1, 2)  # doctest: +FLOAT_CMP
+    (-6.8, 1.2)
+
+This is of course equivalent to an
+`~astropy.modeling.projections.AffineTransformation2D` with the appropriate
+transformation matrix::
+
+    >>> from numpy import allclose
+    >>> from astropy.modeling.models import AffineTransformation2D
+    >>> affine = AffineTransformation2D(matrix=[[0, -3.4], [1.2, 0]])
+    >>> # May be small numerical differences due to different implementations
+    >>> allclose(scale_and_rotate(1, 2), affine(1, 2))
+    True
+
+
+.. _compound-model-indexing:
+
+Indexing and slicing
+--------------------
+
+As seen in some of the previous examples in this document, when creating a
+compound model each component of the model is assigned an integer index
+starting from zero.  These indices are assigned simply by reading the
+expression that defined the model, from left to right, regardless of the order
+of operations.  For example::
+
+    >>> from astropy.modeling.models import Const1D
+    >>> A = Const1D.rename('A')
+    >>> B = Const1D.rename('B')
+    >>> C = Const1D.rename('C')
+    >>> M = A + B * C
+    >>> M
+    <class '__main__.CompoundModel...'>
+    Name: CompoundModel...
+    ...
+    Expression: [0] + [1] * [2]
+    Components:
+        [0]: <class '__main__.A'>
+        Name: A (Const1D)
+        ...
+    <BLANKLINE>
+        [1]: <class '__main__.B'>
+        Name: B (Const1D)
+        ...
+    <BLANKLINE>
+        [2]: <class '__main__.C'>
+        Name: C (Const1D)
+        ...
+
+In this example the expression is evaluated ``(B * C) + A``--that is, the
+multiplication is evaluated before the addition per usual arithmetic rules.
+However, the components of this model are simply read off left to right from
+the expression ``A + B * C``, with ``A -> 0``, ``B -> 1``, ``C -> 2``.  If we
+had instead defined ``M = C * B + A`` then the indices would be reversed
+(though the expression is mathematically equivalent).  This convention is
+chosen for simplicity--given the list of components it is not necessary to
+jump around when mentally mapping them to the expression.
+
+We can pull out each individual component of the compound model ``M`` by using
+indexing notation on it.  Following from the above example, ``M[1]`` should
+return the model ``B``::
+
+    >>> M[1]
+    <class '__main__.B'>
+    Name: B (Const1D)
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude',)
+
+We can also take a *slice* of the compound model.  This returns a new compound
+model that evaluates the *subexpression* involving the models selected by the
+slice.  This follows the same semantics as slicing a `list` or array in Python.
+The start point is inclusive and the end point is exclusive.  So a slice like
+``M[1:3]`` (or just ``M[1:]``) selects models ``B`` and ``C`` (and all
+*operators* between them).  So the resulting model evaluates just the
+subexpression ``B * C``::
+
+    >>> M[1:]
+    <class 'astropy.modeling.utils.CompoundModel...'>
+    Name: CompoundModel...
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude_1', 'amplitude_2')
+    Expression: [0] * [1]
+    Components:
+        [0]: <class '__main__.B'>
+        Name: B (Const1D)
+        ...
+    <BLANKLINE>
+        [1]: <class '__main__.C'>
+        Name: C (Const1D)
+        ...
+
+The new compound model for the subexpression can be instantiated and evaluated
+like any other::
+
+    >>> m = M[1:](2, 3)
+    >>> m
+    <CompoundModel...(amplitude_1=2.0, amplitude_2=3.0)>
+    >>> m(0)
+    6.0
+
+Although the model ``M`` was composed entirely of ``Const1D`` models in this
+example, it was useful to give each component a unique name (``A``, ``B``,
+``C``) in order to differentiate between them.  This can also be used for
+indexing and slicing::
+
+    >>> M['B']
+    <class '__main__.B'>
+    Name: B (Const1D)
+    Inputs: ('x',)
+    Outputs: ('y',)
+    Fittable parameters: ('amplitude',)
+
+In this case ``M['B']`` is equivalent to ``M[1]``.  But by using the name we do
+not have to worry about what index that component is in (this becomes
+especially useful when combining multiple compound models).  A current
+limitation, however, is that each component of a compound model must have a
+unique name--if some components have duplicate names then they can only be
+accessed by their integer index.  This may improve in a future release.
+
+Slicing also works with names.  When using names the start and end points are
+*both inclusive*::
+
+    >>> M['B':'C']
+    <class 'astropy.modeling.utils.CompoundModel...'>
+    ...
+    Expression: [0] * [1]
+    Components:
+        [0]: <class '__main__.B'>
+        Name: B (Const1D)
+        ...
+    <BLANKLINE>
+        [1]: <class '__main__.C'>
+        Name: C (Const1D)
+        ...
+
+So in this case ``M['B':'C']`` is equivalent to ``M[1:3]``.
+
+All of the above applies equally well to compound models composed of model
+instances.  Individual model instances can be given a name by passing in the
+``name=`` argument when instantiating them.  These names are used in the same was
+as class names were in the class-based examples::
+
+    >>> a = Const1D(amplitude=1, name='A')
+    >>> b = Const1D(amplitude=2, name='B')
+    >>> c = Const1D(amplitude=3, name='C')
+    >>> m = a + b * c
+
+Because this model is composed entirely of constants it doesn't matter what
+input we pass in, so 0 is used without loss of generality::
+
+    >>> m(0)
+    7.0
+    >>> m[1:](0)  # b * c
+    6.0
+    >>> m['A':'B'](0)  # a + b
+    3.0
+    >>> m['B':'C'](0)  # b * c, again
+    6.0
+
+
+.. _compound-model-parameters:
+
+Parameters
+----------
+
+A question that frequently comes up when first encountering compound models is
+how exactly all the parameters are dealt with.  By now we've seen a few
+examples that give some hints, but a more detailed explanation is in order.
+This is also one of the biggest areas for possible improvements--the current
+behavior is meant to be practical, but is not ideal.  (Some possible
+improvements include being able to rename parameters, and providing a means of
+narrowing down the number of parameters in a compound model.)
+
+As explained in the general documentation for model :ref:`parameters
+<modeling-parameters>`, every model has an attribute called
+`~astropy.modeling.Model.param_names` that contains a tuple of all the model's
+adjustable parameters.  These names are given in a canonical order that also
+corresponds to the order in which the parameters should be specified when
+instantiating the model.
+
+The simple scheme used currently for naming parameters in a compound model is
+this:  The ``param_names`` from each component model are concatenated with each
+other in order from left to right as explained in the section on
+:ref:`compound-model-indexing`.  However, each parameter name is appended with
+``_<#>``, where ``<#>`` is the index of the component model that parameter
+belongs to.  For example::
+
+    >>> Gaussian1D.param_names
+    ('amplitude', 'mean', 'stddev')
+    >>> (Gaussian1D + Gaussian1D).param_names
+    ('amplitude_0', 'mean_0', 'stddev_0', 'amplitude_1', 'mean_1', 'stddev_1')
+
+For consistency's sake, this scheme is followed even if not all of the
+components have overlapping parameter names::
+
+    >>> from astropy.modeling.models import Redshift
+    >>> (Redshift | (Gaussian1D + Gaussian1D)).param_names
+    ('z_0', 'amplitude_1', 'mean_1', 'stddev_1', 'amplitude_2', 'mean_2',
+    'stddev_2')
+
+On some level a scheme like this is necessary in order for the compound model
+to maintain some consistency with other models with respect to the interface to
+its parameters.  However, if one gets lost it is also possible to take
+advantage of :ref:`indexing <compound-model-indexing>` to make things easier.
+When returning a single component from a compound model the parameters
+associated with that component are accessible through their original names, but
+are still tied back to the compound model::
+
+    >>> a = Gaussian1D(1, 0, 0.2, name='A')
+    >>> b = Gaussian1D(2.5, 0.5, 0.1, name='B')
+    >>> m.amplitude_0
+    Parameter('amplitude_0', value=1.0)
+
+is equivalent to::
+
+    >>> m['A'].amplitude
+    Parameter('amplitude', value=1.0)
+
+You can think of these both as different "views" of the same parameter.
+Updating one updates the other::
+
+    >>> m.amplitude_0 = 42
+    >>> m['A'].amplitude
+    Parameter('amplitude', value=42.0)
+    >>> m['A'].amplitude = 99
+    >>> m.amplitude_0
+    Parameter('amplitude_0', value=99.0)
+
+Note, however, that the original
+`~astropy.modeling.functional_models.Gaussian1D` instance ``a`` has not been
+updated::
+
+    >>> a.amplitude
+    Parameter('amplitude', value=1.0)
+
+This is because currently, when a compound model is created, copies are made of
+the original models.
+
+
+.. _compound-model-mappings:
+
+Advanced mappings
+-----------------
+
+We have seen in some previous examples how models can be chained together to
+form a "pipeline" of transformations by using model :ref:`composition
+<compound-model-composition>` and :ref:`concatenation
+<compound-model-concatenation>`.  To aid the creation of more complex chains of
+transformations (for example for a WCS transformation) a new class of
+"`mapping <astropy.modeling.mappings>`" models is provided.
+
+Mapping models do not (currently) take any parameters, nor do they perform any
+numeric operation.  They are for use solely with the :ref:`concatenation
+<compound-model-concatenation>` (``&``) and :ref:`composition
+<compound-model-composition>` (``|``) operators, and can be used to control how
+the inputs and outputs of models are ordered, and how outputs from one model
+are mapped to inputs of another model in a composition.
+
+Currently there are only two mapping models:
+`~astropy.modeling.mappings.Identity`, and (the somewhat generically named)
+`~astropy.modeling.mappings.Mapping`.
+
+The `~astropy.modeling.mappings.Identity` mapping simply passes one or more
+inputs through, unchanged.  It must be instantiated with an integer specifying
+the number of inputs/outputs it accepts.  This can be used to trivially expand
+the "dimensionality" of a model in terms of the number of inputs it accepts.
+In the section on :ref:`concatenation <compound-model-concatenation>` we saw
+an example like::
+
+    >>> m = (Scale(1.2) & Scale(3.4)) | Rotation2D(90)
+
+where two coordinate inputs are scaled individually and then rotated into each
+other.  However, say we wanted to scale only one of those coordinates.  It
+would be fine to simply use ``Scale(1)`` for one them, or any other model that
+is effectively a no-op.  But that also adds unnecessary computational overhead,
+so we might as well simply specify that that coordinate is not to be scaled or
+transformed in any way.  This is a good use case for
+`~astropy.modeling.mappings.Identity`::
+
+    >>> from astropy.modeling.models import Identity
+    >>> m = Scale(1.2) & Identity(1)
+    >>> m(1, 2)  # doctest: +FLOAT_CMP
+    (1.2, 2.0)
+
+This scales the first input, and passes the second one through unchanged.  We
+can use this to build up more complicated steps in a many-axis WCS
+transformation.  If for example we had 3 axes and only wanted to scale the
+first one::
+
+    >>> m = Scale(1.2) & Identity(2)
+    >>> m(1, 2, 3)  # doctest: +FLOAT_CMP
+    (1.2, 2.0, 3.0)
+
+(Naturally, the last example could also be written out ``Scale(1.2) &
+Identity(1) & Identity(1)``.)
+
+The `~astropy.modeling.mappings.Mapping` model is similar in that it does not
+modify any of its inputs.  However, it is more general in that it allows inputs
+to be duplicated, reordered, or even dropped outright.  It is instantiated with
+a single argument: a `tuple`, the number of items of which correspond to the
+number of outputs the `~astropy.modeling.mappings.Mapping` should produce.  A
+1-tuple means that whatever inputs come in to the
+`~astropy.modeling.mappings.Mapping`, only one will be output.  And so on for
+2-tuple or higher (though the length of the tuple cannot be greater than the
+number of inputs--it will not pull values out of thin air).  The elements of
+this mapping are integers corresponding to the indices of the inputs.  For
+example, a mapping of ``Mapping((0,))`` is equivalent to ``Identity(1)``--it
+simply takes the first (0-th) input and returns it::
+
+    >>> from astropy.modeling.models import Mapping
+    >>> m = Mapping((0,))
+    >>> m(1.0)
+    1.0
+
+Likewise ``Mapping((0, 1))`` is equivalent to ``Identity(2)``, and so on.
+However, `~astropy.modeling.mappings.Mapping` also allows outputs to be
+reordered arbitrarily::
+
+    >>> m = Mapping((1, 0))
+    >>> m(1.0, 2.0)
+    (2.0, 1.0)
+    >>> m = Mapping((1, 0, 2))
+    >>> m(1.0, 2.0, 3.0)
+    (2.0, 1.0, 3.0)
+
+Outputs may also be dropped::
+
+    >>> m = Mapping((1,))
+    >>> m(1.0, 2.0)
+    2.0
+    >>> m = Mapping((0, 2))
+    >>> m(1.0, 2.0, 3.0)
+    (1.0, 3.0)
+
+Or duplicated::
+
+    >>> m = Mapping((0, 0))
+    >>> m(1.0)
+    (1.0, 1.0)
+    >>> m = Mapping((0, 1, 1, 2))
+    >>> m(1.0, 2.0, 3.0)
+    (1.0, 2.0, 2.0, 3.0)
+
+
+A complicated example that performs multiple transformations, some separable,
+some not, on three coordinate axes might look something like::
+
+    >>> from astropy.modeling.models import Polynomial1D as Poly1D
+    >>> from astropy.modeling.models import Polynomial2D as Poly2D
+    >>> m = ((Poly1D(3, c0=1, c3=1) & Identity(1) & Poly1D(2, c2=1)) |
+    ...      Mapping((0, 2, 1)) |
+    ...      (Poly2D(4, c0_0=1, c1_1=1, c2_2=2) & Gaussian1D(1, 0, 4)))
+    ...
+    >>> m(2, 3, 4)  # doctest: +FLOAT_CMP
+    (41617.0, 0.7548396019890073)
+
+
+
+This expression takes three inputs: :math:`x`, :math:`y`, and :math:`z`.  It
+first takes :math:`x \rightarrow x^3 + 1` and :math:`z \rightarrow z^2`.
+Then it remaps the axes so that :math:`x` and :math:`z` are passed in to the
+`~astropy.modeling.polynomial.Polynomial2D` to evaluate
+:math:`2x^2z^2 + xz + 1`, while simultaneously evaluating a Gaussian on
+:math:`y`.  The end result is a reduction down to two coordinates.  You can
+confirm for yourself that the result is correct.
+
+This opens up the possibility of essentially arbitrarily complex transformation
+graphs.  Currently the tools do not exist to make it easy to navigate and
+reason about highly complex compound models that use these mappings, but that
+is a possible enhancement for future versions.
diff --git a/docs/modeling/design.rst b/docs/modeling/design.rst
deleted file mode 100644
index fd5ef09..0000000
--- a/docs/modeling/design.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-.. _modeling-design:
-
-*******************
-Models Design Goals
-*******************
-
-The `astropy.modeling` and `astropy.modeling.fitting` modules described here
-are designed to work as peers. The goal is to be able to add models without
-explicit reference to fitting algorithms and likewise, add different fitting
-algorithms without changing the existing models.
-
-Furthermore, the models are designed to be combined in many ways. It is
-possible, for example, to combine models `serially
-<astropy.modeling.SerialCompositeModel>` so that the output values of one
-model are used as input values to another.  It is also possible to form a new
-model by combining models in `parallel
-<astropy.modeling.SummedCompositeModel>` (each model is evaluated
-separately with the original input and the deltas are summed).  Since models
-may have multiple input values, machinery is provided that allows assigning
-outputs from one model into the appropriate input of another in a flexible way,
-`~astropy.modeling.LabeledInput`. Finally, it is permitted to combine any
-number of models using all of these mechanisms simultaneously.  A composite
-model can be used to make further composite models.
-
-In the future this will support a model language which will allow using models
-in algebraic operations like
-
-.. math:: model = (model_1 + model_2) * model_3
diff --git a/docs/modeling/fitting.rst b/docs/modeling/fitting.rst
index 691c0fe..6de39f1 100644
--- a/docs/modeling/fitting.rst
+++ b/docs/modeling/fitting.rst
@@ -34,12 +34,12 @@ Fitting examples
       >>> p1.c1 = 2
       >>> print(p1)
       Model: Polynomial1D
-      Inputs: 1
-      Outputs: 1
+      Inputs: ('x',)
+      Outputs: ('y',)
       Model set size: 1
       Degree: 3
       Parameters:
-          c0  c1  c2  c3
+           c0  c1  c2  c3
           --- --- --- ---
           1.0 2.0 0.0 0.0
       >>> x = np.arange(10)
diff --git a/docs/modeling/index.rst b/docs/modeling/index.rst
index 8ace246..04149f2 100644
--- a/docs/modeling/index.rst
+++ b/docs/modeling/index.rst
@@ -13,22 +13,24 @@ Introduction
 model evaluation and fitting. It currently supports 1-D and 2-D models and
 fitting with parameter constraints.
 
-It is :ref:`designed <modeling-design>` to be easily extensible and flexible.
-Models do not reference fitting algorithms explicitly and new fitting
-algorithms may be added without changing the existing models (though not all
-models can be used with all fitting algorithms due to constraints such as model
-linearity).
+It is designed to be easily extensible and flexible.  Models do not reference
+fitting algorithms explicitly and new fitting algorithms may be added without
+changing the existing models (though not all models can be used with all
+fitting algorithms due to constraints such as model linearity).
 
 The goal is to eventually provide a rich toolset of models and fitters such
 that most users will not need to define new model classes, nor special purpose
 fitting routines (while making it reasonably easy to do when necessary).
 
-.. warning::
+.. note::
 
     `astropy.modeling` is currently a work-in-progress, and thus it is likely
-    there will be significant API changes in later versions of Astropy. If you
-    have specific ideas for how it might be improved, feel free to let us know
-    on the `astropy-dev mailing list`_ or at http://feedback.astropy.org
+    there will still be API changes in later versions of Astropy.  Backwards
+    compatibility support between versions will still be maintained as much as
+    possible, but new features and enhancements are coming in future versions.
+    If you have specific ideas for how it might be improved, feel free to let
+    us know on the `astropy-dev mailing list`_ or at
+    http://feedback.astropy.org
 
 
 Getting started
@@ -52,8 +54,8 @@ parametrized functions::
     >>> g = models.Gaussian1D(amplitude=1.2, mean=0.9, stddev=0.5)
     >>> print(g)
     Model: Gaussian1D
-    Inputs: 1
-    Outputs: 1
+    Inputs: ('x',)
+    Outputs: ('y',)
     Model set size: 1
     Parameters:
         amplitude mean stddev
@@ -144,6 +146,7 @@ background in an image.
 .. plot::
    :include-source:
 
+    import warnings
     import numpy as np
     from astropy.modeling import models, fitting
 
@@ -156,7 +159,11 @@ background in an image.
     # Fit the data using astropy.modeling
     p_init = models.Polynomial2D(degree=2)
     fit_p = fitting.LevMarLSQFitter()
-    p = fit_p(p_init, x, y, z)
+
+    with warnings.catch_warnings():
+        # Ignore model linearity warning from the fitter
+        warnings.simplefilter('ignore')
+        p = fit_p(p_init, x, y, z)
 
     # Plot the data with the best-fit model
     plt.figure(figsize=(8,2.5))
@@ -181,9 +188,9 @@ Model sets
 ----------
 
 In some cases it is necessary to describe many models of the same type but with
-different parameter values.  This could be done simply by instantiating as many
-instances of a `~astropy.modeling.Model` as are needed.  But that can be
-inefficient for a large number of models.  To that end, all model classes in
+different sets of parameter values.  This could be done simply by instantiating
+as many instances of a `~astropy.modeling.Model` as are needed.  But that can
+be inefficient for a large number of models.  To that end, all model classes in
 `astropy.modeling` can also be used to represent a model *set* which is a
 collection of models of the same type, but with different values for their
 parameters.
@@ -197,8 +204,8 @@ the array corresponds to one model in the set::
     ...                       stddev=[0.1, 0.2], n_models=2)
     >>> print(g)
     Model: Gaussian1D
-    Inputs: 1
-    Outputs: 1
+    Inputs: ('x',)
+    Outputs: ('y',)
     Model set size: 2
     Parameters:
         amplitude mean stddev
@@ -237,30 +244,101 @@ response of each pixel in a data cube.  This can greatly speed up the fitting
 process, especially for linear models.
 
 
+.. _compound-models-intro:
+
+Compound models
+---------------
+.. versionadded:: 1.0
+
+    This feature is experimental and expected to see significant further
+    development, but the basic usage is stable and expected to see wide use.
+
+While the Astropy modeling package makes it very easy to define :doc:`new
+models <new>` either from existing functions, or by writing a
+`~astropy.modeling.Model` subclass, an additional way to create new models is
+by combining them using arithmetic expressions.  This works with models built
+into Astropy, and most user-defined models as well.  For example, it is
+possible to create a superposition of two Gaussians like so::
+
+    >>> from astropy.modeling import models
+    >>> g1 = models.Gaussian1D(1, 0, 0.2)
+    >>> g2 = models.Gaussian1D(2.5, 0.5, 0.1)
+    >>> g1_plus_2 = g1 + g2
+
+The resulting object ``g1_plus_2`` is itself a new model.  Evaluating, say,
+``g1_plus_2(0.25)`` is the same as evaluating ``g1(0.25) + g2(0.25)``::
+
+    >>> g1_plus_2(0.25)  # doctest: +FLOAT_CMP
+    0.5676756958301329
+    >>> g1_plus_2(0.25) == g1(0.25) + g2(0.25)
+    True
+
+This model can be further combined with other models in new expressions.  It is
+also possible to define entire new model *classes* using arithmetic expressions
+of other model classes.  This allows general compound models to be created
+without specifying any parameter values up front.  This more advanced usage is
+explained in more detail in the :ref:`compound model documentation
+<compound-model-classes>`.
+
+These new compound models can also be fitted to data, like most other models:
+
+.. plot::
+    :include-source:
+
+    import numpy as np
+    from astropy.modeling import models, fitting
+
+    # Generate fake data
+    np.random.seed(42)
+    g1 = models.Gaussian1D(1, 0, 0.2)
+    g2 = models.Gaussian1D(2.5, 0.5, 0.1)
+    x = np.linspace(-1, 1, 200)
+    y = g1(x) + g2(x) + np.random.normal(0., 0.2, x.shape)
+
+    # Now to fit the data create a new superposition with initial
+    # guesses for the parameters:
+    gg_init = models.Gaussian1D(1, 0, 0.1) + models.Gaussian1D(2, 0.5, 0.1)
+    fitter = fitting.SLSQPLSQFitter()
+    gg_fit = fitter(gg_init, x, y)
+
+    # Plot the data with the best-fit model
+    plt.figure(figsize=(8,5))
+    plt.plot(x, y, 'ko')
+    plt.plot(x, gg_fit(x), 'r-', lw=2)
+    plt.xlabel('Position')
+    plt.ylabel('Flux')
+
+This works for 1-D models, 2-D models, and combinations thereof, though there
+are some complexities involved in correctly matching up the inputs and outputs
+of all models used to build a compound model.  You can learn more details in
+the :doc:`compound-models` documentation.
+
+
 Using `astropy.modeling`
 ========================
 
 .. toctree::
    :maxdepth: 1
 
-   parameters
    models
+   parameters
    fitting
+   compound-models
    new
    algorithms
-   design
 
 
 Reference/API
 =============
 
 .. automodapi:: astropy.modeling
-.. automodapi:: astropy.modeling.fitting
+.. automodapi:: astropy.modeling.mappings
 .. automodapi:: astropy.modeling.functional_models
-.. automodapi:: astropy.modeling.optimizers
 .. automodapi:: astropy.modeling.powerlaws
 .. automodapi:: astropy.modeling.polynomial
 .. automodapi:: astropy.modeling.projections
-.. automodapi:: astropy.modeling.statistic
 .. automodapi:: astropy.modeling.rotations
+.. automodapi:: astropy.modeling.fitting
+.. automodapi:: astropy.modeling.optimizers
+.. automodapi:: astropy.modeling.statistic
 
diff --git a/docs/modeling/models.rst b/docs/modeling/models.rst
index 085c64a..23a0cdd 100644
--- a/docs/modeling/models.rst
+++ b/docs/modeling/models.rst
@@ -1,4 +1,5 @@
 .. include:: links.inc
+.. _modeling-instantiating:
 
 ***********************************
 Instantiating and Evaluating Models
@@ -63,6 +64,7 @@ error::
     with parameter 'stddev' of shape (3,).  All parameter arrays must have
     shapes that are mutually compatible according to the broadcasting rules.
 
+.. _modeling-model-sets:
 
 Model Sets
 ==========
@@ -214,8 +216,8 @@ The examples here assume this import statement was executed::
       ...                 stddev=[0.15, .1], n_models=2)
       >>> print g1
       Model: Gaussian1D
-      Inputs: 1
-      Outputs: 1
+      Inputs: ('x',)
+      Outputs: ('y',)
       Model set size: 2
       Parameters:
           amplitude mean stddev
@@ -270,8 +272,8 @@ The examples here assume this import statement was executed::
       >>> p1.c1 = [0, 1, 2, 3, 4]
       >>> print p1
       Model: Polynomial1D
-      Inputs: 1
-      Outputs: 1
+      Inputs: ('x',)
+      Outputs: ('y',)
       Model set size: 5
       Degree: 1
       Parameters:
diff --git a/docs/modeling/new.rst b/docs/modeling/new.rst
index 9ce916c..2e2dcbd 100644
--- a/docs/modeling/new.rst
+++ b/docs/modeling/new.rst
@@ -1,29 +1,34 @@
+.. _modeling-new-classes:
+
 Defining New Model Classes
 ==========================
 
 This document describes how to add a model to the package or to create a
 user-defined model. In short, one needs to define all model parameters and
-write an eval function which evaluates the model.  If the model is fittable, a
-function to compute the derivatives with respect to parameters is required
-if a linear fitting algorithm is to be used and optional if a non-linear fitter is to be used.
+write a function which evaluates the model, that is, computes the mathematical
+function that implements the model.  If the model is fittable, a function to
+compute the derivatives with respect to parameters is required if a linear
+fitting algorithm is to be used and optional if a non-linear fitter is to be
+used.
 
 
-Custom 1-D models
------------------
+Basic custom models
+-------------------
 
-For 1-D models, the `~astropy.modeling.functional_models.custom_model_1d`
-decorator is provided to make it very easy to define new models. The following
-example demonstrates how to set up a model consisting of two Gaussians:
+For most cases, the `~astropy.modeling.custom_model` decorator provides an
+easy way to make a new `~astropy.modeling.Model` class from an existing Python
+callable. The following example demonstrates how to set up a model consisting
+of two Gaussians:
 
 .. plot::
    :include-source:
 
     import numpy as np
-    from astropy.modeling.models import custom_model_1d
+    from astropy.modeling.models import custom_model
     from astropy.modeling.fitting import LevMarLSQFitter
 
     # Define model
-    @custom_model_1d
+    @custom_model
     def sum_of_gaussians(x, amplitude1=1., mean1=-1., sigma1=1.,
                             amplitude2=1., mean2=1., sigma2=1.):
         return (amplitude1 * np.exp(-0.5 * ((x - mean1) / sigma1)**2) +
@@ -45,17 +50,24 @@ example demonstrates how to set up a model consisting of two Gaussians:
     plt.plot(x, y, 'o', color='k')
     plt.plot(x, m(x), color='r', lw=2)
 
-.. note::
 
-    Currently this shortcut for model definition only works for 1-D models, but
-    it is being expanded to support 2 or greater dimension models.
+This decorator also supports setting a model's
+`~astropy.modeling.FittableModel.fit_deriv` as well as creating models with
+more than one inputs.  It can also be used as a normal factory function (for
+example ``SumOfGaussians = custom_model(sum_of_gaussians)``) rather than as a
+decorator.  See the `~astropy.modeling.custom_model` documentation for more
+examples.
 
 
 A step by step definition of a 1-D Gaussian model
 -------------------------------------------------
 
-The example described in `Custom 1-D models`_ can be used for most 1-D cases,
-but the following section described how to construct model classes in general.
+The example described in `Basic custom models`_ can be used for most simple
+cases, but the following section describes how to construct model classes in
+general.  Defining a full model class may be desirable, for example, to
+provide more specialized parameters, or to implement special functionality not
+supported by the basic `~astropy.modeling.custom_model` factory function.
+
 The details are explained below with a 1-D Gaussian model as an example.  There
 are two base classes for models. If the model is fittable, it should inherit
 from `~astropy.modeling.FittableModel`; if not it should subclass
@@ -68,65 +80,78 @@ include a default value for that parameter, a text description of the parameter
 (useful for `help` and documentation generation), as well default constraints
 and custom getters/setters for the parameter value.
 
-If the first argument ``name`` is specified it must be identical to the class
-attribute being assigned that Parameter.  As such, Parameters take their name
-from this attribute by default.  In other words, ``amplitude =
-Parameter('amplitude')`` is equivalent to ``amplitude = Parameter()``.  This
-differs from Astropy v0.3.x, where it was necessary to provide the name twice.
-
 ::
 
-    from astropy.modeling import FittableModel, Parameter, formt_input
+    from astropy.modeling import FittableModel, Parameter
+
+    class Gaussian1D(FittableModel):
+        inputs = ('x',)
+        outputs = ('y',)
 
-    class Gaussian1DModel(FittableModel):
         amplitude = Parameter()
         mean = Parameter()
         stddev = Parameter()
 
-At a minimum, the ``__init__`` method takes all parameters and a few keyword
-arguments such as values for constraints::
-
-    def __init__(self, amplitude, mean, stddev, **kwargs):
-        # Note that this __init__ does nothing different from the base class's
-        # __init__.  The main point of defining it is so that the function
-        # signature is more informative.
-        super(Gaussian1DModel, self).__init__(
-            amplitude=amplitude, mean=mean, stddev=stddev, **kwargs)
-
-.. note::
-
-    If a parameter is defined with a default value you may make the argument
-    for that parameter in the ``__init__`` optional.  Otherwise it is
-    recommended to make it a required argument.  In the above example none of
-    the parameters have default values.
+The ``inputs`` and ``outputs`` class attributes must be tuples of strings
+indicating the number of independent variables that are input to evaluate the
+model, and the number of outputs it returns.  The labels of the inputs and
+outputs (in this case ``'x'`` and ``'y'`` respectively) are currently used for
+informational purposes only and have no requirements on them other than that
+they do not conflict with parameter names.  Outputs may have the same labels as
+inputs (eg. ``inputs = ('x', 'y')`` and ``outputs = ('x', 'y')``).  However,
+inputs must not conflict with each other (eg. ``inputs = ('x', 'x')`` is
+incorrect) and likewise for outputs.  The lengths of these tuples are
+important for specifying the correct number of inputs and outputs.  These
+attributes supersede the ``n_inputs`` and ``n_outputs`` attributes in older
+versions of this package.
+
+There are two helpful base classes in the modeling package that can be used to
+avoid specifying ``inputs`` and ``outputs`` for most common models.  These are
+`~astropy.modeling.Fittable1DModel` and `~astropy.modeling.Fittable2DModel`.
+For example, the real `~astropy.modeling.functional_models.Gaussian1D` model is
+actually a subclass of `~astropy.modeling.Fittable1DModel`.  This helps cut
+down on boilerplate by not having to specify ``inputs`` and ``outputs`` for
+many models (follow the link to Gaussian1D to see its source code, for
+example).
 
 Fittable models can be linear or nonlinear in a regression sense. The default
 value of the `~astropy.modeling.Model.linear` attribute is ``False``.  Linear
-models should define the ``linear`` class attribute as ``True``.
-The `~astropy.modeling.Model.n_inputs` attribute stores the number of
-input variables the model expects.  The
-`~astropy.modeling.Model.n_outputs` attribute stores the number of output
-variables returned after evaluating the model.  These two attributes are used
-with composite models.
-
-Next, provide methods called ``eval`` to evaluate the model and ``fit_deriv``,
-to compute its derivatives with respect to parameters.  These may be normal
-methods, `classmethod`, or `staticmethod`, though the convention is to use
-`staticmethod` when the function does not depend on any of the object's other
-attributes (i.e., it does not reference ``self``).  The evaluation method takes
-all input coordinates as separate arguments and all of the model's parameters
-in the same order they would be listed by
+models should define the ``linear`` class attribute as ``True``.  Because this
+model is non-linear we can stick with the default.
+
+Next, provide methods called ``evaluate`` to evaluate the model and
+``fit_deriv``, to compute its derivatives with respect to parameters.  These
+may be normal methods, `classmethod`, or `staticmethod`, though the convention
+is to use `staticmethod` when the function does not depend on any of the
+object's other attributes (i.e., it does not reference ``self``) or any of the
+class's other attributes as in the case of `classmethod`.  The evaluation
+method takes all input coordinates as separate arguments and all of the model's
+parameters in the same order they would be listed by
 `~astropy.modeling.Model.param_names`.
 
 For this example::
 
     @staticmethod
-    def eval(x, amplitude, mean, stddev):
+    def evaluate(x, amplitude, mean, stddev):
         return amplitude * np.exp((-(1 / (2. * stddev**2)) * (x - mean)**2))
 
-The ``fit_deriv`` method takes as input all coordinates as separate arguments.
-There is an option to compute numerical derivatives for nonlinear models in
-which case the ``fit_deriv`` method should be ``None``::
+It should be made clear that the ``evaluate`` method must be designed to take
+the model's parameter values as arguments.  This may seem at odds with the fact
+that the parameter values are already available via attribute of the model
+(eg. ``model.amplitude``).  However, passing the parameter values directly to
+``evaluate`` is a more efficient way to use it in many cases, such as fitting.
+
+Users of your model would not generally use ``evaluate`` directly.  Instead
+they create an instance of the model and call it on some input.  The
+``__call__`` method of models uses ``evaluate`` internally, but users do not
+need to be aware of it.  The default ``__call__`` implementation also handles
+details such as checking that the inputs are correctly formatted and follow
+Numpy's broadcasting rules before attempting to evaluate the model.
+
+Like ``evaluate``, the ``fit_deriv`` method takes as input all coordinates and
+all parameter values as arguments.  There is an option to compute numerical
+derivatives for nonlinear models in which case the ``fit_deriv`` method should
+be ``None``::
 
     @staticmethod
     def fit_deriv(x, amplitude, mean, stddev):
@@ -140,91 +165,104 @@ which case the ``fit_deriv`` method should be ``None``::
         return [d_amplitude, d_mean, d_stddev]
 
 
-Finally, the ``__call__`` method takes input coordinates as separate arguments.
-It reformats them (if necessary) using the `~astropy.modeling.format_input`
-wrapper/decorator and calls the eval method to perform the model evaluation
-using the input variables and a special property called
-`~astropy.modeling.Model.param_sets` which returns a list of all the parameter
-values over all models in the set.
-
-The reason there is a separate eval method is to allow fitters to call the eval
-method with different parameters which is necessary for updating the
-approximation while fitting, and for fitting with constraints.::
-
-    @format_input
-    def __call__(self, x):
-        return self.eval(x, *self.param_sets)
+Note that we did *not* have to define an ``__init__`` method or a ``__call__``
+method for our model (this contrasts with Astropy versions 0.4.x and earlier).
+For most models the ``__init__`` follows the same pattern, taking the parameter
+values as positional arguments, followed by several optional keyword arguments
+(constraints, etc.).  The modeling framework automatically generates an
+``__init__`` for your class that has the correct calling signature (see for
+yourself by calling ``help(Gaussian1D.__init__)`` on the example model we just
+defined).
+
+There are cases where it might be desirable to define a custom ``__init__``.
+For example, the `~astropy.modeling.functional_models.Gaussian2D` model takes
+an optional ``cov_matrix`` argument which can be used as an alternative way to
+specify the x/y_stddev and theta parameters.  This is perfectly valid so long
+as the ``__init__`` determines appropriate values for the actual parameters and
+then calls the super ``__init__`` with the standard arguments.  Schematically
+this looks something like:
+
+.. code-block:: python
+
+    def __init__(self, amplitude, x_mean, y_mean, x_stddev=None,
+                 y_stddev=None, theta=None, cov_matrix=None, **kwargs):
+        # The **kwargs here should be understood as other keyword arguments
+        # accepted by the basic Model.__init__ (such as constraints)
+        if cov_matrix is not None:
+            # Set x/y_stddev and theta from the covariance matrix
+            x_stddev = ...
+            y_stddev = ...
+            theta = ...
+
+        # Don't pass on cov_matrix since it doesn't mean anything to the base
+        # class
+        super(Gaussian2D, self).__init__(amplitude, x_mean, y_mean, x_stddev,
+                                         y_stddev, theta, **kwargs)
 
 
 Full example
 ^^^^^^^^^^^^
 
-::
+.. code-block:: python
 
-    from astropy.modeling import FittableModel, Parameter, format_input
+    from astropy.modeling import FittableModel, Parameter
 
-    class Gaussian1DModel(FittableModel):
+    class Gaussian1D(FittableModel):
         amplitude = Parameter()
         mean = Parameter()
         stddev = Parameter()
 
-    def __init__(self, amplitude, mean, stddev, **kwargs):
-        # Note that this __init__ does nothing different from the base class's
-        # __init__.  The main point of defining it is so that the function
-        # signature is more informative.
-        super(Gaussian1DModel, self).__init__(
-            amplitude=amplitude, mean=mean, stddev=stddev, **kwargs)
+        @staticmethod
+        def evaluate(x, amplitude, mean, stddev):
+            return amplitude * np.exp((-(1 / (2. * stddev**2)) * (x - mean)**2))
 
-    @staticmethod
-    def eval(x, amplitude, mean, stddev):
-        return amplitude * np.exp((-(1 / (2. * stddev**2)) * (x - mean)**2))
-
-    @staticmethod
-    def fit_deriv(x, amplitude, mean, stddev):
-        d_amplitude = np.exp((-(1 / (stddev**2)) * (x - mean)**2))
-        d_mean = (2 * amplitude *
-                  np.exp((-(1 / (stddev**2)) * (x - mean)**2)) *
-                  (x - mean) / (stddev**2))
-        d_stddev = (2 * amplitude *
-                    np.exp((-(1 / (stddev**2)) * (x - mean)**2)) *
-                    ((x - mean)**2) / (stddev**3))
-        return [d_amplitude, d_mean, d_stddev]
-
-    @format_input
-    def __call__(self, x):
-        return self.eval(x, *self.param_sets)
+        @staticmethod
+        def fit_deriv(x, amplitude, mean, stddev):
+            d_amplitude = np.exp((-(1 / (stddev**2)) * (x - mean)**2))
+            d_mean = (2 * amplitude *
+                      np.exp((-(1 / (stddev**2)) * (x - mean)**2)) *
+                      (x - mean) / (stddev**2))
+            d_stddev = (2 * amplitude *
+                        np.exp((-(1 / (stddev**2)) * (x - mean)**2)) *
+                        ((x - mean)**2) / (stddev**3))
+            return [d_amplitude, d_mean, d_stddev]
 
 
 A full example of a LineModel
 -----------------------------
 
-::
+This example demonstrates one other optional feature for model classes, which
+is an *inverse*.  An `~astropy.modeling.Model.inverse` implementation should be
+a `property` that returns a new model instance (not necessarily of the same
+class as the model being inverted) that computes the inverse of that model, so
+that for some model instance with an inverse, ``model.inverse(model(*input)) ==
+input``.
+
+.. code-block:: python
 
-    from astropy.modeling import models, Parameter, format_input
+    from astropy.modeling import FittableModel, Parameter
     import numpy as np
 
-    class LineModel(models.PolynomialModel):
+    class LineModel(FittableModel):
         slope = Parameter()
         intercept = Parameter()
         linear = True
 
-    def __init__(self, slope, intercept, **kwargs):
-        super(LineModel, self).__init__(slope=slope, intercept=intercept,
-                                        **kwargs)
+        @staticmethod
+        def evaluate(x, slope, intercept):
+            return slope * x + intercept
 
-    @staticmethod
-    def eval(x, slope, intercept):
-        return slope * x + intercept
-
-    @staticmethod
-    def fit_deriv(x, slope, intercept):
-        d_slope = x
-        d_intercept = np.ones_like(x)
-        return [d_slope, d_intercept]
+        @staticmethod
+        def fit_deriv(x, slope, intercept):
+            d_slope = x
+            d_intercept = np.ones_like(x)
+            return [d_slope, d_intercept]
 
-    @format_input
-    def __call__(self, x):
-        return self.eval(x, *self.param_sets)
+        @property
+        def inverse(self):
+            new_slope = self.slope ** -1
+            new_intercept = -self.intercept / self.slope
+            return LineModel(slope=new_slope, intercept=new_intercept)
 
 
 Defining New Fitter Classes
@@ -264,7 +302,7 @@ squared residuals is used as a measure of fitting.::
 
 The ``__call__`` method performs the fitting. As a minimum it takes all
 coordinates as separate arguments. Additional arguments are passed as
-necessary.::
+necessary::
 
     def __call__(self, model, x, y , maxiter=MAXITER, epsilon=EPS):
         if model.linear:
@@ -288,7 +326,7 @@ This section describes how to write a new fitter with a user-defined statistic
 function.  The example below shows a specialized class which fits a straight
 line with uncertainties in both variables.
 
-The following import statements are needed.::
+The following import statements are needed::
 
     import numpy as np
     from astropy.modeling.fitting import (_validate_model,
@@ -333,7 +371,7 @@ class.::
 In general, to define a new fitter, all one needs to do is provide a statistic
 function and an optimizer. In this example we will let the optimizer be an
 optional argument to the fitter and will set the statistic to ``chi_line``
-above.::
+above::
 
     class LineFitter(Fitter):
         """
@@ -350,7 +388,7 @@ above.::
             super(LineFitter, self).__init__(optimizer,
                                              statistic=self.statistic)
 
-The last thing to define is the ``__call__`` method.::
+The last thing to define is the ``__call__`` method::
 
     def __call__(self, model, x, y, x_sigma=None, y_sigma=None, **kwargs):
         """
diff --git a/docs/modeling/parameters.rst b/docs/modeling/parameters.rst
index 1287756..129af6b 100644
--- a/docs/modeling/parameters.rst
+++ b/docs/modeling/parameters.rst
@@ -45,7 +45,7 @@ Parameter examples
 
       >>> from astropy.modeling import models
       >>> models.Gaussian1D.param_names
-      ['amplitude', 'mean', 'stddev']
+      ('amplitude', 'mean', 'stddev')
 
   The order of the items in the ``param_names`` list is relevant--this
   is the same order in which values for those parameters should be passed in
@@ -74,7 +74,7 @@ Parameter examples
 
       >>> p1 = models.Polynomial1D(degree=3, c0=1.0, c1=0.0, c2=2.0, c3=3.0)
       >>> p1.param_names
-      ['c0', 'c1', 'c2', 'c3']
+      ('c0', 'c1', 'c2', 'c3')
       >>> p1
       <Polynomial1D(3, c0=1.0, c1=0.0, c2=2.0, c3=3.0)>
 
diff --git a/docs/nddata/decorator.rst b/docs/nddata/decorator.rst
new file mode 100644
index 0000000..c79c1a4
--- /dev/null
+++ b/docs/nddata/decorator.rst
@@ -0,0 +1,71 @@
+*********************************************
+Decorating functions to accept NDData objects
+*********************************************
+
+.. important:: The functionality described here is still experimental and will
+               likely evolve over time as more packages make use of it.
+
+Introduction
+============
+
+The `astropy.nddata` module includes a decorator
+:func:`~astropy.nddata.support_nddata` that makes it easy for developers and
+users to write functions that can accept either :class:`~astropy.nddata.NDData`
+objects and also separate arguments.
+
+Getting started
+===============
+
+Let's consider the following function::
+
+    def test(data, wcs=None, unit=None, n_iterations=3):
+        ...
+
+Now let's say that we want to be able to call the function as ``test(nd)``
+where ``nd`` is a :class:`~astropy.nddata.NDData` instance. We can decorate
+this function using :func:`~astropy.nddata.support_nddata`::
+
+    from astropy.nddata import support_nddata
+
+    @support_nddata
+    def test(data, wcs=None, unit=None, n_iterations=3):
+        ...
+
+which makes it so that when the user calls ``test(nd)``, the function would
+automatically be called with::
+
+    test(nd.data, wcs=nd.wcs, unit=nd.unit)
+
+That is, the decorator looks at the signature of the function and checks if any
+of the arguments are also properties of the ``NDData`` object, and passes them
+as individual arguments. The function can also be called with separate
+arguments as if it wasn't decorated.
+
+An exception is raised if an ``NDData`` property is set but the function does
+not accept it - for example, if ``wcs`` is set, but the function cannot support
+WCS objects, an error would be raised. On the other hand, if an argument in the
+function does not exist in the ``NDData`` object or is not set, it is simply
+left to its default value.
+
+If the function call succeeds, then the decorator returns the values from the
+function unmodified by default. However, in some cases we may want to return
+separate ``data``, ``wcs``, etc. if these were passed in separately, and a new
+:class:`~astropy.nddata.NDData` instance otherwise. To do this, you can specify
+``repack=True`` in the decorator and provide a list of the names of the output
+arguments from the function::
+
+    @support_nddata(repack=True, returns=['data', 'wcs'])
+    def test(data, wcs=None, unit=None, n_iterations=3):
+        ...
+
+With this, the function will return separate values if ``test`` is called with
+separate arguments, and an object with the same class type as the input if the
+input is an :class:`~astropy.nddata.NDData` or subclass instance.
+
+Finally, the decorator can be made to restrict input to specific ``NDData``
+sub-classes (and sub-classes of those) using the ``accepts`` option::
+
+    @support_nddata(accepts=CCDImage)
+    def test(data, wcs=None, unit=None, n_iterations=3):
+        ...
+
diff --git a/docs/nddata/index.rst b/docs/nddata/index.rst
index c771144..b8f91d5 100644
--- a/docs/nddata/index.rst
+++ b/docs/nddata/index.rst
@@ -7,18 +7,38 @@ N-dimensional datasets (`astropy.nddata`)
 Introduction
 ============
 
-`astropy.nddata` provides the `~astropy.nddata.NDData`
-class and related tools to manage n-dimensional array-based data (e.g.
-CCD images, IFU data, grid-based simulation data, ...). This is more than
-just `numpy.ndarray` objects, because it provides metadata that cannot
-be easily provided by a single array.
+The `~astropy.nddata` package provides a uniform interface to N-dimensional
+datasets in astropy through:
 
-.. note:: The `~astropy.nddata.NDData` class is still under
-          development, and support for WCS and units is not yet implemented.
++ The `~astropy.nddata.NDDataBase` metaclass to define an astropy-wide
+  interface to N-dimensional data sets while allowing flexibility in
+  how those datasets are represented internally.
++ The `~astropy.nddata.NDData` class, which provides a basic container for
+  gridded N-dimensional datasets.
++ Several mixin classes for adding functionality to `~astropy.nddata.NDData`
+  containers.
++ A decorator, `~astropy.nddata.support_nddata`, for facilitating use of
+  `~astropy.nddata` objects  in functions in astropy and affiliated packages.
+
+.. warning::
+
+  `~astropy.nddata` has changed significantly in astropy 1.0. See the section
+  :ref:`nddata_transition` for more information.
 
 Getting started
 ===============
 
+Of the classes provided by `~astropy.nddata`, the place to start for most
+users will be `~astropy.nddata.NDData`, which by default uses a numpy array to
+store the data. Designers of new classes should also look at
+`~astropy.nddata.NDDataBase` before deciding what to subclass from.
+
+NDData
+------
+
+The primary purpose of `~astropy.nddata.NDData` is to act as a *container* for
+data, metadata, and other related information like a mask.
+
 An `~astropy.nddata.NDData` object can be instantiated by passing it an
 n-dimensional Numpy array::
 
@@ -27,14 +47,12 @@ n-dimensional Numpy array::
     >>> array = np.zeros((12, 12, 12))  # a 3-dimensional array with all zeros
     >>> ndd = NDData(array)
 
-This object has a few attributes in common with Numpy:
+or something that can be converted to an array::
 
-    >>> ndd.ndim
-    3
-    >>> ndd.shape
-    (12, 12, 12)
-    >>> ndd.dtype
-    dtype('float64')
+    >>> ndd2 = NDData([1, 2, 3, 4])
+
+It is also possible to initialize `~astropy.nddata.NDData` with more exotic
+objects; see :ref:`nddata_details` for more information.
 
 The underlying Numpy array can be accessed via the ``data`` attribute::
 
@@ -42,18 +60,101 @@ The underlying Numpy array can be accessed via the ``data`` attribute::
     array([[[ 0., 0., 0., ...
     ...
 
-Values can be masked using the ``mask`` attribute, which should be a boolean
-Numpy array with the same dimensions as the data, e.g.::
+Values can be masked using the ``mask`` attribute::
 
-     >>> ndd.mask = ndd.data > 0.9
+     >>> ndd_masked = NDData(ndd, mask = ndd.data > 0.9)
+     INFO: Overwriting NDData's current mask with specified mask [astropy.nddata.nddata]
 
 A mask value of `True` indicates a value that should be ignored, while a mask
 value of `False` indicates a valid value.
 
-Similarly, attributes are available to store generic meta-data, flags, and
-uncertainties, and the `~astropy.nddata.NDData` class includes methods to
-combine datasets with arithmetic operations (which include uncertainties propagation).
-These are described in :doc:`nddata`.
+
+Similar attributes are available to store:
+
++ generic meta-data, in ``meta``,
++ a unit for the data values, in ``unit`` and
++ an uncertainty for the data values, in ``uncertainty``. Note that the
+  ``uncertainty`` must have a string attribute called ``uncertainty_type``.
+
+Note that a `~astropy.nddata.NDData` object is not sliceable::
+
+    >>> ndd2[1:3]        # doctest: +SKIP
+    Traceback (most recent call last):
+        ...
+    TypeError: 'NDData' object has no attribute '__getitem__'
+
+
+
+Mixins for additional functionality
+-----------------------------------
+
+Several classes are provided to add functionality to the basic ``NDData``
+container. They include:
+
++ `~astropy.nddata.NDSlicingMixin` to handle slicing of N-dimensional data.
++ `~astropy.nddata.NDArithmeticMixin` to allow arithmetic operations on
+  `~astropy.nddata.NDData` objects that include support propagation of
+  uncertainties (in limited cases).
++ `~astropy.nddata.NDIOMixin` to use existing astropy functionality for input
+  (with the method ``read``) and output (with the method ``write``).
+
+To use these mixins, create a new class that includes the appropriate mixins
+as subclasses. For example, to make a class that includes slicing, but not
+arithmetic or I/O::
+
+    >>> from astropy.nddata import NDData, NDSlicingMixin
+    >>> class NDDataSliceable(NDSlicingMixin, NDData): pass
+
+Note that the body of the class need not contain any code; all of the
+functionality is provided by the ``NDData`` container and the mixins. The
+order of the classes is important because python works from right to left in
+determining the order in which methods are resolved.
+
+``NDDataSliceable`` is initialized the same way that `~astropy.nddata.NDData` is::
+
+    >>> ndd_sliceable = NDDataSliceable([1, 2, 3, 4])
+
+but can be sliced::
+
+    >>> ndd_sliceable[1:3]
+    NDDataSliceable([2, 3])
+
+The class `~astropy.nddata.NDDataArray` is an example of a class which
+utilizes mixins *and* adds functionality.
+
+NDDataBase for making new subclasses
+------------------------------------
+
+`~astropy.nddata.NDDataBase` is a metaclass provided to support the creation
+of objects that support the NDData interface but need the freedom to define
+their own ways of storing data, unit, metadata and/or other properties. It
+should be used instead of `~astropy.nddata.NDData` as the starting point for
+any class for which the `~astropy.nddata.NDData` class is too restrictive.
+
+.. _nddata_transition:
+
+Transition to astropy 1.0
+=========================
+
+The nddata package underwent substantial revision as a result of `APE 7`_;
+please see that APE for an extensive discussion of the motivation and the
+changes.
+
+The most important changes are that:
+
++ ``NDData`` does not provide a numpy-like interface; to use its data use the
+  ``data`` attribute instead.
++ Slicing is no provided in the base `~astropy.nddata.NDData`.
++ Arithmetic is no longer included in the base `~astropy.nddata.NDData` class.
+
+Code that only uses the metadata features of `~astropy.nddata.NDData` should
+not need to be modified.
+
+Code that uses the arithemtic methods that used to be included in
+`~astropy.nddata.NDData` and relied on it to behave like a numpy array should
+instead subclass `~astropy.nddata.NDDataArray`; that class is equivalent to
+the original `~astropy.nddata.NDData` class.
+
 
 Using ``nddata``
 ================
@@ -62,6 +163,8 @@ Using ``nddata``
    :maxdepth: 2
 
    nddata.rst
+   decorator.rst
+   mixins/index.rst
    subclassing.rst
 
 Reference/API
@@ -69,3 +172,8 @@ Reference/API
 
 .. automodapi:: astropy.nddata
     :no-inheritance-diagram:
+
+.. automodapi:: astropy.nddata.utils
+    :no-inheritance-diagram:
+
+.. _APE 7: https://github.com/astropy/astropy-APEs/blob/master/APE7.rst
diff --git a/docs/nddata/mixins/index.rst b/docs/nddata/mixins/index.rst
new file mode 100644
index 0000000..27e4ef3
--- /dev/null
+++ b/docs/nddata/mixins/index.rst
@@ -0,0 +1,9 @@
+Mixins for added functionality
+==============================
+
+.. toctree::
+    :maxdepth: 2
+
+    ndslicing.rst
+    ndarithmetic.rst
+    ndio.rst
diff --git a/docs/nddata/mixins/ndarithmetic.rst b/docs/nddata/mixins/ndarithmetic.rst
new file mode 100644
index 0000000..46042e5
--- /dev/null
+++ b/docs/nddata/mixins/ndarithmetic.rst
@@ -0,0 +1,49 @@
+Arithmetic mixin
+================
+
+Overview
+--------
+
+The `~astropy.nddata.NDArithmeticMixin` adds methods for performing basic
+operations on `~astropy.nddata.NDData` objects:
+:meth:`~astropy.nddata.NDArithmeticMixin.add`,
+:meth:`~astropy.nddata.NDArithmeticMixin.subtract`,
+:meth:`~astropy.nddata.NDArithmeticMixin.multiply` and
+:meth:`~astropy.nddata.NDArithmeticMixin.divide`.
+
+The operations are permitted only if the two operands have the same WCS and
+shape and the units, if any, consistent with the operation performed.  The
+result is masked at a particular grid point if either of the operands is
+masked at that point.
+
+The operations include a framework to propagate uncertainties that are based
+on the classes `~astropy.nddata.NDUncertainty`.
+
+.. warning:: Uncertainty propagation is still experimental, and does not take
+             into account correlated uncertainties.
+
+Usage
+-----
+
+As with other mixins, using the arithmetic mixin starts with defining your own
+class::
+
+    >>> from astropy.nddata import NDData, NDArithmeticMixin
+    >>> class MyNDDataArithmetic(NDArithmeticMixin, NDData): pass
+
+Then, create instances of this new object with your data the way you would
+with a plain `~astropy.nddata.NDData` object::
+
+    >>> ndd1 = MyNDDataArithmetic([1, 2])
+    >>> ndd2 = MyNDDataArithmetic([3, 4])
+
+The mixin adds methods on these instances for combining them::
+
+    >>> ndd1.add(ndd2)
+    MyNDDataArithmetic([ 4.,  6.])
+    >>> ndd2.multiply(ndd1)
+    MyNDDataArithmetic([ 3.,  8.])
+
+One important note: the order you list the mixins and `~astropy.nddata.NDData`
+matters; the base   class, `~astropy.nddata.NDData` should be on the far
+right.
diff --git a/docs/nddata/mixins/ndio.rst b/docs/nddata/mixins/ndio.rst
new file mode 100644
index 0000000..4863d59
--- /dev/null
+++ b/docs/nddata/mixins/ndio.rst
@@ -0,0 +1,11 @@
+I/O mixin
+=========
+
+The I/O mixin, `~astropy.nddata.NDIOMixin`, adds ``read`` and ``write``
+methods that us the astropy I/O registry.
+
+The mixin itself simply creates the read/write methods; it does not register
+any readers or writers with the I/O registry. Subclasses of
+`~astropy.nddata.NDDataBase` or `~astropy.nddata.NDData` need to include this
+mixin, implement a reader and writer, *and* register it with the I/O
+framework. See :ref:`io_registry` for details.
diff --git a/docs/nddata/mixins/ndslicing.rst b/docs/nddata/mixins/ndslicing.rst
new file mode 100644
index 0000000..d1ed830
--- /dev/null
+++ b/docs/nddata/mixins/ndslicing.rst
@@ -0,0 +1,22 @@
+Slicing mixin
+=============
+
+The slicing mixin adds the ability to index an `~astropy.nddata.NDData` object
+in a manner similar to a numpy array. Slicing returns a new
+`~astropy.nddata.NDData` object with the shape indicated by the slice.
+
+The first step in creating an `~astropy.nddata.NDData`-based object with
+slicing is to create a new class::
+
+    >>> from astropy.nddata import NDData, NDSlicingMixin
+    >>> class MyNDDataWithSlicing(NDSlicingMixin, NDData): pass
+
+Then, initialize the new object the same way you would initialize a plain
+`~astropy.nddata.NDData` object::
+
+    >>> sliceable_ndd = MyNDDataWithSlicing([1, 2, 3, 4])
+    >>> sliceable_ndd[1:3]
+    MyNDDataWithSlicing([2, 3])
+
+One important note: the order you list the mixins and `~astropy.nddata.NDData`
+matters; the base class, `~astropy.nddata.NDData` should be on the far right.
diff --git a/docs/nddata/nddata.rst b/docs/nddata/nddata.rst
index 278f081..b31b977 100644
--- a/docs/nddata/nddata.rst
+++ b/docs/nddata/nddata.rst
@@ -1,5 +1,25 @@
-NDData overview
-===============
+.. _nddata_details:
+
+NDData
+======
+
+Overview
+--------
+
+The `~astropy.nddata.NDData` class is a container for gridded N-dimensional
+data. It has a ``data`` attribute, which can be any object that presents an
+array-like interface, and optional attributes:
+
++  ``meta``, for metadata
++ ``unit`` for the ``data`` unit
++ ``uncertainty`` for the uncertainty of the data (which could be standard
+  deviation,variance, or something else),
++ ``mask`` for the ``data``
++ ``wcs``, representing the relationship  between ``data`` and world
+  coordinates.
+
+Of these, only ``mask`` and  ``uncertainty`` may be changed after the NDData
+object is created.
 
 Initializing
 ------------
@@ -25,108 +45,91 @@ An `~astropy.nddata.NDData` object can also be instantiated by passing it an
 As above, the data in``ndd2`` is a reference to the data in ``ndd1``, so
 changes to one will affect the other.
 
-This object has a few attributes in common with Numpy:
+It can also be instantiated by passing in an object that can be converted to a
+numpy numerical array::
 
-    >>> ndd.ndim
-    3
-    >>> ndd.shape
-    (12, 12, 12)
-    >>> ndd.dtype
-    dtype('float64')
+    >>> ndd3 = NDData([1, 2, 3, 4])
 
-The underlying Numpy array can be accessed via the ``data`` attribute::
+The final way to instantiate an `~astropy.nddata.NDData` object is with a data
+object that presents a numpy array-like interface. If the object passed to the
+intializer has all three of the attributes ``shape``, ``__getitem__`` (so it
+is indexable) and ``__array__`` (so that it can act like a numpy array in
+expression) then the ``data`` attribute will be set to that object.
 
-    >>> ndd.data
-    array([[[ 0.,  0.,  0., ...
+The purpose of this mechanism is to allow considerable flexibility in the
+objects used to store the data while providing a useful to default (numpy
+array).
 
 Mask
 ----
 
-Values can be masked using the ``mask`` attribute, which should be a boolean
-Numpy array with the same dimensions as the data, e.g.::
+Values can be masked using the ``mask`` attribute.  One straightforward way to
+provide a mask is to use a boolean numpy array::
+
+     >>> ndd_masked = NDData(ndd, mask = ndd.data > 0.9)
+     INFO: Overwriting NDData's current mask with specified mask [astropy.nddata.nddata]
 
-     >>> ndd.mask = ndd.data > 0.9
+Another is to simply initialize an `~astropy.nddata.NDData` object  with a
+masked numpy array::
+
+    >>> masked_array = np.ma.array([1, 2, 3, 4], mask=[1, 0, 0, 1])
+    >>> ndd_masked = NDData(masked_array)
+    >>> ndd_masked.mask
+    array([ True, False, False,  True], dtype=bool)
 
 A mask value of `True` indicates a value that should be ignored, while a mask
 value of `False` indicates a valid value.
 
-Flags
------
-
-Values can be assigned one or more flags. The ``flags`` attribute is used to
-store either a single Numpy array (of any type) with dimensions matching that
-of the data, or a `~astropy.nddata.FlagCollection`, which is
-essentially a dictionary of Numpy arrays (of any type) with the same shape as
-the data. The following example demonstrates setting a single set of integer
-flags::
+There is no requirement that the mask actually be a numpy array; for example,
+a function which evaluates a mask value as needed is acceptable as long as it
+follows the convention that `True` indicates a value that should be ignored.
 
-    >>> ndd.flags = np.zeros(ndd.shape)
-    >>> ndd.flags[ndd.data < 0.1] = 1
-    >>> ndd.flags[ndd.data < 0.01] = 2
+Unit
+----
 
-but one can also have multiple flag layers with different types::
+The unit of the data can be set by either explicitly providing an astropy unit
+when creating the ``NDData`` object::
 
-    >>> from astropy.nddata import FlagCollection
-    >>> ndd.flags = FlagCollection(shape=(12, 12, 12))
-    >>> ndd.flags['photometry'] = np.zeros(ndd.shape, dtype=str)
-    >>> ndd.flags['photometry'][ndd.data > 0.9] = 's'
-    >>> ndd.flags['cosmic_rays'] = np.zeros(ndd.shape, dtype=int)
-    >>> ndd.flags['cosmic_rays'][ndd.data > 0.99] = 99
+    >>> import astropy.units as u
+    >>> ndd_unit = NDData([1, 2, 3, 4], unit="meter")
+    >>> ndd_unit.unit
+    Unit("m")
 
-and flags can easily be used to set the mask::
+or by initializing with data that is an astropy `~astropy.units.Quantity`::
 
-    >>> ndd.mask = ndd.flags['cosmic_rays'] == 99
+    >>> q = [1, 2, 3, 4] * u.meter
+    >>> ndd_unit2 = NDData(q)
+    >>> ndd_unit2.unit
+    Unit("m")
 
 Uncertainties
 -------------
 
 `~astropy.nddata.NDData` objects have an ``uncertainty`` attribute that can be
-used to set the uncertainty on the data values. This is done by using classes
-to represent the uncertainties of a given type. For example, to set standard
-deviation uncertainties on the pixel values, you can do::
-
-    >>> from astropy.nddata import StdDevUncertainty
-    >>> ndd.uncertainty = StdDevUncertainty(np.ones((12, 12, 12)) * 0.1)
-
-.. note:: For information on creating your own uncertainty classes,
-          see :doc:`subclassing`.
-
-Arithmetic
-----------
+used to set the uncertainty on the data values. The ``uncertainty`` must have
+an attribute ``uncertainty_type`` which is a string.
 
-Provided that the world coordinate system (WCS) and shape match, and that the
-units are consistent, two :class:`~astropy.nddata.NDData` instances can be
-added, subtracted, multiplied or divided from each other, with uncertainty
-propagation, creating a new :class:`~astropy.nddata.NDData` object::
+While not a requirement, the following ``uncertainty_type`` strings
+are strongly recommended for common ways of specifying normal
+distributions:
 
-    ndd3 = ndd1.add(ndd2)
-    ndd4 = ndd1.subtract(ndd2)
-    ndd5 = ndd1.multiply(ndd2)
-    ndd6 = ndd1.divide(ndd2)
++ ``"std"``: if ``uncertainty`` stores the standard deviation/sigma
+  (either a single value or on a per-pixel basis).
++ ``"var"``: if ``uncertainty`` stores the variance (either a single
+  value or on a per-pixel basis).
++ ``"ivar"``: if ``uncertainty`` stores the inverse variance (either a
+  single value or on a per-pixel basis).
 
-The purpose of the :meth:`~astropy.nddata.nddata.NDData.add`,
-:meth:`~astropy.nddata.nddata.NDData.subtract`,
-:meth:`~astropy.nddata.nddata.NDData.multiply` and
-:meth:`~astropy.nddata.nddata.NDData.divide` methods is to allow the
-combination of two data objects that have common WCS and shape and units
-consistent with the operation performed, with consistent behavior for masks,
-and with a framework to propagate uncertainties. Currently any flags on the
-operands are dropped so that the result of the operation always has no flags.
-These methods are intended for use by sub-classes and functions that deal with
-more complex combinations.
 
-Entries that are masked in either of the operands are also masked in the
-result.
-
-.. warning:: Uncertainty propagation is still experimental, and does not take
-             into account correlated uncertainties.
+.. note:: For information on creating your own uncertainty classes,
+          see :doc:`subclassing`.
 
 Meta-data
 ---------
 
-The :class:`~astropy.nddata.NDData` class includes a ``meta`` attribute
-that defaults to an empty dictionary, and can be used to set overall meta-data
-for the dataset::
+The :class:`~astropy.nddata.NDData` class includes a ``meta`` attribute that
+defaults to an empty ordered dictionary, and can be used to set overall meta-
+data for the dataset::
 
     ndd.meta['exposure_time'] = 340.
     ndd.meta['filter'] = 'J'
@@ -135,24 +138,36 @@ Elements of the meta-data dictionary can be set to any valid Python object::
 
     ndd.meta['history'] = ['calibrated', 'aligned', 'flat-fielded']
 
+The metadata can be any python object that presents a dict-like interface. For
+example, a FITS header can be used as the metadata::
+
+    >>> from astropy.io import fits
+    >>> header = fits.Header()
+    >>> header['observer'] = 'Edwin Hubble'
+    >>> ndd = NDData(np.zeros([10, 10]), meta=header)
+    >>> ndd.meta['observer']
+    'Edwin Hubble'
+
+WCS
+---
+
+At the moment the ``wcs`` attribute can be set to any object, though in the
+future it may be restricted to an `~astropy.wcs.WCS` object once a generalized
+WCS object is developed.
+
 Converting to Numpy arrays
 --------------------------
 
-`~astropy.nddata.NDData` objects can also be easily converted to
-numpy arrays::
+Data should be accessed through the ``data`` attribute::
 
-    >>> import numpy as np
-    >>> arr = np.array(ndd)
-    >>> np.all(arr == mydataarray)  # doctest: +SKIP
-    True
+    >>> array = np.asarray(ndd.data)
 
-If a ``mask`` is defined, this will result in a `~numpy.ma.MaskedArray`, so
-in all cases a useable `numpy.ndarray` or subclass will result. This allows
-straightforward plotting of `~astropy.nddata.NDData` objects with 1-
-and 2-dimensional datasets using Matplotlib::
+Though using ``np.asarray`` is not required it will ensure that an additional
+copy of the data is not made if the data is a numpy array.
 
-    >>> from matplotlib import pyplot as plt  # doctest: +SKIP
-    >>> plt.plot(ndd)  # doctest: +SKIP
+Note that if the data is masked you must explicitly construct a numpy masked
+array like this::
 
-This works because the Matplotlib plotting functions automatically convert
-their inputs using `numpy.array`.
+    >>> input_array = np.ma.array([1, 2, 3, 4], mask=[1, 0, 0, 1])
+    >>> ndd_masked = NDData(input_array)
+    >>> masked_array = np.ma.array(ndd_masked.data, mask=ndd_masked.mask)
diff --git a/docs/nddata/subclassing.rst b/docs/nddata/subclassing.rst
index 2360aa2..060e448 100644
--- a/docs/nddata/subclassing.rst
+++ b/docs/nddata/subclassing.rst
@@ -1,8 +1,51 @@
-Subclassing `~astropy.nddata.NDData` and `~astropy.nddata.NDUncertainty`
-=======================================================================================
+Subclassing
+===========
+
+There are a couple of choices to be made in subclassing from the nddata
+package. For the greatest flexibility, subclass from
+`~astropy.nddata.NDDataBase`, which places (almost) no restrictions on any of
+its attributes. In many cases, subclassing `~astropy.nddata.NDData` will work
+instead; it is more straightforward but places some minimal restrictions on
+how the data can be represented.
+
+`~astropy.nddata.NDDataBase`
+----------------------------
+
+The class `~astropy.nddata.NDDataBase` is a metaclass -- when subclassing it,
+all properties of `~astropy.nddata.NDDataBase` except ``uncertainty`` *must*
+be overriden in the subclass. For an example of how to do this, see the source
+code for `astropy.nddata.NDData`.
+
+Subclassing from `~astropy.nddata.NDDataBase` gives you complete flexibility
+in how you implement data storage and the other properties. If your data is
+stored in a numpy array (or something that behaves like a numpy array), it may
+be more straightforward to subclass `~astropy.nddata.NDData` instead of
+`~astropy.nddata.NDDataBase`.
+
+`~astropy.nddata.NDData`
+------------------------
+
+This class serves as the base for subclasses that use a numpy array (or
+something that presents a numpy-like interface) as the ``data`` attribute.
+
+For an example of a class that includes mixins and subclasses
+`~astropy.nddata.NDData` to add additional functionality, see
+`~astropy.nddata.NDDataArray`.
 
 Subclassing `~astropy.nddata.NDUncertainty`
----------------------------------------------------
+-------------------------------------------
+
+This is done by using classes to represent the uncertainties of a given type.
+For example, to set standard deviation uncertainties on the pixel values, you
+can do::
+
+    >>> import numpy as np
+    >>> from astropy.nddata import NDData, StdDevUncertainty
+    >>> array = np.zeros((12, 12, 12))  # a 3-dimensional array with all zeros
+    >>> ndd = NDData(array)
+    >>> uncertainty = StdDevUncertainty(np.ones((12, 12, 12)) * 0.1)
+    >>> ndd_uncertainty = NDData(ndd, uncertainty=uncertainty)
+    INFO: Overwriting NDData's current uncertainty being overwritten with specified uncertainty [astropy.nddata.nddata]
 
 New error classes should sub-class from `~astropy.nddata.NDUncertainty`, and
 should provide methods with the following API::
@@ -51,7 +94,7 @@ variables with more explicit names, e.g::
            right_uncertainty = other_nddata.uncertainty.array
 
            ...
-           
+
 Note that the above example assumes that the errors are stored in an ``array``
 attribute, but this does not have to be the case.
 
diff --git a/docs/nitpick-exceptions b/docs/nitpick-exceptions
index fb300c5..a7acba1 100644
--- a/docs/nitpick-exceptions
+++ b/docs/nitpick-exceptions
@@ -42,6 +42,8 @@ py:class numpy.ma.core.MaskedArray
 py:class numpy.core.records.recarray
 py:class xmlrpclib.Fault
 py:class xmlrpclib.Error
+py:class xmlrpc.client.Fault
+py:class xmlrpc.client.Error
 
 # Pending on python docs links issue #11975
 py:class list
@@ -52,4 +54,5 @@ py:obj list.extend
 py:obj list.index
 py:obj list.insert
 py:meth list.pop
-py:obj list.remove
\ No newline at end of file
+py:obj list.remove
+py:class classmethod
diff --git a/docs/rtd-pip-requirements b/docs/rtd-pip-requirements
index bfd058a..1d066a7 100644
--- a/docs/rtd-pip-requirements
+++ b/docs/rtd-pip-requirements
@@ -1,4 +1,4 @@
 -e git+http://github.com/astropy/astropy-helpers.git#egg=astropy_helpers
-numpy>=1.5.0
+numpy>=1.6.0
 matplotlib
 Cython
diff --git a/docs/stability.rst b/docs/stability.rst
index 7909132..e34bc75 100644
--- a/docs/stability.rst
+++ b/docs/stability.rst
@@ -62,6 +62,17 @@ The current planned and existing sub-packages are:
         </tr>
         <tr>
             <td>
+                astropy.analytic_functions
+            </td>
+            <td align='center'>
+                <img alt="dev" src="_images/dev.png">
+            </td>
+            <td>
+                New in v1.0.
+            </td>
+        </tr>
+        <tr>
+            <td>
                 astropy.constants
             </td>
             <td align='center'>
@@ -242,6 +253,17 @@ The current planned and existing sub-packages are:
         </tr>
         <tr>
             <td>
+                astropy.visualization
+            </td>
+            <td align='center'>
+                <img alt="dev" src="_images/dev.png">
+            </td>
+            <td>
+                New in v1.0, and in development.
+            </td>
+        </tr>
+        <tr>
+            <td>
                 astropy.vo
             </td>
             <td align='center'>
diff --git a/docs/table/access_table.rst b/docs/table/access_table.rst
index 4051739..3904fb9 100644
--- a/docs/table/access_table.rst
+++ b/docs/table/access_table.rst
@@ -48,6 +48,14 @@ the data contained in that object relate to the original table data
   t[np.array([1, 3, 4])]  # Table object with rows 1, 3, 4 (copy)
   t['a', 'c']  # Table with cols 'a', 'c' (copy)
   dat = np.array(t)  # Copy table data to numpy structured array object
+  t['a'].quantity  # an astropy.units.Quantity for Column 'a'
+  t['a'].to('km')  # an astropy.units.Quantity for Column 'a' in units of kilometers
+
+.. Note::
+   Although they appear nearly equivalent, there is a factor of two performance
+   difference between ``t[1]['a']`` (slower, because an intermediate |Row|
+   object gets created) versus ``t['a'][1]`` (faster).  Always use the latter
+   when possible.
 
 **Print table or column**
 ::
@@ -76,12 +84,12 @@ For all the following examples it is assumed that the table has been created as
   >>> from astropy.table import Table, Column
   >>> import numpy as np
 
-  >>> arr = np.arange(15).reshape(5, 3)
+  >>> arr = np.arange(15, dtype=np.int32).reshape(5, 3)
   >>> t = Table(arr, names=('a', 'b', 'c'), meta={'keywords': {'key1': 'val1'}})
   >>> t['a'].format = "%6.3f"  # print as a float with 3 digits after decimal point
   >>> t['a'].unit = 'm sec^-1'
   >>> t['a'].description = 'unladen swallow velocity'
-  >>> print t
+  >>> print(t)
        a      b   c
     m sec^-1
     -------- --- ---
@@ -115,23 +123,29 @@ meta-data is simply an ordered dictionary (OrderedDict_) by default.
 Accessing data
 """"""""""""""
 
-As expected one can access a table column by name and get an element from that
+As expected you can access a table column by name and get an element from that
 column with a numerical index::
 
   >>> t['a']  # Column 'a'
-  <Column name='a' unit='m sec^-1' format='%6.3f' description='unladen swallow velocity'>
-  array([ 0,  3,  6,  9, 12])
+  <Column name='a' dtype='int32' unit='m sec^-1' format='%6.3f' description='unladen swallow velocity' length=5>
+   0.000
+   3.000
+   6.000
+   9.000
+  12.000
+
 
   >>> t['a'][1]  # Row 1 of column 'a'
   3
 
-When a table column is printed, either with ``print`` or via the ``str()``
-built-in function, it is formatted according to the ``format`` attribute (see
-:ref:`table_format_string`)::
+When a table column is printed, it is formatted according to the ``format``
+attribute (see :ref:`table_format_string`).  Note the difference between the
+column representation above and how it appears via ``print()`` or ``str()``::
 
   >>> print(t['a'])
-      a
-    ------
+     a
+  m sec^-1
+  --------
      0.000
      3.000
      6.000
@@ -162,15 +176,20 @@ meta-data and column definitions are copied.
 ::
 
   >>> t[2:5]  # Table object with rows 2:5 (reference)
-  <Table rows=3 names=('a','b','c') units=('m sec^-1',None,None)>
-  array([(6, 7, 8), (9, 10, 11), (12, 13, 14)],
-        dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])
+  <Table masked=False length=3>
+     a       b     c
+  m sec^-1
+   int32   int32 int32
+  -------- ----- -----
+     6.000     7     8
+     9.000    10    11
+    12.000    13    14
 
 It is possible to select table rows with an array of indexes or by specifying
 multiple column names.  This returns a copy of the original table for the
 selected rows or columns.  ::
 
-  >>> print t[[1, 3, 4]]  # Table object with rows 1, 3, 4 (copy)
+  >>> print(t[[1, 3, 4]])  # Table object with rows 1, 3, 4 (copy)
        a      b   c
     m sec^-1
     -------- --- ---
@@ -179,7 +198,7 @@ selected rows or columns.  ::
       12.000  13  14
 
 
-  >>> print t[np.array([1, 3, 4])]  # Table object with rows 1, 3, 4 (copy)
+  >>> print(t[np.array([1, 3, 4])])  # Table object with rows 1, 3, 4 (copy)
        a      b   c
     m sec^-1
     -------- --- ---
@@ -188,8 +207,8 @@ selected rows or columns.  ::
       12.000  13  14
 
 
-  >>> print t['a', 'c']  # or t[['a', 'c']] or t[('a', 'c')]
-  ...                    # Table with cols 'a', 'c' (copy)
+  >>> print(t['a', 'c'])  # or t[['a', 'c']] or t[('a', 'c')]
+  ...                     # Table with cols 'a', 'c' (copy)
        a      c
     m sec^-1
     -------- ---
@@ -199,7 +218,7 @@ selected rows or columns.  ::
        9.000  11
       12.000  14
 
-Finally, one can access the underlying table data as a native `numpy`
+Finally, you can access the underlying table data as a native `numpy`
 structured array by creating a copy or reference with ``np.array``::
 
   >>> data = np.array(t)  # copy of data in t as a structured array
@@ -234,27 +253,32 @@ too large then rows and/or columns are cut from the middle so it fits.  For exam
 
   >>> arr = np.arange(3000).reshape(100, 30)  # 100 rows x 30 columns array
   >>> t = Table(arr)
-  >>> print t
-  col0 col1 col2 col3 col4 col5 col6 ... col24 col25 col26 col27 col28 col29
-  ---- ---- ---- ---- ---- ---- ---- ... ----- ----- ----- ----- ----- -----
-     0    1    2    3    4    5    6 ...    24    25    26    27    28    29
-    30   31   32   33   34   35   36 ...    54    55    56    57    58    59
-    60   61   62   63   64   65   66 ...    84    85    86    87    88    89
-    90   91   92   93   94   95   96 ...   114   115   116   117   118   119
-   120  121  122  123  124  125  126 ...   144   145   146   147   148   149
-   150  151  152  153  154  155  156 ...   174   175   176   177   178   179
-   180  181  182  183  184  185  186 ...   204   205   206   207   208   209
-   210  211  212  213  214  215  216 ...   234   235   236   237   238   239
-   240  241  242  243  244  245  246 ...   264   265   266   267   268   269
-   ...  ...  ...  ...  ...  ...  ... ...   ...   ...   ...   ...   ...   ...
-  2760 2761 2762 2763 2764 2765 2766 ...  2784  2785  2786  2787  2788  2789
-  2790 2791 2792 2793 2794 2795 2796 ...  2814  2815  2816  2817  2818  2819
-  2820 2821 2822 2823 2824 2825 2826 ...  2844  2845  2846  2847  2848  2849
-  2850 2851 2852 2853 2854 2855 2856 ...  2874  2875  2876  2877  2878  2879
-  2880 2881 2882 2883 2884 2885 2886 ...  2904  2905  2906  2907  2908  2909
-  2910 2911 2912 2913 2914 2915 2916 ...  2934  2935  2936  2937  2938  2939
-  2940 2941 2942 2943 2944 2945 2946 ...  2964  2965  2966  2967  2968  2969
-  2970 2971 2972 2973 2974 2975 2976 ...  2994  2995  2996  2997  2998  2999
+  >>> print(t)
+  col0 col1 col2 col3 col4 col5 col6 ... col23 col24 col25 col26 col27 col28 col29
+  ---- ---- ---- ---- ---- ---- ---- ... ----- ----- ----- ----- ----- ----- -----
+     0    1    2    3    4    5    6 ...    23    24    25    26    27    28    29
+    30   31   32   33   34   35   36 ...    53    54    55    56    57    58    59
+    60   61   62   63   64   65   66 ...    83    84    85    86    87    88    89
+    90   91   92   93   94   95   96 ...   113   114   115   116   117   118   119
+   120  121  122  123  124  125  126 ...   143   144   145   146   147   148   149
+   150  151  152  153  154  155  156 ...   173   174   175   176   177   178   179
+   180  181  182  183  184  185  186 ...   203   204   205   206   207   208   209
+   210  211  212  213  214  215  216 ...   233   234   235   236   237   238   239
+   240  241  242  243  244  245  246 ...   263   264   265   266   267   268   269
+   270  271  272  273  274  275  276 ...   293   294   295   296   297   298   299
+   ...  ...  ...  ...  ...  ...  ... ...   ...   ...   ...   ...   ...   ...   ...
+  2670 2671 2672 2673 2674 2675 2676 ...  2693  2694  2695  2696  2697  2698  2699
+  2700 2701 2702 2703 2704 2705 2706 ...  2723  2724  2725  2726  2727  2728  2729
+  2730 2731 2732 2733 2734 2735 2736 ...  2753  2754  2755  2756  2757  2758  2759
+  2760 2761 2762 2763 2764 2765 2766 ...  2783  2784  2785  2786  2787  2788  2789
+  2790 2791 2792 2793 2794 2795 2796 ...  2813  2814  2815  2816  2817  2818  2819
+  2820 2821 2822 2823 2824 2825 2826 ...  2843  2844  2845  2846  2847  2848  2849
+  2850 2851 2852 2853 2854 2855 2856 ...  2873  2874  2875  2876  2877  2878  2879
+  2880 2881 2882 2883 2884 2885 2886 ...  2903  2904  2905  2906  2907  2908  2909
+  2910 2911 2912 2913 2914 2915 2916 ...  2933  2934  2935  2936  2937  2938  2939
+  2940 2941 2942 2943 2944 2945 2946 ...  2963  2964  2965  2966  2967  2968  2969
+  2970 2971 2972 2973 2974 2975 2976 ...  2993  2994  2995  2996  2997  2998  2999
+  Length = 100 rows
 
 more() method
 '''''''''''''
@@ -292,59 +316,48 @@ meaning as shown below::
   >>> t['col29'].unit = 'kg sec m**-2'
 
   >>> t.pprint(max_lines=8, max_width=40)
-        col0     ...    col29
-        km2      ... kg sec m**-2
-    ------------ ... ------------
-    0.000000e+00 ...         29.0
-    3.000000e+01 ...         59.0
-             ... ...          ...
-    2.940000e+03 ...       2969.0
-    2.970000e+03 ...       2999.0
-
+      col0     ...    col29
+      km2      ... kg sec m**-2
+  ------------ ... ------------
+  0.000000e+00 ...         29.0
+           ... ...          ...
+  2.940000e+03 ...       2969.0
+  2.970000e+03 ...       2999.0
+  Length = 100 rows
 
   >>> t.pprint(max_lines=8, max_width=40, show_unit=True)
       col0     ...    col29
       km2      ... kg sec m**-2
   ------------ ... ------------
   0.000000e+00 ...         29.0
-  3.000000e+01 ...         59.0
            ... ...          ...
   2.940000e+03 ...       2969.0
   2.970000e+03 ...       2999.0
+  Length = 100 rows
 
   >>> t.pprint(max_lines=8, max_width=40, show_name=False)
-        km2      ... kg sec m**-2
-    ------------ ... ------------
-    0.000000e+00 ...         29.0
-    3.000000e+01 ...         59.0
-    6.000000e+01 ...         89.0
-             ... ...          ...
-    2.940000e+03 ...       2969.0
-    2.970000e+03 ...       2999.0
+      km2      ... kg sec m**-2
+  ------------ ... ------------
+  0.000000e+00 ...         29.0
+  3.000000e+01 ...         59.0
+           ... ...          ...
+  2.940000e+03 ...       2969.0
+  2.970000e+03 ...       2999.0
+  Length = 100 rows
 
 In order to force printing all values regardless of the output length or width
 set ``max_lines`` or ``max_width`` to ``-1``, respectively.  For the wide
-table in this example one sees 6 lines of wrapped output like the following::
-
-  >>> t.pprint(max_lines=6, max_width=-1)  # doctest: +SKIP
-      col0         col1     col2   col3   col4   col5   col6   col7   col8   col
-  9  col10  col11  col12  col13  col14  col15  col16  col17  col18  col19  col20
-    col21  col22  col23  col24  col25  col26  col27  col28  col29
-  ------------ ----------- ------ ------ ------ ------ ------ ------ ------ ----
-  -- ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ -----
-  - ------ ------ ------ ------ ------ ------ ------ ------ ------
-  0.000000e+00    1.000000    2.0    3.0    4.0    5.0    6.0    7.0    8.0    9
-  .0   10.0   11.0   12.0   13.0   14.0   15.0   16.0   17.0   18.0   19.0   20.
-  0   21.0   22.0   23.0   24.0   25.0   26.0   27.0   28.0   29.0
-  3.000000e+01   31.000000   32.0   33.0   34.0   35.0   36.0   37.0   38.0   39
-  .0   40.0   41.0   42.0   43.0   44.0   45.0   46.0   47.0   48.0   49.0   50.
-  0   51.0   52.0   53.0   54.0   55.0   56.0   57.0   58.0   59.0
-           ...         ...    ...    ...    ...    ...    ...    ...    ...    .
-  ..    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ..
-  .    ...    ...    ...    ...    ...    ...    ...    ...    ...
-  2.970000e+03 2971.000000 2972.0 2973.0 2974.0 2975.0 2976.0 2977.0 2978.0 2979
-  .0 2980.0 2981.0 2982.0 2983.0 2984.0 2985.0 2986.0 2987.0 2988.0 2989.0 2990.
-  0 2991.0 2992.0 2993.0 2994.0 2995.0 2996.0 2997.0 2998.0 2999.0
+table in this example you see 6 lines of wrapped output like the following::
+
+  >>> t.pprint(max_lines=8, max_width=-1)  # doctest: +SKIP
+      col0         col1     col2   col3   col4   col5   col6   col7   col8   col9  col10  col11  col12  col13  col14  col15  col16  col17  col18  col19  col20  col21  col22  col23  col24  col25  col26  col27  col28     col29
+      km2                                                                                                                                                                                                               kg sec m**-2
+  ------------ ----------- ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------------
+  0.000000e+00    1.000000    2.0    3.0    4.0    5.0    6.0    7.0    8.0    9.0   10.0   11.0   12.0   13.0   14.0   15.0   16.0   17.0   18.0   19.0   20.0   21.0   22.0   23.0   24.0   25.0   26.0   27.0   28.0         29.0
+           ...         ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...          ...
+  2.940000e+03 2941.000000 2942.0 2943.0 2944.0 2945.0 2946.0 2947.0 2948.0 2949.0 2950.0 2951.0 2952.0 2953.0 2954.0 2955.0 2956.0 2957.0 2958.0 2959.0 2960.0 2961.0 2962.0 2963.0 2964.0 2965.0 2966.0 2967.0 2968.0       2969.0
+  2.970000e+03 2971.000000 2972.0 2973.0 2974.0 2975.0 2976.0 2977.0 2978.0 2979.0 2980.0 2981.0 2982.0 2983.0 2984.0 2985.0 2986.0 2987.0 2988.0 2989.0 2990.0 2991.0 2992.0 2993.0 2994.0 2995.0 2996.0 2997.0 2998.0       2999.0
+  Length = 100 rows
 
 For columns the syntax and behavior of
 :func:`~astropy.table.Column.pprint` is the same except that there is no
@@ -355,10 +368,10 @@ For columns the syntax and behavior of
   ------
      3.0
     33.0
-    63.0
      ...
   2943.0
   2973.0
+  Length = 100 rows
 
 pformat() method
 ''''''''''''''''
@@ -370,8 +383,6 @@ the Table :meth:`~astropy.table.Table.pformat` or Column
 :meth:`~astropy.table.Table.pprint` output.
 
   >>> lines = t['col3'].pformat(max_lines=8)
-  >>> lines
-  [' col3 ', '------', '   3.0', '  33.0', '  63.0', '   ...', '2943.0', '2973.0']
 
 Multidimensional columns
 ''''''''''''''''''''''''
@@ -405,11 +416,83 @@ In order to see all the data values for a multidimensional column use the
 column representation.  This uses the standard `numpy` mechanism for printing
 any array::
 
-  >>> t['a']
-  <Column name='a' unit=None format=None description=None>
+  >>> t['a'].data
   array([[[ 1,  2],
           [10, 20]],
          [[ 3,  4],
           [30, 40]],
          [[ 5,  6],
           [50, 60]]])
+
+Columns and Quantities
+''''''''''''''''''''''
+Columns with units that the `astropy.units` package understands can be
+converted explicitly to ``~astropy.units.Quantity`` objects via the
+:attr:`~astropy.table.Column.quantity` property and the
+:meth:`~astropy.table.Column.to` method::
+
+  >>> from astropy.table import Table
+  >>> from astropy import units as u
+  >>> data = [[1., 2., 3.],[40000., 50000., 60000.]]
+  >>> t = Table(data, names=('a', 'b'))
+  >>> t['a'].unit = u.m
+  >>> t['b'].unit = 'km/s'
+  >>> t['a'].quantity
+  <Quantity [ 1., 2., 3.] m>
+  >>> t['b'].to(u.kpc/u.Myr)  # doctest: +FLOAT_CMP
+  <Quantity [ 40.9084866 , 51.13560825, 61.3627299 ] kpc / Myr>
+
+Note that the :attr:`~astropy.table.Column.quantity` property is actually
+a *view* of the data in the column, not a copy.  Hence, you can set the
+values of a column in a way that respects units by making in-place
+changes to the :attr:`~astropy.table.Column.quantity` property::
+
+  >>> t['b']
+  <Column name='b' dtype='float64' unit='km / s' length=3>
+  40000.0
+  50000.0
+  60000.0
+
+  >>> t['b'].quantity[0] = 45000000*u.m/u.s
+  >>> t['b']
+  <Column name='b' dtype='float64' unit='km / s' length=3>
+  45000.0
+  50000.0
+  60000.0
+
+Even without explicit conversion, columns with units can be treated like
+like an Astropy `~astropy.units.Quantity` in *some* arithmetic
+expressions (see the warning below for caveats to this)::
+
+  >>> t['a'] + .005*u.km
+  <Quantity [ 6., 7., 8.] m>
+  >>> from astropy.constants import c
+  >>> (t['b'] / c).decompose()  # doctest: +FLOAT_CMP
+  <Quantity [ 0.15010384, 0.16678205, 0.20013846]>
+
+.. warning::
+
+  Table columns do *not* always behave the same as
+  `~astropy.units.Quantity`. Table columns act more like regular numpy
+  arrays unless either explicitly converted to a
+  `~astropy.units.Quantity` or combined with an
+  `~astropy.units.Quantity` using an arithmetic operator.For example,
+  the following does not work the way you would expect::
+
+    >>> import numpy as np
+    >>> from astropy.table import Table
+    >>> data = [[30, 90]]
+    >>> t = Table(data, names=('angle',))
+    >>> t['angle'].unit = 'deg'
+    >>> np.sin(t['angle'])  # doctest: +FLOAT_CMP
+    <Column name='angle' dtype='float64' unit='deg' length=2>
+    -0.988031624093
+     0.893996663601
+
+  This is wrong both in that it says the unit is degrees, *and* ``sin``
+  treated the values and radians rather than degrees.  If at all in
+  doubt that you'll get the right result, the safest choice is to
+  explicitly convert to `~astropy.units.Quantity`::
+
+    >>> np.sin(t['angle'].quantity)  # doctest: +FLOAT_CMP
+    <Quantity [ 0.5, 1. ]>
diff --git a/docs/table/construct_table.rst b/docs/table/construct_table.rst
index 4d8025f..0cfa14d 100644
--- a/docs/table/construct_table.rst
+++ b/docs/table/construct_table.rst
@@ -60,14 +60,18 @@ keyword or they will be auto-generated as ``col<N>``.
 
 ::
 
-  >>> a = [1, 4]
+  >>> a = np.array([1, 4], dtype=np.int32)
   >>> b = [2.0, 5.0]
   >>> c = ['x', 'y']
   >>> t = Table([a, b, c], names=('a', 'b', 'c'))
   >>> t
-  <Table rows=2 names=('a','b','c')>
-  array([(1, 2.0, 'x'), (4, 5.0, 'y')],
-        dtype=[('a', '<i8'), ('b', '<f8'), ('c', 'S1')])
+  <Table masked=False length=2>
+    a      b       c
+  int32 float64 string8
+  ----- ------- -------
+      1     2.0       x
+      4     5.0       y
+
 
 **Make a new table using columns from the first table**
 
@@ -75,9 +79,12 @@ Once you have a |Table| then you can make new table by selecting columns
 and putting this into a Python list, e.g. ``[ t['c'], t['a'] ]``::
 
   >>> Table([t['c'], t['a']])
-  <Table rows=2 names=('c','a')>
-  array([('x', 1), ('y', 4)],
-        dtype=[('c', 'S1'), ('a', '<i8')])
+  <Table masked=False length=2>
+     c      a
+  string8 int32
+  ------- -----
+        x     1
+        y     4
 
 **Make a new table using expressions involving columns**
 
@@ -86,9 +93,12 @@ directly in arithmetic expressions.  This allows for a compact way of making a
 new table with modified column values::
 
   >>> Table([t['a']**2, t['b'] + 10])
-  <Table rows=2 names=('a','b')>
-  array([(1, 12.0), (16, 15.0)],
-        dtype=[('a', '<i8'), ('b', '<f8')])
+  <Table masked=False length=2>
+    a      b
+  int32 float64
+  ----- -------
+      1    12.0
+     16    15.0
 
 
 **Different types of column data**
@@ -100,10 +110,13 @@ of different data types to initialize a table::
   >>> b = np.array([[2, 3], [5, 6]])  # vector column
   >>> c = Column(['x', 'y'], name='axis')
   >>> arr = (a, b, c)
-  >>> Table(arr)  # Data column named "c" has a name "axis" that table
-  <Table rows=2 names=('col0','col1','axis')>
-  array([(1, [2, 3], 'x'), (4, [5, 6], 'y')],
-        dtype=[('col0', '<i8'), ('col1', '<i8', (2,)), ('axis', 'S1')])
+  >>> Table(arr)  # doctest: +SKIP
+  <Table masked=False length=2>
+   col0 col1 [2]   axis
+  int64  int64   string8
+  ----- -------- -------
+      1   2 .. 3       x
+      4   5 .. 6       y
 
 Notice that in the third column the existing column name ``'axis'`` is used.
 
@@ -112,22 +125,28 @@ Dict of columns
 """"""""""""""""
 A dictionary of column data can be used to initialize a |Table|.
 
-  >>> arr = {'a': [1, 4],
+  >>> arr = {'a': np.array([1, 4], dtype=np.int32),
   ...        'b': [2.0, 5.0],
   ...        'c': ['x', 'y']}
   >>>
   >>> Table(arr)  # doctest: +SKIP
-  <Table rows=2 names=('a','c','b')>
-  array([(1, 'x', 2.0), (4, 'y', 5.0)],
-        dtype=[('a', '<i8'), ('c', 'S1'), ('b', '<f8')])
+  <Table masked=False length=2>
+    a      c       b
+  int32 string8 float64
+  ----- ------- -------
+      1       x     2.0
+      4       y     5.0
 
 **Specify the column order and optionally the data types**
 ::
 
-  >>> Table(arr, names=('a', 'b', 'c'), dtype=('f4', 'i4', 'S2'))
-  <Table rows=2 names=('a','b','c')>
-  array([(1.0, 2, 'x'), (4.0, 5, 'y')],
-        dtype=[('a', '<f4'), ('b', '<i4'), ('c', 'S2')])
+  >>> Table(arr, names=('a', 'b', 'c'), dtype=('f8', 'i4', 'S2'))
+  <Table masked=False length=2>
+     a      b      c
+  float64 int32 string16
+  ------- ----- --------
+      1.0     2        x
+      4.0     5        y
 
 **Different types of column data**
 
@@ -136,10 +155,13 @@ The input column data can be any data type that can initialize a |Column| object
   >>> arr = {'a': (1, 4),
   ...        'b': np.array([[2, 3], [5, 6]]),
   ...        'c': Column(['x', 'y'], name='axis')}
-  >>> Table(arr, names=('a', 'b', 'c'))
-  <Table rows=2 names=('a','b','c')>
-  array([(1, [2, 3], 'x'), (4, [5, 6], 'y')],
-        dtype=[('a', '<i8'), ('b', '<i8', (2,)), ('c', 'S1')])
+  >>> Table(arr, names=('a', 'b', 'c'))  # doctest: +SKIP
+  <Table masked=False length=2>
+    a   b [2]     c
+  int64 int64  string8
+  ----- ------ -------
+      1 2 .. 3       x
+      4 5 .. 6       y
 
 Notice that the key ``'c'`` takes precedence over the existing column name
 ``'axis'`` in the third column.  Also see that the ``'b'`` column is a vector
@@ -185,10 +207,13 @@ list of dict objects.  The keys determine the column names::
 
   >>> data = [{'a': 5, 'b': 10},
   ...         {'a': 15, 'b': 20}]
-  >>> Table(rows=data)
-  <Table rows=2 names=('a','b')>
-  array([(5, 10), (15, 20)],
-        dtype=[('a', '<i8'), ('b', '<i8')])
+  >>> Table(rows=data)  # doctest: +SKIP
+  <Table masked=False length=2>
+    a     b
+  int64 int64
+  ----- -----
+      5    10
+     15    20
 
 Every row must have the same set of keys or a ValueError will be thrown::
 
@@ -232,14 +257,17 @@ created using::
 
   >>> arr = np.array([(1, 2.0, 'x'),
   ...                 (4, 5.0, 'y')],
-  ...                dtype=[('a', 'i8'), ('b', 'f8'), ('c', 'S2')])
+  ...                dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'S2')])
 
 From ``arr`` it is simple to create the corresponding |Table| object::
 
   >>> Table(arr)
-  <Table rows=2 names=('a','b','c')>
-  array([(1, 2.0, 'x'), (4, 5.0, 'y')],
-        dtype=[('a', '<i8'), ('b', '<f8'), ('c', 'S2')])
+  <Table masked=False length=2>
+    a      b       c
+  int32 float64 string16
+  ----- ------- --------
+      1     2.0        x
+      4     5.0        y
 
 Note that in the above example and most the following ones we are creating a
 table and immediately asking the interactive Python interpreter to print the
@@ -258,24 +286,32 @@ The column names can be changed from the original values by providing the
 ``names`` argument::
 
   >>> Table(arr, names=('a_new', 'b_new', 'c_new'))
-  <Table rows=2 names=('a_new','b_new','c_new')>
-  array([(1, 2.0, 'x'), (4, 5.0, 'y')],
-        dtype=[('a_new', '<i8'), ('b_new', '<f8'), ('c_new', 'S2')])
+  <Table masked=False length=2>
+  a_new  b_new   c_new
+  int32 float64 string16
+  ----- ------- --------
+      1     2.0        x
+      4     5.0        y
 
 **New data types**
 
 Likewise the data type for each column can by changed with ``dtype``::
 
   >>> Table(arr, dtype=('f4', 'i4', 'S4'))
-  <Table rows=2 names=('a','b','c')>
-  array([(1.0, 2, 'x'), (4.0, 5, 'y')],
-        dtype=[('a', '<f4'), ('b', '<i4'), ('c', 'S4')])
+  <Table masked=False length=2>
+     a      b      c
+  float32 int32 string32
+  ------- ----- --------
+      1.0     2        x
+      4.0     5        y
 
   >>> Table(arr, names=('a_new', 'b_new', 'c_new'), dtype=('f4', 'i4', 'S4'))
-  <Table rows=2 names=('a_new','b_new','c_new')>
-  array([(1.0, 2, 'x'), (4.0, 5, 'y')],
-        dtype=[('a_new', '<f4'), ('b_new', '<i4'), ('c_new', 'S4')])
-
+  <Table masked=False length=2>
+   a_new  b_new  c_new
+  float32 int32 string32
+  ------- ----- --------
+      1.0     2        x
+      4.0     5        y
 
 
 NumPy homogeneous array
@@ -289,19 +325,25 @@ generated as ``col<N>`` where ``<N>`` is the column number.
 ::
 
   >>> arr = np.array([[1, 2, 3],
-  ...                 [4, 5, 6]])
+  ...                 [4, 5, 6]], dtype=np.int32)
   >>> Table(arr)
-  <Table rows=2 names=('col0','col1','col2')>
-  array([(1, 2, 3), (4, 5, 6)],
-        dtype=[('col0', '<i8'), ('col1', '<i8'), ('col2', '<i8')])
+  <Table masked=False length=2>
+   col0  col1  col2
+  int32 int32 int32
+  ----- ----- -----
+      1     2     3
+      4     5     6
 
 **Column names and types specified**
 ::
 
   >>> Table(arr, names=('a_new', 'b_new', 'c_new'), dtype=('f4', 'i4', 'S4'))
-  <Table rows=2 names=('a_new','b_new','c_new')>
-  array([(1.0, 2, '3'), (4.0, 5, '6')],
-        dtype=[('a_new', '<f4'), ('b_new', '<i4'), ('c_new', 'S4')])
+  <Table masked=False length=2>
+   a_new  b_new  c_new
+  float32 int32 string32
+  ------- ----- --------
+      1.0     2        3
+      4.0     5        6
 
 **Referencing the original data**
 
@@ -321,15 +363,18 @@ homogeneous `numpy` array input is interpreted as a list of rows::
   ...        [4, 5, 6]]
   >>> np_arr = np.array(arr)
 
-  >>> Table(arr)    # Two columns, three rows
-  <Table rows=3 names=('col0','col1')>
-  array([(1, 4), (2, 5), (3, 6)],
-        dtype=[('col0', '<i8'), ('col1', '<i8')])
+  >>> print(Table(arr))    # Two columns, three rows
+  col0 col1
+  ---- ----
+     1    4
+     2    5
+     3    6
 
-  >>> Table(np_arr)  # Three columns, two rows
-  <Table rows=2 names=('col0','col1','col2')>
-  array([(1, 2, 3), (4, 5, 6)],
-        dtype=[('col0', '<i8'), ('col1', '<i8'), ('col2', '<i8')])
+  >>> print(Table(np_arr))  # Three columns, two rows
+  col0 col1 col2
+  ---- ---- ----
+     1    2    3
+     4    5    6
 
 This dichotomy is needed to support flexible list input while retaining the
 natural interpretation of 2-d `numpy` arrays where the first index corresponds
@@ -341,25 +386,27 @@ A new table can be created by selecting a subset of columns in an existing
 table::
 
   >>> t = Table(names=('a', 'b', 'c'))
-  >>> t2 = t['c', 'b', 'a']  # Makes a copy of the data
-  >>> print t2
-   c   b   a
-  --- --- ---
+  >>> t['c', 'b', 'a']  # Makes a copy of the data
+  <Table masked=False length=0>
+     c       b       a
+  float64 float64 float64
+  ------- ------- -------
 
 An alternate way to use the ``columns`` attribute (explained in the
 `TableColumns`_ section) to initialize a new table.  This let's you choose
 columns by their numerical index or name and supports slicing syntax::
 
   >>> Table(t.columns[0:2])
-  <Table rows=0 names=('a','b')>
-  array([],
-        dtype=[('a', '<f8'), ('b', '<f8')])
+  <Table masked=False length=0>
+     a       b
+  float64 float64
+  ------- -------
 
   >>> Table([t.columns[0], t.columns['c']])
-  <Table rows=0 names=('a','c')>
-  array([],
-        dtype=[('a', '<f8'), ('c', '<f8')])
-
+  <Table masked=False length=0>
+     a       c
+  float64 float64
+  ------- -------
 
 Initialization Details
 ^^^^^^^^^^^^^^^^^^^^^^
@@ -523,19 +570,9 @@ occurs::
     ...
   ValueError: Cannot specify dtype when copy=False
 
-Another caveat in using referenced data is that you cannot add new row to the
-table.  This generates an error because of conflict between the two references
-to the same underlying memory.  Internally, adding a row may involve moving
-the data to a new memory location which would corrupt the input data object.
-`numpy` does not allow this::
-
-  >>> t.add_row([1, 2, 3])
-  Traceback (most recent call last):
-    File "<stdin>", line 1, in <module>
-    File "astropy/table/table.py", line 760, in add_row
-      self._data.resize((newlen,), refcheck=False)
-  ValueError: cannot resize this array: it does not own its data
-
+Another caveat in using referenced data is that you if add a new row to the
+table then the reference to the original data array is lost and instead the
+table will now hold a copy of the original values (in addition to the new row).
 
 Column and TableColumns classes
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -717,13 +754,10 @@ So now look at the ways to select columns from a |TableColumns| object:
 ::
 
   >>> t.columns[1]  # Choose columns by index
-  <Column name='b' unit=None format=None description=None>
-  array([], dtype=float64)
+  <Column name='b' dtype='float64' length=0>
 
   >>> t.columns['b']  # Choose column by name
-  <Column name='b' unit=None format=None description=None>
-  array([], dtype=float64)
-
+  <Column name='b' dtype='float64' length=0>
 
 .. _subclassing_table:
 
@@ -778,13 +812,13 @@ are contained in a numpy object-dtype column named ``params``::
   ...    """
   ...    def __getitem__(self, item):
   ...        if item not in self.colnames:
-  ...            return self.data['params'][item]
+  ...            return super(ParamsRow, self).__getitem__('params')[item]
   ...        else:
-  ...            return self.data[item]
+  ...            return super(ParamsRow, self).__getitem__(item)
   ...
   ...    def keys(self):
   ...        out = [name for name in self.colnames if name != 'params']
-  ...        params = [key.lower() for key in sorted(self.data['params'])]
+  ...        params = [key.lower() for key in sorted(self['params'])]
   ...        return out + params
   ...
   ...    def values(self):
diff --git a/docs/table/implementation_change_1.0.rst b/docs/table/implementation_change_1.0.rst
new file mode 100644
index 0000000..65a1055
--- /dev/null
+++ b/docs/table/implementation_change_1.0.rst
@@ -0,0 +1,188 @@
+.. include:: references.txt
+
+.. |table_before| image:: table_before_1.0.png
+   :width: 45%
+
+.. |table_after| image:: table_after_1.0.png
+   :width: 45%
+
+.. |column_before| image:: table_column_before_1.0.png
+   :width: 45%
+
+.. |column_after| image:: table_column_after_1.0.png
+   :width: 45%
+
+.. |row_before| image:: table_row_before_1.0.png
+   :width: 73%
+
+.. |row_after| image:: table_row_after_1.0.png
+   :width: 83%
+
+
+.. _table_implementation_change:
+
+Table implementation change in 1.0
+----------------------------------
+
+This page discusses the change in the internal implementation of the |Table|
+class which took place starting from version 1.0 of astropy.  The motivation
+for making this change is discussed in the `Benefits`_ section.
+
+Architecture
+^^^^^^^^^^^^^^
+
+Data container
+""""""""""""""
+
+The images below illustrate the basic architecture of the |Table| class for
+astropy versions 0.4.x and earlier (left) and after version 1.0 (right).
+
+On the left side (before 1.0) the fundamental data container is a numpy
+structured array referenced as an internal attribute ``_data``.  All public
+methods and operations (e.g. column access, row indexing) are done via this
+internal `~numpy.ndarray` object.  The ``columns`` attribute is used to manage
+table columns and provide access.  It is a |TableColumns| object which is
+essentially an ordered dictionary of |Column| or |MaskedColumn| objects which
+provide views of the ``_data`` array.
+
+On the right side (after 1.0) the fundamental data container is now the
+collection of individual column objects and there is no longer a structured
+array associated with the table.  Each |Column| object is the sole owner of its
+data.  As before, the ``columns`` attribute is used to manage columns and
+provide access.
+
+|table_before| |table_after|
+
+Columns
+""""""""
+
+For versions before 1.0 the |Column| object is an `~numpy.ndarray` subclass with
+a *memory view* of the corresponding column in the ``_data`` array.  This means
+that the physical memory for the |Column| object data is exactly the same as
+the memory storing the ``_data`` array. Therefore updating an element in the
+column results in the corresponding update in the ``_data`` value.  This model
+is convenient in many ways, but also has drawbacks.  In particular, astropy
+tables are easily mutable (e.g. you can add or remove columns) while numpy
+structured arrays are not.  This means that key operations require
+regenerating the entire ``_data`` structured array and likewise regenerating
+all the |Column| view objects.  This is relatively slow and results in
+additional code complexity to always ensure correspondence.
+
+Starting with version 1.0 the |Column| object is the same `~numpy.ndarray`
+subclass but it is sole owner of the data.  This simplifies table management
+considerably along with making operations like adding or removing columns
+*much* faster because there is no structured array to regenerate.
+
+|column_before| |column_after|
+
+Rows
+"""""
+
+A |Row| object corresponds to a single row in the table.  For versions before
+1.0, when a |Row| object is requested it uses numpy indexing into the table
+``_data`` array to generate a ``numpy.void`` or ``numpy.ma.mvoid`` object as the
+``data`` attribute [#]_.  This delegates most of the row access functionality like
+``row['a']`` to the numpy void classes. For unmasked tables this ``data``
+attribute is a memory view of the parent table row, though for masked tables
+(due to the implementation of numpy masked arrays), the ``data`` attribute is
+*not* a view.
+
+|row_before|
+
+For version 1.0 and later, the |Row| object does not create a view of the full
+row at any point.  Instead it manages access (like ``row['a']``) dynamically in
+a way that maintains the same interface.  Due to improved implementation this
+is actually faster.
+
+The row ``data`` attribute is part of the public API before 1.0, therefore it
+is still available in 1.0 but as a *deprecated* property.  In this case
+accessing ``data`` runs the `~astropy.table.Row.as_void()` method to dynamically
+create and return a ``numpy.void`` or ``numpy.ma.mvoid`` object.  This provides a
+copy of the original data, not a view.  Code which was relying on the row
+``data`` attribute as a *view* into the parent table will need to be modified.
+
+|row_after|
+
+.. [#] ``numpy.void`` is a ``dtype`` that can be used to represent structures
+         of arbitrary byte width.
+
+Differences
+^^^^^^^^^^^
+
+``Row.data``
+""""""""""""
+
+The ``data`` property of the |Row| object is deprecated in version 1.0 and
+may be removed in a later version.  Code which requires access to a
+``numpy.void`` or ``numpy.ma.mvoid`` object corresponding to a table row
+can now use the `~astropy.table.Row.as_void()` method.  This is public and
+stable, with the caveat that it is relatively slow and returns a copy of the
+row data, not a view.
+
+``Table._data``
+"""""""""""""""
+
+While the ``_data`` property of the |Table| object is not part of the public
+API in any astropy release, some users may have let this creep into their
+code as back-door access to the numpy object.  In version 1.0 this attribute is
+formally deprecated and will generate a warning.
+
+From 1.0 the public method for getting the corresponding numpy structured array
+or masked array version of a table is the |Table| method
+`~astropy.table.Table.as_array()`.  This dynamically generates the requested
+object, making a copy of the table data.  Be aware that the ``_data`` property
+calls `~astropy.table.Table.as_array()`, so accessing ``_data`` will
+effectively double the memory usage of the table.
+
+An alternative is to use `~numpy.array` to do the conversion, e.g. for an
+astropy |Table| object named ``dat`` use ``np_dat = np.array(dat)``.  Be aware that
+for a masked table this operation always returns a pure `~numpy.ndarray`
+with data corresponding to the unmasked values.
+
+High-level operations
+"""""""""""""""""""""
+
+In version 1.0 the operations described in :ref:`table_operations` rely on
+`~astropy.table.Table.as_array()` to create numpy structured arrays which
+are used in the actual array manipulations.  This creates temporary copies of
+the tables.
+
+Performance regressions
+"""""""""""""""""""""""
+
+From version 1.0 most common operations run at the same speed or are faster
+(sometimes significantly faster).  The only operations which are noticeably
+slower are adding a row in a masked table (~2 times slower) and setting a
+column like ``dat['a'][:] = 10`` in a masked table (~6 times slower).
+
+
+Benefits
+^^^^^^^^
+
+The key benefits of the version 1.0 change are as follows:
+
+- Allows for much faster addition or removal of columns.  A common idiom is
+  creating a table and then adding columns::
+
+    >>> from astropy.table import Table
+    >>> import numpy as np
+    >>> t = Table()
+    >>> t['a'] = np.arange(100)
+    >>> t['b'] = np.random.uniform(size=100)
+    >>> t['c'] = t['a'] + t['b']
+
+  Prior to 1.0 this idiom was extremely inefficient because the underlying
+  structured array was being entirely regenerated with each column addition.
+  From 1.0 forward this is fast and a good way to write code.
+
+- Provides the infrastructure to allow for Tables to easily hold column types
+  beyond just |Column| and |MaskedColumn|.  This includes
+  `~astropy.units.Quantity`, `~astropy.time.Time`, and
+  `~astropy.coordinates.SkyCoord` objects.  Other ideas like nested |Table|
+  objects are also possible.
+
+- Generally faster because of improved implementation in key areas.
+  Column-based access is faster because the column data are held in contiguous
+  memory instead of being strided within the numpy structure array.
+
+- Reduces code complexity in a number of core table routines.
diff --git a/docs/table/implementation_details.rst b/docs/table/implementation_details.rst
new file mode 100644
index 0000000..98694b6
--- /dev/null
+++ b/docs/table/implementation_details.rst
@@ -0,0 +1,47 @@
+.. include:: references.txt
+
+.. |column_after| image:: table_column_after_1.0.png
+   :width: 45%
+
+
+
+.. _table_implementation_details:
+
+Table implementation details
+-----------------------------
+
+This page provides a brief overview of the |Table| class implementation, in
+particular highlighting the internal data storage architecture.  This is aimed
+at developers and/or users who are interested in optimal use of the |Table|
+class.  Note that this applies to astropy version 1.0 and later.  For
+differences between version 1.0 and 0.4.x see the
+:ref:`table_implementation_change` page.
+
+The image below illustrates the basic architecture of the |Table| class.
+The fundamental data container is an ordered dictionary of individual column
+objects maintained as the ``columns`` attribute.  It is via this container
+that columns are managed and accessed.
+
+.. image:: table_architecture.png
+   :width: 45%
+
+Each |Column| (or |MaskedColumn|) object is an `~numpy.ndarray` subclass and is
+the sole owner of its data.  Maintaining the table as separate columns
+simplifies table management considerably.  It also makes operations like adding
+or removing columns much faster in comparison to implementations using a numpy
+structured array container.
+
+As shown below, a |Row| object corresponds to a single row in the table.  The
+|Row| object does not create a view of the full row at any point.  Instead it
+manages access (e.g. ``row['a']``) dynamically by referencing the appropriate
+elements of the parent table.
+
+.. image:: table_row.png
+   :width: 83%
+
+In some cases it is desirable to have a static copy of the full row.  This is
+available via the `~astropy.table.Row.as_void()` method, which creates and
+returns a ``numpy.void`` or ``numpy.ma.mvoid`` object with a copy of the
+original data.  For backward compatibility the row ``data`` attribute is
+available but as a *deprecated* property.
+
diff --git a/docs/table/index.rst b/docs/table/index.rst
index 3632bc6..7b26fad 100644
--- a/docs/table/index.rst
+++ b/docs/table/index.rst
@@ -30,6 +30,18 @@ Currently `astropy.table` is used when reading an ASCII table using
 `astropy.io.ascii`.  Future releases of AstroPy are expected to use
 the |Table| class for other subpackages such as `astropy.io.votable` and `astropy.io.fits` .
 
+.. Note::
+
+   Starting with version 1.0 of astropy the internal implementation of the
+   |Table| class changed so that it no longer uses numpy structured arrays as
+   the core table data container.  Instead the table is stored as a collection
+   of individual column objects.  *For most users there is NO CHANGE to the
+   interface and behavior of |Table| objects.*
+
+   The page on :ref:`table_implementation_change` provides details about the
+   change.  This includes discussion of the table architecture, key differences,
+   and benefits of the change.
+
 Getting Started
 ===============
 
@@ -48,29 +60,47 @@ and ``c``.  These columns have integer, float, and string values respectively::
   >>> t = Table([a, b, c], names=('a', 'b', 'c'), meta={'name': 'first table'})
 
 If you have row-oriented input data such as a list of records, use the ``rows``
-keyword::
+keyword.  In this example we also explicitly set the data types for each column::
 
   >>> data_rows = [(1, 2.0, 'x'),
   ...              (4, 5.0, 'y'),
   ...              (5, 8.2, 'z')]
-  >>> t = Table(rows=data_rows, names=('a', 'b', 'c'), meta={'name': 'first table'})
+  >>> t = Table(rows=data_rows, names=('a', 'b', 'c'), meta={'name': 'first table'},
+  ...           dtype=('i4', 'f8', 'S1'))
 
 There are a few ways to examine the table.  You can get detailed information
 about the table values and column definitions as follows::
 
   >>> t
-  <Table rows=3 names=('a','b','c')>
-  array([(1, 2.0, 'x'), (4, 5.0, 'y'), (5, 8..., 'z')],
-        dtype=[('a', '<i8'), ('b', '<f8'), ('c', 'S1')])
-
-One can also assign an unit to the columns. If any column has an unit 
+  <Table masked=False length=3>
+    a      b       c
+  int32 float64 string8
+  ----- ------- -------
+      1     2.0       x
+      4     5.0       y
+      5     8.2       z
+
+You can also assign a unit to the columns. If any column has a unit
 assigned, all units would be shown as follows::
 
   >>> t['b'].unit = 's'
   >>> t
-  <Table rows=3 names=('a','b','c') units=(None,'s',None)>
-  array([(1, 2.0, 'x'), (4, 5.0, 'y'), (5, 8..., 'z')], 
-        dtype=[('a', '<i8'), ('b', '<f8'), ('c', 'S1')])
+  <Table masked=False length=3>
+    a      b       c
+           s
+  int32 float64 string8
+  ----- ------- -------
+      1     2.0       x
+      4     5.0       y
+      5     8.2       z
+
+A column with a unit works with and can be easily converted to an
+`~astropy.units.Quantity` object::
+
+  >>> t['b'].quantity
+  <Quantity [ 2. , 5. , 8.2] s>
+  >>> t['b'].to('min')  # doctest: +FLOAT_CMP
+  <Quantity [ 0.03333333, 0.08333333, 0.13666667] min>
 
 From within the IPython notebook, the table is displayed as a formatted HTML table:
 
@@ -91,8 +121,8 @@ If you do not like the format of a particular column, you can change it::
 
   >>> t['b'].format = '7.3f'
   >>> print(t)
-   a     b     c 
-         s       
+   a     b     c
+         s
   --- ------- ---
     1   2.000   x
     4   5.000   y
@@ -123,8 +153,10 @@ Now examine some high-level information about the table::
 Access the data by column or row using familiar `numpy` structured array syntax::
 
   >>> t['a']       # Column 'a'
-  <Column name='a' unit=None format=None description=None>
-  array([1, 4, 5])
+  <Column name='a' dtype='int32' length=3>
+  1
+  4
+  5
 
   >>> t['a'][1]    # Row 1 of column 'a'
   4
@@ -132,17 +164,17 @@ Access the data by column or row using familiar `numpy` structured array syntax:
   >>> t[1]         # Row obj for with row 1 values
   <Row 1 of table
    values=(4, 5.0, 'y')
-   dtype=[('a', '<i8'), ('b', '<f8'), ('c', 'S1')]>
+   dtype=[('a', '<i4'), ('b', '<f8'), ('c', 'S1')]>
 
   >>> t[1]['a']    # Column 'a' of row 1
   4
 
-One can retrieve a subset of a table by rows (using a slice) or
+You can retrieve a subset of a table by rows (using a slice) or
 columns (using column names), where the subset is returned as a new table::
 
   >>> print(t[0:2])      # Table object with rows 0 and 1
-   a     b     c 
-         s       
+   a     b     c
+         s
   --- ------- ---
     1   2.000   x
     4   5.000   y
@@ -162,8 +194,8 @@ Modifying table values in place is flexible and works as one would expect::
   >>> t[1]['b'] = -9              # Set column 'b' of row 1
   >>> t[0:2]['b'] = 100.0         # Set column 'b' of rows 0 and 1
   >>> print(t)
-   a     b     c 
-         s       
+   a     b     c
+         s
   --- ------- ---
    -1 100.000   x
     8 100.000   W
@@ -183,24 +215,19 @@ Adding a new row of data to the table is as follows::
   >>> len(t)
   4
 
-Lastly, one can create a table with support for missing values, for example by setting
+Lastly, you can create a table with support for missing values, for example by setting
 ``masked=True``::
 
-  >>> t = Table([a, b, c], names=('a', 'b', 'c'), masked=True)
+  >>> t = Table([a, b, c], names=('a', 'b', 'c'), masked=True, dtype=('i4', 'f8', 'S1'))
   >>> t['a'].mask = [True, True, False]
   >>> t
-  <Table rows=3 names=('a','b','c')>
-  masked_array(data = [(--, 2.0, 'x') (--, 5.0, 'y') (5, 8..., 'z')],
-               mask = [(True, False, False) (True, False, False) (False, False, False)],
-         fill_value = (999999, 1e+20, 'N'),
-              dtype = [('a', '<i8'), ('b', '<f8'), ('c', 'S1')])
-
-  >>> print(t)
-   a   b   c
-  --- --- ---
-   -- 2.0   x
-   -- 5.0   y
-    5 8.2   z
+  <Table masked=True length=3>
+    a      b       c
+  int32 float64 string8
+  ----- ------- -------
+     --     2.0       x
+     --     5.0       y
+      5     8.2       z
 
 .. _using_astropy_table:
 
@@ -257,6 +284,23 @@ I/O with tables
 
    io.rst
 
+Mixin columns
+----------------
+
+.. toctree::
+   :maxdepth: 2
+
+   mixin_columns.rst
+
+Implementation
+----------------
+
+.. toctree::
+   :maxdepth: 2
+
+   implementation_details.rst
+   implementation_change_1.0.rst
+
 Reference/API
 =============
 
diff --git a/docs/table/io.rst b/docs/table/io.rst
index b88e7eb..801eff1 100644
--- a/docs/table/io.rst
+++ b/docs/table/io.rst
@@ -34,8 +34,8 @@ the file format, for instance ``'ascii.daophot'``::
 It is possible to load tables directly from the Internet using URLs. For example,
 download tables from Vizier catalogues in CDS format (``'ascii.cds'``)::
 
-    >>> t = Table.read("ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/snrs.dat", 
-    ...         readme="ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/ReadMe", 
+    >>> t = Table.read("ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/snrs.dat",
+    ...         readme="ftp://cdsarc.u-strasbg.fr/pub/cats/VII/253/ReadMe",
     ...         format="ascii.cds")
 
 For certain file formats, the format can be automatically detected, for
diff --git a/docs/table/masking.rst b/docs/table/masking.rst
index 29b6ceb..e1c5f2b 100644
--- a/docs/table/masking.rst
+++ b/docs/table/masking.rst
@@ -38,13 +38,14 @@ A masked table can be created in several ways:
 **Create a new table object and specify masked=True** ::
 
   >>> from astropy.table import Table, Column, MaskedColumn
-  >>> t = Table([(1, 2), (3, 4)], names=('a', 'b'), masked=True)
+  >>> t = Table([(1, 2), (3, 4)], names=('a', 'b'), masked=True, dtype=('i4', 'i8'))
   >>> t
-  <Table rows=2 names=('a','b')>
-  masked_array(data = [(1, 3) (2, 4)],
-               mask = [(False, False) (False, False)],
-         fill_value = (999999, 999999),
-              dtype = [('a', '<i8'), ('b', '<i8')])
+  <Table masked=True length=2>
+    a     b
+  int32 int64
+  ----- -----
+      1     3
+      2     4
   <BLANKLINE>
 
 Notice the table attributes ``mask`` and ``fill_value`` that are
diff --git a/docs/table/mixin_columns.rst b/docs/table/mixin_columns.rst
new file mode 100644
index 0000000..734d0d4
--- /dev/null
+++ b/docs/table/mixin_columns.rst
@@ -0,0 +1,276 @@
+.. include:: references.txt
+.. |join| replace:: :func:`~astropy.table.join`
+.. |Quantity| replace:: :class:`~astropy.units.Quantity`
+.. |Time| replace:: :class:`~astropy.time.Time`
+.. |SkyCoord| replace:: :class:`~astropy.coordinates.SkyCoord`
+
+.. _mixin_columns:
+
+Mixin columns
+---------------
+
+Version 1.0 of astropy introduces a new concept of the "Mixin
+Column" in tables which allows integration of appropriate non-|Column| based
+class objects within a |Table| object.  These mixin column objects are not
+converted in any way but are used natively.
+
+The available built-in mixin column classes are:
+
+- |Quantity|
+- |SkyCoord|
+- |Time|
+
+.. Warning::
+
+   The interface for using mixin columns is experimental at this point and it
+   is not recommended to use this feature in production code.  There are known
+   limitations and some table functionality which is not yet implemented for
+   mixin columns.  API changes are likely and since the code is all new there
+   may be some bugs.
+
+As a first example we can create a table and add a time column::
+
+  >>> from astropy.table import Table
+  >>> from astropy.time import Time
+  >>> t = Table()
+  >>> t['index'] = [1, 2]
+  >>> t['time'] = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02'])
+  >>> print(t)
+  index           time
+  ----- -----------------------
+      1 2001-01-02T12:34:56.000
+      2 2001-02-03T00:01:02.000
+
+The important point here is that the ``time`` column is a bona fide |Time| object::
+
+  >>> t['time']
+  <Time object: scale='utc' format='isot' value=['2001-01-02T12:34:56.000' '2001-02-03T00:01:02.000']>
+  >>> t['time'].mjd
+  array([ 51911.52425926,  51943.00071759])
+
+.. _quantity_and_qtable:
+
+Quantity and QTable
+^^^^^^^^^^^^^^^^^^^
+
+The ability to natively handle |Quantity| objects within a table makes it
+easier to manipulate tabular data with units in a natural and robust way.
+However, this feature introduces an ambiguity because data with a unit
+(e.g. from a FITS binary table) can be represented as either a |Column| with a
+``unit`` attribute or as a |Quantity| object. In order to retain complete
+backward compatibility with astropy versions prior to 1.0, a minor variant of
+the |Table| class called |QTable| is available.  |QTable| is exactly the same
+as |Table| except that |Quantity| is the default for any data column with a
+defined unit.
+
+If you take advantage of the |Quantity| infrastructure in your analysis then
+|QTable| is the preferred way to create tables with units.  If instead you use
+table column units more as a descriptive label then the plain |Table| class is
+probably the best class to use.
+
+To illustrate these concepts we first create a standard |Table| where we supply as input a
+|Time| object and a |Quantity| object with units of ``m / s``.  In this case
+the quantity is converted to a |Column| (which has a ``unit`` attribute but
+does not have all the features of a |Quantity|)::
+
+  >>> import astropy.units as u
+  >>> t = Table()
+  >>> t['index'] = [1, 2]
+  >>> t['time'] = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02'])
+  >>> t['velocity'] = [3, 4] * u.m / u.s
+
+  >>> print(t)
+  index           time          velocity
+                                 m / s
+  ----- ----------------------- --------
+      1 2001-01-02T12:34:56.000      3.0
+      2 2001-02-03T00:01:02.000      4.0
+
+  >>> type(t['velocity'])
+  <class 'astropy.table.column.Column'>
+
+  >>> t['velocity'].unit
+  Unit("m / s")
+
+  >>> (t['velocity'] ** 2).unit  # WRONG because Column is not smart about unit
+  Unit("m / s")
+
+So instead let's do the same thing using a quantity table |QTable|::
+
+  >>> from astropy.table import QTable
+
+  >>> qt = QTable()
+  >>> qt['index'] = [1, 2]
+  >>> qt['time'] = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02'])
+  >>> qt['velocity'] = [3, 4] * u.m / u.s
+
+Now we print the table again but this time notice that the individual values
+all have units because this is how |Quantity| prints a single array element::
+
+  >>> print(qt)
+  index           time           velocity
+                                  m / s
+  ----- ----------------------- ---------
+      1 2001-01-02T12:34:56.000 3.0 m / s
+      2 2001-02-03T00:01:02.000 4.0 m / s
+
+The ``velocity`` column is now a |Quantity| and behaves accordingly::
+
+  >>> type(qt['velocity'])
+  <class 'astropy.units.quantity.Quantity'>
+
+  >>> qt['velocity'].unit
+  Unit("m / s")
+
+  >>> (qt['velocity'] ** 2).unit  # GOOD!
+  Unit("m2 / s2")
+
+You can easily convert |Table| to |QTable| and vice-versa::
+
+  >>> qt2 = QTable(t)
+  >>> type(qt2['velocity'])
+  <class 'astropy.units.quantity.Quantity'>
+
+  >>> t2 = Table(qt2)
+  >>> type(t2['velocity'])
+  <class 'astropy.table.column.Column'>
+
+Details and caveats
+^^^^^^^^^^^^^^^^^^^
+
+Most common table operations behave as expected when mixin columns are part of
+the table.  However, there are limitations in the current implementation.
+
+**Adding or inserting a row**
+
+Adding or inserting a row works as expected only for mixin classes that are
+mutable (data can changed internally) and that have an ``insert()`` method.
+|Quantity| supports ``insert()`` but |Time| and |SkyCoord| do not.  If we try to
+insert a row into the previously defined table an exception occurs::
+
+  >>> qt.add_row((1, '2001-02-03T00:01:02', 5 * u.m / u.s))
+  Traceback (most recent call last):
+    ...
+  ValueError: Unable to insert row because of exception in column 'time':
+  'Time' object has no attribute 'insert'
+
+**Masking**
+
+Mixin columns do not support masking, but there is limited support for use of
+mixins within a masked table.  In this case a ``mask`` attribute is assigned to
+the mixin column object.  This ``mask`` is a special object that is a boolean
+array of ``False`` corresponding to the mixin data shape.  The ``mask`` looks
+like a normal numpy array but an exception will be raised if ``True`` is assigned
+to any element.  The consequences of the limitation are most obvious in the
+high-level table operations.
+
+**High-level table operations**
+
+The table below gives a summary of support for high-level operations on tables
+that contain mixin columns:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 28 72
+
+   * - Operation
+     - Support
+   * - :ref:`grouped-operations`
+     - Not implemented yet, but no fundamental limitation
+   * - :ref:`stack-vertically`
+     - Not implemented yet, pending definition of generic concatenation protocol
+   * - :ref:`stack-horizontally`
+     - Works if output mixin columns do not require masking
+   * - :ref:`table-join`
+     - Works if output mixin columns do not require masking; no mixin key
+       columns allowed
+   * - :ref:`unique-rows`
+     - Not implemented yet, uses grouped operations
+
+**Mixin column attributes**
+
+For mixin columns the column attributes ``name``, ``unit``, ``dtype``,
+``format``, ``description`` and ``meta`` are currently stored in a simple
+dictionary called `_astropy_column_attrs`.  These attributes can be manipulated
+with the functions ``col_getattr`` and ``col_setattr`` which are available in
+the ``astropy.table.column`` module.  These methods are not part of
+the astropy public API and are likely to change in the future.
+
+**ASCII table writing**
+
+Mixin columns can be written out to file using the `astropy.io.ascii` module,
+but the fast C-based writers are not available.  Instead the legacy pure-Python
+writers will be used.
+
+
+.. _mixin_protocol:
+
+Mixin protocol
+^^^^^^^^^^^^^^
+
+A key idea behind mixin columns is that any class which satisfies a specified
+protocol can be used.  That means many user-defined class objects which handle
+array-like data can be used natively within a |Table|.  The protocol is
+relatively simple and requires that a class behave like a minimal numpy array
+with the following properties:
+
+- Contains array-like data
+- Supports getting data as a single item, slicing, or index array access
+- Has a ``shape`` attribute
+- Has a ``__len__`` method for length
+- Has a ``_astropy_column_attrs`` attribute, which tells the |Table| class to
+  use the object natively instead of converting to a |Column|
+
+The `Example: ArrayWrapper`_ section shows a working minimal example of a class
+which can be used as a mixin column.  A `pandas.Series
+<http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html>`_
+object can function as a mixin column as well.
+
+Other interesting possibilities for mixin columns include:
+
+- Columns which are dynamically computed as a function of other columns (AKA
+  spreadsheet)
+- Columns which are themselves a |Table|, i.e. nested tables
+
+.. _arraywrapper_example:
+
+Example: ArrayWrapper
+^^^^^^^^^^^^^^^^^^^^^
+
+The code listing below shows a example of a data container class which acts as
+a mixin column class.  This class is a simple wrapper around a numpy array.  It
+is used in the astropy mixin test suite and is fully compliant as a mixin
+column.
+
+::
+
+  class ArrayWrapper(object):
+      """
+      Minimal mixin using a simple wrapper around a numpy array
+      """
+      _astropy_column_attrs = None
+
+      def __init__(self, data):
+          self.data = np.array(data)
+          col_setattr(self, 'dtype', self.data.dtype)
+
+      def __getitem__(self, item):
+          if isinstance(item, (int, np.integer)):
+              out = self.data[item]
+          else:
+              out = self.__class__(self.data[item])
+          return out
+
+      def __setitem__(self, item, value):
+          self.data[item] = value
+
+      def __len__(self):
+          return len(self.data)
+
+      @property
+      def shape(self):
+          return self.data.shape
+
+      def __repr__(self):
+          return ("<{0} name='{1}' data={2}>"
+                  .format(self.__class__.__name__, col_getattr(self, 'name'), self.data))
diff --git a/docs/table/modify_table.rst b/docs/table/modify_table.rst
index 2b01e68..1a9948a 100644
--- a/docs/table/modify_table.rst
+++ b/docs/table/modify_table.rst
@@ -50,6 +50,19 @@ Instead use ``table[column][row]`` order::
   >>> t['a'][np.array([1, 2])] = [3., 5.]
   >>> t['a'][np.where(t['a'] > 3)] = 3.
 
+You can also modify data columns with ``unit`` set in a way that follows
+the conventions of `~astropy.units.Quantity` by using the
+:attr:`~astropy.table.Column.quantity` property::
+
+  >>> from astropy import units as u
+  >>> tu = Table([[1, 2.5]], names=('a',))
+  >>> tu['a'].unit = u.m
+  >>> tu['a'].quantity[:] = [1, 2] * u.km
+  >>> tu['a']
+  <Column name='a' dtype='float64' unit='m' length=2>
+  1000.0
+  2000.0
+
 **Add a column or columns**
 
 A single column can be added to a table using syntax like adding a dict value.
@@ -80,8 +93,12 @@ Finally, columns can also be added from
   >>> from astropy import units as u
   >>> t['d'] = np.arange(1., 6.) * u.m
   >>> t['d']
-  <Column name='d' unit='m' format=None description=None>
-  array([ 1., 2., 3., 4., 5.])
+  <Column name='d' dtype='float64' unit='m' length=5>
+  1.0
+  2.0
+  3.0
+  4.0
+  5.0
 
 **Remove columns**
 ::
diff --git a/docs/table/operations.rst b/docs/table/operations.rst
index 7d770a1..610bb13 100644
--- a/docs/table/operations.rst
+++ b/docs/table/operations.rst
@@ -30,6 +30,9 @@ table from one or more input tables.  This includes:
    * - `Join`_
      - Database-style join of two tables
      - `~astropy.table.join`
+   * - `Unique rows`_
+     - Unique table rows by keys
+     - `~astropy.table.unique`
 
 
 .. _grouped-operations:
@@ -64,7 +67,7 @@ a new table sorted by ``name`` which has a ``groups`` property specifying the un
 values of ``name`` and the corresponding table rows::
 
   >>> obs_by_name = obs.group_by('name')
-  >>> print obs_by_name  # doctest: +SKIP
+  >>> print(obs_by_name)  # doctest: +SKIP
   name  obs_date  mag_b mag_v
   ---- ---------- ----- -----
   M101 2012-01-02  15.1  13.5  << First group (index=0, key='M101')
@@ -78,13 +81,13 @@ values of ``name`` and the corresponding table rows::
    M82 2012-02-14  15.2  15.5
    M82 2012-03-26  15.7  16.5
                                << End of groups (index=10)
-  >>> print obs_by_name.groups.keys
+  >>> print(obs_by_name.groups.keys)
   name
   ----
   M101
    M31
    M82
-  >>> print obs_by_name.groups.indices
+  >>> print(obs_by_name.groups.indices)
   [ 0  4  7 10]
 
 The ``groups`` property is the portal to all grouped operations with tables and columns.
@@ -108,7 +111,7 @@ the required groups.
 As an example, to get the average magnitudes for each object on each observing
 night, we would first group the table on both ``name`` and ``obs_date`` as follows::
 
-  >>> print obs.group_by(['name', 'obs_date']).groups.keys
+  >>> print(obs.group_by(['name', 'obs_date']).groups.keys)
   name  obs_date
   ---- ----------
   M101 2012-01-02
@@ -128,7 +131,7 @@ groups or subsets of groups.  In all cases this returns a new grouped table.
 For instance to get the sub-table which corresponds to the second group (index=1)
 do::
 
-  >>> print obs_by_name.groups[1]
+  >>> print(obs_by_name.groups[1])
   name  obs_date  mag_b mag_v
   ---- ---------- ----- -----
    M31 2012-01-02  17.0  17.5
@@ -138,7 +141,7 @@ do::
 To get the first and second groups together use a slice::
 
   >>> groups01 = obs_by_name.groups[0:2]
-  >>> print groups01
+  >>> print(groups01)
   name  obs_date  mag_b mag_v
   ---- ---------- ----- -----
   M101 2012-01-02  15.1  13.5
@@ -148,7 +151,7 @@ To get the first and second groups together use a slice::
    M31 2012-01-02  17.0  17.5
    M31 2012-01-02  17.1  17.4
    M31 2012-02-14  16.9  17.3
-  >>> print groups01.groups.keys
+  >>> print(groups01.groups.keys)
   name
   ----
   M101
@@ -158,7 +161,7 @@ You can also supply a numpy array of indices or a boolean mask to select particu
 groups, e.g.::
 
   >>> mask = obs_by_name.groups.keys['name'] == 'M101'
-  >>> print obs_by_name.groups[mask]
+  >>> print(obs_by_name.groups[mask])
   name  obs_date  mag_b mag_v
   ---- ---------- ----- -----
   M101 2012-01-02  15.1  13.5
@@ -171,7 +174,7 @@ One can iterate over the group sub-tables and corresponding keys with::
   >>> from itertools import izip
   >>> for key, group in izip(obs_by_name.groups.keys, obs_by_name.groups):
   ...     print('****** {0} *******'.format(key['name']))
-  ...     print group
+  ...     print(group)
   ...     print
   ...
   ****** M101 *******
@@ -216,7 +219,7 @@ Examples::
 
   >>> for key, group in izip(cg.groups.keys, cg.groups):
   ...     print('****** {0} *******'.format(key))
-  ...     print group
+  ...     print(group)
   ...     print
   ...
   ****** bar *******
@@ -250,7 +253,7 @@ the `~astropy.table.groups.TableGroups.aggregate` method::
 
   >>> obs_mean = obs_by_name.groups.aggregate(np.mean)  # doctest: +SKIP
   WARNING: Cannot aggregate column 'obs_date' [astropy.table.groups]
-  >>> print obs_mean  # doctest: +SKIP
+  >>> print(obs_mean)  # doctest: +SKIP
   name mag_b mag_v
   ---- ----- ------
   M101  15.0 13.725
@@ -269,14 +272,14 @@ it is automatically ignored from aggregation.
 From a grouped table it is possible to select one or more columns on which
 to perform the aggregation::
 
-  >>> print obs_by_name['mag_b'].groups.aggregate(np.mean)
+  >>> print(obs_by_name['mag_b'].groups.aggregate(np.mean))
   mag_b
   -----
    15.0
    17.0
    15.7
 
-  >>> print obs_by_name['name', 'mag_v', 'mag_b'].groups.aggregate(np.mean)
+  >>> print(obs_by_name['name', 'mag_v', 'mag_b'].groups.aggregate(np.mean))
   name mag_v  mag_b
   ---- ------ -----
   M101 13.725  15.0
@@ -290,7 +293,7 @@ A single column of data can be aggregated as well::
   >>> cg = c.group_by(key_vals)
   >>> cg_sums = cg.groups.aggregate(np.sum)
   >>> for key, cg_sum in izip(cg.groups.keys, cg_sums):
-  ...     print 'Sum for {0} = {1}'.format(key, cg_sum)
+  ...     print('Sum for {0} = {1}'.format(key, cg_sum))
   ...
   Sum for bar = 2
   Sum for foo = 8
@@ -351,7 +354,7 @@ An example of using this function is::
   >>> tg = t.group_by('a')
   >>> t_positive = tg.groups.filter(all_positive)
   >>> for group in t_positive.groups:
-  ...     print group
+  ...     print(group)
   ...     print
   ...
    a   b   c
@@ -402,7 +405,7 @@ column names in common::
 
 Now we can stack these two tables::
 
-  >>> print vstack([obs1, obs2])
+  >>> print(vstack([obs1, obs2]))
     name   obs_date  mag_b logLx
   ------- ---------- ----- -----
       M31 2012-01-02  17.0  42.5
@@ -417,7 +420,7 @@ table those values are marked as missing.  This is the default behavior and corr
 ``join_type='outer'``.  There are two other allowed values for the ``join_type`` argument,
 ``'inner'`` and ``'exact'``::
 
-  >>> print vstack([obs1, obs2], join_type='inner')
+  >>> print(vstack([obs1, obs2], join_type='inner'))
     name   obs_date  logLx
   ------- ---------- -----
       M31 2012-01-02  42.5
@@ -427,7 +430,7 @@ table those values are marked as missing.  This is the default behavior and corr
       M31 1999-01-05  43.1
       M82 2012-10-30  45.0
 
-  >>> print vstack([obs1, obs2], join_type='exact')
+  >>> print(vstack([obs1, obs2], join_type='exact'))
   Traceback (most recent call last):
     ...
   TableMergeError: Inconsistent columns in input arrays (use 'inner'
@@ -442,7 +445,7 @@ More than two tables can be stacked by supplying a list of table objects::
 
   >>> obs3 = Table.read("""name    obs_date    mag_b  logLx
   ...                      M45     2012-02-03  15.0   40.5""", format='ascii')
-  >>> print vstack([obs1, obs2, obs3])
+  >>> print(vstack([obs1, obs2, obs3]))
     name   obs_date  mag_b logLx
   ------- ---------- ----- -----
       M31 2012-01-02  17.0  42.5
@@ -480,7 +483,7 @@ For example, suppose one has the following two tables::
 
 Now we can stack these two tables horizontally::
 
-  >>> print hstack([t1, t2])
+  >>> print(hstack([t1, t2]))
    a   b   c   d     e
   --- --- --- ---- -----
     1 foo 1.4  ham  eggs
@@ -494,13 +497,13 @@ values.  This is illustrated in the example above.  The other options give the
 intersection of rows, where ``'exact'`` requires that all tables have exactly the same
 number of rows::
 
-  >>> print hstack([t1, t2], join_type='inner')
+  >>> print(hstack([t1, t2], join_type='inner'))
    a   b   c   d     e
   --- --- --- ---- -----
     1 foo 1.4  ham  eggs
     2 bar 2.1 spam toast
 
-  >>> print hstack([t1, t2], join_type='exact')
+  >>> print(hstack([t1, t2], join_type='exact'))
   Traceback (most recent call last):
     ...
   TableMergeError: Inconsistent number of rows in input arrays (use 'inner' or
@@ -512,7 +515,7 @@ below also illustrates the behavior when there is a conflict in the input column
 
   >>> t3 = Table.read("""a    b
   ...                    M45  2012-02-03""", format='ascii')
-  >>> print hstack([t1, t2, t3])
+  >>> print(hstack([t1, t2, t3]))
   a_1 b_1  c   d     e   a_3    b_3
   --- --- --- ---- ----- --- ----------
     1 foo 1.4  ham  eggs M45 2012-02-03
@@ -553,7 +556,7 @@ that are common to both tables.  In this case the key columns are ``name`` and
 follows::
 
   >>> opt_xray = join(optical, xray)
-  >>> print opt_xray
+  >>> print(opt_xray)
   name  obs_date  mag_b mag_v logLx
   ---- ---------- ----- ----- -----
    M82 2012-10-29  16.2  15.2  45.0
@@ -561,7 +564,7 @@ follows::
 We can perform the match only by ``name`` by providing the ``keys`` argument, which can be
 either a single column name or a list of column names::
 
-  >>> print join(optical, xray, keys='name')
+  >>> print(join(optical, xray, keys='name'))
   name obs_date_1 mag_b mag_v obs_date_2 logLx
   ---- ---------- ----- ----- ---------- -----
    M31 2012-01-02  17.0  16.0 1999-01-05  43.1
@@ -578,7 +581,7 @@ the two tables on the key columns.
 If one wants to make a new table which has *every* row from the left table and includes
 matching values from the right table when available, this is known as a left join::
 
-  >>> print join(optical, xray, join_type='left')
+  >>> print(join(optical, xray, join_type='left'))
   name  obs_date  mag_b mag_v logLx
   ---- ---------- ----- ----- -----
   M101 2012-10-31  15.1  15.5    --
@@ -591,7 +594,7 @@ surprised that there is no X-ray data for M31 in the output.  Remember that the
 matching key includes both ``name`` and ``obs_date``.  Specifying the key as only the
 ``name`` column gives::
 
-  >>> print join(optical, xray, join_type='left', keys='name')
+  >>> print(join(optical, xray, join_type='left', keys='name'))
   name obs_date_1 mag_b mag_v obs_date_2 logLx
   ---- ---------- ----- ----- ---------- -----
   M101 2012-10-31  15.1  15.5         --    --
@@ -603,7 +606,7 @@ values (when available) using ``join_type='right'``.
 
 Finally, to make a table with the union of rows from both tables do an "outer" join::
 
-  >>> print join(optical, xray, join_type='outer')
+  >>> print(join(optical, xray, join_type='outer'))
     name   obs_date  mag_b mag_v logLx
   ------- ---------- ----- ----- -----
      M101 2012-10-31  15.1  15.5    --
@@ -622,14 +625,14 @@ values.  For example the following tables have multiple rows for the key column
   >>> from astropy.table import Table, join
   >>> left = Table([[0, 1, 1, 2], ['L1', 'L2', 'L3', 'L4']], names=('key', 'L'))
   >>> right = Table([[1, 1, 2, 4], ['R1', 'R2', 'R3', 'R4']], names=('key', 'R'))
-  >>> print left
+  >>> print(left)
   key  L
   --- ---
     0  L1
     1  L2
     1  L3
     2  L4
-  >>> print right
+  >>> print(right)
   key  R
   --- ---
     1  R1
@@ -644,7 +647,7 @@ the left or right table, the corresponding column values are designated as missi
 
 .. doctest-skip:: win32
 
-  >>> print join(left, right, join_type='outer')
+  >>> print(join(left, right, join_type='outer'))
   key  L   R
   --- --- ---
     0  L1  --
@@ -667,7 +670,7 @@ left and right tables:
 
 .. doctest-skip:: win32
 
-  >>> print join(left, right, join_type='inner')
+  >>> print(join(left, right, join_type='inner'))
   key  L   R
   --- --- ---
     1  L2  R1
@@ -707,9 +710,9 @@ keyword arguments that control the renaming behavior:
 This is most easily understood by example using the ``optical`` and ``xray`` tables
 in the |join| example defined previously::
 
-  >>> print join(optical, xray, keys='name',
+  >>> print(join(optical, xray, keys='name',
   ...            table_names=['OPTICAL', 'XRAY'],
-  ...            uniq_col_name='{table_name}_{col_name}')
+  ...            uniq_col_name='{table_name}_{col_name}'))
   name OPTICAL_obs_date mag_b mag_v XRAY_obs_date logLx
   ---- ---------------- ----- ----- ------------- -----
    M31       2012-01-02  17.0  16.0    1999-01-05  43.1
@@ -769,3 +772,58 @@ order and taking the first value which is defined (i.e. is not None).  For examp
 
 The rules for merging are as for `Merging metadata`_, and the
 ``metadata_conflicts`` option also controls the merging of column attributes.
+
+
+.. _unique-rows:
+
+Unique rows
+^^^^^^^^^^^
+
+Sometimes it makes sense to use only rows with unique key columns or even
+fully unique rows from a table. This can be done using the above described
+:func:`~astropy.table.Table.group_by` method and ``groups`` attribute, or
+with the `~astropy.table.unique` convenience method. The
+`~astropy.table.unique` method returns with a sorted table containing the
+first row for each unique ``keys`` column value. If no ``keys`` is provided
+it returns with a sorted table containing all the fully unique rows.
+
+A simple example is a list of objects with photometry from various observing
+runs. Using ``'name'`` as the only ``keys``, it returns with the first
+occurrence of each of the three targets::
+
+  >>> from astropy import table
+  >>> obs = table.Table.read("""name    obs_date    mag_b  mag_v
+  ...                           M31     2012-01-02  17.0   17.5
+  ...                           M82     2012-02-14  16.2   14.5
+  ...                           M101    2012-01-02  15.1   13.5
+  ...                           M31     2012-01-02  17.1   17.4
+  ...                           M101    2012-01-02  15.1   13.5
+  ...                           M82     2012-02-14  16.2   14.5
+  ...                           M31     2012-02-14  16.9   17.3
+  ...                           M82     2012-02-14  15.2   15.5
+  ...                           M101    2012-02-14  15.0   13.6
+  ...                           M82     2012-03-26  15.7   16.5
+  ...                           M101    2012-03-26  15.1   13.5
+  ...                           M101    2012-03-26  14.8   14.3
+  ...                           """, format='ascii')
+  >>> unique_by_name = table.unique(obs, keys='name')
+  >>> print(unique_by_name)
+  name  obs_date  mag_b mag_v
+  ---- ---------- ----- -----
+  M101 2012-01-02  15.1  13.5
+   M31 2012-01-02  17.0  17.5
+   M82 2012-02-14  16.2  14.5
+
+Using multiple columns as ``keys``::
+
+  >>> unique_by_name_date = table.unique(obs, keys=['name', 'obs_date'])
+  >>> print(unique_by_name_date)
+  name  obs_date  mag_b mag_v
+  ---- ---------- ----- -----
+  M101 2012-01-02  15.1  13.5
+  M101 2012-02-14  15.0  13.6
+  M101 2012-03-26  15.1  13.5
+   M31 2012-01-02  17.0  17.5
+   M31 2012-02-14  16.9  17.3
+   M82 2012-02-14  16.2  14.5
+   M82 2012-03-26  15.7  16.5
diff --git a/docs/table/references.txt b/docs/table/references.txt
index 383dab7..884557a 100644
--- a/docs/table/references.txt
+++ b/docs/table/references.txt
@@ -1,5 +1,6 @@
 .. |Row| replace:: :class:`~astropy.table.Row`
 .. |Table| replace:: :class:`~astropy.table.Table`
+.. |QTable| replace:: :class:`~astropy.table.QTable`
 .. |Column| replace:: :class:`~astropy.table.Column`
 .. |MaskedColumn| replace:: :class:`~astropy.table.MaskedColumn`
 .. |TableColumns| replace:: :class:`~astropy.table.TableColumns`
diff --git a/docs/table/table_after_1.0.png b/docs/table/table_after_1.0.png
new file mode 100644
index 0000000..817a983
Binary files /dev/null and b/docs/table/table_after_1.0.png differ
diff --git a/docs/table/table_architecture.png b/docs/table/table_architecture.png
new file mode 100644
index 0000000..7966629
Binary files /dev/null and b/docs/table/table_architecture.png differ
diff --git a/docs/table/table_before_1.0.png b/docs/table/table_before_1.0.png
new file mode 100644
index 0000000..bad178e
Binary files /dev/null and b/docs/table/table_before_1.0.png differ
diff --git a/docs/table/table_column_after_1.0.png b/docs/table/table_column_after_1.0.png
new file mode 100644
index 0000000..817a983
Binary files /dev/null and b/docs/table/table_column_after_1.0.png differ
diff --git a/docs/table/table_column_before_1.0.png b/docs/table/table_column_before_1.0.png
new file mode 100644
index 0000000..f289627
Binary files /dev/null and b/docs/table/table_column_before_1.0.png differ
diff --git a/docs/table/table_repr_html.png b/docs/table/table_repr_html.png
index b57ea0f..4b39d63 100644
Binary files a/docs/table/table_repr_html.png and b/docs/table/table_repr_html.png differ
diff --git a/docs/table/table_row.png b/docs/table/table_row.png
new file mode 100644
index 0000000..0cdcbae
Binary files /dev/null and b/docs/table/table_row.png differ
diff --git a/docs/table/table_row_after_1.0.png b/docs/table/table_row_after_1.0.png
new file mode 100644
index 0000000..4d9c154
Binary files /dev/null and b/docs/table/table_row_after_1.0.png differ
diff --git a/docs/table/table_row_before_1.0.png b/docs/table/table_row_before_1.0.png
new file mode 100644
index 0000000..276382e
Binary files /dev/null and b/docs/table/table_row_before_1.0.png differ
diff --git a/docs/time/index.rst b/docs/time/index.rst
index 2112cb0..b862365 100644
--- a/docs/time/index.rst
+++ b/docs/time/index.rst
@@ -133,24 +133,25 @@ that derives from the base :class:`~astropy.time.TimeFormat` class.
 This class structure can be easily adapted and extended by users for
 specialized time formats not supplied in `astropy.time`.
 
-=========  =================================================  ==============================
-Format            Class                                        Example argument
-=========  =================================================  ==============================
-byear      :class:`~astropy.time.TimeBesselianEpoch`          1950.0
-byear_str  :class:`~astropy.time.TimeBesselianEpochString`    'B1950.0'
-cxcsec     :class:`~astropy.time.TimeCxcSec`                  63072064.184
-datetime   :class:`~astropy.time.TimeDatetime`                datetime(2000, 1, 2, 12, 0, 0)
-gps        :class:`~astropy.time.TimeGPS`                     630720013.0
-iso        :class:`~astropy.time.TimeISO`                     '2000-01-01 00:00:00.000'
-isot       :class:`~astropy.time.TimeISOT`                    '2000-01-01T00:00:00.000'
-jd         :class:`~astropy.time.TimeJD`                      2451544.5
-jyear      :class:`~astropy.time.TimeJulianEpoch`             2000.0
-jyear_str  :class:`~astropy.time.TimeJulianEpochString`       'J2000.0'
-mjd        :class:`~astropy.time.TimeMJD`                     51544.0
-plot_date  :class:`~astropy.time.TimePlotDate`                730120.0003703703
-unix       :class:`~astropy.time.TimeUnix`                    946684800.0
-yday       :class:`~astropy.time.TimeYearDayTime`             2000:001:00:00:00.000
-=========  =================================================  ==============================
+===========  =================================================  ==============================
+Format            Class                                         Example argument
+===========  =================================================  ==============================
+byear        :class:`~astropy.time.TimeBesselianEpoch`          1950.0
+byear_str    :class:`~astropy.time.TimeBesselianEpochString`    'B1950.0'
+cxcsec       :class:`~astropy.time.TimeCxcSec`                  63072064.184
+datetime     :class:`~astropy.time.TimeDatetime`                datetime(2000, 1, 2, 12, 0, 0)
+decimalyear  :class:`~astropy.time.TimeDecimalYear`             2000.45
+gps          :class:`~astropy.time.TimeGPS`                     630720013.0
+iso          :class:`~astropy.time.TimeISO`                     '2000-01-01 00:00:00.000'
+isot         :class:`~astropy.time.TimeISOT`                    '2000-01-01T00:00:00.000'
+jd           :class:`~astropy.time.TimeJD`                      2451544.5
+jyear        :class:`~astropy.time.TimeJulianEpoch`             2000.0
+jyear_str    :class:`~astropy.time.TimeJulianEpochString`       'J2000.0'
+mjd          :class:`~astropy.time.TimeMJD`                     51544.0
+plot_date    :class:`~astropy.time.TimePlotDate`                730120.0003703703
+unix         :class:`~astropy.time.TimeUnix`                    946684800.0
+yday         :class:`~astropy.time.TimeYearDayTime`             2000:001:00:00:00.000
+===========  =================================================  ==============================
 
 Subformat
 """""""""
@@ -253,6 +254,14 @@ appropriate::
   <Time object: scale='utc' format='mjd' value=[ 100.  200.]>
   >>> t[2]
   <Time object: scale='utc' format='mjd' value=300.0>
+  >>> t = Time(np.arange(50000., 50003.)[:, np.newaxis],
+  ...          np.arange(0., 1., 0.5), format='mjd') 
+  >>> t
+  <Time object: scale='utc' format='mjd' value=[[ 50000.   50000.5]
+   [ 50001.   50001.5]
+   [ 50002.   50002.5]]>
+  >>> t[0]
+  <Time object: scale='utc' format='mjd' value=[ 50000.   50000.5]>
 
 .. _astropy-time-inferring-input:
 
diff --git a/docs/units/decomposing_and_composing.rst b/docs/units/decomposing_and_composing.rst
index 915f28c..d222d95 100644
--- a/docs/units/decomposing_and_composing.rst
+++ b/docs/units/decomposing_and_composing.rst
@@ -16,7 +16,7 @@ methods::
   Unit("2.17987e-18 kg m2 / s2")
 
 You can limit the selection of units that you want to decompose to
-using the `bases` keyword argument::
+using the ``bases`` keyword argument::
 
   >>> u.Ry.decompose(bases=[u.m, u.N])
   Unit("2.17987e-18 m N")
diff --git a/docs/units/equivalencies.rst b/docs/units/equivalencies.rst
index 6ff694b..c9d6098 100644
--- a/docs/units/equivalencies.rst
+++ b/docs/units/equivalencies.rst
@@ -185,7 +185,7 @@ requires the beam area and frequency as arguments.  Example::
 Temperature Energy Equivalency
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-This equivalency allows conversion between temperature and its equivalent 
+This equivalency allows conversion between temperature and its equivalent
 in energy (i.e., the temperature multiplied by the Boltzmann constant),
 usually expressed in electronvolts. This is used frequently for
 observations at high-energy, be it for solar or X-ray astronomy. Example::
@@ -274,22 +274,22 @@ all kinds of things that ``Hz`` can be converted to::
   >>> u.Hz.find_equivalent_units(equivalencies=u.spectral())
     Primary name | Unit definition        | Aliases
   [
-    AU           | 1.49598e+11 m          | au             ,
-    Angstrom     | 1e-10 m                | AA, angstrom   ,
-    Bq           | 1 / s                  | becquerel      ,
-    Ci           | 2.7027e-11 / s         | curie          ,
-    Hz           | 1 / s                  | Hertz, hertz   ,
-    J            | kg m2 / s2             | Joule, joule   ,
-    Ry           | 2.17987e-18 kg m2 / s2 | rydberg        ,
-    cm           | 0.01 m                 | centimeter     ,
-    eV           | 1.60218e-19 kg m2 / s2 | electronvolt   ,
-    erg          | 1e-07 kg m2 / s2       |                ,
-    k            | 100 / m                | Kayser, kayser ,
-    lyr          | 9.46073e+15 m          | lightyear      ,
-    m            | irreducible            | meter          ,
-    micron       | 1e-06 m                |                ,
-    pc           | 3.08568e+16 m          | parsec         ,
-    solRad       | 6.95508e+08 m          | R_sun, Rsun    ,
+    AU           | 1.49598e+11 m          | au, astronomical_unit ,
+    Angstrom     | 1e-10 m                | AA, angstrom          ,
+    Bq           | 1 / s                  | becquerel             ,
+    Ci           | 2.7027e-11 / s         | curie                 ,
+    Hz           | 1 / s                  | Hertz, hertz          ,
+    J            | kg m2 / s2             | Joule, joule          ,
+    Ry           | 2.17987e-18 kg m2 / s2 | rydberg               ,
+    cm           | 0.01 m                 | centimeter            ,
+    eV           | 1.60218e-19 kg m2 / s2 | electronvolt          ,
+    erg          | 1e-07 kg m2 / s2       |                       ,
+    k            | 100 / m                | Kayser, kayser        ,
+    lyr          | 9.46073e+15 m          | lightyear             ,
+    m            | irreducible            | meter                 ,
+    micron       | 1e-06 m                |                       ,
+    pc           | 3.08568e+16 m          | parsec                ,
+    solRad       | 6.95508e+08 m          | R_sun, Rsun           ,
   ]
 
 .. _equivalency-context:
diff --git a/docs/units/format.rst b/docs/units/format.rst
index b9750bf..7f3d294 100644
--- a/docs/units/format.rst
+++ b/docs/units/format.rst
@@ -122,10 +122,10 @@ formats:
     Unlike the "generic" string format, this will only accept or
     generate units defined in the FITS standard.
 
-  - ``"vounit"``: The `proposed IVOA standard
-    <http://www.ivoa.net/Documents/VOUnits/>`__ for representing units
-    in the VO.  Again, based on the FITS syntax, but the collection of
-    supported units is different.
+  - ``"vounit"``: The `Units in the VO 1.0
+    <http://www.ivoa.net/Documents/VOUnits/>`__ standard for
+    representing units in the VO.  Again, based on the FITS syntax,
+    but the collection of supported units is different.
 
   - ``"cds"``: `Standards for astronomical catalogues from Centre de
     Données astronomiques de Strasbourg
@@ -152,6 +152,20 @@ following formats:
 
        \mathrm{\frac{erg}{s\,cm^{2}}}
 
+  - ``"latex_inline"``: Writes units out using LaTeX math syntax using the
+    `IAU Style Manual
+    <http://www.iau.org/static/publications/stylemanual1989.pdf>`__
+    recommendations for unit presentation, using negative powers instead of
+    fractions, as required by some journals (e.g., `Apj and AJ
+    <http://aas.org/authors/manuscript-preparation-aj-apj-author-instructions#_Toc2.2>`_.)
+    Best suited for unit representation inline with text::
+
+      >>> fluxunit.to_string('latex_inline')  # doctest: +SKIP
+
+    .. math::
+
+       \mathrm{erg\,s^{-1}\,cm^{-2}}
+
   - ``"console"``: Writes a multi-line representation of the unit
     useful for display in a text console::
 
@@ -183,8 +197,9 @@ Normally, passing an unrecognized unit string raises an exception::
   Traceback (most recent call last):
     ...
   ValueError: 'Angstroem' did not parse as fits unit: At col 0, Unit
-  u'Angstroem' not supported by the FITS standard. Did you mean
-  Angstrom or angstrom?
+  'Angstroem' not supported by the FITS standard. Did you mean
+  Angstrom (deprecated), angstrom (deprecated) or nm (with data
+  multiplied by 0.1)?
 
 However, the `~astropy.units.Unit` constructor has the keyword
 argument ``parse_strict`` that can take one of three values to control
diff --git a/docs/units/index.rst b/docs/units/index.rst
index 547d4cb..2960bdb 100644
--- a/docs/units/index.rst
+++ b/docs/units/index.rst
@@ -11,13 +11,13 @@ Units and Quantities (`astropy.units`)
 Introduction
 ============
 
-`astropy.units` handles defining, converting between, and performing 
-arithmetic with physical quantities. Examples of physical quantities 
+`astropy.units` handles defining, converting between, and performing
+arithmetic with physical quantities. Examples of physical quantities
 are meters, seconds, Hz, etc.
 
-`astropy.units` does not know spherical geometry or sexagesimal 
-(hours, min, sec): if you want to deal with celestial coordinates, 
-see the `astropy.coordinates` package.  
+`astropy.units` does not know spherical geometry or sexagesimal
+(hours, min, sec): if you want to deal with celestial coordinates,
+see the `astropy.coordinates` package.
 
 Getting Started
 ===============
@@ -152,7 +152,7 @@ See Also
 - `FITS Standard <http://fits.gsfc.nasa.gov/fits_standard.html>`_ for
   units in FITS.
 
-- The `proposed IVOA standard
+- The `Units in the VO 1.0 Standard
   <http://www.ivoa.net/Documents/VOUnits/>`_ for representing units in
   the VO.
 
diff --git a/docs/units/quantity.rst b/docs/units/quantity.rst
index 8ed3f6b..75443b5 100644
--- a/docs/units/quantity.rst
+++ b/docs/units/quantity.rst
@@ -249,6 +249,38 @@ Instead, only dimensionless values can be converted to plain Python scalars:
     >>> int(6. * u.km / (2. * u.m))
     3000
 
+Functions Accepting Quantities
+------------------------------
+
+Validation of quantity arguments to functions can lead to many repetitons 
+of the same checking code. A decorator is provided which verifies that certain
+arguments to a function are `~astropy.units.Quantity` objects and that the units
+are compatible with a desired unit.
+
+The decorator does not convert the unit to the desired unit, say arcseconds
+to degrees, it merely checks that such a conversion is possible, thus verifying 
+that the `~astropy.units.Quantity` argument can be used in calculations.
+
+The decorator `~astropy.units.quantity_input` accepts keyword arguments to 
+spcifiy which arguments should be validated and what unit they are expected to 
+be compatible with:
+
+    >>> @u.quantity_input(myarg=u.deg)
+    ... def myfunction(myarg):
+    ...     return myarg.unit
+
+    >>> myfunction(100*u.arcsec)
+    Unit("arcsec")
+
+Under Python 3 you can use the annotations syntax to provide the units:
+
+    >>> @u.quantity_input  # doctest: +SKIP
+    ... def myfunction(myarg: u.arcsec):
+    ...     return myarg.unit
+
+    >>> myfunction(100*u.arcsec)  # doctest: +SKIP
+    Unit("arcsec")
+
 Known issues with conversion to numpy arrays
 --------------------------------------------
 
diff --git a/docs/utils/index.rst b/docs/utils/index.rst
index b9514d2..f01ec4e 100644
--- a/docs/utils/index.rst
+++ b/docs/utils/index.rst
@@ -20,15 +20,15 @@ Because of the mostly standalone and grab-bag nature of these utilities, they
 are generally best understood through their docstrings, and hence this
 documentation does not have detailed sections like the other packages.
 
-.. note::
-    The ``astropy.utils.compat`` subpackage is not included in this
+.. note:: The ``astropy.utils.compat`` subpackage is not included in this
     documentation. It contains utility modules for compatibility with
-    older/newer versions of python, as well as including some bugfixes
-    for the stdlib that are important for Astropy. It is recommended
-    that developers at least glance over the source code for this
-    subpackage, but it cannot be reliably included here because of the
-    large amount of version-specific code it contains.
-
+    older/newer versions of python and numpy, as well as including some
+    bugfixes for the stdlib that are important for Astropy. It is recommended
+    that developers at least glance over the source code for this subpackage,
+    but most of it cannot be reliably included here because of the large
+    amount of version-specific code it contains. For numpy, however, there are
+    :ref:`instructions <numpy-compatibility>` on how to deal with issues of
+    compatibility between different versions.
 
 Reference/API
 =============
@@ -37,6 +37,15 @@ Reference/API
 .. automodapi:: astropy.utils.misc
     :no-inheritance-diagram:
 
+.. automodapi:: astropy.utils.decorators
+    :no-inheritance-diagram:
+
+.. automodapi:: astropy.utils.codegen
+    :no-inheritance-diagram:
+
+.. automodapi:: astropy.utils.introspection
+    :no-inheritance-diagram:
+
 .. automodapi:: astropy.utils.exceptions
     :no-inheritance-diagram:
 
diff --git a/docs/utils/numpy.rst b/docs/utils/numpy.rst
new file mode 100644
index 0000000..4b4d8ed
--- /dev/null
+++ b/docs/utils/numpy.rst
@@ -0,0 +1,54 @@
+:orphan:
+
+.. _numpy-compatibility:
+
+NumPy compatibility
+===================
+
+NumPy_ forms an essential basis for astropy, and astropy's development has led
+to the identification of problems with some of numpy's functionality. Often,
+these are corrected in later versions of numpy, but in order for astropy not
+to depend on these, work-arounds are made, usually in the code.  If functions
+are used in more than one place, however, it can be more convenient to provide
+patched routines. Hence, `astropy.utils.compat.numpy`.
+
+
+Adding a patched routine
+------------------------
+
+To ensure that patched code is only used when required, and that it will be
+easy to remove it if it is no longer needed for any supported version of
+NumPy_, the following procedure should be used to add a patched routine:
+
+* Copy over a correct version of the relevant numpy file to its
+  corresponding location below the ``astropy/utils/compat/numpy`` directory.
+* In this file, remove everything that does not have to be changed.  If
+  necessary, import required pieces from numpy.
+* Define a function that tests whether or not a patched version is needed, by
+  directly testing whether the desired functionality is present. Suggested
+  function names are ``PR####`` with a relevant numpy pull request number,
+  or ``GE####`` with a version number.
+* Place the redefinition of the relevant piece of code inside an ``if``
+  statement that uses the function just defined.  This should ensure that if a
+  sufficiently high version of numpy is used, no replacement is made.
+* In ``numpy/__init__.py``, import your patched code.
+* In ``numpy/tests``, add a new test routine that tests that the patch is used
+  when necessary (i.e., test the test function), and that it provides the
+  desired functionality. 
+
+For an example, see ``numpy/lib/stride_tricks.py`` and the corresponding
+``numpy/tests/test_broadcast_arrays.py``.
+
+Note that patched routines will normally only be considered if they are part 
+of NumPy_. Thus, if the patch concerns a new bug discovered in numpy, a `pull
+request <https://github.com/numpy/numpy/pulls>`__ should first be made to
+NumPy_ (which can of course form the basis of a `pull request 
+<https://github.com/astropy/astropy/pulls>`__ to ``astropy``).
+
+
+Reference/API
+=============
+.. automodapi:: astropy.utils.compat.numpy
+    :no-inheritance-diagram:
+
+.. _Numpy: http://numpy.scipy.org/
diff --git a/docs/visualization/index.rst b/docs/visualization/index.rst
new file mode 100644
index 0000000..91c191f
--- /dev/null
+++ b/docs/visualization/index.rst
@@ -0,0 +1,43 @@
+.. _astropy-visualization:
+
+********************************************
+Data Visualization (`astropy.visualization`)
+********************************************
+
+Introduction
+============
+
+`astropy.visualization` provides functionality that can be helpful when
+visualizing data.
+At the moment, the main functionality is image normalizing
+(including both scaling and stretching).
+Another feature included here is a plotting style for matplotlib.
+
+Using `astropy.visualization`
+=============================
+
+.. toctree::
+   :maxdepth: 2
+
+   normalization.rst
+
+
+.. _fits2bitmap:
+
+Scripts
+=======
+
+This module includes a command-line script, ``fits2bitmap`` to convert FITS
+images to bitmaps, including scaling and stretching of the image. To find out
+more about the available options and how to use it, type::
+
+    $ fits2bitmap --help
+
+Reference/API
+=============
+
+.. automodapi:: astropy.visualization.mpl_style
+
+.. automodapi:: astropy.visualization
+
+.. automodapi:: astropy.visualization.mpl_normalize
diff --git a/docs/visualization/normalization.rst b/docs/visualization/normalization.rst
new file mode 100644
index 0000000..0fca42e
--- /dev/null
+++ b/docs/visualization/normalization.rst
@@ -0,0 +1,157 @@
+**********************************
+Image stretching and normalization
+**********************************
+
+The `astropy.visualization` module provides a framework for transforming values in
+images (and more generally any arrays), typically for the purpose of
+visualization. Two main types of transformations are provided:
+
+* Normalization to the [0:1] range using lower and upper limits where
+  :math:`x` represents the values in the original image:
+
+.. math::
+
+    y = \frac{x - v_{\rm min}}{v_{\rm max} - v_{\rm min}}
+
+* *Stretching* of values in the [0:1] range to the [0:1] range using a linear
+  or non-linear function:
+  
+.. math::
+
+    z = f(y)
+
+In addition, classes are provided in order to identify lower and upper limits
+for a dataset based on specific algorithms (such as using percentiles).
+
+Identifying lower and upper limits, as well as re-normalizing, is described in
+the `Intervals and Normalization`_ section, while stretching is described in
+the `Stretching`_ section.
+
+
+Intervals and Normalization
+===========================
+
+Several classes are provided for determining intervals and for normalizing values
+in this interval to the [0:1] range. One of the simplest examples is the
+:class:`~astropy.visualization.MinMaxInterval` which determines the limits of the
+values based on the minimum and maximum values in the array. The class is
+instantiated with no arguments::
+
+
+    >>> from astropy.visualization import MinMaxInterval
+    >>> interval = MinMaxInterval()
+
+and the limits can be determined by calling the
+:meth:`~astropy.visualization.MinMaxInterval.get_limits` method, which takes the
+array of values::
+
+    >>> interval.get_limits([1, 3, 4, 5, 6])
+    (1, 6)
+
+The ``interval`` instance can also be called like a function to actually
+normalize values to the range::
+
+    >>> interval([1, 3, 4, 5, 6])
+    array([ 0. ,  0.4,  0.6,  0.8,  1. ])
+
+Other interval classes include :class:`~astropy.visualization.ManualInterval`,
+:class:`~astropy.visualization.PercentileInterval`, and
+:class:`~astropy.visualization.AsymmetricPercentileInterval`. For these three,
+values in the array can fall outside of the limits given by the interval. A
+``clip`` argument is provided to control the behavior of the normalization when
+values fall outside the limits::
+
+
+    >>> from astropy.visualization import PercentileInterval
+    >>> interval = PercentileInterval(50.)
+    >>> interval.get_limits([1, 3, 4, 5, 6])
+    (3.0, 5.0)
+    >>> interval([1, 3, 4, 5, 6])  # default is clip=True
+    array([ 0. ,  0. ,  0.5,  1. ,  1. ])
+    >>> interval([1, 3, 4, 5, 6], clip=False)
+    array([-1. ,  0. ,  0.5,  1. ,  1.5])
+
+Stretching
+==========
+
+In addition to classes that can scale values to the [0:1] range, a number of
+classes are provide to 'stretch' the values using different functions. These
+map a [0:1] range onto a transformed [0:1] range. A simple example is the
+:class:`~astropy.visualization.SqrtStretch` class::
+
+    >>> from astropy.visualization import SqrtStretch
+    >>> stretch = SqrtStretch()
+    >>> stretch([0., 0.25, 0.5, 0.75, 1.])
+    array([ 0.        ,  0.5       ,  0.70710678,  0.8660254 ,  1.        ])
+
+As for the intervals, values outside the [0:1] range can be treated differently
+depending on the ``clip`` argument. By default, output values are clipped to
+the [0:1] range::
+
+
+    >>> stretch([-1., 0., 0.5, 1., 1.5])
+    array([ 0.       ,  0.        ,  0.70710678,  1.        ,  1.        ])
+
+but this can be disabled::
+
+    >>> stretch([-1., 0., 0.5, 1., 1.5], clip=False)
+    array([        nan,  0.        ,  0.70710678,  1.        ,  1.22474487])
+
+.. note:: The stretch functions are similar but not always strictly identical
+          to those used in e.g. `DS9 <http://ds9.si.edu/site/Home.html>`_
+          (although they should have the same behavior). The equations for the
+          DS9 stretches can be found `here <http://ds9.si.edu/ref/how.html>`_
+          and can be compared to the equations for our stretches provided in
+          the `astropy.visualization` API section. The main difference between our
+          stretches and DS9 is that we have adjusted them so that the [0:1]
+          range always maps exactly to the [0:1] range.
+
+Combining transformations
+=========================
+
+Any stretches and intervals can be chained by using the ``+`` operator, which
+returns a new transformation. For example, to apply normalization based on a
+percentile value, followed by a square root stretch, you can do::
+
+    >>> transform = SqrtStretch() + PercentileInterval(90.)
+    >>> transform([1, 3, 4, 5, 6])
+    array([ 0.        ,  0.60302269,  0.76870611,  0.90453403,  1.        ])
+    
+As before, the combined transformation can also accept a ``clip`` argument
+(which is `True` by default).
+
+Matplotlib normalization
+========================
+
+Matplotlib allows a custom normalization and stretch to be used when showing
+data, and requires a :class:`~matplotlib.colors.Normalize` object to be passed
+to e.g. :meth:`~matplotlib.axes.Axes.imshow`. The `astropy.visualization` module
+provides a class, :class:`~astropy.visualization.mpl_normalize.ImageNormalize`, which wraps the
+stretch functions from `Stretching`_ into an object Matplotlib understands. The
+:class:`~astropy.visualization.mpl_normalize.ImageNormalize` class takes the limits (which you
+can determine from the `Intervals and Normalization`_ classes) and the stretch
+instance:
+
+.. plot::
+   :include-source:
+   :align: center
+
+    import numpy as np
+    import matplotlib.pyplot as plt
+
+    from astropy.visualization import SqrtStretch
+    from astropy.visualization.mpl_normalize import ImageNormalize
+
+    # Generate test image
+    image = np.arange(65536).reshape((256, 256))
+
+    # Create normalizer object
+    norm = ImageNormalize(vmin=0., vmax=65536, stretch=SqrtStretch())
+
+    # Make the figure
+    fig = plt.figure()
+    ax = fig.add_subplot(1,1,1)
+    im = ax.imshow(image, norm=norm)
+    fig.colorbar(im)
+
+As shown above, the colorbar ticks are automatically adjusted.
\ No newline at end of file
diff --git a/docs/wcs/index.rst b/docs/wcs/index.rst
index 6e5b121..aeb37a6 100644
--- a/docs/wcs/index.rst
+++ b/docs/wcs/index.rst
@@ -171,6 +171,29 @@ through `Wcsprm.cunit <astropy.wcs.Wcsprm.cunit>`), for example,
 - ``HPX``: HEALPix
 - ``XPH``: HEALPix polar, aka "butterfly"
 
+Subsetting and Pixel Scales
+===========================
+
+WCS objects can be broken apart into their constituent axes using the
+`~astropy.wcs.WCS.sub` function.  There is also a `~astropy.wcs.WCS.celestial`
+convenience function that will return a WCS object with only the celestial axes
+included.
+
+The pixel scales of a celestial image or the pixel dimensions of a non-celestial
+image can be extracted with the utility functions
+`~astropy.wcs.utils.proj_plane_pixel_scales` and
+`~astropy.wcs.utils.non_celestial_pixel_scales`. Likewise, celestial pixel
+area can be extracted with the utility function
+`~astropy.wcs.utils.proj_plane_pixel_area`.
+
+Matplotlib plots with correct WCS projection
+============================================
+
+The `WCSAxes <http://wcsaxes.readthedocs.org>`_ affiliated package adds the
+ability to use the :class:`~astropy.wcs.WCS` to define projections in
+Matplotlib. More information on installing and using WCSAxes can be found `here
+<http://wcsaxes.readthedocs.org>`__.
+
 Other information
 =================
 
@@ -192,6 +215,7 @@ Reference/API
 
 .. automodapi:: astropy.wcs
 
+.. automodapi:: astropy.wcs.utils
 
 Acknowledgments and Licenses
 ============================
diff --git a/docs/whatsnew/0.4.rst b/docs/whatsnew/0.4.rst
index 155c884..e07161c 100644
--- a/docs/whatsnew/0.4.rst
+++ b/docs/whatsnew/0.4.rst
@@ -150,7 +150,7 @@ rather than the intended public API location.
 
 This will affect URLs pointing to specific documentation pages.  For
 example, this URL points to the v0.3 location of the
-`astropy.cosmology.luminosity_distance` function:
+``astropy.cosmology.luminosity_distance`` function:
 
 * http://docs.astropy.org/en/v0.3/api/astropy.cosmology.funcs.luminosity_distance.html
 
diff --git a/docs/whatsnew/1.0.rst b/docs/whatsnew/1.0.rst
new file mode 100644
index 0000000..6056582
--- /dev/null
+++ b/docs/whatsnew/1.0.rst
@@ -0,0 +1,247 @@
+.. doctest-skip-all
+
+.. _whatsnew-1.0:
+
+==========================
+What's New in Astropy 1.0?
+==========================
+
+Overview
+--------
+
+
+About Long-term support
+-----------------------
+
+Astropy v1.0 is a long-term support (LTS) release.  This means v1.0 will
+be supported with bug fixes for 2 years from its release, rather than 6
+months like the non-LTS releases. More details about this, including a
+wider rationale for Astropy's version numbering scheme, can be found in
+`Astropy Proposal for Enhancement 2  <https://github.com/astropy/astropy-APEs/blob/master/APE2.rst>`_.
+
+Support for Alt/Az coordinates
+------------------------------
+
+The `~astropy.coordinates` package now supports conversion to/from AltAz
+coordinates.  This means `~astropy.coordinates` can now be used for planning
+observations.  For example::
+
+    >>> from astropy import units as u
+    >>> from astropy.time import Time
+    >>> from astropy.coordinates import SkyCoord, EarthLocation, AltAz
+    >>> greenwich = EarthLocation(lat=51.477*u.deg,lon=0*u.deg)
+    >>> albireo = SkyCoord('19h30m43.2805s +27d57m34.8483s')
+    >>> altaz = albireo.transform_to(AltAz(location=greenwich, obstime=Time('2014-6-21 0:00')))
+    >>> print altaz.alt, altaz.az
+    60d32m28.4576s 133d45m36.4967s
+
+For a more detailed outline of this new functionality, see the
+:ref:`observing-example` and the `~astropy.coordinates.AltAz` documentation.
+
+To enable this functionality, `~astropy.coordinates` now also contains
+the full IAU-sanctioned coordinate transformation stack from ICRS to AltAz.
+To view the full set of coordinate frames now available, see the coordinates
+:ref:`astropy-coordinates-api`.
+
+
+New Galactocentric coordinate frame
+-----------------------------------
+
+Added a new, customizable :class:`~astropy.coordinates.Galactocentric`
+coordinate frame. The other coordinate frames (e.g.,
+:class:`~astropy.coordinates.ICRS`, :class:`~astropy.coordinates.Galactic`)
+are all Heliocentric (or barycentric). The center of this new coordinate frame
+is at the center of the Galaxy, with customizable parameters allowing the user
+to specify the distance to the Galactic center (``galcen_distance``), the
+ICRS position of the Galactic center (``galcen_ra``, ``galcen_dec``), the
+height of the Sun above the Galactic midplane (``z_sun``), and a final roll
+angle that allows for specifying the orientation of the z axis (``roll``)::
+
+    >>> from astropy import units as u
+    >>> from astropy.coordinates import SkyCoord, Galactocentric
+    >>> c = SkyCoord(ra=152.718 * u.degree,
+    ...              dec=-11.214 * u.degree,
+    ...              distance=21.5 * u.kpc)
+    >>> c.transform_to(Galactocentric)
+    <SkyCoord (Galactocentric: galcen_distance=8.3 kpc, galcen_ra=266d24m18.36s, galcen_dec=-28d56m10.23s, z_sun=27.0 pc, roll=0.0 deg): (x, y, z) in kpc
+        (-13.6512648452, -16.6847348677, 12.4862582821)>
+    >>> c.transform_to(Galactocentric(galcen_distance=8*u.kpc, z_sun=15*u.pc))
+    <SkyCoord (Galactocentric: galcen_distance=8.0 kpc, galcen_ra=266d24m18.36s, galcen_dec=-28d56m10.23s, z_sun=15.0 pc, roll=0.0 deg): (x, y, z) in kpc
+        (-13.368458678, -16.6847348677, 12.466872262)>
+
+New :ref:`astropy-visualization` subpackage
+-------------------------------------------
+
+The new :ref:`Data Visualization <astropy-visualization>` package is intended
+to collect functionality that can be helpful when visualizing data. At the
+moment, the main functionality is image normalizing (including both scaling and
+stretching) but this will be expanded in future. Included in the image
+normalization functionality is the ability to compute interval limits on data,
+(such as percentile limits), stretching with non-linear functions (such as
+square root or arcsinh functions), and the ability to use custom stretches in
+`Matplotlib <http://www.matplotlib.org>`_ that are correctly reflected in the
+colorbar:
+
+.. plot::
+   :include-source:
+   :align: center
+
+    import numpy as np
+    import matplotlib.pyplot as plt
+
+    from astropy.visualization import SqrtStretch
+    from astropy.visualization.mpl_normalize import ImageNormalize
+
+    # Generate test image
+    image = np.arange(65536).reshape((256, 256))
+
+    # Create normalizer object
+    norm = ImageNormalize(vmin=0., vmax=65536, stretch=SqrtStretch())
+
+    fig = plt.figure(figsize=(6,3))
+    ax = fig.add_subplot(1,1,1)
+    im = ax.imshow(image, norm=norm, origin='lower', aspect='auto')
+    fig.colorbar(im)
+
+New :ref:`astropy_analytic_functions` subpackage
+------------------------------------------------
+
+This subpackage provides analytic functions that are commonly used in
+astronomy. These already understand `~astropy.units.Quantity`, i.e., they can
+handle units of input and output parameters. For instance, to calculate the
+blackbody flux for 10000K at 6000 Angstrom:
+
+>>> astropy import units as u
+>>> from astropy.analytic_functions import blackbody_lambda, blackbody_nu
+>>> blackbody_lambda(6000 * u.AA, 10000 * u.K)
+<Quantity 15315791.836941158 erg / (Angstrom cm2 s sr)>
+>>> blackbody_nu(6000 * u.AA, 10000 * u.K)
+<Quantity 0.00018391673686797075 erg / (cm2 Hz s sr)
+
+See :ref:`astropy_analytic_functions` for more details.
+
+In future versions of Astropy, the functions in this module might also be
+accessible as `~astropy.modeling.Model` classes.
+
+Fast readers/writers for ASCII files
+------------------------------------
+
+The :mod:`astropy.io.ascii` module now includes a significantly faster Cython/C engine
+for reading and writing ASCII files.  This is available for the following
+formats: ``basic``, ``commented_header``, ``csv``, ``no_header``, ``rdb``, and
+``tab``.  On average the new engine is about 4 to 5 times faster than the
+corresponding pure-Python implementation, and is often comparable to the speed
+of the `pandas <http://pandas.pydata.org/pandas-docs/stable/>`_ ASCII file
+interface (`read_csv
+<http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table>`_ and
+`to_csv
+<http://pandas.pydata.org/pandas-docs/stable/io.html#io-store-in-csv>`_).  The
+fast reader has parallel processing option that allows harnessing multiple
+cores for input parsing to achieve even greater speed gains.
+
+By default, :func:`~astropy.io.ascii.read` and :func:`~astropy.io.ascii.write`
+will attempt to use the fast C engine when dealing with compatible formats.
+Certain features of the full read / write interface are not available in the
+fast version, in which case the pure-Python version will automatically be used.
+
+For full details including extensive performance testing, see :ref:`fast_ascii_io`.
+
+New features in :ref:`astropy-modeling`
+---------------------------------------
+
+New subclasses of `~astropy.modeling.Model` are now a bit easier to define,
+requiring less boilerplate code in general.  Now all that is necessary to
+define a new model class is an `~astropy.modeling.Model.evaluate` method that
+computes the model.  Optionally one can define :ref:`fittable parameters
+<modeling-parameters>`, a `~astropy.modeling.FittableModel.fit_deriv`, and/or
+an `~astropy.modeling.Model.inverse`.  The new, improved
+`~astropy.modeling.custom_model` decorator reduces to boilerplate needed for
+many models even more.  See :ref:`modeling-new-classes` for more details.
+
+Array broadcasting has also been improved, enabling a broader range of
+possibilities for the values of model parameters and inputs.  Support has also
+been improved for :ref:`modeling-model-sets` (previously referred to as
+parameter sets) which can be thought of like an array of models of the same
+class, each with different sets of parameters, which can be fitted
+simultaneously either to the same data, or to different data sets per model.
+See :ref:`modeling-instantiating` for more details.
+
+It is now possible to create *compound* models by combining existing models
+using the standard arithmetic operators such as ``+`` and ``*``, as well as
+functional composition using the ``|`` operator.  This provides a powerful
+and flexible new way to create more complex models without having to define
+any special classes or functions.  For example::
+
+    >>> from astropy.modeling.models import Gaussian1D
+    >>> gaussian1 = Gaussian1D(1, 0, 0.2)
+    >>> gaussian2 = Gaussian1D(2.5, 0.5, 0.1)
+    >>> sum_of_gaussians = gaussian1 + gaussian2
+
+The resulting model works like any other model, and also works with the
+fitting framework.  See the
+:ref:`introduction to compound models <compound-models-intro>` and full
+:ref:`compound models documentation <compound-models>` for more examples.
+
+Support for 'mixin' columns in :ref:`astropy-table`
+---------------------------------------------------
+
+.. |Quantity| replace:: :class:`~astropy.units.Quantity`
+.. |Time| replace:: :class:`~astropy.time.Time`
+.. |SkyCoord| replace:: :class:`~astropy.coordinates.SkyCoord`
+.. |Table| replace:: :class:`~astropy.table.Table`
+.. |Column| replace:: :class:`~astropy.table.Column`
+.. |QTable| replace:: :class:`~astropy.table.QTable`
+
+Version 1.0 of astropy introduces a new concept of the "Mixin
+Column" in tables which allows integration of appropriate non-|Column| based
+class objects within a |Table| object.  These mixin column objects are not
+converted in any way but are used natively.
+
+The available built-in mixin column classes are |Quantity|, |SkyCoord|, and
+|Time|.  User classes for array-like objects that support the
+:ref:`mixin_protocol` can also be used in tables as mixin columns.
+
+.. Warning::
+
+   While the astropy developers are excited about this new capability and
+   intend to improve it, the interface for using mixin columns is not stable at
+   this point and it is not recommended for use in production code.
+
+As an example we can create a table and add a time column::
+
+  >>> from astropy.table import Table
+  >>> from astropy.time import Time
+  >>> t = Table()
+  >>> t['index'] = [1, 2]
+  >>> t['time'] = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02'])
+  >>> print(t)
+  index           time
+  ----- -----------------------
+      1 2001-01-02T12:34:56.000
+      2 2001-02-03T00:01:02.000
+
+The important point here is that the ``time`` column is a bona fide |Time| object::
+
+  >>> t['time']
+  <Time object: scale='utc' format='isot' value=['2001-01-02T12:34:56.000' '2001-02-03T00:01:02.000']>
+  >>> t['time'].mjd
+  array([ 51911.52425926,  51943.00071759])
+
+For all the details, including a new |QTable| class, please see :ref:`mixin_columns`.
+
+Deprecation and backward-incompatible changes
+---------------------------------------------
+
+.. Dropped support for Numpy 1.5
+.. Other big API changes
+
+Full change log
+---------------
+
+To see a detailed list of all changes in version 1.0 and prior, please see the
+:ref:`changelog`.
+
+Note on future versions
+-----------------------
+
+
diff --git a/docs/whatsnew/index.rst b/docs/whatsnew/index.rst
index 8c3310b..cc9d0d3 100644
--- a/docs/whatsnew/index.rst
+++ b/docs/whatsnew/index.rst
@@ -5,6 +5,7 @@ Major Release History
 .. toctree::
    :maxdepth: 1
 
+   1.0
    0.4
    0.3
    0.2
diff --git a/licenses/NUMPY_LICENSE.rst b/licenses/NUMPY_LICENSE.rst
new file mode 100644
index 0000000..7e972cf
--- /dev/null
+++ b/licenses/NUMPY_LICENSE.rst
@@ -0,0 +1,30 @@
+Copyright (c) 2005-2011, NumPy Developers.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+
+    * Neither the name of the NumPy Developers nor the names of any
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/scripts/README.rst b/scripts/README.rst
deleted file mode 100644
index dc9cf3b..0000000
--- a/scripts/README.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Scripts
-=======
-
-This directory contains command-line scripts used by the astropy package.
-
diff --git a/scripts/fitscheck b/scripts/fitscheck
deleted file mode 100755
index 514b2e8..0000000
--- a/scripts/fitscheck
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /usr/bin/env python
-
-import astropy.io.fits.scripts.fitscheck
-import sys
-
-
-if __name__ == '__main__':
-    sys.exit(astropy.io.fits.scripts.fitscheck.main())
diff --git a/scripts/fitsdiff b/scripts/fitsdiff
deleted file mode 100755
index b848131..0000000
--- a/scripts/fitsdiff
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /usr/bin/env python
-
-import astropy.io.fits.scripts.fitsdiff
-import sys
-
-
-if __name__ == '__main__':
-    sys.exit(astropy.io.fits.scripts.fitsdiff.main())
diff --git a/scripts/fitsheader b/scripts/fitsheader
deleted file mode 100755
index 0da3300..0000000
--- a/scripts/fitsheader
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-
-import astropy.io.fits.scripts.fitsheader
-
-astropy.io.fits.scripts.fitsheader.main()
diff --git a/scripts/samp_hub b/scripts/samp_hub
deleted file mode 100755
index 5fde941..0000000
--- a/scripts/samp_hub
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env python
-from astropy.vo.samp.hub_script import hub_script
-hub_script()
-
diff --git a/scripts/volint b/scripts/volint
deleted file mode 100755
index 899600e..0000000
--- a/scripts/volint
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-
-import astropy.io.votable.volint
-
-astropy.io.votable.volint.main()
diff --git a/scripts/wcslint b/scripts/wcslint
deleted file mode 100755
index f1fa44e..0000000
--- a/scripts/wcslint
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-
-import astropy.wcs.wcslint
-
-astropy.wcs.wcslint.main()
diff --git a/setup.cfg b/setup.cfg
index ec3c62d..80f2c25 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -23,3 +23,14 @@ bitmap = static/wininst_background.bmp
 
 [ah_bootstrap]
 auto_use = True
+
+[pep8]
+# E101 - mix of tabs and spaces
+# W191 - use of tabs
+# W291 - trailing whitespace
+# W293 - trailing whitespace
+# E111 - 4 spaces per indentation level
+# E112 - 4 spaces per indentation level
+# E113 - 4 spaces per indentation level
+select = E101,W191,W291,W293,E111,E112,E113
+exclude = extern,sphinx,*parsetab.py
diff --git a/setup.py b/setup.py
index 549756c..7fcfe08 100755
--- a/setup.py
+++ b/setup.py
@@ -17,15 +17,15 @@ builtins._ASTROPY_SETUP_ = True
 
 import astropy
 from astropy_helpers.setup_helpers import (
-    register_commands, adjust_compiler, get_package_info, get_debug_option,
-    is_distutils_display_option)
+    register_commands, adjust_compiler, get_package_info, get_debug_option)
+from astropy_helpers.distutils_helpers import is_distutils_display_option
 from astropy_helpers.git_helpers import get_git_devstr
 from astropy_helpers.version_helpers import generate_version_py
 
 NAME = 'astropy'
 
 # VERSION should be PEP386 compatible (http://www.python.org/dev/peps/pep-0386)
-VERSION = '0.4.4'
+VERSION = '1.0rc1'
 
 # Indicates if this version is a release version
 RELEASE = 'dev' not in VERSION
@@ -47,10 +47,6 @@ adjust_compiler(NAME)
 # Freeze build information in version.py
 generate_version_py(NAME, VERSION, RELEASE, get_debug_option(NAME))
 
-# Treat everything in scripts except README.rst as a script to be installed
-scripts = [fname for fname in glob.glob(os.path.join('scripts', '*'))
-           if os.path.basename(fname) != 'README.rst']
-
 # Get configuration information from all of the various subpackages.
 # See the docstring for setup_helpers.update_package_files for more
 # details.
@@ -69,6 +65,16 @@ for hook in [('prereleaser', 'middle'), ('releaser', 'middle'),
     hook_func = 'astropy.utils.release:' + '_'.join(hook)
     entry_points[hook_ep] = ['%s = %s' % (hook_name, hook_func)]
 
+# Command-line scripts
+entry_points['console_scripts'] = [
+    'fits2bitmap = astropy.visualization.scripts.fits2bitmap:main',
+    'fitscheck = astropy.io.fits.scripts.fitscheck:main',
+    'fitsdiff = astropy.io.fits.scripts.fitsdiff:main',
+    'fitsheader = astropy.io.fits.scripts.fitsheader:main',
+    'samp_hub = astropy.vo.samp.hub_script:hub_script',
+    'volint = astropy.io.votable.volint:main',
+    'wcslint = astropy.wcs.wcslint:main',
+]
 
 setup_requires = ['numpy>=' + astropy.__minimum_numpy_version__]
 install_requires = ['numpy>=' + astropy.__minimum_numpy_version__]
@@ -81,7 +87,6 @@ if is_distutils_display_option():
 setup(name=NAME,
       version=VERSION,
       description='Community-developed python astronomy tools',
-      scripts=scripts,
       requires=['numpy'],  # scipy not required, but strongly recommended
       setup_requires=setup_requires,
       install_requires=install_requires,
@@ -107,7 +112,7 @@ setup(name=NAME,
       ],
       cmdclass=cmdclassd,
       zip_safe=False,
-      use_2to3=True,
+      use_2to3=False,
       entry_points=entry_points,
       **package_info
 )

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/python-astropy.git



More information about the debian-science-commits mailing list